summaryrefslogtreecommitdiffstats
path: root/build/build-clang
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 00:47:55 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 00:47:55 +0000
commit26a029d407be480d791972afb5975cf62c9360a6 (patch)
treef435a8308119effd964b339f76abb83a57c29483 /build/build-clang
parentInitial commit. (diff)
downloadfirefox-e51783d008170d9ab27d25da98ca3a38b0a41b67.tar.xz
firefox-e51783d008170d9ab27d25da98ca3a38b0a41b67.zip
Adding upstream version 124.0.1.upstream/124.0.1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'build/build-clang')
-rw-r--r--build/build-clang/1stage.json4
-rw-r--r--build/build-clang/2stages.json3
-rw-r--r--build/build-clang/4stages-pgo.json7
-rw-r--r--build/build-clang/D146664.patch99
-rw-r--r--build/build-clang/README53
-rw-r--r--build/build-clang/Remove-FlushViewOfFile-when-unmaping-gcda-files.patch31
-rw-r--r--build/build-clang/allow-unversioned-android.patch36
-rw-r--r--build/build-clang/android-mangling-error_clang_12.patch24
-rwxr-xr-xbuild/build-clang/build-clang.py843
-rw-r--r--build/build-clang/clang-14.json13
-rw-r--r--build/build-clang/clang-17.json18
-rw-r--r--build/build-clang/clang-18.json21
-rw-r--r--build/build-clang/clang-8-missing-header.patch12
-rw-r--r--build/build-clang/clang-8.0.json10
-rw-r--r--build/build-clang/clang-tidy-ci.patch34
-rw-r--r--build/build-clang/clang-tidy-external-linux64.json11
-rw-r--r--build/build-clang/clang-tidy-linux64.json10
-rw-r--r--build/build-clang/clang-tidy-macosx64.json7
-rw-r--r--build/build-clang/clang-tidy-win64.json7
-rw-r--r--build/build-clang/clang-trunk.json21
-rw-r--r--build/build-clang/compiler-rt-rss-limit-heap-profile.patch49
-rw-r--r--build/build-clang/downgrade-mangling-error_clang_12.patch23
-rw-r--r--build/build-clang/find_symbolizer_linux_clang_10.patch58
-rw-r--r--build/build-clang/find_symbolizer_linux_clang_15.patch53
-rw-r--r--build/build-clang/fuzzing_ccov_build_clang_12.patch27
-rw-r--r--build/build-clang/linux64.json5
-rw-r--r--build/build-clang/llvmorg-10-init-136-gb288d90b39f4.patch37
-rw-r--r--build/build-clang/llvmorg-15-init-16512-g4b1e3d193706.patch138
-rw-r--r--build/build-clang/macosx64-aarch64.json3
-rw-r--r--build/build-clang/macosx64.json9
-rw-r--r--build/build-clang/partial-revert-llvmorg-16-init-17151-gaa0883b59ae1_clang_17.patch13
-rw-r--r--build/build-clang/partial-revert-llvmorg-17-init-17713-gc8e055d485ea.patch33
-rw-r--r--build/build-clang/profile.json6
-rw-r--r--build/build-clang/revert-llvmorg-15-init-11205-gcead4eceb01b_clang_16.patch1027
-rw-r--r--build/build-clang/revert-llvmorg-15-init-11205-gcead4eceb01b_clang_18.patch972
-rw-r--r--build/build-clang/revert-llvmorg-15-init-13446-g7524fe962e47.patch39
-rw-r--r--build/build-clang/revert-llvmorg-16-init-11301-g163bb6d64e5f_clang_17.patch172
-rw-r--r--build/build-clang/revert-llvmorg-16-init-11301-g163bb6d64e5f_clang_18.patch183
-rw-r--r--build/build-clang/revert-llvmorg-17-init-4120-g02e8eb1a438b.patch118
-rw-r--r--build/build-clang/revert-llvmorg-17-init-4120-g02e8eb1a438b_clang_18.patch115
-rw-r--r--build/build-clang/revert-llvmorg-18-init-6188-gc649f29c24c9.patch466
-rw-r--r--build/build-clang/revert-llvmorg-18-init-6193-gb88cffeafd39.patch63
-rw-r--r--build/build-clang/revert-llvmorg-18-init-6208-g2baf4a06ef06.patch28
-rw-r--r--build/build-clang/skip-3-stages.json6
-rw-r--r--build/build-clang/skip-stage-1-win64.json7
-rw-r--r--build/build-clang/skip-stage-1.json6
-rw-r--r--build/build-clang/unpoison-thread-stacks_clang_10.patch64
-rw-r--r--build/build-clang/win64-ret-null-on-commitment-limit_clang_14.patch14
-rw-r--r--build/build-clang/win64.json7
49 files changed, 5005 insertions, 0 deletions
diff --git a/build/build-clang/1stage.json b/build/build-clang/1stage.json
new file mode 100644
index 0000000000..4633a3e93e
--- /dev/null
+++ b/build/build-clang/1stage.json
@@ -0,0 +1,4 @@
+{
+ "stages": "1",
+ "targets": "X86;ARM;AArch64;WebAssembly"
+}
diff --git a/build/build-clang/2stages.json b/build/build-clang/2stages.json
new file mode 100644
index 0000000000..e34226758d
--- /dev/null
+++ b/build/build-clang/2stages.json
@@ -0,0 +1,3 @@
+{
+ "stages": "2"
+}
diff --git a/build/build-clang/4stages-pgo.json b/build/build-clang/4stages-pgo.json
new file mode 100644
index 0000000000..8f0c5aa97d
--- /dev/null
+++ b/build/build-clang/4stages-pgo.json
@@ -0,0 +1,7 @@
+{
+ "stages": "4",
+ "targets": "X86;ARM;AArch64;WebAssembly",
+ "pgo": true,
+ "ranlib": "{MOZ_FETCHES_DIR}/clang/bin/llvm-ranlib",
+ "ar": "{MOZ_FETCHES_DIR}/clang/bin/llvm-ar"
+}
diff --git a/build/build-clang/D146664.patch b/build/build-clang/D146664.patch
new file mode 100644
index 0000000000..9813c6c86e
--- /dev/null
+++ b/build/build-clang/D146664.patch
@@ -0,0 +1,99 @@
+From b57ff6da9c8b281ae9312e245fd3372e7ffaff28 Mon Sep 17 00:00:00 2001
+From: Mike Hommey <mh@glandium.org>
+Date: Thu, 23 Mar 2023 06:52:28 +0900
+Subject: [PATCH] Apply the same fallbacks as runtimes search for stdlib search
+
+When building clang with e.g. LLVM_ENABLE_RUNTIMES=libcxx;libunwind,
+those runtimes end up in the stdlib search directory, and when
+LLVM_ENABLE_PER_TARGET_RUNTIME_DIR is set, that ends up in a
+target-specific subdirectory. The stdlib search does handle the
+situation, but when the target in question is Android, the same issues
+as those that required fallbacks for runtimes search apply.
+
+Traditionally, those libraries are shipped as part of the Android NDK,
+but when one builds their own clang for Android, they may want to use
+the runtimes from the same version rather than the ones from the NDK.
+
+Differential Revision: https://reviews.llvm.org/D146664
+---
+ clang/lib/Driver/ToolChain.cpp | 42 +++++++++++++++++++---------------
+ 1 file changed, 24 insertions(+), 18 deletions(-)
+
+diff --git a/clang/lib/Driver/ToolChain.cpp b/clang/lib/Driver/ToolChain.cpp
+index 2dba975a5a8f..9052099cad5e 100644
+--- a/clang/lib/Driver/ToolChain.cpp
++++ b/clang/lib/Driver/ToolChain.cpp
+@@ -569,15 +569,9 @@ const char *ToolChain::getCompilerRTArgString(const llvm::opt::ArgList &Args,
+ return Args.MakeArgString(getCompilerRT(Args, Component, Type));
+ }
+
+-ToolChain::path_list ToolChain::getRuntimePaths() const {
+- path_list Paths;
+- auto addPathForTriple = [this, &Paths](const llvm::Triple &Triple) {
+- SmallString<128> P(D.ResourceDir);
+- llvm::sys::path::append(P, "lib", Triple.str());
+- Paths.push_back(std::string(P.str()));
+- };
+-
+- addPathForTriple(getTriple());
++template <typename F>
++static void fillPaths(const ToolChain &TC, F addPathForTriple) {
++ addPathForTriple(TC.getTriple());
+
+ // When building with per target runtime directories, various ways of naming
+ // the Arm architecture may have been normalised to simply "arm".
+@@ -594,30 +588,42 @@ ToolChain::path_list ToolChain::getRuntimePaths() const {
+ //
+ // M profile Arm is bare metal and we know they will not be using the per
+ // target runtime directory layout.
+- if (getTriple().getArch() == Triple::arm && !getTriple().isArmMClass()) {
+- llvm::Triple ArmTriple = getTriple();
++ if (TC.getTriple().getArch() == Triple::arm &&
++ !TC.getTriple().isArmMClass()) {
++ llvm::Triple ArmTriple = TC.getTriple();
+ ArmTriple.setArch(Triple::arm);
+ addPathForTriple(ArmTriple);
+ }
+
+ // Android targets may include an API level at the end. We still want to fall
+ // back on a path without the API level.
+- if (getTriple().isAndroid() &&
+- getTriple().getEnvironmentName() != "android") {
+- llvm::Triple TripleWithoutLevel = getTriple();
++ if (TC.getTriple().isAndroid() &&
++ TC.getTriple().getEnvironmentName() != "android") {
++ llvm::Triple TripleWithoutLevel = TC.getTriple();
+ TripleWithoutLevel.setEnvironmentName("android");
+ addPathForTriple(TripleWithoutLevel);
+ }
++}
+
++ToolChain::path_list ToolChain::getRuntimePaths() const {
++ path_list Paths;
++ auto addPathForTriple = [this, &Paths](const llvm::Triple &Triple) {
++ SmallString<128> P(D.ResourceDir);
++ llvm::sys::path::append(P, "lib", Triple.str());
++ Paths.push_back(std::string(P.str()));
++ };
++ fillPaths(*this, addPathForTriple);
+ return Paths;
+ }
+
+ ToolChain::path_list ToolChain::getStdlibPaths() const {
+ path_list Paths;
+- SmallString<128> P(D.Dir);
+- llvm::sys::path::append(P, "..", "lib", getTripleString());
+- Paths.push_back(std::string(P.str()));
+-
++ auto addPathForTriple = [this, &Paths](const llvm::Triple &Triple) {
++ SmallString<128> P(D.Dir);
++ llvm::sys::path::append(P, "..", "lib", Triple.str());
++ Paths.push_back(std::string(P.str()));
++ };
++ fillPaths(*this, addPathForTriple);
+ return Paths;
+ }
+
+--
+2.39.0.1.g6739ec1790
+
diff --git a/build/build-clang/README b/build/build-clang/README
new file mode 100644
index 0000000000..5b13edeeb9
--- /dev/null
+++ b/build/build-clang/README
@@ -0,0 +1,53 @@
+build-clang.py
+==============
+
+A script to build clang from source.
+
+```
+usage: build-clang.py [-h] -c CONFIG [--clean]
+
+optional arguments:
+ -h, --help show this help message and exit
+ -c CONFIG, --config CONFIG
+ Clang configuration file
+ --clean Clean the build directory
+```
+
+Pre-requisites
+--------------
+* Working build toolchain.
+* git
+* CMake
+* Ninja
+* Python 2.7 and 3
+
+Please use the latest available CMake for your platform to avoid surprises.
+
+Config file format
+------------------
+
+build-clang.py accepts a JSON config format with the following fields:
+
+* stages: Use 1, 2, 3 or 4 to select different compiler stages. The default is 2.
+* cc: Path to the bootsraping C Compiler.
+* cxx: Path to the bootsraping C++ Compiler.
+* as: Path to the assembler tool.
+* ar: Path to the library archiver tool.
+* ranlib: Path to the ranlib tool (optional).
+* ld: Path to the linker.
+* patches: Optional list of patches to apply.
+* build_type: The type of build to make. Supported types: Release, Debug, RelWithDebInfo or MinSizeRel.
+* targets: The targets supported by the final stage LLVM/clang.
+* build_clang_tidy: Whether to build clang-tidy with the Mozilla checks imported. The default is false.
+* osx_cross_compile: Whether to invoke CMake for OS X cross compile builds.
+* assertions: Whether to enable LLVM assertions. The default is false.
+* pgo: Whether to build with PGO (requires stages == 4). The default is false.
+
+The revisions are defined in taskcluster/ci/fetch/toolchains.yml. They are usually commit sha1s corresponding to upstream tags.
+
+Environment Variables
+---------------------
+
+The following environment variables are used for cross-compile builds targeting OS X on Linux.
+
+* CROSS_SYSROOT: Path to the OS X SDK directory for cross compile builds.
diff --git a/build/build-clang/Remove-FlushViewOfFile-when-unmaping-gcda-files.patch b/build/build-clang/Remove-FlushViewOfFile-when-unmaping-gcda-files.patch
new file mode 100644
index 0000000000..a3ea2d75f9
--- /dev/null
+++ b/build/build-clang/Remove-FlushViewOfFile-when-unmaping-gcda-files.patch
@@ -0,0 +1,31 @@
+From 78a6bcfed4b73f13b9973afd69b76067dd4a5dde Mon Sep 17 00:00:00 2001
+From: Calixte Denizet <calixte.denizet@gmail.com>
+Date: Mon, 4 Oct 2021 11:07:56 +0200
+Subject: [PATCH] Remove FlushViewOfFile when unmaping gcda files - it can
+ causes bad performances with slow disks; - MS docs say that it's mainly
+ useful in case of hard failures (OS crash, electrical failure, ...): so it's
+ useless to call this function when ccov builds run on CI.
+
+---
+ compiler-rt/lib/profile/GCDAProfiling.c | 5 -----
+ 1 file changed, 5 deletions(-)
+
+diff --git a/compiler-rt/lib/profile/GCDAProfiling.c b/compiler-rt/lib/profile/GCDAProfiling.c
+index 4293e8f7b5bf..83650d33c95d 100644
+--- a/compiler-rt/lib/profile/GCDAProfiling.c
++++ b/compiler-rt/lib/profile/GCDAProfiling.c
+@@ -286,11 +286,6 @@ static int map_file() {
+
+ static void unmap_file() {
+ #if defined(_WIN32)
+- if (!FlushViewOfFile(write_buffer, file_size)) {
+- fprintf(stderr, "profiling: %s: cannot flush mapped view: %lu\n", filename,
+- GetLastError());
+- }
+-
+ if (!UnmapViewOfFile(write_buffer)) {
+ fprintf(stderr, "profiling: %s: cannot unmap mapped view: %lu\n", filename,
+ GetLastError());
+--
+2.33.0
+
diff --git a/build/build-clang/allow-unversioned-android.patch b/build/build-clang/allow-unversioned-android.patch
new file mode 100644
index 0000000000..afd82bfc25
--- /dev/null
+++ b/build/build-clang/allow-unversioned-android.patch
@@ -0,0 +1,36 @@
+diff --git a/clang/lib/Driver/ToolChain.cpp b/clang/lib/Driver/ToolChain.cpp
+index 31245964c4ba..dbdccd95bb4f 100644
+--- a/clang/lib/Driver/ToolChain.cpp
++++ b/clang/lib/Driver/ToolChain.cpp
+@@ -689,7 +689,6 @@ ToolChain::getFallbackAndroidTargetPath(StringRef BaseDir) const {
+ unsigned BestVersion = 0;
+
+ SmallString<32> TripleDir;
+- bool UsingUnversionedDir = false;
+ std::error_code EC;
+ for (llvm::vfs::directory_iterator LI = getVFS().dir_begin(BaseDir, EC), LE;
+ !EC && LI != LE; LI = LI.increment(EC)) {
+@@ -698,14 +697,12 @@ ToolChain::getFallbackAndroidTargetPath(StringRef BaseDir) const {
+ if (DirNameSuffix.consume_front(TripleWithoutLevelStr)) {
+ if (DirNameSuffix.empty() && TripleDir.empty()) {
+ TripleDir = DirName;
+- UsingUnversionedDir = true;
+ } else {
+ unsigned Version;
+ if (!DirNameSuffix.getAsInteger(10, Version) && Version > BestVersion &&
+ Version < TripleVersion) {
+ BestVersion = Version;
+ TripleDir = DirName;
+- UsingUnversionedDir = false;
+ }
+ }
+ }
+@@ -716,8 +713,6 @@ ToolChain::getFallbackAndroidTargetPath(StringRef BaseDir) const {
+
+ SmallString<128> P(BaseDir);
+ llvm::sys::path::append(P, TripleDir);
+- if (UsingUnversionedDir)
+- D.Diag(diag::warn_android_unversioned_fallback) << P << getTripleString();
+ return std::string(P);
+ }
+
diff --git a/build/build-clang/android-mangling-error_clang_12.patch b/build/build-clang/android-mangling-error_clang_12.patch
new file mode 100644
index 0000000000..315756d30b
--- /dev/null
+++ b/build/build-clang/android-mangling-error_clang_12.patch
@@ -0,0 +1,24 @@
+Workaround segfault in clang's mangling code that is tickled when
+attempting to mangle the declaration:
+ std:__ndk1::__find_detail::__find_exactly_one_checked::__matches
+in the <tuple> header in the Android NDK.
+This codepath is exercised by MozsearchIndexer.cpp (the searchfox
+indexer) when indexing on Android. See also
+https://bugs.llvm.org/show_bug.cgi?id=40747
+
+diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp
+index 4420f6a2c1c3..39792e6b7350 100644
+--- a/clang/lib/AST/ItaniumMangle.cpp
++++ b/clang/lib/AST/ItaniumMangle.cpp
+@@ -3954,6 +3954,11 @@ void CXXNameMangler::mangleExpression(const Expr *E, unsigned Arity,
+ // produces no output, where ImplicitlyConvertedToType and AsTemplateArg need
+ // to be preserved.
+ recurse:
++ if (!E) {
++ Out << "MOZ_WE_HACKED_AROUND_BUG_1500941";
++ return;
++ }
++
+ switch (E->getStmtClass()) {
+ case Expr::NoStmtClass:
+ #define ABSTRACT_STMT(Type)
diff --git a/build/build-clang/build-clang.py b/build/build-clang/build-clang.py
new file mode 100755
index 0000000000..08e05483f5
--- /dev/null
+++ b/build/build-clang/build-clang.py
@@ -0,0 +1,843 @@
+#!/usr/bin/python3
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+# Only necessary for flake8 to be happy...
+import argparse
+import errno
+import fnmatch
+import glob
+import json
+import os
+import os.path
+import platform
+import re
+import shutil
+import subprocess
+import sys
+import tarfile
+from contextlib import contextmanager
+from shutil import which
+
+import zstandard
+
+SUPPORTED_TARGETS = {
+ "x86_64-unknown-linux-gnu": ("Linux", "x86_64"),
+ "x86_64-pc-windows-msvc": ("Windows", "AMD64"),
+ "x86_64-apple-darwin": ("Darwin", "x86_64"),
+ "aarch64-apple-darwin": ("Darwin", "arm64"),
+}
+
+
+def is_llvm_toolchain(cc, cxx):
+ return "clang" in cc and "clang" in cxx
+
+
+def check_run(args):
+ print(" ".join(args), file=sys.stderr, flush=True)
+ if args[0] == "cmake":
+ # CMake `message(STATUS)` messages, as appearing in failed source code
+ # compiles, appear on stdout, so we only capture that.
+ p = subprocess.Popen(args, stdout=subprocess.PIPE)
+ lines = []
+ for line in p.stdout:
+ lines.append(line)
+ sys.stdout.write(line.decode())
+ sys.stdout.flush()
+ r = p.wait()
+ if r != 0 and os.environ.get("UPLOAD_DIR"):
+ cmake_output_re = re.compile(b'See also "(.*/CMakeOutput.log)"')
+ cmake_error_re = re.compile(b'See also "(.*/CMakeError.log)"')
+
+ def find_first_match(re):
+ for l in lines:
+ match = re.search(l)
+ if match:
+ return match
+
+ output_match = find_first_match(cmake_output_re)
+ error_match = find_first_match(cmake_error_re)
+
+ upload_dir = os.environ["UPLOAD_DIR"].encode("utf-8")
+ if output_match or error_match:
+ mkdir_p(upload_dir)
+ if output_match:
+ shutil.copy2(output_match.group(1), upload_dir)
+ if error_match:
+ shutil.copy2(error_match.group(1), upload_dir)
+ else:
+ r = subprocess.call(args)
+ assert r == 0
+
+
+def run_in(path, args):
+ with chdir(path):
+ check_run(args)
+
+
+@contextmanager
+def chdir(path):
+ d = os.getcwd()
+ print('cd "%s"' % path, file=sys.stderr)
+ os.chdir(path)
+ try:
+ yield
+ finally:
+ print('cd "%s"' % d, file=sys.stderr)
+ os.chdir(d)
+
+
+def patch(patch, srcdir):
+ patch = os.path.realpath(patch)
+ check_run(["patch", "-d", srcdir, "-p1", "-i", patch, "--fuzz=0", "-s"])
+
+
+def import_clang_tidy(source_dir, build_clang_tidy_alpha, build_clang_tidy_external):
+ clang_plugin_path = os.path.join(os.path.dirname(sys.argv[0]), "..", "clang-plugin")
+ clang_tidy_path = os.path.join(source_dir, "clang-tools-extra/clang-tidy")
+ sys.path.append(clang_plugin_path)
+ from import_mozilla_checks import do_import
+
+ import_options = {
+ "alpha": build_clang_tidy_alpha,
+ "external": build_clang_tidy_external,
+ }
+ do_import(clang_plugin_path, clang_tidy_path, import_options)
+
+
+def build_package(package_build_dir, cmake_args):
+ if not os.path.exists(package_build_dir):
+ os.mkdir(package_build_dir)
+ # If CMake has already been run, it may have been run with different
+ # arguments, so we need to re-run it. Make sure the cached copy of the
+ # previous CMake run is cleared before running it again.
+ if os.path.exists(package_build_dir + "/CMakeCache.txt"):
+ os.remove(package_build_dir + "/CMakeCache.txt")
+ if os.path.exists(package_build_dir + "/CMakeFiles"):
+ shutil.rmtree(package_build_dir + "/CMakeFiles")
+
+ run_in(package_build_dir, ["cmake"] + cmake_args)
+ run_in(package_build_dir, ["ninja", "install", "-v"])
+
+
+@contextmanager
+def updated_env(env):
+ old_env = os.environ.copy()
+ os.environ.update(env)
+ yield
+ os.environ.clear()
+ os.environ.update(old_env)
+
+
+def build_tar_package(name, base, directory):
+ name = os.path.realpath(name)
+ print("tarring {} from {}/{}".format(name, base, directory), file=sys.stderr)
+ assert name.endswith(".tar.zst")
+
+ cctx = zstandard.ZstdCompressor()
+ with open(name, "wb") as f, cctx.stream_writer(f) as z:
+ with tarfile.open(mode="w|", fileobj=z) as tf:
+ with chdir(base):
+ tf.add(directory)
+
+
+def mkdir_p(path):
+ try:
+ os.makedirs(path)
+ except OSError as e:
+ if e.errno != errno.EEXIST or not os.path.isdir(path):
+ raise
+
+
+def delete(path):
+ if os.path.isdir(path):
+ shutil.rmtree(path)
+ else:
+ try:
+ os.unlink(path)
+ except Exception:
+ pass
+
+
+def install_import_library(build_dir, clang_dir):
+ shutil.copy2(
+ os.path.join(build_dir, "lib", "clang.lib"), os.path.join(clang_dir, "lib")
+ )
+
+
+def is_darwin(target):
+ return "-apple-darwin" in target
+
+
+def is_linux(target):
+ return "-linux-gnu" in target
+
+
+def is_windows(target):
+ return "-windows-msvc" in target
+
+
+def is_cross_compile(target):
+ return SUPPORTED_TARGETS[target] != (platform.system(), platform.machine())
+
+
+def build_one_stage(
+ cc,
+ cxx,
+ asm,
+ ar,
+ ranlib,
+ ldflags,
+ src_dir,
+ stage_dir,
+ package_name,
+ build_type,
+ assertions,
+ target,
+ targets,
+ is_final_stage=False,
+ profile=None,
+):
+ if not os.path.exists(stage_dir):
+ os.mkdir(stage_dir)
+
+ build_dir = stage_dir + "/build"
+ inst_dir = stage_dir + "/" + package_name
+
+ # cmake doesn't deal well with backslashes in paths.
+ def slashify_path(path):
+ return path.replace("\\", "/")
+
+ def cmake_base_args(cc, cxx, asm, ar, ranlib, ldflags, inst_dir):
+ machine_targets = targets if is_final_stage and targets else "X86"
+
+ cmake_args = [
+ "-GNinja",
+ "-DCMAKE_C_COMPILER=%s" % slashify_path(cc[0]),
+ "-DCMAKE_CXX_COMPILER=%s" % slashify_path(cxx[0]),
+ "-DCMAKE_ASM_COMPILER=%s" % slashify_path(asm[0]),
+ "-DCMAKE_AR=%s" % slashify_path(ar),
+ "-DCMAKE_C_FLAGS_INIT=%s" % " ".join(cc[1:]),
+ "-DCMAKE_CXX_FLAGS_INIT=%s" % " ".join(cxx[1:]),
+ "-DCMAKE_ASM_FLAGS_INIT=%s" % " ".join(asm[1:]),
+ "-DCMAKE_EXE_LINKER_FLAGS_INIT=%s" % " ".join(ldflags),
+ "-DCMAKE_SHARED_LINKER_FLAGS_INIT=%s" % " ".join(ldflags),
+ "-DCMAKE_BUILD_TYPE=%s" % build_type,
+ "-DCMAKE_INSTALL_PREFIX=%s" % inst_dir,
+ "-DLLVM_TARGETS_TO_BUILD=%s" % machine_targets,
+ "-DLLVM_ENABLE_PER_TARGET_RUNTIME_DIR=OFF",
+ "-DLLVM_ENABLE_ASSERTIONS=%s" % ("ON" if assertions else "OFF"),
+ "-DLLVM_ENABLE_BINDINGS=OFF",
+ "-DLLVM_ENABLE_CURL=OFF",
+ "-DLLVM_INCLUDE_TESTS=OFF",
+ ]
+ if is_llvm_toolchain(cc[0], cxx[0]):
+ cmake_args += ["-DLLVM_ENABLE_LLD=ON"]
+ elif is_windows(target) and is_cross_compile(target):
+ raise Exception(
+ "Cannot cross-compile for Windows with a compiler that is not clang"
+ )
+
+ if "TASK_ID" in os.environ:
+ cmake_args += [
+ "-DCLANG_REPOSITORY_STRING=taskcluster-%s" % os.environ["TASK_ID"],
+ ]
+ projects = ["clang", "lld"]
+ if is_final_stage:
+ projects.append("clang-tools-extra")
+ else:
+ cmake_args.append("-DLLVM_TOOL_LLI_BUILD=OFF")
+
+ cmake_args.append("-DLLVM_ENABLE_PROJECTS=%s" % ";".join(projects))
+
+ # There is no libxml2 on Windows except if we build one ourselves.
+ # libxml2 is only necessary for llvm-mt, but Windows can just use the
+ # native MT tool.
+ if not is_windows(target) and is_final_stage:
+ cmake_args += ["-DLLVM_ENABLE_LIBXML2=FORCE_ON"]
+ if is_linux(target) and is_final_stage:
+ sysroot = os.path.join(os.environ.get("MOZ_FETCHES_DIR", ""), "sysroot")
+ if os.path.exists(sysroot):
+ cmake_args += ["-DLLVM_BINUTILS_INCDIR=/usr/include"]
+ cmake_args += ["-DCMAKE_SYSROOT=%s" % sysroot]
+ # Work around the LLVM build system not building the i386 compiler-rt
+ # because it doesn't allow to use a sysroot for that during the cmake
+ # checks.
+ cmake_args += ["-DCAN_TARGET_i386=1"]
+ cmake_args += ["-DLLVM_ENABLE_TERMINFO=OFF"]
+ if is_windows(target):
+ cmake_args.insert(-1, "-DLLVM_EXPORT_SYMBOLS_FOR_PLUGINS=ON")
+ cmake_args.insert(-1, "-DCMAKE_MSVC_RUNTIME_LIBRARY=MultiThreaded")
+ if is_cross_compile(target):
+ cmake_args += [
+ f"-DCMAKE_TOOLCHAIN_FILE={src_dir}/cmake/platforms/WinMsvc.cmake",
+ f"-DLLVM_NATIVE_TOOLCHAIN={os.path.dirname(os.path.dirname(cc[0]))}",
+ f"-DHOST_ARCH={target[: -len('-pc-windows-msvc')]}",
+ f"-DLLVM_WINSYSROOT={os.environ['VSINSTALLDIR']}",
+ "-DLLVM_DISABLE_ASSEMBLY_FILES=ON",
+ ]
+ else:
+ # libllvm as a shared library is not supported on Windows
+ cmake_args += ["-DLLVM_LINK_LLVM_DYLIB=ON"]
+ if ranlib is not None:
+ cmake_args += ["-DCMAKE_RANLIB=%s" % slashify_path(ranlib)]
+ if is_darwin(target) and is_cross_compile(target):
+ arch = "arm64" if target.startswith("aarch64") else "x86_64"
+ cmake_args += [
+ "-DCMAKE_SYSTEM_NAME=Darwin",
+ "-DCMAKE_SYSTEM_VERSION=%s" % os.environ["MACOSX_DEPLOYMENT_TARGET"],
+ "-DCMAKE_OSX_SYSROOT=%s" % slashify_path(os.getenv("CROSS_SYSROOT")),
+ "-DCMAKE_FIND_ROOT_PATH=%s" % slashify_path(os.getenv("CROSS_SYSROOT")),
+ "-DCMAKE_FIND_ROOT_PATH_MODE_PROGRAM=NEVER",
+ "-DCMAKE_FIND_ROOT_PATH_MODE_LIBRARY=ONLY",
+ "-DCMAKE_FIND_ROOT_PATH_MODE_INCLUDE=ONLY",
+ "-DCMAKE_MACOSX_RPATH=ON",
+ "-DCMAKE_OSX_ARCHITECTURES=%s" % arch,
+ "-DDARWIN_osx_ARCHS=%s" % arch,
+ "-DDARWIN_osx_SYSROOT=%s" % slashify_path(os.getenv("CROSS_SYSROOT")),
+ "-DLLVM_DEFAULT_TARGET_TRIPLE=%s" % target,
+ "-DCMAKE_C_COMPILER_TARGET=%s" % target,
+ "-DCMAKE_CXX_COMPILER_TARGET=%s" % target,
+ "-DCMAKE_ASM_COMPILER_TARGET=%s" % target,
+ ]
+ if arch == "arm64":
+ cmake_args += [
+ "-DDARWIN_osx_BUILTIN_ARCHS=arm64",
+ ]
+ # Starting in LLVM 11 (which requires SDK 10.12) the build tries to
+ # detect the SDK version by calling xcrun. Cross-compiles don't have
+ # an xcrun, so we have to set the version explicitly.
+ cmake_args += [
+ "-DDARWIN_macosx_OVERRIDE_SDK_VERSION=%s"
+ % os.environ["MACOSX_DEPLOYMENT_TARGET"],
+ ]
+
+ if profile == "gen":
+ # Per https://releases.llvm.org/10.0.0/docs/HowToBuildWithPGO.html
+ cmake_args += [
+ "-DLLVM_BUILD_INSTRUMENTED=IR",
+ "-DLLVM_BUILD_RUNTIME=No",
+ ]
+ elif profile:
+ cmake_args += [
+ "-DLLVM_PROFDATA_FILE=%s" % profile,
+ ]
+
+ # Using LTO for both profile generation and usage to avoid most
+ # "function control flow change detected (hash mismatch)" error.
+ if profile and not is_windows(target):
+ cmake_args.append("-DLLVM_ENABLE_LTO=Thin")
+ return cmake_args
+
+ cmake_args = []
+ cmake_args += cmake_base_args(cc, cxx, asm, ar, ranlib, ldflags, inst_dir)
+ cmake_args += [src_dir]
+ build_package(build_dir, cmake_args)
+
+ # For some reasons the import library clang.lib of clang.exe is not
+ # installed, so we copy it by ourselves.
+ if is_windows(target) and is_final_stage:
+ install_import_library(build_dir, inst_dir)
+
+
+# Return the absolute path of a build tool. We first look to see if the
+# variable is defined in the config file, and if so we make sure it's an
+# absolute path to an existing tool, otherwise we look for a program in
+# $PATH named "key".
+#
+# This expects the name of the key in the config file to match the name of
+# the tool in the default toolchain on the system (for example, "ld" on Unix
+# and "link" on Windows).
+def get_tool(config, key):
+ f = None
+ if key in config:
+ f = config[key].format(**os.environ)
+ if os.path.isabs(f):
+ if not os.path.exists(f):
+ raise ValueError("%s must point to an existing path" % key)
+ return f
+
+ # Assume that we have the name of some program that should be on PATH.
+ tool = which(f) if f else which(key)
+ if not tool:
+ raise ValueError("%s not found on PATH" % (f or key))
+ return tool
+
+
+# This function is intended to be called on the final build directory when
+# building clang-tidy. Also clang-format binaries are included that can be used
+# in conjunction with clang-tidy.
+# As a separate binary we also ship clangd for the language server protocol that
+# can be used as a plugin in `vscode`.
+# Its job is to remove all of the files which won't be used for clang-tidy or
+# clang-format to reduce the download size. Currently when this function
+# finishes its job, it will leave final_dir with a layout like this:
+#
+# clang/
+# bin/
+# clang-apply-replacements
+# clang-format
+# clang-tidy
+# clangd
+# run-clang-tidy
+# include/
+# * (nothing will be deleted here)
+# lib/
+# clang/
+# 4.0.0/
+# include/
+# * (nothing will be deleted here)
+# share/
+# clang/
+# clang-format-diff.py
+# clang-tidy-diff.py
+# run-clang-tidy.py
+def prune_final_dir_for_clang_tidy(final_dir, target):
+ # Make sure we only have what we expect.
+ dirs = [
+ "bin",
+ "include",
+ "lib",
+ "lib32",
+ "libexec",
+ "msbuild-bin",
+ "share",
+ "tools",
+ ]
+ if is_linux(target):
+ dirs.append("x86_64-unknown-linux-gnu")
+ for f in glob.glob("%s/*" % final_dir):
+ if os.path.basename(f) not in dirs:
+ raise Exception("Found unknown file %s in the final directory" % f)
+ if not os.path.isdir(f):
+ raise Exception("Expected %s to be a directory" % f)
+
+ kept_binaries = [
+ "clang-apply-replacements",
+ "clang-format",
+ "clang-tidy",
+ "clangd",
+ "clang-query",
+ "run-clang-tidy",
+ ]
+ re_clang_tidy = re.compile(r"^(" + "|".join(kept_binaries) + r")(\.exe)?$", re.I)
+ for f in glob.glob("%s/bin/*" % final_dir):
+ if re_clang_tidy.search(os.path.basename(f)) is None:
+ delete(f)
+
+ # Keep include/ intact.
+
+ # Remove the target-specific files.
+ if is_linux(target):
+ if os.path.exists(os.path.join(final_dir, "x86_64-unknown-linux-gnu")):
+ shutil.rmtree(os.path.join(final_dir, "x86_64-unknown-linux-gnu"))
+
+ # In lib/, only keep lib/clang/N.M.O/include and the LLVM shared library.
+ re_ver_num = re.compile(r"^\d+(?:\.\d+\.\d+)?$", re.I)
+ for f in glob.glob("%s/lib/*" % final_dir):
+ name = os.path.basename(f)
+ if name == "clang":
+ continue
+ if is_darwin(target) and name in ["libLLVM.dylib", "libclang-cpp.dylib"]:
+ continue
+ if is_linux(target) and (
+ fnmatch.fnmatch(name, "libLLVM*.so")
+ or fnmatch.fnmatch(name, "libclang-cpp.so*")
+ ):
+ continue
+ delete(f)
+ for f in glob.glob("%s/lib/clang/*" % final_dir):
+ if re_ver_num.search(os.path.basename(f)) is None:
+ delete(f)
+ for f in glob.glob("%s/lib/clang/*/*" % final_dir):
+ if os.path.basename(f) != "include":
+ delete(f)
+
+ # Completely remove libexec/, msbuild-bin and tools, if it exists.
+ shutil.rmtree(os.path.join(final_dir, "libexec"))
+ for d in ("msbuild-bin", "tools"):
+ d = os.path.join(final_dir, d)
+ if os.path.exists(d):
+ shutil.rmtree(d)
+
+ # In share/, only keep share/clang/*tidy*
+ re_clang_tidy = re.compile(r"format|tidy", re.I)
+ for f in glob.glob("%s/share/*" % final_dir):
+ if os.path.basename(f) != "clang":
+ delete(f)
+ for f in glob.glob("%s/share/clang/*" % final_dir):
+ if re_clang_tidy.search(os.path.basename(f)) is None:
+ delete(f)
+
+
+def main():
+ parser = argparse.ArgumentParser()
+ parser.add_argument(
+ "-c",
+ "--config",
+ action="append",
+ required=True,
+ type=argparse.FileType("r"),
+ help="Clang configuration file",
+ )
+ parser.add_argument(
+ "--clean", required=False, action="store_true", help="Clean the build directory"
+ )
+ parser.add_argument(
+ "--skip-tar",
+ required=False,
+ action="store_true",
+ help="Skip tar packaging stage",
+ )
+ parser.add_argument(
+ "--skip-patch",
+ required=False,
+ action="store_true",
+ help="Do not patch source",
+ )
+
+ args = parser.parse_args()
+
+ if not os.path.exists("llvm/README.txt"):
+ raise Exception(
+ "The script must be run from the root directory of the llvm-project tree"
+ )
+ source_dir = os.getcwd()
+ build_dir = source_dir + "/build"
+
+ if args.clean:
+ shutil.rmtree(build_dir)
+ os.sys.exit(0)
+
+ llvm_source_dir = source_dir + "/llvm"
+
+ config = {}
+ # Merge all the configs we got from the command line.
+ for c in args.config:
+ this_config_dir = os.path.dirname(c.name)
+ this_config = json.load(c)
+ patches = this_config.get("patches")
+ if patches:
+ this_config["patches"] = [os.path.join(this_config_dir, p) for p in patches]
+ for key, value in this_config.items():
+ old_value = config.get(key)
+ if old_value is None:
+ config[key] = value
+ elif value is None:
+ if key in config:
+ del config[key]
+ elif type(old_value) != type(value):
+ raise Exception(
+ "{} is overriding `{}` with a value of the wrong type".format(
+ c.name, key
+ )
+ )
+ elif isinstance(old_value, list):
+ for v in value:
+ if v not in old_value:
+ old_value.append(v)
+ elif isinstance(old_value, dict):
+ raise Exception("{} is setting `{}` to a dict?".format(c.name, key))
+ else:
+ config[key] = value
+
+ stages = 2
+ if "stages" in config:
+ stages = int(config["stages"])
+ if stages not in (1, 2, 3, 4):
+ raise ValueError("We only know how to build 1, 2, 3, or 4 stages.")
+ skip_stages = 0
+ if "skip_stages" in config:
+ # The assumption here is that the compiler given in `cc` and other configs
+ # is the result of the last skip stage, built somewhere else.
+ skip_stages = int(config["skip_stages"])
+ if skip_stages >= stages:
+ raise ValueError("Cannot skip more stages than are built.")
+ pgo = False
+ if "pgo" in config:
+ pgo = config["pgo"]
+ if pgo not in (True, False):
+ raise ValueError("Only boolean values are accepted for pgo.")
+ build_type = "Release"
+ if "build_type" in config:
+ build_type = config["build_type"]
+ if build_type not in ("Release", "Debug", "RelWithDebInfo", "MinSizeRel"):
+ raise ValueError(
+ "We only know how to do Release, Debug, RelWithDebInfo or "
+ "MinSizeRel builds"
+ )
+ targets = config.get("targets")
+ build_clang_tidy = False
+ if "build_clang_tidy" in config:
+ build_clang_tidy = config["build_clang_tidy"]
+ if build_clang_tidy not in (True, False):
+ raise ValueError("Only boolean values are accepted for build_clang_tidy.")
+ build_clang_tidy_alpha = False
+ # check for build_clang_tidy_alpha only if build_clang_tidy is true
+ if build_clang_tidy and "build_clang_tidy_alpha" in config:
+ build_clang_tidy_alpha = config["build_clang_tidy_alpha"]
+ if build_clang_tidy_alpha not in (True, False):
+ raise ValueError(
+ "Only boolean values are accepted for build_clang_tidy_alpha."
+ )
+ build_clang_tidy_external = False
+ # check for build_clang_tidy_external only if build_clang_tidy is true
+ if build_clang_tidy and "build_clang_tidy_external" in config:
+ build_clang_tidy_external = config["build_clang_tidy_external"]
+ if build_clang_tidy_external not in (True, False):
+ raise ValueError(
+ "Only boolean values are accepted for build_clang_tidy_external."
+ )
+ assertions = False
+ if "assertions" in config:
+ assertions = config["assertions"]
+ if assertions not in (True, False):
+ raise ValueError("Only boolean values are accepted for assertions.")
+
+ for t in SUPPORTED_TARGETS:
+ if not is_cross_compile(t):
+ host = t
+ break
+ else:
+ raise Exception(
+ f"Cannot use this script on {platform.system()} {platform.machine()}"
+ )
+
+ target = config.get("target", host)
+ if target not in SUPPORTED_TARGETS:
+ raise ValueError(f"{target} is not a supported target.")
+
+ if is_cross_compile(target) and not is_linux(host):
+ raise Exception("Cross-compilation is only supported on Linux")
+
+ if is_darwin(target):
+ os.environ["MACOSX_DEPLOYMENT_TARGET"] = (
+ "11.0" if target.startswith("aarch64") else "10.12"
+ )
+
+ if is_windows(target):
+ exe_ext = ".exe"
+ cc_name = "clang-cl"
+ cxx_name = "clang-cl"
+ else:
+ exe_ext = ""
+ cc_name = "clang"
+ cxx_name = "clang++"
+
+ cc = get_tool(config, "cc")
+ cxx = get_tool(config, "cxx")
+ asm = get_tool(config, "ml" if is_windows(target) else "as")
+ # Not using lld here as default here because it's not in PATH. But clang
+ # knows how to find it when they are installed alongside each others.
+ ar = get_tool(config, "lib" if is_windows(target) else "ar")
+ ranlib = None if is_windows(target) else get_tool(config, "ranlib")
+
+ if not os.path.exists(source_dir):
+ os.makedirs(source_dir)
+
+ if not args.skip_patch:
+ for p in config.get("patches", []):
+ patch(p, source_dir)
+
+ package_name = "clang"
+ if build_clang_tidy:
+ package_name = "clang-tidy"
+ if not args.skip_patch:
+ import_clang_tidy(
+ source_dir, build_clang_tidy_alpha, build_clang_tidy_external
+ )
+
+ if not os.path.exists(build_dir):
+ os.makedirs(build_dir)
+
+ stage1_dir = build_dir + "/stage1"
+ stage1_inst_dir = stage1_dir + "/" + package_name
+
+ final_stage_dir = stage1_dir
+
+ if is_darwin(target):
+ extra_cflags = []
+ extra_cxxflags = []
+ extra_cflags2 = []
+ extra_cxxflags2 = []
+ extra_asmflags = []
+ # It's unfortunately required to specify the linker used here because
+ # the linker flags are used in LLVM's configure step before
+ # -DLLVM_ENABLE_LLD is actually processed.
+ extra_ldflags = [
+ "-fuse-ld=lld",
+ "-Wl,-dead_strip",
+ ]
+ elif is_linux(target):
+ extra_cflags = []
+ extra_cxxflags = []
+ extra_cflags2 = ["-fPIC"]
+ # Silence clang's warnings about arguments not being used in compilation.
+ extra_cxxflags2 = [
+ "-fPIC",
+ "-Qunused-arguments",
+ ]
+ extra_asmflags = []
+ # Avoid libLLVM internal function calls going through the PLT.
+ extra_ldflags = ["-Wl,-Bsymbolic-functions"]
+ # For whatever reason, LLVM's build system will set things up to turn
+ # on -ffunction-sections and -fdata-sections, but won't turn on the
+ # corresponding option to strip unused sections. We do it explicitly
+ # here. LLVM's build system is also picky about turning on ICF, so
+ # we do that explicitly here, too.
+
+ # It's unfortunately required to specify the linker used here because
+ # the linker flags are used in LLVM's configure step before
+ # -DLLVM_ENABLE_LLD is actually processed.
+ if is_llvm_toolchain(cc, cxx):
+ extra_ldflags += ["-fuse-ld=lld", "-Wl,--icf=safe"]
+ extra_ldflags += ["-Wl,--gc-sections"]
+ elif is_windows(target):
+ extra_cflags = []
+ extra_cxxflags = []
+ # clang-cl would like to figure out what it's supposed to be emulating
+ # by looking at an MSVC install, but we don't really have that here.
+ # Force things on based on WinMsvc.cmake.
+ # Ideally, we'd just use WinMsvc.cmake as a toolchain file, but it only
+ # really works for cross-compiles, which this is not.
+ with open(os.path.join(llvm_source_dir, "cmake/platforms/WinMsvc.cmake")) as f:
+ compat = [
+ item
+ for line in f
+ for item in line.split()
+ if "-fms-compatibility-version=" in item
+ ][0]
+ extra_cflags2 = [compat]
+ extra_cxxflags2 = [compat]
+ extra_asmflags = []
+ extra_ldflags = []
+
+ upload_dir = os.getenv("UPLOAD_DIR")
+ if assertions and upload_dir:
+ extra_cflags2 += ["-fcrash-diagnostics-dir=%s" % upload_dir]
+ extra_cxxflags2 += ["-fcrash-diagnostics-dir=%s" % upload_dir]
+
+ if skip_stages < 1:
+ build_one_stage(
+ [cc] + extra_cflags,
+ [cxx] + extra_cxxflags,
+ [asm] + extra_asmflags,
+ ar,
+ ranlib,
+ extra_ldflags,
+ llvm_source_dir,
+ stage1_dir,
+ package_name,
+ build_type,
+ assertions,
+ target,
+ targets,
+ is_final_stage=(stages == 1),
+ )
+
+ if stages >= 2 and skip_stages < 2:
+ stage2_dir = build_dir + "/stage2"
+ stage2_inst_dir = stage2_dir + "/" + package_name
+ final_stage_dir = stage2_dir
+ if skip_stages < 1:
+ cc = stage1_inst_dir + "/bin/%s%s" % (cc_name, exe_ext)
+ cxx = stage1_inst_dir + "/bin/%s%s" % (cxx_name, exe_ext)
+ asm = stage1_inst_dir + "/bin/%s%s" % (cc_name, exe_ext)
+ build_one_stage(
+ [cc] + extra_cflags2,
+ [cxx] + extra_cxxflags2,
+ [asm] + extra_asmflags,
+ ar,
+ ranlib,
+ extra_ldflags,
+ llvm_source_dir,
+ stage2_dir,
+ package_name,
+ build_type,
+ assertions,
+ target,
+ targets,
+ is_final_stage=(stages == 2),
+ profile="gen" if pgo else None,
+ )
+
+ if stages >= 3 and skip_stages < 3:
+ stage3_dir = build_dir + "/stage3"
+ stage3_inst_dir = stage3_dir + "/" + package_name
+ final_stage_dir = stage3_dir
+ if skip_stages < 2:
+ cc = stage2_inst_dir + "/bin/%s%s" % (cc_name, exe_ext)
+ cxx = stage2_inst_dir + "/bin/%s%s" % (cxx_name, exe_ext)
+ asm = stage2_inst_dir + "/bin/%s%s" % (cc_name, exe_ext)
+ build_one_stage(
+ [cc] + extra_cflags2,
+ [cxx] + extra_cxxflags2,
+ [asm] + extra_asmflags,
+ ar,
+ ranlib,
+ extra_ldflags,
+ llvm_source_dir,
+ stage3_dir,
+ package_name,
+ build_type,
+ assertions,
+ target,
+ targets,
+ (stages == 3),
+ )
+ if pgo:
+ llvm_profdata = stage2_inst_dir + "/bin/llvm-profdata%s" % exe_ext
+ merge_cmd = [llvm_profdata, "merge", "-o", "merged.profdata"]
+ profraw_files = glob.glob(
+ os.path.join(stage2_dir, "build", "profiles", "*.profraw")
+ )
+ run_in(stage3_dir, merge_cmd + profraw_files)
+ if stages == 3:
+ mkdir_p(upload_dir)
+ shutil.copy2(os.path.join(stage3_dir, "merged.profdata"), upload_dir)
+ return
+
+ if stages >= 4 and skip_stages < 4:
+ stage4_dir = build_dir + "/stage4"
+ final_stage_dir = stage4_dir
+ profile = None
+ if pgo:
+ if skip_stages == 3:
+ profile_dir = os.environ.get("MOZ_FETCHES_DIR", "")
+ else:
+ profile_dir = stage3_dir
+ profile = os.path.join(profile_dir, "merged.profdata")
+ if skip_stages < 3:
+ cc = stage3_inst_dir + "/bin/%s%s" % (cc_name, exe_ext)
+ cxx = stage3_inst_dir + "/bin/%s%s" % (cxx_name, exe_ext)
+ asm = stage3_inst_dir + "/bin/%s%s" % (cc_name, exe_ext)
+ build_one_stage(
+ [cc] + extra_cflags2,
+ [cxx] + extra_cxxflags2,
+ [asm] + extra_asmflags,
+ ar,
+ ranlib,
+ extra_ldflags,
+ llvm_source_dir,
+ stage4_dir,
+ package_name,
+ build_type,
+ assertions,
+ target,
+ targets,
+ (stages == 4),
+ profile=profile,
+ )
+
+ if build_clang_tidy:
+ prune_final_dir_for_clang_tidy(
+ os.path.join(final_stage_dir, package_name), target
+ )
+
+ if not args.skip_tar:
+ build_tar_package("%s.tar.zst" % package_name, final_stage_dir, package_name)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/build/build-clang/clang-14.json b/build/build-clang/clang-14.json
new file mode 100644
index 0000000000..b565fefc74
--- /dev/null
+++ b/build/build-clang/clang-14.json
@@ -0,0 +1,13 @@
+{
+ "patches": [
+ "find_symbolizer_linux_clang_10.patch",
+ "android-mangling-error_clang_12.patch",
+ "unpoison-thread-stacks_clang_10.patch",
+ "downgrade-mangling-error_clang_12.patch",
+ "Remove-FlushViewOfFile-when-unmaping-gcda-files.patch",
+ "fuzzing_ccov_build_clang_12.patch",
+ "llvmorg-15-init-16512-g4b1e3d193706.patch",
+ "win64-ret-null-on-commitment-limit_clang_14.patch",
+ "compiler-rt-rss-limit-heap-profile.patch"
+ ]
+}
diff --git a/build/build-clang/clang-17.json b/build/build-clang/clang-17.json
new file mode 100644
index 0000000000..960c7c6754
--- /dev/null
+++ b/build/build-clang/clang-17.json
@@ -0,0 +1,18 @@
+{
+ "patches": [
+ "find_symbolizer_linux_clang_15.patch",
+ "android-mangling-error_clang_12.patch",
+ "unpoison-thread-stacks_clang_10.patch",
+ "downgrade-mangling-error_clang_12.patch",
+ "fuzzing_ccov_build_clang_12.patch",
+ "partial-revert-llvmorg-17-init-17713-gc8e055d485ea.patch",
+ "revert-llvmorg-17-init-4120-g02e8eb1a438b.patch",
+ "partial-revert-llvmorg-16-init-17151-gaa0883b59ae1_clang_17.patch",
+ "revert-llvmorg-16-init-11301-g163bb6d64e5f_clang_17.patch",
+ "revert-llvmorg-15-init-13446-g7524fe962e47.patch",
+ "revert-llvmorg-15-init-11205-gcead4eceb01b_clang_16.patch",
+ "D146664.patch",
+ "win64-ret-null-on-commitment-limit_clang_14.patch",
+ "compiler-rt-rss-limit-heap-profile.patch"
+ ]
+}
diff --git a/build/build-clang/clang-18.json b/build/build-clang/clang-18.json
new file mode 100644
index 0000000000..5f66e58947
--- /dev/null
+++ b/build/build-clang/clang-18.json
@@ -0,0 +1,21 @@
+{
+ "patches": [
+ "allow-unversioned-android.patch",
+ "find_symbolizer_linux_clang_15.patch",
+ "android-mangling-error_clang_12.patch",
+ "unpoison-thread-stacks_clang_10.patch",
+ "downgrade-mangling-error_clang_12.patch",
+ "fuzzing_ccov_build_clang_12.patch",
+ "revert-llvmorg-18-init-6208-g2baf4a06ef06.patch",
+ "revert-llvmorg-18-init-6193-gb88cffeafd39.patch",
+ "revert-llvmorg-18-init-6188-gc649f29c24c9.patch",
+ "partial-revert-llvmorg-17-init-17713-gc8e055d485ea.patch",
+ "revert-llvmorg-17-init-4120-g02e8eb1a438b_clang_18.patch",
+ "partial-revert-llvmorg-16-init-17151-gaa0883b59ae1_clang_17.patch",
+ "revert-llvmorg-16-init-11301-g163bb6d64e5f_clang_18.patch",
+ "revert-llvmorg-15-init-13446-g7524fe962e47.patch",
+ "revert-llvmorg-15-init-11205-gcead4eceb01b_clang_18.patch",
+ "win64-ret-null-on-commitment-limit_clang_14.patch",
+ "compiler-rt-rss-limit-heap-profile.patch"
+ ]
+}
diff --git a/build/build-clang/clang-8-missing-header.patch b/build/build-clang/clang-8-missing-header.patch
new file mode 100644
index 0000000000..a6f1fac040
--- /dev/null
+++ b/build/build-clang/clang-8-missing-header.patch
@@ -0,0 +1,12 @@
+diff --git a/llvm/utils/benchmark/src/benchmark_register.h b/llvm/utils/benchmark/src/benchmark_register.h
+index 0705e219f2fa..4caa5ad4da07 100644
+--- a/llvm/utils/benchmark/src/benchmark_register.h
++++ b/llvm/utils/benchmark/src/benchmark_register.h
+@@ -1,6 +1,7 @@
+ #ifndef BENCHMARK_REGISTER_H
+ #define BENCHMARK_REGISTER_H
+
++#include <limits>
+ #include <vector>
+
+ #include "check.h"
diff --git a/build/build-clang/clang-8.0.json b/build/build-clang/clang-8.0.json
new file mode 100644
index 0000000000..77e71e837f
--- /dev/null
+++ b/build/build-clang/clang-8.0.json
@@ -0,0 +1,10 @@
+{
+ "cc": "/usr/bin/gcc",
+ "cxx": "/usr/bin/g++",
+ "as": "/usr/bin/gcc",
+ "targets": "X86;WebAssembly",
+ "patches": [
+ "clang-8-missing-header.patch",
+ "llvmorg-10-init-136-gb288d90b39f4.patch"
+ ]
+}
diff --git a/build/build-clang/clang-tidy-ci.patch b/build/build-clang/clang-tidy-ci.patch
new file mode 100644
index 0000000000..6c31752136
--- /dev/null
+++ b/build/build-clang/clang-tidy-ci.patch
@@ -0,0 +1,34 @@
+diff --git a/clang-tools-extra/clang-tidy/ClangTidy.cpp b/clang-tools-extra/clang-tidy/ClangTidy.cpp
+index 7de313ad4da6..697f98c362d1 100644
+--- a/clang-tools-extra/clang-tidy/ClangTidy.cpp
++++ b/clang-tools-extra/clang-tidy/ClangTidy.cpp
+@@ -432,6 +432,7 @@ ClangTidyASTConsumerFactory::createASTConsumer(
+
+ for (auto &Check : Checks) {
+ Check->registerMatchers(&*Finder);
++ Check->registerPPCallbacks(Compiler);
+ Check->registerPPCallbacks(*SM, PP, ModuleExpanderPP);
+ }
+
+diff --git a/clang-tools-extra/clang-tidy/ClangTidyCheck.h b/clang-tools-extra/clang-tidy/ClangTidyCheck.h
+index 9b41e5836de7..d8938b8fe05e 100644
+--- a/clang-tools-extra/clang-tidy/ClangTidyCheck.h
++++ b/clang-tools-extra/clang-tidy/ClangTidyCheck.h
+@@ -20,6 +20,7 @@
+
+ namespace clang {
+
++class CompilerInstance;
+ class SourceManager;
+
+ namespace tidy {
+@@ -69,6 +70,9 @@ public:
+ return true;
+ }
+
++ /// This has been deprecated in clang 9 - needed by mozilla-must-override
++ virtual void registerPPCallbacks(CompilerInstance &Compiler) {}
++
+ /// Override this to register ``PPCallbacks`` in the preprocessor.
+ ///
+ /// This should be used for clang-tidy checks that analyze preprocessor-
diff --git a/build/build-clang/clang-tidy-external-linux64.json b/build/build-clang/clang-tidy-external-linux64.json
new file mode 100644
index 0000000000..897911d3e3
--- /dev/null
+++ b/build/build-clang/clang-tidy-external-linux64.json
@@ -0,0 +1,11 @@
+{
+ "stages": "1",
+ "build_clang_tidy": true,
+ "cc": "{MOZ_FETCHES_DIR}/clang/bin/clang",
+ "cxx": "{MOZ_FETCHES_DIR}/clang/bin/clang++",
+ "as": "{MOZ_FETCHES_DIR}/clang/bin/clang",
+ "patches": [
+ "clang-tidy-ci.patch"
+ ],
+ "build_clang_tidy_external": true
+}
diff --git a/build/build-clang/clang-tidy-linux64.json b/build/build-clang/clang-tidy-linux64.json
new file mode 100644
index 0000000000..e654aeef92
--- /dev/null
+++ b/build/build-clang/clang-tidy-linux64.json
@@ -0,0 +1,10 @@
+{
+ "stages": "1",
+ "build_clang_tidy": true,
+ "cc": "{MOZ_FETCHES_DIR}/clang/bin/clang",
+ "cxx": "{MOZ_FETCHES_DIR}/clang/bin/clang++",
+ "as": "{MOZ_FETCHES_DIR}/clang/bin/clang",
+ "patches": [
+ "clang-tidy-ci.patch"
+ ]
+}
diff --git a/build/build-clang/clang-tidy-macosx64.json b/build/build-clang/clang-tidy-macosx64.json
new file mode 100644
index 0000000000..6da85803f5
--- /dev/null
+++ b/build/build-clang/clang-tidy-macosx64.json
@@ -0,0 +1,7 @@
+{
+ "stages": "1",
+ "build_clang_tidy": true,
+ "patches": [
+ "clang-tidy-ci.patch"
+ ]
+}
diff --git a/build/build-clang/clang-tidy-win64.json b/build/build-clang/clang-tidy-win64.json
new file mode 100644
index 0000000000..6da85803f5
--- /dev/null
+++ b/build/build-clang/clang-tidy-win64.json
@@ -0,0 +1,7 @@
+{
+ "stages": "1",
+ "build_clang_tidy": true,
+ "patches": [
+ "clang-tidy-ci.patch"
+ ]
+}
diff --git a/build/build-clang/clang-trunk.json b/build/build-clang/clang-trunk.json
new file mode 100644
index 0000000000..5f66e58947
--- /dev/null
+++ b/build/build-clang/clang-trunk.json
@@ -0,0 +1,21 @@
+{
+ "patches": [
+ "allow-unversioned-android.patch",
+ "find_symbolizer_linux_clang_15.patch",
+ "android-mangling-error_clang_12.patch",
+ "unpoison-thread-stacks_clang_10.patch",
+ "downgrade-mangling-error_clang_12.patch",
+ "fuzzing_ccov_build_clang_12.patch",
+ "revert-llvmorg-18-init-6208-g2baf4a06ef06.patch",
+ "revert-llvmorg-18-init-6193-gb88cffeafd39.patch",
+ "revert-llvmorg-18-init-6188-gc649f29c24c9.patch",
+ "partial-revert-llvmorg-17-init-17713-gc8e055d485ea.patch",
+ "revert-llvmorg-17-init-4120-g02e8eb1a438b_clang_18.patch",
+ "partial-revert-llvmorg-16-init-17151-gaa0883b59ae1_clang_17.patch",
+ "revert-llvmorg-16-init-11301-g163bb6d64e5f_clang_18.patch",
+ "revert-llvmorg-15-init-13446-g7524fe962e47.patch",
+ "revert-llvmorg-15-init-11205-gcead4eceb01b_clang_18.patch",
+ "win64-ret-null-on-commitment-limit_clang_14.patch",
+ "compiler-rt-rss-limit-heap-profile.patch"
+ ]
+}
diff --git a/build/build-clang/compiler-rt-rss-limit-heap-profile.patch b/build/build-clang/compiler-rt-rss-limit-heap-profile.patch
new file mode 100644
index 0000000000..f7dfdfcdae
--- /dev/null
+++ b/build/build-clang/compiler-rt-rss-limit-heap-profile.patch
@@ -0,0 +1,49 @@
+diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common_libcdep.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_common_libcdep.cpp
+index 8fd398564280..b7c4820971bb 100644
+--- a/compiler-rt/lib/sanitizer_common/sanitizer_common_libcdep.cpp
++++ b/compiler-rt/lib/sanitizer_common/sanitizer_common_libcdep.cpp
+@@ -29,6 +29,7 @@ void *BackgroundThread(void *arg) {
+ const uptr hard_rss_limit_mb = common_flags()->hard_rss_limit_mb;
+ const uptr soft_rss_limit_mb = common_flags()->soft_rss_limit_mb;
+ const bool heap_profile = common_flags()->heap_profile;
++ const bool rss_limit_heap_profile = common_flags()->rss_limit_heap_profile;
+ uptr prev_reported_rss = 0;
+ uptr prev_reported_stack_depot_size = 0;
+ bool reached_soft_rss_limit = false;
+@@ -56,6 +57,10 @@ void *BackgroundThread(void *arg) {
+ Report("%s: hard rss limit exhausted (%zdMb vs %zdMb)\n",
+ SanitizerToolName, hard_rss_limit_mb, current_rss_mb);
+ DumpProcessMap();
++ if (rss_limit_heap_profile) {
++ Printf("\n\nHEAP PROFILE at RSS %zdMb\n", current_rss_mb);
++ __sanitizer_print_memory_profile(90, 20);
++ }
+ Die();
+ }
+ if (soft_rss_limit_mb) {
+@@ -63,6 +68,11 @@ void *BackgroundThread(void *arg) {
+ reached_soft_rss_limit = true;
+ Report("%s: soft rss limit exhausted (%zdMb vs %zdMb)\n",
+ SanitizerToolName, soft_rss_limit_mb, current_rss_mb);
++ if (rss_limit_heap_profile) {
++ Printf("\n\nHEAP PROFILE at RSS %zdMb\n", current_rss_mb);
++ __sanitizer_print_memory_profile(90, 20);
++ rss_during_last_reported_profile = current_rss_mb;
++ }
+ SetRssLimitExceeded(true);
+ } else if (soft_rss_limit_mb >= current_rss_mb &&
+ reached_soft_rss_limit) {
+diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_flags.inc b/compiler-rt/lib/sanitizer_common/sanitizer_flags.inc
+index 6148ae56067c..a0fbb8e14bd5 100644
+--- a/compiler-rt/lib/sanitizer_common/sanitizer_flags.inc
++++ b/compiler-rt/lib/sanitizer_common/sanitizer_flags.inc
+@@ -147,6 +147,9 @@ COMMON_FLAG(uptr, max_allocation_size_mb, 0,
+ "If non-zero, malloc/new calls larger than this size will return "
+ "nullptr (or crash if allocator_may_return_null=false).")
+ COMMON_FLAG(bool, heap_profile, false, "Experimental heap profiler, asan-only")
++COMMON_FLAG(bool, rss_limit_heap_profile, false,
++ "Experimental heap profiler (only when hard/soft rss limit "
++ "exceeded, asan-only")
+ COMMON_FLAG(s32, allocator_release_to_os_interval_ms,
+ ((bool)SANITIZER_FUCHSIA || (bool)SANITIZER_WINDOWS) ? -1 : 5000,
+ "Only affects a 64-bit allocator. If set, tries to release unused "
diff --git a/build/build-clang/downgrade-mangling-error_clang_12.patch b/build/build-clang/downgrade-mangling-error_clang_12.patch
new file mode 100644
index 0000000000..ad31306ff3
--- /dev/null
+++ b/build/build-clang/downgrade-mangling-error_clang_12.patch
@@ -0,0 +1,23 @@
+Downgrade unimplemented mangling diagnostic from error to note.
+This codepath is exercised by MozsearchIndexer.cpp (the searchfox
+indexer) when indexing on Windows. We can do without having the
+unimplemented bits for now as long the compiler doesn't fail the
+build. See also https://bugs.llvm.org/show_bug.cgi?id=39294
+
+diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp
+index 4420f6a2c1c3..4d9a6434d245 100644
+--- a/clang/lib/AST/ItaniumMangle.cpp
++++ b/clang/lib/AST/ItaniumMangle.cpp
+@@ -4028,10 +4028,11 @@ recurse:
+ if (!NullOut) {
+ // As bad as this diagnostic is, it's better than crashing.
+ DiagnosticsEngine &Diags = Context.getDiags();
+- unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,
++ unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Remark,
+ "cannot yet mangle expression type %0");
+ Diags.Report(E->getExprLoc(), DiagID)
+ << E->getStmtClassName() << E->getSourceRange();
++ Out << "MOZ_WE_HACKED_AROUND_BUG_1418415";
+ return;
+ }
+ break;
diff --git a/build/build-clang/find_symbolizer_linux_clang_10.patch b/build/build-clang/find_symbolizer_linux_clang_10.patch
new file mode 100644
index 0000000000..1ddb02024d
--- /dev/null
+++ b/build/build-clang/find_symbolizer_linux_clang_10.patch
@@ -0,0 +1,58 @@
+We currently need this patch because ASan only searches PATH to find the
+llvm-symbolizer binary to symbolize ASan traces. On testing machines, this
+can be installed in PATH easily. However, for e.g. the ASan Nightly Project,
+where we ship an ASan build, including llvm-symbolizer, to the user, we
+cannot expect llvm-symbolizer to be on PATH. Instead, we should try to look
+it up next to the binary. This patch implements the functionality for Linux
+only until there is similar functionality provided upstream.
+
+diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_file.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_file.cpp
+index 79930d79425..cfb4f90c0d5 100644
+--- a/compiler-rt/lib/sanitizer_common/sanitizer_file.cpp
++++ b/compiler-rt/lib/sanitizer_common/sanitizer_file.cpp
+@@ -20,6 +20,10 @@
+ #include "sanitizer_common.h"
+ #include "sanitizer_file.h"
+
++#if SANITIZER_LINUX
++#include "sanitizer_posix.h"
++#endif
++
+ namespace __sanitizer {
+
+ void CatastrophicErrorWrite(const char *buffer, uptr length) {
+@@ -194,6 +198,34 @@ char *FindPathToBinary(const char *name) {
+ if (*end == '\0') break;
+ beg = end + 1;
+ }
++
++#if SANITIZER_LINUX
++ // If we cannot find the requested binary in PATH, we should try to locate
++ // it next to the binary, in case it is shipped with the build itself
++ // (e.g. llvm-symbolizer shipped with sanitizer build to symbolize on client.
++ if (internal_readlink("/proc/self/exe", buffer.data(), kMaxPathLength) < 0)
++ return nullptr;
++
++ uptr buf_len = internal_strlen(buffer.data());
++
++ /* Avoid using dirname() here */
++ while (buf_len > 0) {
++ if (buffer[buf_len - 1] == '/')
++ break;
++ buf_len--;
++ }
++
++ if (!buf_len)
++ return nullptr;
++
++ if (buf_len + name_len + 1 <= kMaxPathLength) {
++ internal_memcpy(&buffer[buf_len], name, name_len);
++ buffer[buf_len + name_len] = '\0';
++ if (FileExists(buffer.data()))
++ return internal_strdup(buffer.data());
++ }
++#endif
++
+ return nullptr;
+ }
+
diff --git a/build/build-clang/find_symbolizer_linux_clang_15.patch b/build/build-clang/find_symbolizer_linux_clang_15.patch
new file mode 100644
index 0000000000..63309e8f00
--- /dev/null
+++ b/build/build-clang/find_symbolizer_linux_clang_15.patch
@@ -0,0 +1,53 @@
+diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_file.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_file.cpp
+index 7ef499ce07b1..8fd682f943fe 100644
+--- a/compiler-rt/lib/sanitizer_common/sanitizer_file.cpp
++++ b/compiler-rt/lib/sanitizer_common/sanitizer_file.cpp
+@@ -21,6 +21,10 @@
+ #include "sanitizer_file.h"
+ # include "sanitizer_interface_internal.h"
+
++#if SANITIZER_LINUX
++#include "sanitizer_posix.h"
++#endif
++
+ namespace __sanitizer {
+
+ void CatastrophicErrorWrite(const char *buffer, uptr length) {
+@@ -206,11 +210,35 @@ char *FindPathToBinary(const char *name) {
+ return internal_strdup(name);
+ }
+
++ uptr name_len = internal_strlen(name);
++ InternalMmapVector<char> buffer(kMaxPathLength);
++
++#if SANITIZER_LINUX
++ // If we cannot find the requested binary in PATH, we should try to locate
++ // it next to the binary, in case it is shipped with the build itself
++ // (e.g. llvm-symbolizer shipped with sanitizer build to symbolize on client.
++ if (internal_readlink("/proc/self/exe", buffer.data(), kMaxPathLength) >= 0) {
++ uptr buf_len = internal_strlen(buffer.data());
++
++ /* Avoid using dirname() here */
++ while (buf_len > 0) {
++ if (buffer[buf_len - 1] == '/')
++ break;
++ buf_len--;
++ }
++
++ if (buf_len && buf_len + name_len + 1 <= kMaxPathLength) {
++ internal_memcpy(&buffer[buf_len], name, name_len);
++ buffer[buf_len + name_len] = '\0';
++ if (FileExists(buffer.data()))
++ return internal_strdup(buffer.data());
++ }
++ }
++#endif
++
+ const char *path = GetEnv("PATH");
+ if (!path)
+ return nullptr;
+- uptr name_len = internal_strlen(name);
+- InternalMmapVector<char> buffer(kMaxPathLength);
+ const char *beg = path;
+ while (true) {
+ const char *end = internal_strchrnul(beg, kPathSeparator);
diff --git a/build/build-clang/fuzzing_ccov_build_clang_12.patch b/build/build-clang/fuzzing_ccov_build_clang_12.patch
new file mode 100644
index 0000000000..1b60a95b91
--- /dev/null
+++ b/build/build-clang/fuzzing_ccov_build_clang_12.patch
@@ -0,0 +1,27 @@
+From 98bf90ef5ea3dd848ce7d81a662eb7499d11c91c Mon Sep 17 00:00:00 2001
+From: Calixte Denizet <calixte.denizet@gmail.com>
+Date: Fri, 16 Apr 2021 10:05:34 +0200
+Subject: [PATCH] [Gcov] Don't run global destructor in ccov builds when env
+ MOZ_FUZZING_CCOV is existing
+
+---
+ compiler-rt/lib/profile/GCDAProfiling.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/compiler-rt/lib/profile/GCDAProfiling.c b/compiler-rt/lib/profile/GCDAProfiling.c
+index 4293e8f7b5bf..6cda4bc7601f 100644
+--- a/compiler-rt/lib/profile/GCDAProfiling.c
++++ b/compiler-rt/lib/profile/GCDAProfiling.c
+@@ -586,6 +586,9 @@ void llvm_writeout_files(void) {
+ __attribute__((destructor(100)))
+ #endif
+ static void llvm_writeout_and_clear(void) {
++ if (getenv("MOZ_FUZZING_CCOV")) {
++ return;
++ }
+ llvm_writeout_files();
+ fn_list_remove(&writeout_fn_list);
+ }
+--
+2.30.2
+
diff --git a/build/build-clang/linux64.json b/build/build-clang/linux64.json
new file mode 100644
index 0000000000..48690dbdaa
--- /dev/null
+++ b/build/build-clang/linux64.json
@@ -0,0 +1,5 @@
+{
+ "cc": "/usr/lib/llvm-13/bin/clang",
+ "cxx": "/usr/lib/llvm-13/bin/clang++",
+ "as": "/usr/lib/llvm-13/bin/clang"
+}
diff --git a/build/build-clang/llvmorg-10-init-136-gb288d90b39f4.patch b/build/build-clang/llvmorg-10-init-136-gb288d90b39f4.patch
new file mode 100644
index 0000000000..c5ca0ba0ee
--- /dev/null
+++ b/build/build-clang/llvmorg-10-init-136-gb288d90b39f4.patch
@@ -0,0 +1,37 @@
+From 79e6696d121b978b4482ce74119c6bbc7a9ce30f Mon Sep 17 00:00:00 2001
+From: Than McIntosh <thanm@google.com>
+Date: Fri, 19 Jul 2019 13:13:54 +0000
+Subject: [PATCH] [NFC] include cstdint/string prior to using uint8_t/string
+
+Summary: include proper header prior to use of uint8_t typedef
+and std::string.
+
+Subscribers: llvm-commits
+
+Reviewers: cherry
+
+Tags: #llvm
+
+Differential Revision: https://reviews.llvm.org/D64937
+
+llvm-svn: 366572
+---
+ llvm/include/llvm/Demangle/MicrosoftDemangleNodes.h | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/llvm/include/llvm/Demangle/MicrosoftDemangleNodes.h b/llvm/include/llvm/Demangle/MicrosoftDemangleNodes.h
+index 9e3478e9fd29..efd55339418b 100644
+--- a/llvm/include/llvm/Demangle/MicrosoftDemangleNodes.h
++++ b/llvm/include/llvm/Demangle/MicrosoftDemangleNodes.h
+@@ -4,6 +4,8 @@
+ #include "llvm/Demangle/Compiler.h"
+ #include "llvm/Demangle/StringView.h"
+ #include <array>
++#include <cstdint>
++#include <string>
+
+ class OutputStream;
+
+--
+2.41.0.3.g1cb8d410ac
+
diff --git a/build/build-clang/llvmorg-15-init-16512-g4b1e3d193706.patch b/build/build-clang/llvmorg-15-init-16512-g4b1e3d193706.patch
new file mode 100644
index 0000000000..5ddb6a52de
--- /dev/null
+++ b/build/build-clang/llvmorg-15-init-16512-g4b1e3d193706.patch
@@ -0,0 +1,138 @@
+From 8482662676a4b6ef79a718c8c09943cb15241664 Mon Sep 17 00:00:00 2001
+From: Tom Stellard <tstellar@redhat.com>
+Date: Tue, 21 Jun 2022 22:22:11 -0700
+Subject: [PATCH] [gold] Ignore bitcode from sections inside object files
+
+-fembed-bitcode will put bitcode into special sections within object
+files, but this is not meant to be used by LTO, so the gold plugin
+should ignore it.
+
+https://github.com/llvm/llvm-project/issues/47216
+
+Reviewed By: tejohnson, MaskRay
+
+Differential Revision: https://reviews.llvm.org/D116995
+---
+ llvm/docs/BitCodeFormat.rst | 3 ++-
+ llvm/docs/GoldPlugin.rst | 4 ++++
+ .../tools/gold/X86/Inputs/bcsection-lib.ll | 6 +++++
+ llvm/test/tools/gold/X86/Inputs/bcsection.s | 5 ++++
+ llvm/test/tools/gold/X86/bcsection.ll | 23 +++++++++++++++----
+ llvm/tools/gold/gold-plugin.cpp | 8 +++++++
+ 6 files changed, 43 insertions(+), 6 deletions(-)
+ create mode 100644 llvm/test/tools/gold/X86/Inputs/bcsection-lib.ll
+
+diff --git a/llvm/docs/BitCodeFormat.rst b/llvm/docs/BitCodeFormat.rst
+index 8e81a7daa459..df1f6915d7d5 100644
+--- a/llvm/docs/BitCodeFormat.rst
++++ b/llvm/docs/BitCodeFormat.rst
+@@ -475,7 +475,8 @@ formats. This wrapper format is useful for accommodating LTO in compilation
+ pipelines where intermediate objects must be native object files which contain
+ metadata in other sections.
+
+-Not all tools support this format.
++Not all tools support this format. For example, lld and the gold plugin will
++ignore these sections when linking object files.
+
+ .. _encoding of LLVM IR:
+
+diff --git a/llvm/docs/GoldPlugin.rst b/llvm/docs/GoldPlugin.rst
+index ce310bc2cf3c..07d2fc203eba 100644
+--- a/llvm/docs/GoldPlugin.rst
++++ b/llvm/docs/GoldPlugin.rst
+@@ -17,6 +17,10 @@ and above also supports LTO via plugins. However, usage of the LLVM
+ gold plugin with ld.bfd is not tested and therefore not officially
+ supported or recommended.
+
++As of LLVM 15, the gold plugin will ignore bitcode from the ``.llvmbc``
++section inside of ELF object files. However, LTO with bitcode files
++is still supported.
++
+ .. _`gold linker`: http://sourceware.org/binutils
+ .. _`GCC LTO`: http://gcc.gnu.org/wiki/LinkTimeOptimization
+ .. _`gold plugin interface`: http://gcc.gnu.org/wiki/whopr/driver
+diff --git a/llvm/test/tools/gold/X86/Inputs/bcsection-lib.ll b/llvm/test/tools/gold/X86/Inputs/bcsection-lib.ll
+new file mode 100644
+index 000000000000..ef3557c19cdc
+--- /dev/null
++++ b/llvm/test/tools/gold/X86/Inputs/bcsection-lib.ll
+@@ -0,0 +1,6 @@
++declare void @elf_func()
++
++define i32 @lib_func() {
++ call void @elf_func()
++ ret i32 0
++}
+diff --git a/llvm/test/tools/gold/X86/Inputs/bcsection.s b/llvm/test/tools/gold/X86/Inputs/bcsection.s
+index ede1e5c532dd..c523612563b4 100644
+--- a/llvm/test/tools/gold/X86/Inputs/bcsection.s
++++ b/llvm/test/tools/gold/X86/Inputs/bcsection.s
+@@ -1,2 +1,7 @@
++.global elf_func
++
++elf_func:
++ ret
++
+ .section .llvmbc
+ .incbin "bcsection.bc"
+diff --git a/llvm/test/tools/gold/X86/bcsection.ll b/llvm/test/tools/gold/X86/bcsection.ll
+index 6d3481f8f966..09882d83fe91 100644
+--- a/llvm/test/tools/gold/X86/bcsection.ll
++++ b/llvm/test/tools/gold/X86/bcsection.ll
+@@ -2,16 +2,29 @@
+ ; RUN: llvm-as -o %t/bcsection.bc %s
+
+ ; RUN: llvm-mc -I=%t -filetype=obj -triple=x86_64-unknown-unknown -o %t/bcsection.bco %p/Inputs/bcsection.s
+-; RUN: llvm-nm --no-llvm-bc %t/bcsection.bco 2>&1 | FileCheck %s -check-prefix=NO-SYMBOLS
+-; NO-SYMBOLS: no symbols
++; RUN: llc -filetype=obj -mtriple=x86_64-unknown-unknown -o %t/bcsection-lib.o %p/Inputs/bcsection-lib.ll
+
+-; RUN: %gold -r -o %t/bcsection.o -m elf_x86_64 -plugin %llvmshlibdir/LLVMgold%shlibext %t/bcsection.bco
+-; RUN: llvm-nm --no-llvm-bc %t/bcsection.o | FileCheck %s
++; RUN: %gold -shared --no-undefined -o %t/bcsection.so -m elf_x86_64 -plugin %llvmshlibdir/LLVMgold%shlibext %t/bcsection.bco %t/bcsection-lib.o
++
++; This test checks that the gold plugin does not attempt to use the bitcode
++; in the .llvmbc section for LTO. bcsection-lib.o calls a function that is
++; present the symbol table of bcsection.bco, but not included in the embedded
++; bitcode. If the linker were to use the bitcode, then the symbols in the
++; symbol table of bcsection.bco will be ignored and the link will fail.
++;
++; bcsection.bco:
++; .text:
++; elf_func
++; .llvmbc:
++; bitcode_func
++;
++; bcsection-lib.o:
++; calls elf_func()
+
+ target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+ target triple = "x86_64-unknown-unknown"
+
+ ; CHECK: main
+-define i32 @main() {
++define i32 @bitcode_func() {
+ ret i32 0
+ }
+diff --git a/llvm/tools/gold/gold-plugin.cpp b/llvm/tools/gold/gold-plugin.cpp
+index 180c181368e3..294c7a3d6178 100644
+--- a/llvm/tools/gold/gold-plugin.cpp
++++ b/llvm/tools/gold/gold-plugin.cpp
+@@ -540,6 +540,14 @@ static ld_plugin_status claim_file_hook(const ld_plugin_input_file *file,
+ BufferRef = Buffer->getMemBufferRef();
+ }
+
++ // Only use bitcode files for LTO. InputFile::create() will load bitcode
++ // from the .llvmbc section within a binary object, this bitcode is typically
++ // generated by -fembed-bitcode and is not to be used by LLVMgold.so for LTO.
++ if (identify_magic(BufferRef.getBuffer()) != file_magic::bitcode) {
++ *claimed = 0;
++ return LDPS_OK;
++ }
++
+ *claimed = 1;
+
+ Expected<std::unique_ptr<InputFile>> ObjOrErr = InputFile::create(BufferRef);
+--
+2.37.1.1.g659da70093
+
diff --git a/build/build-clang/macosx64-aarch64.json b/build/build-clang/macosx64-aarch64.json
new file mode 100644
index 0000000000..ecbb483e77
--- /dev/null
+++ b/build/build-clang/macosx64-aarch64.json
@@ -0,0 +1,3 @@
+{
+ "target": "aarch64-apple-darwin"
+}
diff --git a/build/build-clang/macosx64.json b/build/build-clang/macosx64.json
new file mode 100644
index 0000000000..2576c0c05f
--- /dev/null
+++ b/build/build-clang/macosx64.json
@@ -0,0 +1,9 @@
+{
+ "target": "x86_64-apple-darwin",
+ "cc": "{MOZ_FETCHES_DIR}/clang/bin/clang",
+ "cxx": "{MOZ_FETCHES_DIR}/clang/bin/clang++",
+ "as": "{MOZ_FETCHES_DIR}/clang/bin/clang",
+ "ar": "{MOZ_FETCHES_DIR}/clang/bin/llvm-ar",
+ "ranlib": "{MOZ_FETCHES_DIR}/clang/bin/llvm-ranlib",
+ "ld": "{MOZ_FETCHES_DIR}/clang/bin/clang"
+}
diff --git a/build/build-clang/partial-revert-llvmorg-16-init-17151-gaa0883b59ae1_clang_17.patch b/build/build-clang/partial-revert-llvmorg-16-init-17151-gaa0883b59ae1_clang_17.patch
new file mode 100644
index 0000000000..f95caa508b
--- /dev/null
+++ b/build/build-clang/partial-revert-llvmorg-16-init-17151-gaa0883b59ae1_clang_17.patch
@@ -0,0 +1,13 @@
+diff --git a/lld/MachO/LTO.cpp b/lld/MachO/LTO.cpp
+index fdae7e4bd1b7..ac607cfb1100 100644
+--- a/lld/MachO/LTO.cpp
++++ b/lld/MachO/LTO.cpp
+@@ -64,8 +64,6 @@ static lto::Config createConfig() {
+ pm.add(createObjCARCContractPass());
+ };
+
+- c.AlwaysEmitRegularLTOObj = !config->ltoObjPath.empty();
+-
+ c.TimeTraceEnabled = config->timeTraceEnabled;
+ c.TimeTraceGranularity = config->timeTraceGranularity;
+ c.DebugPassManager = config->ltoDebugPassManager;
diff --git a/build/build-clang/partial-revert-llvmorg-17-init-17713-gc8e055d485ea.patch b/build/build-clang/partial-revert-llvmorg-17-init-17713-gc8e055d485ea.patch
new file mode 100644
index 0000000000..96ac988380
--- /dev/null
+++ b/build/build-clang/partial-revert-llvmorg-17-init-17713-gc8e055d485ea.patch
@@ -0,0 +1,33 @@
+Revert the parts of c8e055d485eabf1c8830d77797e3686ced0f7754 that require
+cead4eceb01b935fae07bf4a7e91911b344d2fec, which we revert.
+
+diff --git a/llvm/include/llvm/DebugInfo/BTF/BTFContext.h b/llvm/include/llvm/DebugInfo/BTF/BTFContext.h
+index c16bee613322..7b0412b91c2e 100644
+--- a/llvm/include/llvm/DebugInfo/BTF/BTFContext.h
++++ b/llvm/include/llvm/DebugInfo/BTF/BTFContext.h
+@@ -34,9 +34,6 @@ public:
+ object::SectionedAddress Address,
+ DILineInfoSpecifier Specifier = DILineInfoSpecifier()) override;
+
+- DILineInfo
+- getLineInfoForDataAddress(object::SectionedAddress Address) override;
+-
+ DILineInfoTable getLineInfoForAddressRange(
+ object::SectionedAddress Address, uint64_t Size,
+ DILineInfoSpecifier Specifier = DILineInfoSpecifier()) override;
+diff --git a/llvm/lib/DebugInfo/BTF/BTFContext.cpp b/llvm/lib/DebugInfo/BTF/BTFContext.cpp
+index 24898739b824..da0f9982881f 100644
+--- a/llvm/lib/DebugInfo/BTF/BTFContext.cpp
++++ b/llvm/lib/DebugInfo/BTF/BTFContext.cpp
+@@ -34,11 +34,6 @@ DILineInfo BTFContext::getLineInfoForAddress(SectionedAddress Address,
+ return Result;
+ }
+
+-DILineInfo BTFContext::getLineInfoForDataAddress(SectionedAddress Address) {
+- // BTF does not convey such information.
+- return {};
+-}
+-
+ DILineInfoTable
+ BTFContext::getLineInfoForAddressRange(SectionedAddress Address, uint64_t Size,
+ DILineInfoSpecifier Specifier) {
diff --git a/build/build-clang/profile.json b/build/build-clang/profile.json
new file mode 100644
index 0000000000..746aa92452
--- /dev/null
+++ b/build/build-clang/profile.json
@@ -0,0 +1,6 @@
+{
+ "stages": "3",
+ "pgo": true,
+ "ranlib": "{MOZ_FETCHES_DIR}/clang/bin/llvm-ranlib",
+ "ar": "{MOZ_FETCHES_DIR}/clang/bin/llvm-ar"
+}
diff --git a/build/build-clang/revert-llvmorg-15-init-11205-gcead4eceb01b_clang_16.patch b/build/build-clang/revert-llvmorg-15-init-11205-gcead4eceb01b_clang_16.patch
new file mode 100644
index 0000000000..93c7e7d767
--- /dev/null
+++ b/build/build-clang/revert-llvmorg-15-init-11205-gcead4eceb01b_clang_16.patch
@@ -0,0 +1,1027 @@
+From cb411520cb7cd5e6e25966911ca55feb5de779e0 Mon Sep 17 00:00:00 2001
+From: Mike Hommey <mh@glandium.org>
+Date: Fri, 4 Nov 2022 14:51:38 +0900
+Subject: [PATCH] Revert "[symbolizer] Parse DW_TAG_variable DIs to show line
+ info for globals"
+
+This reverts commit cead4eceb01b935fae07bf4a7e91911b344d2fec for causing
+yet unidentified problems on some webrtc tests under TSan (bug 1798613).
+---
+ llvm/include/llvm/DebugInfo/DIContext.h | 4 -
+ .../llvm/DebugInfo/DWARF/DWARFContext.h | 2 -
+ llvm/include/llvm/DebugInfo/DWARF/DWARFDie.h | 7 -
+ llvm/include/llvm/DebugInfo/DWARF/DWARFUnit.h | 14 -
+ llvm/include/llvm/DebugInfo/PDB/PDBContext.h | 2 -
+ llvm/lib/DebugInfo/DWARF/DWARFContext.cpp | 97 ++--
+ llvm/lib/DebugInfo/DWARF/DWARFDie.cpp | 60 ---
+ llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp | 97 ----
+ llvm/lib/DebugInfo/PDB/PDBContext.cpp | 7 -
+ llvm/lib/DebugInfo/Symbolize/DIPrinter.cpp | 4 -
+ .../Symbolize/SymbolizableObjectFile.cpp | 8 -
+ .../Symbolize/ELF/data-command-symtab.yaml | 3 -
+ .../tools/llvm-symbolizer/data-location.yaml | 450 ------------------
+ llvm/test/tools/llvm-symbolizer/data.s | 3 -
+ 14 files changed, 61 insertions(+), 697 deletions(-)
+ delete mode 100644 llvm/test/tools/llvm-symbolizer/data-location.yaml
+
+diff --git a/llvm/include/llvm/DebugInfo/DIContext.h b/llvm/include/llvm/DebugInfo/DIContext.h
+index 9b278b696073..a9f98588cf2d 100644
+--- a/llvm/include/llvm/DebugInfo/DIContext.h
++++ b/llvm/include/llvm/DebugInfo/DIContext.h
+@@ -114,8 +114,6 @@ struct DIGlobal {
+ std::string Name;
+ uint64_t Start = 0;
+ uint64_t Size = 0;
+- std::string DeclFile;
+- uint64_t DeclLine = 0;
+
+ DIGlobal() : Name(DILineInfo::BadString) {}
+ };
+@@ -241,8 +239,6 @@ public:
+ virtual DILineInfo getLineInfoForAddress(
+ object::SectionedAddress Address,
+ DILineInfoSpecifier Specifier = DILineInfoSpecifier()) = 0;
+- virtual DILineInfo
+- getLineInfoForDataAddress(object::SectionedAddress Address) = 0;
+ virtual DILineInfoTable getLineInfoForAddressRange(
+ object::SectionedAddress Address, uint64_t Size,
+ DILineInfoSpecifier Specifier = DILineInfoSpecifier()) = 0;
+diff --git a/llvm/include/llvm/DebugInfo/DWARF/DWARFContext.h b/llvm/include/llvm/DebugInfo/DWARF/DWARFContext.h
+index bf591ed554c6..3365ef8d8ee3 100644
+--- a/llvm/include/llvm/DebugInfo/DWARF/DWARFContext.h
++++ b/llvm/include/llvm/DebugInfo/DWARF/DWARFContext.h
+@@ -364,8 +364,6 @@ public:
+ DILineInfo getLineInfoForAddress(
+ object::SectionedAddress Address,
+ DILineInfoSpecifier Specifier = DILineInfoSpecifier()) override;
+- DILineInfo
+- getLineInfoForDataAddress(object::SectionedAddress Address) override;
+ DILineInfoTable getLineInfoForAddressRange(
+ object::SectionedAddress Address, uint64_t Size,
+ DILineInfoSpecifier Specifier = DILineInfoSpecifier()) override;
+diff --git a/llvm/include/llvm/DebugInfo/DWARF/DWARFDie.h b/llvm/include/llvm/DebugInfo/DWARF/DWARFDie.h
+index 149c5ef4e493..4a4d105a2b23 100644
+--- a/llvm/include/llvm/DebugInfo/DWARF/DWARFDie.h
++++ b/llvm/include/llvm/DebugInfo/DWARF/DWARFDie.h
+@@ -280,13 +280,6 @@ public:
+ /// \returns an iterator range for the attributes of the current DIE.
+ iterator_range<attribute_iterator> attributes() const;
+
+- /// Gets the type size (in bytes) for this DIE.
+- ///
+- /// \param PointerSize the pointer size of the containing CU.
+- /// \returns if this is a type DIE, or this DIE contains a DW_AT_type, returns
+- /// the size of the type.
+- std::optional<uint64_t> getTypeSize(uint64_t PointerSize);
+-
+ class iterator;
+
+ iterator begin() const;
+diff --git a/llvm/include/llvm/DebugInfo/DWARF/DWARFUnit.h b/llvm/include/llvm/DebugInfo/DWARF/DWARFUnit.h
+index 9188865b4d77..0341344bc7b8 100644
+--- a/llvm/include/llvm/DebugInfo/DWARF/DWARFUnit.h
++++ b/llvm/include/llvm/DebugInfo/DWARF/DWARFUnit.h
+@@ -9,7 +9,6 @@
+ #ifndef LLVM_DEBUGINFO_DWARF_DWARFUNIT_H
+ #define LLVM_DEBUGINFO_DWARF_DWARFUNIT_H
+
+-#include "llvm/ADT/DenseSet.h"
+ #include "llvm/ADT/STLExtras.h"
+ #include "llvm/ADT/SmallVector.h"
+ #include "llvm/ADT/StringRef.h"
+@@ -28,7 +27,6 @@
+ #include <cstdint>
+ #include <map>
+ #include <memory>
+-#include <set>
+ #include <utility>
+ #include <vector>
+
+@@ -242,11 +240,6 @@ class DWARFUnit {
+ /// std::map::upper_bound for address range lookup.
+ std::map<uint64_t, std::pair<uint64_t, DWARFDie>> AddrDieMap;
+
+- /// Map from the location (interpreted DW_AT_location) of a DW_TAG_variable,
+- /// to the end address and the corresponding DIE.
+- std::map<uint64_t, std::pair<uint64_t, DWARFDie>> VariableDieMap;
+- DenseSet<uint64_t> RootsParsedForVariables;
+-
+ using die_iterator_range =
+ iterator_range<std::vector<DWARFDebugInfoEntry>::iterator>;
+
+@@ -329,9 +322,6 @@ public:
+ /// Recursively update address to Die map.
+ void updateAddressDieMap(DWARFDie Die);
+
+- /// Recursively update address to variable Die map.
+- void updateVariableDieMap(DWARFDie Die);
+-
+ void setRangesSection(const DWARFSection *RS, uint64_t Base) {
+ RangeSection = RS;
+ RangeSectionBase = Base;
+@@ -446,10 +436,6 @@ public:
+ /// cleared.
+ DWARFDie getSubroutineForAddress(uint64_t Address);
+
+- /// Returns variable DIE for the address provided. The pointer is alive as
+- /// long as parsed compile unit DIEs are not cleared.
+- DWARFDie getVariableForAddress(uint64_t Address);
+-
+ /// getInlinedChainForAddress - fetches inlined chain for a given address.
+ /// Returns empty chain if there is no subprogram containing address. The
+ /// chain is valid as long as parsed compile unit DIEs are not cleared.
+diff --git a/llvm/include/llvm/DebugInfo/PDB/PDBContext.h b/llvm/include/llvm/DebugInfo/PDB/PDBContext.h
+index 3163c0a1dae0..7b6793f0a639 100644
+--- a/llvm/include/llvm/DebugInfo/PDB/PDBContext.h
++++ b/llvm/include/llvm/DebugInfo/PDB/PDBContext.h
+@@ -45,8 +45,6 @@ namespace pdb {
+ DILineInfo getLineInfoForAddress(
+ object::SectionedAddress Address,
+ DILineInfoSpecifier Specifier = DILineInfoSpecifier()) override;
+- DILineInfo
+- getLineInfoForDataAddress(object::SectionedAddress Address) override;
+ DILineInfoTable getLineInfoForAddressRange(
+ object::SectionedAddress Address, uint64_t Size,
+ DILineInfoSpecifier Specifier = DILineInfoSpecifier()) override;
+diff --git a/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp b/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
+index 19d7d659a86a..1bcfdecfd588 100644
+--- a/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
++++ b/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
+@@ -1053,25 +1053,7 @@ DWARFCompileUnit *DWARFContext::getCompileUnitForAddress(uint64_t Address) {
+ // First, get the offset of the compile unit.
+ uint64_t CUOffset = getDebugAranges()->findAddress(Address);
+ // Retrieve the compile unit.
+- if (DWARFCompileUnit *OffsetCU = getCompileUnitForOffset(CUOffset))
+- return OffsetCU;
+-
+- // Global variables are often not found by the above search, for one of two
+- // reasons:
+- // 1. .debug_aranges may not include global variables. On clang, it seems we
+- // put the globals in the aranges, but this isn't true for gcc.
+- // 2. Even if the global variable is in a .debug_arange, global variables
+- // may not be captured in the [start, end) addresses described by the
+- // parent compile unit.
+- //
+- // So, we walk the CU's and their child DI's manually, looking for the
+- // specific global variable.
+- for (std::unique_ptr<DWARFUnit> &CU : compile_units()) {
+- if (DWARFDie Die = CU->getVariableForAddress(Address)) {
+- return static_cast<DWARFCompileUnit *>(CU.get());
+- }
+- }
+- return nullptr;
++ return getCompileUnitForOffset(CUOffset);
+ }
+
+ DWARFContext::DIEsForAddress DWARFContext::getDIEsForAddress(uint64_t Address) {
+@@ -1141,6 +1123,64 @@ static bool getFunctionNameAndStartLineForAddress(
+ return FoundResult;
+ }
+
++static std::optional<uint64_t> getTypeSize(DWARFDie Type, uint64_t PointerSize) {
++ if (auto SizeAttr = Type.find(DW_AT_byte_size))
++ if (std::optional<uint64_t> Size = SizeAttr->getAsUnsignedConstant())
++ return Size;
++
++ switch (Type.getTag()) {
++ case DW_TAG_pointer_type:
++ case DW_TAG_reference_type:
++ case DW_TAG_rvalue_reference_type:
++ return PointerSize;
++ case DW_TAG_ptr_to_member_type: {
++ if (DWARFDie BaseType = Type.getAttributeValueAsReferencedDie(DW_AT_type))
++ if (BaseType.getTag() == DW_TAG_subroutine_type)
++ return 2 * PointerSize;
++ return PointerSize;
++ }
++ case DW_TAG_const_type:
++ case DW_TAG_immutable_type:
++ case DW_TAG_volatile_type:
++ case DW_TAG_restrict_type:
++ case DW_TAG_typedef: {
++ if (DWARFDie BaseType = Type.getAttributeValueAsReferencedDie(DW_AT_type))
++ return getTypeSize(BaseType, PointerSize);
++ break;
++ }
++ case DW_TAG_array_type: {
++ DWARFDie BaseType = Type.getAttributeValueAsReferencedDie(DW_AT_type);
++ if (!BaseType)
++ return std::optional<uint64_t>();
++ std::optional<uint64_t> BaseSize = getTypeSize(BaseType, PointerSize);
++ if (!BaseSize)
++ return std::optional<uint64_t>();
++ uint64_t Size = *BaseSize;
++ for (DWARFDie Child : Type) {
++ if (Child.getTag() != DW_TAG_subrange_type)
++ continue;
++
++ if (auto ElemCountAttr = Child.find(DW_AT_count))
++ if (std::optional<uint64_t> ElemCount =
++ ElemCountAttr->getAsUnsignedConstant())
++ Size *= *ElemCount;
++ if (auto UpperBoundAttr = Child.find(DW_AT_upper_bound))
++ if (std::optional<int64_t> UpperBound =
++ UpperBoundAttr->getAsSignedConstant()) {
++ int64_t LowerBound = 0;
++ if (auto LowerBoundAttr = Child.find(DW_AT_lower_bound))
++ LowerBound = LowerBoundAttr->getAsSignedConstant().value_or(0);
++ Size *= *UpperBound - LowerBound + 1;
++ }
++ }
++ return Size;
++ }
++ default:
++ break;
++ }
++ return std::optional<uint64_t>();
++}
++
+ static std::optional<int64_t>
+ getExpressionFrameOffset(ArrayRef<uint8_t> Expr,
+ std::optional<unsigned> FrameBaseReg) {
+@@ -1201,7 +1241,7 @@ void DWARFContext::addLocalsForDie(DWARFCompileUnit *CU, DWARFDie Subprogram,
+ if (std::optional<const char *> Name = dwarf::toString(*NameAttr))
+ Local.Name = *Name;
+ if (auto Type = Die.getAttributeValueAsReferencedDie(DW_AT_type))
+- Local.Size = Type.getTypeSize(getCUAddrSize());
++ Local.Size = getTypeSize(Type, getCUAddrSize());
+ if (auto DeclFileAttr = Die.find(DW_AT_decl_file)) {
+ if (const auto *LT = CU->getContext().getLineTableForUnit(CU))
+ LT->getFileNameByIndex(
+@@ -1242,6 +1282,7 @@ DWARFContext::getLocalsForAddress(object::SectionedAddress Address) {
+ DILineInfo DWARFContext::getLineInfoForAddress(object::SectionedAddress Address,
+ DILineInfoSpecifier Spec) {
+ DILineInfo Result;
++
+ DWARFCompileUnit *CU = getCompileUnitForAddress(Address.Address);
+ if (!CU)
+ return Result;
+@@ -1256,22 +1297,6 @@ DILineInfo DWARFContext::getLineInfoForAddress(object::SectionedAddress Address,
+ Spec.FLIKind, Result);
+ }
+ }
+-
+- return Result;
+-}
+-
+-DILineInfo
+-DWARFContext::getLineInfoForDataAddress(object::SectionedAddress Address) {
+- DILineInfo Result;
+- DWARFCompileUnit *CU = getCompileUnitForAddress(Address.Address);
+- if (!CU)
+- return Result;
+-
+- if (DWARFDie Die = CU->getVariableForAddress(Address.Address)) {
+- Result.FileName = Die.getDeclFile(FileLineInfoKind::AbsoluteFilePath);
+- Result.Line = Die.getDeclLine();
+- }
+-
+ return Result;
+ }
+
+diff --git a/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp
+index 15a2d23c4fd2..9bf15c30f714 100644
+--- a/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp
++++ b/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp
+@@ -492,66 +492,6 @@ void DWARFDie::getCallerFrame(uint32_t &CallFile, uint32_t &CallLine,
+ CallDiscriminator = toUnsigned(find(DW_AT_GNU_discriminator), 0);
+ }
+
+-std::optional<uint64_t> DWARFDie::getTypeSize(uint64_t PointerSize) {
+- if (auto SizeAttr = find(DW_AT_byte_size))
+- if (std::optional<uint64_t> Size = SizeAttr->getAsUnsignedConstant())
+- return Size;
+-
+- switch (getTag()) {
+- case DW_TAG_pointer_type:
+- case DW_TAG_reference_type:
+- case DW_TAG_rvalue_reference_type:
+- return PointerSize;
+- case DW_TAG_ptr_to_member_type: {
+- if (DWARFDie BaseType = getAttributeValueAsReferencedDie(DW_AT_type))
+- if (BaseType.getTag() == DW_TAG_subroutine_type)
+- return 2 * PointerSize;
+- return PointerSize;
+- }
+- case DW_TAG_const_type:
+- case DW_TAG_immutable_type:
+- case DW_TAG_volatile_type:
+- case DW_TAG_restrict_type:
+- case DW_TAG_typedef: {
+- if (DWARFDie BaseType = getAttributeValueAsReferencedDie(DW_AT_type))
+- return BaseType.getTypeSize(PointerSize);
+- break;
+- }
+- case DW_TAG_array_type: {
+- DWARFDie BaseType = getAttributeValueAsReferencedDie(DW_AT_type);
+- if (!BaseType)
+- return std::nullopt;
+- std::optional<uint64_t> BaseSize = BaseType.getTypeSize(PointerSize);
+- if (!BaseSize)
+- return std::nullopt;
+- uint64_t Size = *BaseSize;
+- for (DWARFDie Child : *this) {
+- if (Child.getTag() != DW_TAG_subrange_type)
+- continue;
+-
+- if (auto ElemCountAttr = Child.find(DW_AT_count))
+- if (std::optional<uint64_t> ElemCount =
+- ElemCountAttr->getAsUnsignedConstant())
+- Size *= *ElemCount;
+- if (auto UpperBoundAttr = Child.find(DW_AT_upper_bound))
+- if (std::optional<int64_t> UpperBound =
+- UpperBoundAttr->getAsSignedConstant()) {
+- int64_t LowerBound = 0;
+- if (auto LowerBoundAttr = Child.find(DW_AT_lower_bound))
+- LowerBound = LowerBoundAttr->getAsSignedConstant().value_or(0);
+- Size *= *UpperBound - LowerBound + 1;
+- }
+- }
+- return Size;
+- }
+- default:
+- if (DWARFDie BaseType = getAttributeValueAsReferencedDie(DW_AT_type))
+- return BaseType.getTypeSize(PointerSize);
+- break;
+- }
+- return std::nullopt;
+-}
+-
+ /// Helper to dump a DIE with all of its parents, but no siblings.
+ static unsigned dumpParentChain(DWARFDie Die, raw_ostream &OS, unsigned Indent,
+ DIDumpOptions DumpOpts, unsigned Depth = 0) {
+diff --git a/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp b/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp
+index 74667fcb92bc..148711f0246f 100644
+--- a/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp
++++ b/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp
+@@ -9,7 +9,6 @@
+ #include "llvm/DebugInfo/DWARF/DWARFUnit.h"
+ #include "llvm/ADT/SmallString.h"
+ #include "llvm/ADT/StringRef.h"
+-#include "llvm/BinaryFormat/Dwarf.h"
+ #include "llvm/DebugInfo/DWARF/DWARFAbbreviationDeclaration.h"
+ #include "llvm/DebugInfo/DWARF/DWARFCompileUnit.h"
+ #include "llvm/DebugInfo/DWARF/DWARFContext.h"
+@@ -19,13 +18,11 @@
+ #include "llvm/DebugInfo/DWARF/DWARFDebugRangeList.h"
+ #include "llvm/DebugInfo/DWARF/DWARFDebugRnglists.h"
+ #include "llvm/DebugInfo/DWARF/DWARFDie.h"
+-#include "llvm/DebugInfo/DWARF/DWARFExpression.h"
+ #include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
+ #include "llvm/DebugInfo/DWARF/DWARFListTable.h"
+ #include "llvm/DebugInfo/DWARF/DWARFObject.h"
+ #include "llvm/DebugInfo/DWARF/DWARFSection.h"
+ #include "llvm/DebugInfo/DWARF/DWARFTypeUnit.h"
+-#include "llvm/Object/ObjectFile.h"
+ #include "llvm/Support/DataExtractor.h"
+ #include "llvm/Support/Errc.h"
+ #include "llvm/Support/Path.h"
+@@ -752,100 +749,6 @@ DWARFDie DWARFUnit::getSubroutineForAddress(uint64_t Address) {
+ return R->second.second;
+ }
+
+-void DWARFUnit::updateVariableDieMap(DWARFDie Die) {
+- for (DWARFDie Child : Die) {
+- if (isType(Child.getTag()))
+- continue;
+- updateVariableDieMap(Child);
+- }
+-
+- if (Die.getTag() != DW_TAG_variable)
+- return;
+-
+- Expected<DWARFLocationExpressionsVector> Locations =
+- Die.getLocations(DW_AT_location);
+- if (!Locations) {
+- // Missing DW_AT_location is fine here.
+- consumeError(Locations.takeError());
+- return;
+- }
+-
+- uint64_t Address = UINT64_MAX;
+-
+- for (const DWARFLocationExpression &Location : *Locations) {
+- uint8_t AddressSize = getAddressByteSize();
+- DataExtractor Data(Location.Expr, /*IsLittleEndian=*/true, AddressSize);
+- DWARFExpression Expr(Data, AddressSize);
+- auto It = Expr.begin();
+- if (It == Expr.end())
+- continue;
+-
+- // Match exactly the main sequence used to describe global variables:
+- // `DW_OP_addr[x] [+ DW_OP_plus_uconst]`. Currently, this is the sequence
+- // that LLVM produces for DILocalVariables and DIGlobalVariables. If, in
+- // future, the DWARF producer (`DwarfCompileUnit::addLocationAttribute()` is
+- // a good starting point) is extended to use further expressions, this code
+- // needs to be updated.
+- uint64_t LocationAddr;
+- if (It->getCode() == dwarf::DW_OP_addr) {
+- LocationAddr = It->getRawOperand(0);
+- } else if (It->getCode() == dwarf::DW_OP_addrx) {
+- uint64_t DebugAddrOffset = It->getRawOperand(0);
+- if (auto Pointer = getAddrOffsetSectionItem(DebugAddrOffset)) {
+- LocationAddr = Pointer->Address;
+- }
+- } else {
+- continue;
+- }
+-
+- // Read the optional 2nd operand, a DW_OP_plus_uconst.
+- if (++It != Expr.end()) {
+- if (It->getCode() != dwarf::DW_OP_plus_uconst)
+- continue;
+-
+- LocationAddr += It->getRawOperand(0);
+-
+- // Probe for a 3rd operand, if it exists, bail.
+- if (++It != Expr.end())
+- continue;
+- }
+-
+- Address = LocationAddr;
+- break;
+- }
+-
+- // Get the size of the global variable. If all else fails (i.e. the global has
+- // no type), then we use a size of one to still allow symbolization of the
+- // exact address.
+- uint64_t GVSize = 1;
+- if (DWARFDie BaseType = Die.getAttributeValueAsReferencedDie(DW_AT_type))
+- if (std::optional<uint64_t> Size = Die.getTypeSize(getAddressByteSize()))
+- GVSize = *Size;
+-
+- if (Address != UINT64_MAX)
+- VariableDieMap[Address] = {Address + GVSize, Die};
+-}
+-
+-DWARFDie DWARFUnit::getVariableForAddress(uint64_t Address) {
+- extractDIEsIfNeeded(false);
+-
+- auto RootDie = getUnitDIE();
+-
+- auto RootLookup = RootsParsedForVariables.insert(RootDie.getOffset());
+- if (RootLookup.second)
+- updateVariableDieMap(RootDie);
+-
+- auto R = VariableDieMap.upper_bound(Address);
+- if (R == VariableDieMap.begin())
+- return DWARFDie();
+-
+- // upper_bound's previous item contains Address.
+- --R;
+- if (Address >= R->second.first)
+- return DWARFDie();
+- return R->second.second;
+-}
+-
+ void
+ DWARFUnit::getInlinedChainForAddress(uint64_t Address,
+ SmallVectorImpl<DWARFDie> &InlinedChain) {
+diff --git a/llvm/lib/DebugInfo/PDB/PDBContext.cpp b/llvm/lib/DebugInfo/PDB/PDBContext.cpp
+index e600fb7385f1..0444093d7622 100644
+--- a/llvm/lib/DebugInfo/PDB/PDBContext.cpp
++++ b/llvm/lib/DebugInfo/PDB/PDBContext.cpp
+@@ -64,13 +64,6 @@ DILineInfo PDBContext::getLineInfoForAddress(object::SectionedAddress Address,
+ return Result;
+ }
+
+-DILineInfo
+-PDBContext::getLineInfoForDataAddress(object::SectionedAddress Address) {
+- // Unimplemented. S_GDATA and S_LDATA in CodeView (used to describe global
+- // variables) aren't capable of carrying line information.
+- return DILineInfo();
+-}
+-
+ DILineInfoTable
+ PDBContext::getLineInfoForAddressRange(object::SectionedAddress Address,
+ uint64_t Size,
+diff --git a/llvm/lib/DebugInfo/Symbolize/DIPrinter.cpp b/llvm/lib/DebugInfo/Symbolize/DIPrinter.cpp
+index 877380213f21..496c8149782e 100644
+--- a/llvm/lib/DebugInfo/Symbolize/DIPrinter.cpp
++++ b/llvm/lib/DebugInfo/Symbolize/DIPrinter.cpp
+@@ -206,10 +206,6 @@ void PlainPrinterBase::print(const Request &Request, const DIGlobal &Global) {
+ Name = DILineInfo::Addr2LineBadString;
+ OS << Name << "\n";
+ OS << Global.Start << " " << Global.Size << "\n";
+- if (Global.DeclFile.empty())
+- OS << "??:?\n";
+- else
+- OS << Global.DeclFile << ":" << Global.DeclLine << "\n";
+ printFooter();
+ }
+
+diff --git a/llvm/lib/DebugInfo/Symbolize/SymbolizableObjectFile.cpp b/llvm/lib/DebugInfo/Symbolize/SymbolizableObjectFile.cpp
+index d8ee9264b64f..fcff531895a2 100644
+--- a/llvm/lib/DebugInfo/Symbolize/SymbolizableObjectFile.cpp
++++ b/llvm/lib/DebugInfo/Symbolize/SymbolizableObjectFile.cpp
+@@ -327,14 +327,6 @@ DIGlobal SymbolizableObjectFile::symbolizeData(
+ std::string FileName;
+ getNameFromSymbolTable(ModuleOffset.Address, Res.Name, Res.Start, Res.Size,
+ FileName);
+- Res.DeclFile = FileName;
+-
+- // Try and get a better filename:lineno pair from the debuginfo, if present.
+- DILineInfo DL = DebugInfoContext->getLineInfoForDataAddress(ModuleOffset);
+- if (DL.Line != 0) {
+- Res.DeclFile = DL.FileName;
+- Res.DeclLine = DL.Line;
+- }
+ return Res;
+ }
+
+diff --git a/llvm/test/DebugInfo/Symbolize/ELF/data-command-symtab.yaml b/llvm/test/DebugInfo/Symbolize/ELF/data-command-symtab.yaml
+index 83af3111c5dd..984e444b2fda 100644
+--- a/llvm/test/DebugInfo/Symbolize/ELF/data-command-symtab.yaml
++++ b/llvm/test/DebugInfo/Symbolize/ELF/data-command-symtab.yaml
+@@ -7,15 +7,12 @@
+
+ # CHECK: func
+ # CHECK-NEXT: 4096 1
+-# CHECK-NEXT: ??:?
+ # CHECK-EMPTY:
+ # CHECK-NEXT: data
+ # CHECK-NEXT: 8192 2
+-# CHECK-NEXT: ??:?
+ # CHECK-EMPTY:
+ # CHECK-NEXT: notype
+ # CHECK-NEXT: 8194 3
+-# CHECK-NEXT: ??:?
+ # CHECK-EMPTY:
+
+ --- !ELF
+diff --git a/llvm/test/tools/llvm-symbolizer/data-location.yaml b/llvm/test/tools/llvm-symbolizer/data-location.yaml
+deleted file mode 100644
+index 54f7d9be44a1..000000000000
+--- a/llvm/test/tools/llvm-symbolizer/data-location.yaml
++++ /dev/null
+@@ -1,450 +0,0 @@
+-## Show that when "DATA" is used with an address, it forces the found location
+-## to be symbolized as data, including the source information.
+-
+-# RUN: yaml2obj %s -o %t.so
+-
+-# RUN: llvm-symbolizer 'DATA 0x304d0' 'DATA 0x304d1' 'DATA 0x304d3' \
+-# RUN: 'DATA 0x304c0' 'DATA 0x304c8' 'DATA 0x304d4' 'DATA 0x304dc' \
+-# RUN: 'DATA 0x304d8' --obj=%t.so | FileCheck %s
+-
+-# CHECK: bss_global
+-# CHECK-NEXT: {{[0-9]+}} 4
+-# CHECK-NEXT: /tmp/file.cpp:1
+-# CHECK-EMPTY:
+-
+-## Check that lookups in the middle of the symbol are also resolved correctly.
+-# CHECK: bss_global
+-# CHECK-NEXT: {{[0-9]+}} 4
+-# CHECK-NEXT: /tmp/file.cpp:1
+-# CHECK-EMPTY:
+-# CHECK: bss_global
+-# CHECK-NEXT: {{[0-9]+}} 4
+-# CHECK-NEXT: /tmp/file.cpp:1
+-# CHECK-EMPTY:
+-
+-## Now, the remainder of the symbols.
+-# CHECK-NEXT: data_global
+-# CHECK-NEXT: {{[0-9]+}} 4
+-# CHECK-NEXT: /tmp/file.cpp:2
+-# CHECK-EMPTY:
+-# CHECK-NEXT: str
+-# CHECK-NEXT: {{[0-9]+}} 8
+-# CHECK-NEXT: /tmp/file.cpp:4
+-# CHECK-EMPTY:
+-# CHECK-NEXT: f()::function_global
+-# CHECK-NEXT: {{[0-9]+}} 4
+-# CHECK-NEXT: /tmp/file.cpp:8
+-# CHECK-EMPTY:
+-
+-## Including the one that includes an addend.
+-# CHECK-NEXT: alpha
+-# CHECK-NEXT: {{[0-9]+}} 4
+-# CHECK-NEXT: /tmp/file.cpp:12
+-# CHECK-EMPTY:
+-# CHECK-NEXT: beta
+-# CHECK-NEXT: {{[0-9]+}} 4
+-# CHECK-NEXT: /tmp/file.cpp:13
+-# CHECK-EMPTY:
+-
+-## Ensure there's still a global that's offset-based.
+-# RUN: llvm-dwarfdump --debug-info %t.so | FileCheck %s --check-prefix=OFFSET
+-
+-# OFFSET: DW_AT_location (DW_OP_addrx 0x4, DW_OP_plus_uconst 0x4)
+-
+-################################################################################
+-## File below was generated using:
+-##
+-## $ clang++ -g -O3 /tmp/file.cpp -shared -fuse-ld=lld -nostdlib \
+-## -target aarch64-linux-gnuabi -mllvm -global-merge-ignore-single-use \
+-## -o /tmp/file.so
+-##
+-## With /tmp/file.cpp as:
+-## 1: int bss_global;
+-## 2: int data_global = 2;
+-## 3:
+-## 4: const char* str =
+-## 5: "12345678";
+-## 6:
+-## 7: int* f() {
+-## 8: static int function_global;
+-## 9: return &function_global;
+-## 10: }
+-## 11:
+-## 12: static int alpha;
+-## 13: static int beta;
+-## 14: int *f(bool b) { return beta ? &alpha : &beta; }
+-## 15:
+-##
+-## ... then, one can get the offsets using `nm`, like:
+-## $ nm out.so | grep bss_global
+-## 00000000000038fc B bss_global
+-##
+-## Note the use of the aarch64 target (with -nostdlib in order to allow linkage
+-## without libraries for cross-compilation) as well as -O3 and
+-## -global-merge-ignore-single-use. This is a specific combination that makes
+-## the compiler emit the `alpha` global variable with a more complex
+-## DW_AT_location than just a DW_OP_addr/DW_OP_addrx. In this instance, it
+-## outputs a `DW_AT_location (DW_OP_addrx 0x4, DW_OP_plus_uconst 0x4)`.
+-##
+-## Ideally, this would be tested by invoking clang directly on a C source file,
+-## but unfortunately there's no way to do that for LLVM tests. The other option
+-## is to compile IR to an objfile, but llvm-symbolizer doesn't understand that
+-## two symbols can have the same address in different sections. In the code
+-## above, for example, we'd have bss_global at .bss+0x0, and data_global at
+-## .data+0x0, and so the symbolizer would only print one of them. Hence, we have
+-## the ugly dso-to-yaml blob below.
+-##
+-## For now, constant strings don't have a debuginfo entry, and so can't be
+-## symbolized correctly. In future (if D123534 gets merged), this can be updated
+-## to include a check that llvm-symbolizer can also symbolize constant strings,
+-## like `str` above (basically that &"12345678" should be symbolizable)
+-## to the specific line. Then, you can find the address of the constant string
+-## from the relocation:
+-##
+-## $ nm out.so | grep str
+-## 00000000000038c0 D str
+-## $ llvm-objdump -R out.so | grep 38c0
+-## 00000000000038c0 R_X86_64_RELATIVE *ABS*+0x4f8 # <-- 0x4f8
+-################################################################################
+-
+---- !ELF
+-FileHeader:
+- Class: ELFCLASS64
+- Data: ELFDATA2LSB
+- Type: ET_DYN
+- Machine: EM_AARCH64
+-ProgramHeaders:
+- - Type: PT_PHDR
+- Flags: [ PF_R ]
+- VAddr: 0x40
+- Align: 0x8
+- - Type: PT_LOAD
+- Flags: [ PF_R ]
+- FirstSec: .dynsym
+- LastSec: .eh_frame
+- Align: 0x10000
+- - Type: PT_LOAD
+- Flags: [ PF_X, PF_R ]
+- FirstSec: .text
+- LastSec: .text
+- VAddr: 0x103E4
+- Align: 0x10000
+- - Type: PT_LOAD
+- Flags: [ PF_W, PF_R ]
+- FirstSec: .dynamic
+- LastSec: .dynamic
+- VAddr: 0x20410
+- Align: 0x10000
+- - Type: PT_LOAD
+- Flags: [ PF_W, PF_R ]
+- FirstSec: .data
+- LastSec: .bss
+- VAddr: 0x304C0
+- Align: 0x10000
+- - Type: PT_DYNAMIC
+- Flags: [ PF_W, PF_R ]
+- FirstSec: .dynamic
+- LastSec: .dynamic
+- VAddr: 0x20410
+- Align: 0x8
+- - Type: PT_GNU_RELRO
+- Flags: [ PF_R ]
+- FirstSec: .dynamic
+- LastSec: .dynamic
+- VAddr: 0x20410
+- - Type: PT_GNU_EH_FRAME
+- Flags: [ PF_R ]
+- FirstSec: .eh_frame_hdr
+- LastSec: .eh_frame_hdr
+- VAddr: 0x37C
+- Align: 0x4
+- - Type: PT_GNU_STACK
+- Flags: [ PF_W, PF_R ]
+- Align: 0x0
+-Sections:
+- - Name: .dynsym
+- Type: SHT_DYNSYM
+- Flags: [ SHF_ALLOC ]
+- Address: 0x238
+- Link: .dynstr
+- AddressAlign: 0x8
+- - Name: .gnu.hash
+- Type: SHT_GNU_HASH
+- Flags: [ SHF_ALLOC ]
+- Address: 0x2C8
+- Link: .dynsym
+- AddressAlign: 0x8
+- Header:
+- SymNdx: 0x1
+- Shift2: 0x1A
+- BloomFilter: [ 0x400188002180000C ]
+- HashBuckets: [ 0x1 ]
+- HashValues: [ 0xEE8502A, 0xEE85016, 0xC033991C, 0x61F7372E, 0xB88AB7F ]
+- - Name: .hash
+- Type: SHT_HASH
+- Flags: [ SHF_ALLOC ]
+- Address: 0x2F8
+- Link: .dynsym
+- AddressAlign: 0x4
+- Bucket: [ 5, 0, 4, 0, 3, 0 ]
+- Chain: [ 0, 0, 0, 1, 2, 0 ]
+- - Name: .dynstr
+- Type: SHT_STRTAB
+- Flags: [ SHF_ALLOC ]
+- Address: 0x330
+- AddressAlign: 0x1
+- - Name: .rela.dyn
+- Type: SHT_RELA
+- Flags: [ SHF_ALLOC ]
+- Address: 0x358
+- Link: .dynsym
+- AddressAlign: 0x8
+- Relocations:
+- - Offset: 0x304C8
+- Type: R_AARCH64_RELATIVE
+- Addend: 880
+- - Name: .rodata
+- Type: SHT_PROGBITS
+- Flags: [ SHF_ALLOC, SHF_MERGE, SHF_STRINGS ]
+- Address: 0x370
+- AddressAlign: 0x1
+- EntSize: 0x1
+- Content: '313233343536373800'
+- - Name: .eh_frame_hdr
+- Type: SHT_PROGBITS
+- Flags: [ SHF_ALLOC ]
+- Address: 0x37C
+- AddressAlign: 0x4
+- Content: 011B033B18000000020000006800010034000000740001004C000000
+- - Name: .eh_frame
+- Type: SHT_PROGBITS
+- Flags: [ SHF_ALLOC ]
+- Address: 0x398
+- AddressAlign: 0x8
+- Content: 1400000000000000017A5200017C1E011B0C1F0000000000140000001C0000002C0001000C00000000000000000000001400000034000000200001001C000000000000000000000000000000
+- - Name: .text
+- Type: SHT_PROGBITS
+- Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
+- Address: 0x103E4
+- AddressAlign: 0x4
+- Content: 0001009000501391C0035FD60801009008611391E90308AA2A4540B85F0100710001899AC0035FD6
+- - Name: .dynamic
+- Type: SHT_DYNAMIC
+- Flags: [ SHF_WRITE, SHF_ALLOC ]
+- Address: 0x20410
+- Link: .dynstr
+- AddressAlign: 0x8
+- Entries:
+- - Tag: DT_RELA
+- Value: 0x358
+- - Tag: DT_RELASZ
+- Value: 0x18
+- - Tag: DT_RELAENT
+- Value: 0x18
+- - Tag: DT_RELACOUNT
+- Value: 0x1
+- - Tag: DT_SYMTAB
+- Value: 0x238
+- - Tag: DT_SYMENT
+- Value: 0x18
+- - Tag: DT_STRTAB
+- Value: 0x330
+- - Tag: DT_STRSZ
+- Value: 0x28
+- - Tag: DT_GNU_HASH
+- Value: 0x2C8
+- - Tag: DT_HASH
+- Value: 0x2F8
+- - Tag: DT_NULL
+- Value: 0x0
+- - Name: .data
+- Type: SHT_PROGBITS
+- Flags: [ SHF_WRITE, SHF_ALLOC ]
+- Address: 0x304C0
+- AddressAlign: 0x8
+- Content: '02000000000000000000000000000000'
+- - Name: .bss
+- Type: SHT_NOBITS
+- Flags: [ SHF_WRITE, SHF_ALLOC ]
+- Address: 0x304D0
+- AddressAlign: 0x4
+- Size: 0x10
+- - Name: .debug_abbrev
+- Type: SHT_PROGBITS
+- AddressAlign: 0x1
+- Content: 011101252513050325721710171B25111B120673170000023400032549133F193A0B3B0B0218000003240003253E0B0B0B0000040F004913000005260049130000062E01111B120640187A196E2503253A0B3B0B49133F190000073400032549133A0B3B0B02180000083400032549133A0B3B0B02186E25000009050003253A0B3B0B4913000000
+- - Name: .debug_info
+- Type: SHT_PROGBITS
+- AddressAlign: 0x1
+- Content: AB0000000500010800000000010021000108000000000000000205280000000800000002032E000000000102A1000304050402052E000000000202A101020648000000000402A102044D00000005520000000307080106050C000000016F0D0E0007A500000007082E000000000802A1030008092E000000000D02A1040A080B2E000000000C04A10423040C06061C000000016F0F0E000EA50000000910000EAA00000000042E0000000311020100
+- - Name: .debug_str_offsets
+- Type: SHT_PROGBITS
+- AddressAlign: 0x1
+- Content: 4C00000005000000A2000000000000002C00000059000000280000001C00000072000000640000008C0000008700000069000000140000007B0000009C0000001A0000000E0000008500000076000000
+- - Name: .comment
+- Type: SHT_PROGBITS
+- Flags: [ SHF_MERGE, SHF_STRINGS ]
+- AddressAlign: 0x1
+- EntSize: 0x1
+- Content: 4C696E6B65723A204C4C442031352E302E300000636C616E672076657273696F6E2031352E302E30202868747470733A2F2F6769746875622E636F6D2F6C6C766D2F6C6C766D2D70726F6A6563742E67697420306462616566363162353666306566306162306366333865613932666663316633356265653366662900
+- - Name: .debug_line
+- Type: SHT_PROGBITS
+- AddressAlign: 0x1
+- Content: 620000000500080037000000010101FB0E0D00010101010000000100000101011F010E00000003011F020F051E0100000000006C97BBE59F7DC6A9EA956633431DA63E0400000902E4030100000000001805030A140500BF05190A0105120608740204000101
+- - Name: .debug_line_str
+- Type: SHT_PROGBITS
+- Flags: [ SHF_MERGE, SHF_STRINGS ]
+- AddressAlign: 0x1
+- EntSize: 0x1
+- Content: 2F746D702F66696C652E637070002F7573722F6C6F63616C2F676F6F676C652F686F6D652F6D69746368702F6C6C766D2D6275696C642F6F707400
+-Symbols:
+- - Name: file.cpp
+- Type: STT_FILE
+- Index: SHN_ABS
+- - Name: '$x.0'
+- Section: .text
+- Value: 0x103E4
+- - Name: _ZZ1fvE15function_global
+- Type: STT_OBJECT
+- Section: .bss
+- Value: 0x304D4
+- Size: 0x4
+- - Name: '$d.1'
+- Section: .bss
+- Value: 0x304D0
+- - Name: '$d.2'
+- Section: .data
+- Value: 0x304C0
+- - Name: '$d.3'
+- Section: .rodata
+- Value: 0x370
+- - Name: '$d.4'
+- Section: .debug_abbrev
+- - Name: '$d.5'
+- Section: .debug_info
+- - Name: '$d.6'
+- Section: .debug_str_offsets
+- - Name: '$d.7'
+- Section: .debug_str
+- Value: 0xA2
+- - Name: '$d.8'
+- Section: .debug_addr
+- - Name: _ZL4beta
+- Type: STT_OBJECT
+- Section: .bss
+- Value: 0x304D8
+- Size: 0x4
+- - Name: _ZL5alpha
+- Type: STT_OBJECT
+- Section: .bss
+- Value: 0x304DC
+- Size: 0x4
+- - Name: '$d.9'
+- Section: .comment
+- Value: 0x13
+- - Name: '$d.10'
+- Section: .eh_frame
+- Value: 0x398
+- - Name: '$d.11'
+- Section: .debug_line
+- - Name: '$d.12'
+- Section: .debug_line_str
+- Value: 0xE
+- - Name: _DYNAMIC
+- Section: .dynamic
+- Value: 0x20410
+- Other: [ STV_HIDDEN ]
+- - Name: _Z1fv
+- Type: STT_FUNC
+- Section: .text
+- Binding: STB_GLOBAL
+- Value: 0x103E4
+- Size: 0xC
+- - Name: _Z1fb
+- Type: STT_FUNC
+- Section: .text
+- Binding: STB_GLOBAL
+- Value: 0x103F0
+- Size: 0x1C
+- - Name: bss_global
+- Type: STT_OBJECT
+- Section: .bss
+- Binding: STB_GLOBAL
+- Value: 0x304D0
+- Size: 0x4
+- - Name: data_global
+- Type: STT_OBJECT
+- Section: .data
+- Binding: STB_GLOBAL
+- Value: 0x304C0
+- Size: 0x4
+- - Name: str
+- Type: STT_OBJECT
+- Section: .data
+- Binding: STB_GLOBAL
+- Value: 0x304C8
+- Size: 0x8
+-DynamicSymbols:
+- - Name: _Z1fv
+- Type: STT_FUNC
+- Section: .text
+- Binding: STB_GLOBAL
+- Value: 0x103E4
+- Size: 0xC
+- - Name: _Z1fb
+- Type: STT_FUNC
+- Section: .text
+- Binding: STB_GLOBAL
+- Value: 0x103F0
+- Size: 0x1C
+- - Name: bss_global
+- Type: STT_OBJECT
+- Section: .bss
+- Binding: STB_GLOBAL
+- Value: 0x304D0
+- Size: 0x4
+- - Name: data_global
+- Type: STT_OBJECT
+- Section: .data
+- Binding: STB_GLOBAL
+- Value: 0x304C0
+- Size: 0x4
+- - Name: str
+- Type: STT_OBJECT
+- Section: .data
+- Binding: STB_GLOBAL
+- Value: 0x304C8
+- Size: 0x8
+-DWARF:
+- debug_str:
+- - '/tmp/file.cpp'
+- - _Z1fb
+- - alpha
+- - f
+- - data_global
+- - int
+- - '/usr/local/google/home/mitchp/llvm-build/opt'
+- - bss_global
+- - char
+- - _ZL4beta
+- - str
+- - bool
+- - _ZL5alpha
+- - b
+- - beta
+- - function_global
+- - _Z1fv
+- - 'clang version 15.0.0 (https://github.com/llvm/llvm-project.git 0dbaef61b56f0ef0ab0cf38ea92ffc1f35bee3ff)'
+- debug_addr:
+- - Length: 0x3C
+- Version: 0x5
+- AddressSize: 0x8
+- Entries:
+- - Address: 0x304D0
+- - Address: 0x304C0
+- - Address: 0x304C8
+- - Address: 0x304D4
+- - Address: 0x304D8
+- - Address: 0x103E4
+- - Address: 0x103F0
+-...
+diff --git a/llvm/test/tools/llvm-symbolizer/data.s b/llvm/test/tools/llvm-symbolizer/data.s
+index cc9503c59141..e8039f146dbd 100644
+--- a/llvm/test/tools/llvm-symbolizer/data.s
++++ b/llvm/test/tools/llvm-symbolizer/data.s
+@@ -7,12 +7,9 @@
+
+ # CHECK: d1
+ # CHECK-NEXT: 0 8
+-# CHECK-NEXT: ??:?
+ # CHECK-EMPTY:
+ # CHECK-NEXT: d2
+ # CHECK-NEXT: 8 4
+-# CHECK-NEXT: ??:?
+-# CHECK-EMPTY:
+
+ d1:
+ .quad 0x1122334455667788
+--
+2.38.1.1.g6d9df9d320
+
diff --git a/build/build-clang/revert-llvmorg-15-init-11205-gcead4eceb01b_clang_18.patch b/build/build-clang/revert-llvmorg-15-init-11205-gcead4eceb01b_clang_18.patch
new file mode 100644
index 0000000000..908374789c
--- /dev/null
+++ b/build/build-clang/revert-llvmorg-15-init-11205-gcead4eceb01b_clang_18.patch
@@ -0,0 +1,972 @@
+From cb411520cb7cd5e6e25966911ca55feb5de779e0 Mon Sep 17 00:00:00 2001
+From: Mike Hommey <mh@glandium.org>
+Date: Fri, 4 Nov 2022 14:51:38 +0900
+Subject: [PATCH] Revert "[symbolizer] Parse DW_TAG_variable DIs to show line
+ info for globals"
+
+This reverts commit cead4eceb01b935fae07bf4a7e91911b344d2fec for causing
+yet unidentified problems on some webrtc tests under TSan (bug 1798613).
+---
+ llvm/include/llvm/DebugInfo/DIContext.h | 4 -
+ .../llvm/DebugInfo/DWARF/DWARFContext.h | 2 -
+ llvm/include/llvm/DebugInfo/DWARF/DWARFDie.h | 7 -
+ llvm/include/llvm/DebugInfo/DWARF/DWARFUnit.h | 14 -
+ llvm/include/llvm/DebugInfo/PDB/PDBContext.h | 2 -
+ llvm/lib/DebugInfo/DWARF/DWARFContext.cpp | 97 ++--
+ llvm/lib/DebugInfo/DWARF/DWARFDie.cpp | 60 ---
+ llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp | 97 ----
+ llvm/lib/DebugInfo/PDB/PDBContext.cpp | 7 -
+ llvm/lib/DebugInfo/Symbolize/DIPrinter.cpp | 4 -
+ .../Symbolize/SymbolizableObjectFile.cpp | 8 -
+ .../Symbolize/ELF/data-command-symtab.yaml | 3 -
+ .../tools/llvm-symbolizer/data-location.yaml | 450 ------------------
+ llvm/test/tools/llvm-symbolizer/data.s | 3 -
+ 14 files changed, 61 insertions(+), 697 deletions(-)
+ delete mode 100644 llvm/test/tools/llvm-symbolizer/data-location.yaml
+
+diff --git a/llvm/include/llvm/DebugInfo/DIContext.h b/llvm/include/llvm/DebugInfo/DIContext.h
+index 9b278b696073..a9f98588cf2d 100644
+--- a/llvm/include/llvm/DebugInfo/DIContext.h
++++ b/llvm/include/llvm/DebugInfo/DIContext.h
+@@ -114,8 +114,6 @@ struct DIGlobal {
+ std::string Name;
+ uint64_t Start = 0;
+ uint64_t Size = 0;
+- std::string DeclFile;
+- uint64_t DeclLine = 0;
+
+ DIGlobal() : Name(DILineInfo::BadString) {}
+ };
+@@ -241,8 +239,6 @@ public:
+ virtual DILineInfo getLineInfoForAddress(
+ object::SectionedAddress Address,
+ DILineInfoSpecifier Specifier = DILineInfoSpecifier()) = 0;
+- virtual DILineInfo
+- getLineInfoForDataAddress(object::SectionedAddress Address) = 0;
+ virtual DILineInfoTable getLineInfoForAddressRange(
+ object::SectionedAddress Address, uint64_t Size,
+ DILineInfoSpecifier Specifier = DILineInfoSpecifier()) = 0;
+diff --git a/llvm/include/llvm/DebugInfo/DWARF/DWARFContext.h b/llvm/include/llvm/DebugInfo/DWARF/DWARFContext.h
+index bf591ed554c6..3365ef8d8ee3 100644
+--- a/llvm/include/llvm/DebugInfo/DWARF/DWARFContext.h
++++ b/llvm/include/llvm/DebugInfo/DWARF/DWARFContext.h
+@@ -364,8 +364,6 @@ public:
+ DILineInfo getLineInfoForAddress(
+ object::SectionedAddress Address,
+ DILineInfoSpecifier Specifier = DILineInfoSpecifier()) override;
+- DILineInfo
+- getLineInfoForDataAddress(object::SectionedAddress Address) override;
+ DILineInfoTable getLineInfoForAddressRange(
+ object::SectionedAddress Address, uint64_t Size,
+ DILineInfoSpecifier Specifier = DILineInfoSpecifier()) override;
+diff --git a/llvm/include/llvm/DebugInfo/DWARF/DWARFDie.h b/llvm/include/llvm/DebugInfo/DWARF/DWARFDie.h
+index 149c5ef4e493..4a4d105a2b23 100644
+--- a/llvm/include/llvm/DebugInfo/DWARF/DWARFDie.h
++++ b/llvm/include/llvm/DebugInfo/DWARF/DWARFDie.h
+@@ -280,13 +280,6 @@ public:
+ /// \returns an iterator range for the attributes of the current DIE.
+ iterator_range<attribute_iterator> attributes() const;
+
+- /// Gets the type size (in bytes) for this DIE.
+- ///
+- /// \param PointerSize the pointer size of the containing CU.
+- /// \returns if this is a type DIE, or this DIE contains a DW_AT_type, returns
+- /// the size of the type.
+- std::optional<uint64_t> getTypeSize(uint64_t PointerSize);
+-
+ class iterator;
+
+ iterator begin() const;
+diff --git a/llvm/include/llvm/DebugInfo/DWARF/DWARFUnit.h b/llvm/include/llvm/DebugInfo/DWARF/DWARFUnit.h
+index 9188865b4d77..0341344bc7b8 100644
+--- a/llvm/include/llvm/DebugInfo/DWARF/DWARFUnit.h
++++ b/llvm/include/llvm/DebugInfo/DWARF/DWARFUnit.h
+@@ -9,7 +9,6 @@
+ #ifndef LLVM_DEBUGINFO_DWARF_DWARFUNIT_H
+ #define LLVM_DEBUGINFO_DWARF_DWARFUNIT_H
+
+-#include "llvm/ADT/DenseSet.h"
+ #include "llvm/ADT/STLExtras.h"
+ #include "llvm/ADT/SmallVector.h"
+ #include "llvm/ADT/StringRef.h"
+@@ -28,7 +27,6 @@
+ #include <cstdint>
+ #include <map>
+ #include <memory>
+-#include <set>
+ #include <utility>
+ #include <vector>
+
+@@ -242,11 +240,6 @@ class DWARFUnit {
+ /// std::map::upper_bound for address range lookup.
+ std::map<uint64_t, std::pair<uint64_t, DWARFDie>> AddrDieMap;
+
+- /// Map from the location (interpreted DW_AT_location) of a DW_TAG_variable,
+- /// to the end address and the corresponding DIE.
+- std::map<uint64_t, std::pair<uint64_t, DWARFDie>> VariableDieMap;
+- DenseSet<uint64_t> RootsParsedForVariables;
+-
+ using die_iterator_range =
+ iterator_range<std::vector<DWARFDebugInfoEntry>::iterator>;
+
+@@ -329,9 +322,6 @@ public:
+ /// Recursively update address to Die map.
+ void updateAddressDieMap(DWARFDie Die);
+
+- /// Recursively update address to variable Die map.
+- void updateVariableDieMap(DWARFDie Die);
+-
+ void setRangesSection(const DWARFSection *RS, uint64_t Base) {
+ RangeSection = RS;
+ RangeSectionBase = Base;
+@@ -446,10 +436,6 @@ public:
+ /// cleared.
+ DWARFDie getSubroutineForAddress(uint64_t Address);
+
+- /// Returns variable DIE for the address provided. The pointer is alive as
+- /// long as parsed compile unit DIEs are not cleared.
+- DWARFDie getVariableForAddress(uint64_t Address);
+-
+ /// getInlinedChainForAddress - fetches inlined chain for a given address.
+ /// Returns empty chain if there is no subprogram containing address. The
+ /// chain is valid as long as parsed compile unit DIEs are not cleared.
+diff --git a/llvm/include/llvm/DebugInfo/PDB/PDBContext.h b/llvm/include/llvm/DebugInfo/PDB/PDBContext.h
+index 3163c0a1dae0..7b6793f0a639 100644
+--- a/llvm/include/llvm/DebugInfo/PDB/PDBContext.h
++++ b/llvm/include/llvm/DebugInfo/PDB/PDBContext.h
+@@ -45,8 +45,6 @@ namespace pdb {
+ DILineInfo getLineInfoForAddress(
+ object::SectionedAddress Address,
+ DILineInfoSpecifier Specifier = DILineInfoSpecifier()) override;
+- DILineInfo
+- getLineInfoForDataAddress(object::SectionedAddress Address) override;
+ DILineInfoTable getLineInfoForAddressRange(
+ object::SectionedAddress Address, uint64_t Size,
+ DILineInfoSpecifier Specifier = DILineInfoSpecifier()) override;
+diff --git a/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp b/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
+index 19d7d659a86a..1bcfdecfd588 100644
+--- a/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
++++ b/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
+@@ -1053,25 +1053,7 @@ DWARFCompileUnit *DWARFContext::getCompileUnitForAddress(uint64_t Address) {
+ // First, get the offset of the compile unit.
+ uint64_t CUOffset = getDebugAranges()->findAddress(Address);
+ // Retrieve the compile unit.
+- if (DWARFCompileUnit *OffsetCU = getCompileUnitForOffset(CUOffset))
+- return OffsetCU;
+-
+- // Global variables are often not found by the above search, for one of two
+- // reasons:
+- // 1. .debug_aranges may not include global variables. On clang, it seems we
+- // put the globals in the aranges, but this isn't true for gcc.
+- // 2. Even if the global variable is in a .debug_arange, global variables
+- // may not be captured in the [start, end) addresses described by the
+- // parent compile unit.
+- //
+- // So, we walk the CU's and their child DI's manually, looking for the
+- // specific global variable.
+- for (std::unique_ptr<DWARFUnit> &CU : compile_units()) {
+- if (CU->getVariableForAddress(Address)) {
+- return static_cast<DWARFCompileUnit *>(CU.get());
+- }
+- }
+- return nullptr;
++ return getCompileUnitForOffset(CUOffset);
+ }
+
+ DWARFContext::DIEsForAddress DWARFContext::getDIEsForAddress(uint64_t Address,
+@@ -1141,6 +1123,64 @@ static bool getFunctionNameAndStartLineForAddress(
+ return FoundResult;
+ }
+
++static std::optional<uint64_t> getTypeSize(DWARFDie Type, uint64_t PointerSize) {
++ if (auto SizeAttr = Type.find(DW_AT_byte_size))
++ if (std::optional<uint64_t> Size = SizeAttr->getAsUnsignedConstant())
++ return Size;
++
++ switch (Type.getTag()) {
++ case DW_TAG_pointer_type:
++ case DW_TAG_reference_type:
++ case DW_TAG_rvalue_reference_type:
++ return PointerSize;
++ case DW_TAG_ptr_to_member_type: {
++ if (DWARFDie BaseType = Type.getAttributeValueAsReferencedDie(DW_AT_type))
++ if (BaseType.getTag() == DW_TAG_subroutine_type)
++ return 2 * PointerSize;
++ return PointerSize;
++ }
++ case DW_TAG_const_type:
++ case DW_TAG_immutable_type:
++ case DW_TAG_volatile_type:
++ case DW_TAG_restrict_type:
++ case DW_TAG_typedef: {
++ if (DWARFDie BaseType = Type.getAttributeValueAsReferencedDie(DW_AT_type))
++ return getTypeSize(BaseType, PointerSize);
++ break;
++ }
++ case DW_TAG_array_type: {
++ DWARFDie BaseType = Type.getAttributeValueAsReferencedDie(DW_AT_type);
++ if (!BaseType)
++ return std::optional<uint64_t>();
++ std::optional<uint64_t> BaseSize = getTypeSize(BaseType, PointerSize);
++ if (!BaseSize)
++ return std::optional<uint64_t>();
++ uint64_t Size = *BaseSize;
++ for (DWARFDie Child : Type) {
++ if (Child.getTag() != DW_TAG_subrange_type)
++ continue;
++
++ if (auto ElemCountAttr = Child.find(DW_AT_count))
++ if (std::optional<uint64_t> ElemCount =
++ ElemCountAttr->getAsUnsignedConstant())
++ Size *= *ElemCount;
++ if (auto UpperBoundAttr = Child.find(DW_AT_upper_bound))
++ if (std::optional<int64_t> UpperBound =
++ UpperBoundAttr->getAsSignedConstant()) {
++ int64_t LowerBound = 0;
++ if (auto LowerBoundAttr = Child.find(DW_AT_lower_bound))
++ LowerBound = LowerBoundAttr->getAsSignedConstant().value_or(0);
++ Size *= *UpperBound - LowerBound + 1;
++ }
++ }
++ return Size;
++ }
++ default:
++ break;
++ }
++ return std::optional<uint64_t>();
++}
++
+ static std::optional<int64_t>
+ getExpressionFrameOffset(ArrayRef<uint8_t> Expr,
+ std::optional<unsigned> FrameBaseReg) {
+@@ -1201,7 +1241,7 @@ void DWARFContext::addLocalsForDie(DWARFCompileUnit *CU, DWARFDie Subprogram,
+ if (std::optional<const char *> Name = dwarf::toString(*NameAttr))
+ Local.Name = *Name;
+ if (auto Type = Die.getAttributeValueAsReferencedDie(DW_AT_type))
+- Local.Size = Type.getTypeSize(getCUAddrSize());
++ Local.Size = getTypeSize(Type, getCUAddrSize());
+ if (auto DeclFileAttr = Die.find(DW_AT_decl_file)) {
+ if (const auto *LT = CU->getContext().getLineTableForUnit(CU))
+ LT->getFileNameByIndex(
+@@ -1242,6 +1282,7 @@ DWARFContext::getLocalsForAddress(object::SectionedAddress Address) {
+ DILineInfo DWARFContext::getLineInfoForAddress(object::SectionedAddress Address,
+ DILineInfoSpecifier Spec) {
+ DILineInfo Result;
++
+ DWARFCompileUnit *CU = getCompileUnitForAddress(Address.Address);
+ if (!CU)
+ return Result;
+@@ -1256,22 +1297,6 @@ DILineInfo DWARFContext::getLineInfoForAddress(object::SectionedAddress Address,
+ Spec.FLIKind, Result);
+ }
+ }
+-
+- return Result;
+-}
+-
+-DILineInfo
+-DWARFContext::getLineInfoForDataAddress(object::SectionedAddress Address) {
+- DILineInfo Result;
+- DWARFCompileUnit *CU = getCompileUnitForAddress(Address.Address);
+- if (!CU)
+- return Result;
+-
+- if (DWARFDie Die = CU->getVariableForAddress(Address.Address)) {
+- Result.FileName = Die.getDeclFile(FileLineInfoKind::AbsoluteFilePath);
+- Result.Line = Die.getDeclLine();
+- }
+-
+ return Result;
+ }
+
+diff --git a/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp
+index 66492f7bf804..357b172bf99b 100644
+--- a/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp
++++ b/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp
+@@ -556,11 +556,6 @@ getTypeSizeImpl(DWARFDie Die, uint64_t PointerSize,
+ return std::nullopt;
+ }
+
+-std::optional<uint64_t> DWARFDie::getTypeSize(uint64_t PointerSize) {
+- SmallPtrSet<const DWARFDebugInfoEntry *, 4> Visited;
+- return getTypeSizeImpl(*this, PointerSize, Visited);
+-}
+-
+ /// Helper to dump a DIE with all of its parents, but no siblings.
+ static unsigned dumpParentChain(DWARFDie Die, raw_ostream &OS, unsigned Indent,
+ DIDumpOptions DumpOpts, unsigned Depth = 0) {
+diff --git a/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp b/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp
+index 74667fcb92bc..148711f0246f 100644
+--- a/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp
++++ b/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp
+@@ -9,7 +9,6 @@
+ #include "llvm/DebugInfo/DWARF/DWARFUnit.h"
+ #include "llvm/ADT/SmallString.h"
+ #include "llvm/ADT/StringRef.h"
+-#include "llvm/BinaryFormat/Dwarf.h"
+ #include "llvm/DebugInfo/DWARF/DWARFAbbreviationDeclaration.h"
+ #include "llvm/DebugInfo/DWARF/DWARFCompileUnit.h"
+ #include "llvm/DebugInfo/DWARF/DWARFContext.h"
+@@ -19,13 +18,11 @@
+ #include "llvm/DebugInfo/DWARF/DWARFDebugRangeList.h"
+ #include "llvm/DebugInfo/DWARF/DWARFDebugRnglists.h"
+ #include "llvm/DebugInfo/DWARF/DWARFDie.h"
+-#include "llvm/DebugInfo/DWARF/DWARFExpression.h"
+ #include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
+ #include "llvm/DebugInfo/DWARF/DWARFListTable.h"
+ #include "llvm/DebugInfo/DWARF/DWARFObject.h"
+ #include "llvm/DebugInfo/DWARF/DWARFSection.h"
+ #include "llvm/DebugInfo/DWARF/DWARFTypeUnit.h"
+-#include "llvm/Object/ObjectFile.h"
+ #include "llvm/Support/DataExtractor.h"
+ #include "llvm/Support/Errc.h"
+ #include "llvm/Support/Path.h"
+@@ -752,100 +749,6 @@ DWARFDie DWARFUnit::getSubroutineForAddress(uint64_t Address) {
+ return R->second.second;
+ }
+
+-void DWARFUnit::updateVariableDieMap(DWARFDie Die) {
+- for (DWARFDie Child : Die) {
+- if (isType(Child.getTag()))
+- continue;
+- updateVariableDieMap(Child);
+- }
+-
+- if (Die.getTag() != DW_TAG_variable)
+- return;
+-
+- Expected<DWARFLocationExpressionsVector> Locations =
+- Die.getLocations(DW_AT_location);
+- if (!Locations) {
+- // Missing DW_AT_location is fine here.
+- consumeError(Locations.takeError());
+- return;
+- }
+-
+- uint64_t Address = UINT64_MAX;
+-
+- for (const DWARFLocationExpression &Location : *Locations) {
+- uint8_t AddressSize = getAddressByteSize();
+- DataExtractor Data(Location.Expr, isLittleEndian(), AddressSize);
+- DWARFExpression Expr(Data, AddressSize);
+- auto It = Expr.begin();
+- if (It == Expr.end())
+- continue;
+-
+- // Match exactly the main sequence used to describe global variables:
+- // `DW_OP_addr[x] [+ DW_OP_plus_uconst]`. Currently, this is the sequence
+- // that LLVM produces for DILocalVariables and DIGlobalVariables. If, in
+- // future, the DWARF producer (`DwarfCompileUnit::addLocationAttribute()` is
+- // a good starting point) is extended to use further expressions, this code
+- // needs to be updated.
+- uint64_t LocationAddr;
+- if (It->getCode() == dwarf::DW_OP_addr) {
+- LocationAddr = It->getRawOperand(0);
+- } else if (It->getCode() == dwarf::DW_OP_addrx) {
+- uint64_t DebugAddrOffset = It->getRawOperand(0);
+- if (auto Pointer = getAddrOffsetSectionItem(DebugAddrOffset)) {
+- LocationAddr = Pointer->Address;
+- }
+- } else {
+- continue;
+- }
+-
+- // Read the optional 2nd operand, a DW_OP_plus_uconst.
+- if (++It != Expr.end()) {
+- if (It->getCode() != dwarf::DW_OP_plus_uconst)
+- continue;
+-
+- LocationAddr += It->getRawOperand(0);
+-
+- // Probe for a 3rd operand, if it exists, bail.
+- if (++It != Expr.end())
+- continue;
+- }
+-
+- Address = LocationAddr;
+- break;
+- }
+-
+- // Get the size of the global variable. If all else fails (i.e. the global has
+- // no type), then we use a size of one to still allow symbolization of the
+- // exact address.
+- uint64_t GVSize = 1;
+- if (Die.getAttributeValueAsReferencedDie(DW_AT_type))
+- if (std::optional<uint64_t> Size = Die.getTypeSize(getAddressByteSize()))
+- GVSize = *Size;
+-
+- if (Address != UINT64_MAX)
+- VariableDieMap[Address] = {Address + GVSize, Die};
+-}
+-
+-DWARFDie DWARFUnit::getVariableForAddress(uint64_t Address) {
+- extractDIEsIfNeeded(false);
+-
+- auto RootDie = getUnitDIE();
+-
+- auto RootLookup = RootsParsedForVariables.insert(RootDie.getOffset());
+- if (RootLookup.second)
+- updateVariableDieMap(RootDie);
+-
+- auto R = VariableDieMap.upper_bound(Address);
+- if (R == VariableDieMap.begin())
+- return DWARFDie();
+-
+- // upper_bound's previous item contains Address.
+- --R;
+- if (Address >= R->second.first)
+- return DWARFDie();
+- return R->second.second;
+-}
+-
+ void
+ DWARFUnit::getInlinedChainForAddress(uint64_t Address,
+ SmallVectorImpl<DWARFDie> &InlinedChain) {
+diff --git a/llvm/lib/DebugInfo/PDB/PDBContext.cpp b/llvm/lib/DebugInfo/PDB/PDBContext.cpp
+index e600fb7385f1..0444093d7622 100644
+--- a/llvm/lib/DebugInfo/PDB/PDBContext.cpp
++++ b/llvm/lib/DebugInfo/PDB/PDBContext.cpp
+@@ -64,13 +64,6 @@ DILineInfo PDBContext::getLineInfoForAddress(object::SectionedAddress Address,
+ return Result;
+ }
+
+-DILineInfo
+-PDBContext::getLineInfoForDataAddress(object::SectionedAddress Address) {
+- // Unimplemented. S_GDATA and S_LDATA in CodeView (used to describe global
+- // variables) aren't capable of carrying line information.
+- return DILineInfo();
+-}
+-
+ DILineInfoTable
+ PDBContext::getLineInfoForAddressRange(object::SectionedAddress Address,
+ uint64_t Size,
+diff --git a/llvm/lib/DebugInfo/Symbolize/DIPrinter.cpp b/llvm/lib/DebugInfo/Symbolize/DIPrinter.cpp
+index 877380213f21..496c8149782e 100644
+--- a/llvm/lib/DebugInfo/Symbolize/DIPrinter.cpp
++++ b/llvm/lib/DebugInfo/Symbolize/DIPrinter.cpp
+@@ -206,10 +206,6 @@ void PlainPrinterBase::print(const Request &Request, const DIGlobal &Global) {
+ Name = DILineInfo::Addr2LineBadString;
+ OS << Name << "\n";
+ OS << Global.Start << " " << Global.Size << "\n";
+- if (Global.DeclFile.empty())
+- OS << "??:?\n";
+- else
+- OS << Global.DeclFile << ":" << Global.DeclLine << "\n";
+ printFooter();
+ }
+
+diff --git a/llvm/lib/DebugInfo/Symbolize/SymbolizableObjectFile.cpp b/llvm/lib/DebugInfo/Symbolize/SymbolizableObjectFile.cpp
+index d8ee9264b64f..fcff531895a2 100644
+--- a/llvm/lib/DebugInfo/Symbolize/SymbolizableObjectFile.cpp
++++ b/llvm/lib/DebugInfo/Symbolize/SymbolizableObjectFile.cpp
+@@ -327,14 +327,6 @@ DIGlobal SymbolizableObjectFile::symbolizeData(
+ std::string FileName;
+ getNameFromSymbolTable(ModuleOffset.Address, Res.Name, Res.Start, Res.Size,
+ FileName);
+- Res.DeclFile = FileName;
+-
+- // Try and get a better filename:lineno pair from the debuginfo, if present.
+- DILineInfo DL = DebugInfoContext->getLineInfoForDataAddress(ModuleOffset);
+- if (DL.Line != 0) {
+- Res.DeclFile = DL.FileName;
+- Res.DeclLine = DL.Line;
+- }
+ return Res;
+ }
+
+diff --git a/llvm/test/DebugInfo/Symbolize/ELF/data-command-symtab.yaml b/llvm/test/DebugInfo/Symbolize/ELF/data-command-symtab.yaml
+index 83af3111c5dd..984e444b2fda 100644
+--- a/llvm/test/DebugInfo/Symbolize/ELF/data-command-symtab.yaml
++++ b/llvm/test/DebugInfo/Symbolize/ELF/data-command-symtab.yaml
+@@ -7,15 +7,12 @@
+
+ # CHECK: func
+ # CHECK-NEXT: 4096 1
+-# CHECK-NEXT: ??:?
+ # CHECK-EMPTY:
+ # CHECK-NEXT: data
+ # CHECK-NEXT: 8192 2
+-# CHECK-NEXT: ??:?
+ # CHECK-EMPTY:
+ # CHECK-NEXT: notype
+ # CHECK-NEXT: 8194 3
+-# CHECK-NEXT: ??:?
+ # CHECK-EMPTY:
+
+ --- !ELF
+diff --git a/llvm/test/tools/llvm-symbolizer/data-location.yaml b/llvm/test/tools/llvm-symbolizer/data-location.yaml
+deleted file mode 100644
+index 54f7d9be44a1..000000000000
+--- a/llvm/test/tools/llvm-symbolizer/data-location.yaml
++++ /dev/null
+@@ -1,450 +0,0 @@
+-## Show that when "DATA" is used with an address, it forces the found location
+-## to be symbolized as data, including the source information.
+-
+-# RUN: yaml2obj %s -o %t.so
+-
+-# RUN: llvm-symbolizer 'DATA 0x304d0' 'DATA 0x304d1' 'DATA 0x304d3' \
+-# RUN: 'DATA 0x304c0' 'DATA 0x304c8' 'DATA 0x304d4' 'DATA 0x304dc' \
+-# RUN: 'DATA 0x304d8' --obj=%t.so | FileCheck %s
+-
+-# CHECK: bss_global
+-# CHECK-NEXT: {{[0-9]+}} 4
+-# CHECK-NEXT: /tmp/file.cpp:1
+-# CHECK-EMPTY:
+-
+-## Check that lookups in the middle of the symbol are also resolved correctly.
+-# CHECK: bss_global
+-# CHECK-NEXT: {{[0-9]+}} 4
+-# CHECK-NEXT: /tmp/file.cpp:1
+-# CHECK-EMPTY:
+-# CHECK: bss_global
+-# CHECK-NEXT: {{[0-9]+}} 4
+-# CHECK-NEXT: /tmp/file.cpp:1
+-# CHECK-EMPTY:
+-
+-## Now, the remainder of the symbols.
+-# CHECK-NEXT: data_global
+-# CHECK-NEXT: {{[0-9]+}} 4
+-# CHECK-NEXT: /tmp/file.cpp:2
+-# CHECK-EMPTY:
+-# CHECK-NEXT: str
+-# CHECK-NEXT: {{[0-9]+}} 8
+-# CHECK-NEXT: /tmp/file.cpp:4
+-# CHECK-EMPTY:
+-# CHECK-NEXT: f()::function_global
+-# CHECK-NEXT: {{[0-9]+}} 4
+-# CHECK-NEXT: /tmp/file.cpp:8
+-# CHECK-EMPTY:
+-
+-## Including the one that includes an addend.
+-# CHECK-NEXT: alpha
+-# CHECK-NEXT: {{[0-9]+}} 4
+-# CHECK-NEXT: /tmp/file.cpp:12
+-# CHECK-EMPTY:
+-# CHECK-NEXT: beta
+-# CHECK-NEXT: {{[0-9]+}} 4
+-# CHECK-NEXT: /tmp/file.cpp:13
+-# CHECK-EMPTY:
+-
+-## Ensure there's still a global that's offset-based.
+-# RUN: llvm-dwarfdump --debug-info %t.so | FileCheck %s --check-prefix=OFFSET
+-
+-# OFFSET: DW_AT_location (DW_OP_addrx 0x4, DW_OP_plus_uconst 0x4)
+-
+-################################################################################
+-## File below was generated using:
+-##
+-## $ clang++ -g -O3 /tmp/file.cpp -shared -fuse-ld=lld -nostdlib \
+-## -target aarch64-linux-gnuabi -mllvm -global-merge-ignore-single-use \
+-## -o /tmp/file.so
+-##
+-## With /tmp/file.cpp as:
+-## 1: int bss_global;
+-## 2: int data_global = 2;
+-## 3:
+-## 4: const char* str =
+-## 5: "12345678";
+-## 6:
+-## 7: int* f() {
+-## 8: static int function_global;
+-## 9: return &function_global;
+-## 10: }
+-## 11:
+-## 12: static int alpha;
+-## 13: static int beta;
+-## 14: int *f(bool b) { return beta ? &alpha : &beta; }
+-## 15:
+-##
+-## ... then, one can get the offsets using `nm`, like:
+-## $ nm out.so | grep bss_global
+-## 00000000000038fc B bss_global
+-##
+-## Note the use of the aarch64 target (with -nostdlib in order to allow linkage
+-## without libraries for cross-compilation) as well as -O3 and
+-## -global-merge-ignore-single-use. This is a specific combination that makes
+-## the compiler emit the `alpha` global variable with a more complex
+-## DW_AT_location than just a DW_OP_addr/DW_OP_addrx. In this instance, it
+-## outputs a `DW_AT_location (DW_OP_addrx 0x4, DW_OP_plus_uconst 0x4)`.
+-##
+-## Ideally, this would be tested by invoking clang directly on a C source file,
+-## but unfortunately there's no way to do that for LLVM tests. The other option
+-## is to compile IR to an objfile, but llvm-symbolizer doesn't understand that
+-## two symbols can have the same address in different sections. In the code
+-## above, for example, we'd have bss_global at .bss+0x0, and data_global at
+-## .data+0x0, and so the symbolizer would only print one of them. Hence, we have
+-## the ugly dso-to-yaml blob below.
+-##
+-## For now, constant strings don't have a debuginfo entry, and so can't be
+-## symbolized correctly. In future (if D123534 gets merged), this can be updated
+-## to include a check that llvm-symbolizer can also symbolize constant strings,
+-## like `str` above (basically that &"12345678" should be symbolizable)
+-## to the specific line. Then, you can find the address of the constant string
+-## from the relocation:
+-##
+-## $ nm out.so | grep str
+-## 00000000000038c0 D str
+-## $ llvm-objdump -R out.so | grep 38c0
+-## 00000000000038c0 R_X86_64_RELATIVE *ABS*+0x4f8 # <-- 0x4f8
+-################################################################################
+-
+---- !ELF
+-FileHeader:
+- Class: ELFCLASS64
+- Data: ELFDATA2LSB
+- Type: ET_DYN
+- Machine: EM_AARCH64
+-ProgramHeaders:
+- - Type: PT_PHDR
+- Flags: [ PF_R ]
+- VAddr: 0x40
+- Align: 0x8
+- - Type: PT_LOAD
+- Flags: [ PF_R ]
+- FirstSec: .dynsym
+- LastSec: .eh_frame
+- Align: 0x10000
+- - Type: PT_LOAD
+- Flags: [ PF_X, PF_R ]
+- FirstSec: .text
+- LastSec: .text
+- VAddr: 0x103E4
+- Align: 0x10000
+- - Type: PT_LOAD
+- Flags: [ PF_W, PF_R ]
+- FirstSec: .dynamic
+- LastSec: .dynamic
+- VAddr: 0x20410
+- Align: 0x10000
+- - Type: PT_LOAD
+- Flags: [ PF_W, PF_R ]
+- FirstSec: .data
+- LastSec: .bss
+- VAddr: 0x304C0
+- Align: 0x10000
+- - Type: PT_DYNAMIC
+- Flags: [ PF_W, PF_R ]
+- FirstSec: .dynamic
+- LastSec: .dynamic
+- VAddr: 0x20410
+- Align: 0x8
+- - Type: PT_GNU_RELRO
+- Flags: [ PF_R ]
+- FirstSec: .dynamic
+- LastSec: .dynamic
+- VAddr: 0x20410
+- - Type: PT_GNU_EH_FRAME
+- Flags: [ PF_R ]
+- FirstSec: .eh_frame_hdr
+- LastSec: .eh_frame_hdr
+- VAddr: 0x37C
+- Align: 0x4
+- - Type: PT_GNU_STACK
+- Flags: [ PF_W, PF_R ]
+- Align: 0x0
+-Sections:
+- - Name: .dynsym
+- Type: SHT_DYNSYM
+- Flags: [ SHF_ALLOC ]
+- Address: 0x238
+- Link: .dynstr
+- AddressAlign: 0x8
+- - Name: .gnu.hash
+- Type: SHT_GNU_HASH
+- Flags: [ SHF_ALLOC ]
+- Address: 0x2C8
+- Link: .dynsym
+- AddressAlign: 0x8
+- Header:
+- SymNdx: 0x1
+- Shift2: 0x1A
+- BloomFilter: [ 0x400188002180000C ]
+- HashBuckets: [ 0x1 ]
+- HashValues: [ 0xEE8502A, 0xEE85016, 0xC033991C, 0x61F7372E, 0xB88AB7F ]
+- - Name: .hash
+- Type: SHT_HASH
+- Flags: [ SHF_ALLOC ]
+- Address: 0x2F8
+- Link: .dynsym
+- AddressAlign: 0x4
+- Bucket: [ 5, 0, 4, 0, 3, 0 ]
+- Chain: [ 0, 0, 0, 1, 2, 0 ]
+- - Name: .dynstr
+- Type: SHT_STRTAB
+- Flags: [ SHF_ALLOC ]
+- Address: 0x330
+- AddressAlign: 0x1
+- - Name: .rela.dyn
+- Type: SHT_RELA
+- Flags: [ SHF_ALLOC ]
+- Address: 0x358
+- Link: .dynsym
+- AddressAlign: 0x8
+- Relocations:
+- - Offset: 0x304C8
+- Type: R_AARCH64_RELATIVE
+- Addend: 880
+- - Name: .rodata
+- Type: SHT_PROGBITS
+- Flags: [ SHF_ALLOC, SHF_MERGE, SHF_STRINGS ]
+- Address: 0x370
+- AddressAlign: 0x1
+- EntSize: 0x1
+- Content: '313233343536373800'
+- - Name: .eh_frame_hdr
+- Type: SHT_PROGBITS
+- Flags: [ SHF_ALLOC ]
+- Address: 0x37C
+- AddressAlign: 0x4
+- Content: 011B033B18000000020000006800010034000000740001004C000000
+- - Name: .eh_frame
+- Type: SHT_PROGBITS
+- Flags: [ SHF_ALLOC ]
+- Address: 0x398
+- AddressAlign: 0x8
+- Content: 1400000000000000017A5200017C1E011B0C1F0000000000140000001C0000002C0001000C00000000000000000000001400000034000000200001001C000000000000000000000000000000
+- - Name: .text
+- Type: SHT_PROGBITS
+- Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
+- Address: 0x103E4
+- AddressAlign: 0x4
+- Content: 0001009000501391C0035FD60801009008611391E90308AA2A4540B85F0100710001899AC0035FD6
+- - Name: .dynamic
+- Type: SHT_DYNAMIC
+- Flags: [ SHF_WRITE, SHF_ALLOC ]
+- Address: 0x20410
+- Link: .dynstr
+- AddressAlign: 0x8
+- Entries:
+- - Tag: DT_RELA
+- Value: 0x358
+- - Tag: DT_RELASZ
+- Value: 0x18
+- - Tag: DT_RELAENT
+- Value: 0x18
+- - Tag: DT_RELACOUNT
+- Value: 0x1
+- - Tag: DT_SYMTAB
+- Value: 0x238
+- - Tag: DT_SYMENT
+- Value: 0x18
+- - Tag: DT_STRTAB
+- Value: 0x330
+- - Tag: DT_STRSZ
+- Value: 0x28
+- - Tag: DT_GNU_HASH
+- Value: 0x2C8
+- - Tag: DT_HASH
+- Value: 0x2F8
+- - Tag: DT_NULL
+- Value: 0x0
+- - Name: .data
+- Type: SHT_PROGBITS
+- Flags: [ SHF_WRITE, SHF_ALLOC ]
+- Address: 0x304C0
+- AddressAlign: 0x8
+- Content: '02000000000000000000000000000000'
+- - Name: .bss
+- Type: SHT_NOBITS
+- Flags: [ SHF_WRITE, SHF_ALLOC ]
+- Address: 0x304D0
+- AddressAlign: 0x4
+- Size: 0x10
+- - Name: .debug_abbrev
+- Type: SHT_PROGBITS
+- AddressAlign: 0x1
+- Content: 011101252513050325721710171B25111B120673170000023400032549133F193A0B3B0B0218000003240003253E0B0B0B0000040F004913000005260049130000062E01111B120640187A196E2503253A0B3B0B49133F190000073400032549133A0B3B0B02180000083400032549133A0B3B0B02186E25000009050003253A0B3B0B4913000000
+- - Name: .debug_info
+- Type: SHT_PROGBITS
+- AddressAlign: 0x1
+- Content: AB0000000500010800000000010021000108000000000000000205280000000800000002032E000000000102A1000304050402052E000000000202A101020648000000000402A102044D00000005520000000307080106050C000000016F0D0E0007A500000007082E000000000802A1030008092E000000000D02A1040A080B2E000000000C04A10423040C06061C000000016F0F0E000EA50000000910000EAA00000000042E0000000311020100
+- - Name: .debug_str_offsets
+- Type: SHT_PROGBITS
+- AddressAlign: 0x1
+- Content: 4C00000005000000A2000000000000002C00000059000000280000001C00000072000000640000008C0000008700000069000000140000007B0000009C0000001A0000000E0000008500000076000000
+- - Name: .comment
+- Type: SHT_PROGBITS
+- Flags: [ SHF_MERGE, SHF_STRINGS ]
+- AddressAlign: 0x1
+- EntSize: 0x1
+- Content: 4C696E6B65723A204C4C442031352E302E300000636C616E672076657273696F6E2031352E302E30202868747470733A2F2F6769746875622E636F6D2F6C6C766D2F6C6C766D2D70726F6A6563742E67697420306462616566363162353666306566306162306366333865613932666663316633356265653366662900
+- - Name: .debug_line
+- Type: SHT_PROGBITS
+- AddressAlign: 0x1
+- Content: 620000000500080037000000010101FB0E0D00010101010000000100000101011F010E00000003011F020F051E0100000000006C97BBE59F7DC6A9EA956633431DA63E0400000902E4030100000000001805030A140500BF05190A0105120608740204000101
+- - Name: .debug_line_str
+- Type: SHT_PROGBITS
+- Flags: [ SHF_MERGE, SHF_STRINGS ]
+- AddressAlign: 0x1
+- EntSize: 0x1
+- Content: 2F746D702F66696C652E637070002F7573722F6C6F63616C2F676F6F676C652F686F6D652F6D69746368702F6C6C766D2D6275696C642F6F707400
+-Symbols:
+- - Name: file.cpp
+- Type: STT_FILE
+- Index: SHN_ABS
+- - Name: '$x.0'
+- Section: .text
+- Value: 0x103E4
+- - Name: _ZZ1fvE15function_global
+- Type: STT_OBJECT
+- Section: .bss
+- Value: 0x304D4
+- Size: 0x4
+- - Name: '$d.1'
+- Section: .bss
+- Value: 0x304D0
+- - Name: '$d.2'
+- Section: .data
+- Value: 0x304C0
+- - Name: '$d.3'
+- Section: .rodata
+- Value: 0x370
+- - Name: '$d.4'
+- Section: .debug_abbrev
+- - Name: '$d.5'
+- Section: .debug_info
+- - Name: '$d.6'
+- Section: .debug_str_offsets
+- - Name: '$d.7'
+- Section: .debug_str
+- Value: 0xA2
+- - Name: '$d.8'
+- Section: .debug_addr
+- - Name: _ZL4beta
+- Type: STT_OBJECT
+- Section: .bss
+- Value: 0x304D8
+- Size: 0x4
+- - Name: _ZL5alpha
+- Type: STT_OBJECT
+- Section: .bss
+- Value: 0x304DC
+- Size: 0x4
+- - Name: '$d.9'
+- Section: .comment
+- Value: 0x13
+- - Name: '$d.10'
+- Section: .eh_frame
+- Value: 0x398
+- - Name: '$d.11'
+- Section: .debug_line
+- - Name: '$d.12'
+- Section: .debug_line_str
+- Value: 0xE
+- - Name: _DYNAMIC
+- Section: .dynamic
+- Value: 0x20410
+- Other: [ STV_HIDDEN ]
+- - Name: _Z1fv
+- Type: STT_FUNC
+- Section: .text
+- Binding: STB_GLOBAL
+- Value: 0x103E4
+- Size: 0xC
+- - Name: _Z1fb
+- Type: STT_FUNC
+- Section: .text
+- Binding: STB_GLOBAL
+- Value: 0x103F0
+- Size: 0x1C
+- - Name: bss_global
+- Type: STT_OBJECT
+- Section: .bss
+- Binding: STB_GLOBAL
+- Value: 0x304D0
+- Size: 0x4
+- - Name: data_global
+- Type: STT_OBJECT
+- Section: .data
+- Binding: STB_GLOBAL
+- Value: 0x304C0
+- Size: 0x4
+- - Name: str
+- Type: STT_OBJECT
+- Section: .data
+- Binding: STB_GLOBAL
+- Value: 0x304C8
+- Size: 0x8
+-DynamicSymbols:
+- - Name: _Z1fv
+- Type: STT_FUNC
+- Section: .text
+- Binding: STB_GLOBAL
+- Value: 0x103E4
+- Size: 0xC
+- - Name: _Z1fb
+- Type: STT_FUNC
+- Section: .text
+- Binding: STB_GLOBAL
+- Value: 0x103F0
+- Size: 0x1C
+- - Name: bss_global
+- Type: STT_OBJECT
+- Section: .bss
+- Binding: STB_GLOBAL
+- Value: 0x304D0
+- Size: 0x4
+- - Name: data_global
+- Type: STT_OBJECT
+- Section: .data
+- Binding: STB_GLOBAL
+- Value: 0x304C0
+- Size: 0x4
+- - Name: str
+- Type: STT_OBJECT
+- Section: .data
+- Binding: STB_GLOBAL
+- Value: 0x304C8
+- Size: 0x8
+-DWARF:
+- debug_str:
+- - '/tmp/file.cpp'
+- - _Z1fb
+- - alpha
+- - f
+- - data_global
+- - int
+- - '/usr/local/google/home/mitchp/llvm-build/opt'
+- - bss_global
+- - char
+- - _ZL4beta
+- - str
+- - bool
+- - _ZL5alpha
+- - b
+- - beta
+- - function_global
+- - _Z1fv
+- - 'clang version 15.0.0 (https://github.com/llvm/llvm-project.git 0dbaef61b56f0ef0ab0cf38ea92ffc1f35bee3ff)'
+- debug_addr:
+- - Length: 0x3C
+- Version: 0x5
+- AddressSize: 0x8
+- Entries:
+- - Address: 0x304D0
+- - Address: 0x304C0
+- - Address: 0x304C8
+- - Address: 0x304D4
+- - Address: 0x304D8
+- - Address: 0x103E4
+- - Address: 0x103F0
+-...
+diff --git a/llvm/test/tools/llvm-symbolizer/data.s b/llvm/test/tools/llvm-symbolizer/data.s
+index cc9503c59141..e8039f146dbd 100644
+--- a/llvm/test/tools/llvm-symbolizer/data.s
++++ b/llvm/test/tools/llvm-symbolizer/data.s
+@@ -7,12 +7,9 @@
+
+ # CHECK: d1
+ # CHECK-NEXT: 0 8
+-# CHECK-NEXT: ??:?
+ # CHECK-EMPTY:
+ # CHECK-NEXT: d2
+ # CHECK-NEXT: 8 4
+-# CHECK-NEXT: ??:?
+-# CHECK-EMPTY:
+
+ d1:
+ .quad 0x1122334455667788
+--
+2.38.1.1.g6d9df9d320
+
diff --git a/build/build-clang/revert-llvmorg-15-init-13446-g7524fe962e47.patch b/build/build-clang/revert-llvmorg-15-init-13446-g7524fe962e47.patch
new file mode 100644
index 0000000000..5bd4601827
--- /dev/null
+++ b/build/build-clang/revert-llvmorg-15-init-13446-g7524fe962e47.patch
@@ -0,0 +1,39 @@
+From 12f64ca10837bd68ec30804ebfa21653925ad5cf Mon Sep 17 00:00:00 2001
+From: Mike Hommey <mh@glandium.org>
+Date: Thu, 16 Jun 2022 12:51:29 +0900
+Subject: [PATCH] Revert "[libFuzzer] Use the compiler to link the relocatable
+ object"
+
+This reverts commit 7524fe962e479416fd6318407eff4eed5b96a40b.
+---
+ compiler-rt/lib/fuzzer/CMakeLists.txt | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/compiler-rt/lib/fuzzer/CMakeLists.txt b/compiler-rt/lib/fuzzer/CMakeLists.txt
+index 856cd732d517..d51de53f5acc 100644
+--- a/compiler-rt/lib/fuzzer/CMakeLists.txt
++++ b/compiler-rt/lib/fuzzer/CMakeLists.txt
+@@ -138,15 +138,15 @@ if(OS_NAME MATCHES "Linux|Fuchsia" AND
+ COMPILER_RT_LIBCXX_PATH AND
+ COMPILER_RT_LIBCXXABI_PATH)
+ macro(partially_link_libcxx name dir arch)
+- get_target_flags_for_arch(${arch} target_cflags)
+- if(CMAKE_CXX_COMPILER_ID MATCHES Clang)
+- get_compiler_rt_target(${arch} target)
+- set(target_cflags --target=${target} ${target_cflags})
++ if(${arch} MATCHES "i386")
++ set(EMULATION_ARGUMENT "-m" "elf_i386")
++ else()
++ set(EMULATION_ARGUMENT "")
+ endif()
+ set(cxx_${arch}_merge_dir "${CMAKE_CURRENT_BINARY_DIR}/cxx_${arch}_merge.dir")
+ file(MAKE_DIRECTORY ${cxx_${arch}_merge_dir})
+ add_custom_command(TARGET clang_rt.${name}-${arch} POST_BUILD
+- COMMAND ${CMAKE_CXX_COMPILER} ${target_cflags} -Wl,--whole-archive "$<TARGET_LINKER_FILE:clang_rt.${name}-${arch}>" -Wl,--no-whole-archive ${dir}/lib/libc++.a -r -o ${name}.o
++ COMMAND ${CMAKE_LINKER} ${EMULATION_ARGUMENT} --whole-archive "$<TARGET_LINKER_FILE:clang_rt.${name}-${arch}>" --no-whole-archive ${dir}/lib/libc++.a -r -o ${name}.o
+ COMMAND ${CMAKE_OBJCOPY} --localize-hidden ${name}.o
+ COMMAND ${CMAKE_COMMAND} -E remove "$<TARGET_LINKER_FILE:clang_rt.${name}-${arch}>"
+ COMMAND ${CMAKE_AR} qcs "$<TARGET_LINKER_FILE:clang_rt.${name}-${arch}>" ${name}.o
+--
+2.36.0.1.g2bbe56bd8d
+
diff --git a/build/build-clang/revert-llvmorg-16-init-11301-g163bb6d64e5f_clang_17.patch b/build/build-clang/revert-llvmorg-16-init-11301-g163bb6d64e5f_clang_17.patch
new file mode 100644
index 0000000000..4e217dcf3d
--- /dev/null
+++ b/build/build-clang/revert-llvmorg-16-init-11301-g163bb6d64e5f_clang_17.patch
@@ -0,0 +1,172 @@
+From cf00b30288c4c81b2c6a5af01c38f236148777a0 Mon Sep 17 00:00:00 2001
+From: Mike Hommey <mh@glandium.org>
+Date: Tue, 28 Mar 2023 06:13:36 +0900
+Subject: [PATCH] Revert "[Passes][VectorCombine] enable early run generally
+ and try load folds"
+
+This reverts commit 163bb6d64e5f1220777c3ec2a8b58c0666a74d91.
+It causes various reftest regressions.
+---
+ llvm/lib/Passes/PassBuilderPipelines.cpp | 7 ++++---
+ llvm/lib/Transforms/Vectorize/VectorCombine.cpp | 8 ++------
+ llvm/test/Other/new-pm-defaults.ll | 2 +-
+ .../Other/new-pm-thinlto-postlink-defaults.ll | 1 -
+ .../Other/new-pm-thinlto-postlink-pgo-defaults.ll | 1 -
+ .../new-pm-thinlto-postlink-samplepgo-defaults.ll | 1 -
+ .../Other/new-pm-thinlto-prelink-pgo-defaults.ll | 1 -
+ .../new-pm-thinlto-prelink-samplepgo-defaults.ll | 1 -
+ .../PhaseOrdering/X86/vec-load-combine.ll | 15 +++++++++++----
+ 9 files changed, 18 insertions(+), 19 deletions(-)
+
+diff --git a/llvm/lib/Passes/PassBuilderPipelines.cpp b/llvm/lib/Passes/PassBuilderPipelines.cpp
+index eed29c25714b..b925448cd6c0 100644
+--- a/llvm/lib/Passes/PassBuilderPipelines.cpp
++++ b/llvm/lib/Passes/PassBuilderPipelines.cpp
+@@ -611,9 +611,10 @@ PassBuilder::buildFunctionSimplificationPipeline(OptimizationLevel Level,
+ // Delete small array after loop unroll.
+ FPM.addPass(SROAPass(SROAOptions::ModifyCFG));
+
+- // Try vectorization/scalarization transforms that are both improvements
+- // themselves and can allow further folds with GVN and InstCombine.
+- FPM.addPass(VectorCombinePass(/*TryEarlyFoldsOnly=*/true));
++ // The matrix extension can introduce large vector operations early, which can
++ // benefit from running vector-combine early on.
++ if (EnableMatrix)
++ FPM.addPass(VectorCombinePass(/*TryEarlyFoldsOnly=*/true));
+
+ // Eliminate redundancies.
+ FPM.addPass(MergedLoadStoreMotionPass());
+diff --git a/llvm/lib/Transforms/Vectorize/VectorCombine.cpp b/llvm/lib/Transforms/Vectorize/VectorCombine.cpp
+index 2e489757ebc1..810a9f92bb7a 100644
+--- a/llvm/lib/Transforms/Vectorize/VectorCombine.cpp
++++ b/llvm/lib/Transforms/Vectorize/VectorCombine.cpp
+@@ -1720,12 +1720,6 @@ bool VectorCombine::run() {
+ // dispatching to folding functions if there's no chance of matching.
+ if (IsFixedVectorType) {
+ switch (Opcode) {
+- case Instruction::InsertElement:
+- MadeChange |= vectorizeLoadInsert(I);
+- break;
+- case Instruction::ShuffleVector:
+- MadeChange |= widenSubvectorLoad(I);
+- break;
+ case Instruction::Load:
+ MadeChange |= scalarizeLoadExtract(I);
+ break;
+@@ -1754,9 +1748,11 @@ bool VectorCombine::run() {
+ if (IsFixedVectorType) {
+ switch (Opcode) {
+ case Instruction::InsertElement:
++ MadeChange |= vectorizeLoadInsert(I);
+ MadeChange |= foldInsExtFNeg(I);
+ break;
+ case Instruction::ShuffleVector:
++ MadeChange |= widenSubvectorLoad(I);
+ MadeChange |= foldShuffleOfBinops(I);
+ MadeChange |= foldSelectShuffle(I);
+ break;
+diff --git a/llvm/test/Other/new-pm-defaults.ll b/llvm/test/Other/new-pm-defaults.ll
+index 13612c3bb459..5f84d28af4a6 100644
+--- a/llvm/test/Other/new-pm-defaults.ll
++++ b/llvm/test/Other/new-pm-defaults.ll
+@@ -186,7 +186,7 @@
+ ; CHECK-O-NEXT: Running pass: LoopFullUnrollPass
+ ; CHECK-EP-LOOP-END-NEXT: Running pass: NoOpLoopPass
+ ; CHECK-O-NEXT: Running pass: SROAPass on foo
+-; CHECK-O23SZ-NEXT: Running pass: VectorCombinePass
++; CHECK-MATRIX: Running pass: VectorCombinePass
+ ; CHECK-O23SZ-NEXT: Running pass: MergedLoadStoreMotionPass
+ ; CHECK-O23SZ-NEXT: Running pass: GVNPass
+ ; CHECK-O23SZ-NEXT: Running analysis: MemoryDependenceAnalysis
+diff --git a/llvm/test/Other/new-pm-thinlto-postlink-defaults.ll b/llvm/test/Other/new-pm-thinlto-postlink-defaults.ll
+index 3f5d2d5b153d..ea07128c9f6a 100644
+--- a/llvm/test/Other/new-pm-thinlto-postlink-defaults.ll
++++ b/llvm/test/Other/new-pm-thinlto-postlink-defaults.ll
+@@ -159,7 +159,6 @@
+ ; CHECK-O-NEXT: Running pass: LoopDeletionPass
+ ; CHECK-O-NEXT: Running pass: LoopFullUnrollPass
+ ; CHECK-O-NEXT: Running pass: SROAPass on foo
+-; CHECK-O23SZ-NEXT: Running pass: VectorCombinePass
+ ; CHECK-O23SZ-NEXT: Running pass: MergedLoadStoreMotionPass
+ ; CHECK-O23SZ-NEXT: Running pass: GVNPass
+ ; CHECK-O23SZ-NEXT: Running analysis: MemoryDependenceAnalysis
+diff --git a/llvm/test/Other/new-pm-thinlto-postlink-pgo-defaults.ll b/llvm/test/Other/new-pm-thinlto-postlink-pgo-defaults.ll
+index 29021ceace54..43e943cb6011 100644
+--- a/llvm/test/Other/new-pm-thinlto-postlink-pgo-defaults.ll
++++ b/llvm/test/Other/new-pm-thinlto-postlink-pgo-defaults.ll
+@@ -121,7 +121,6 @@
+ ; CHECK-O-NEXT: Running pass: LoopDeletionPass
+ ; CHECK-O-NEXT: Running pass: LoopFullUnrollPass
+ ; CHECK-O-NEXT: Running pass: SROAPass on foo
+-; CHECK-O23SZ-NEXT: Running pass: VectorCombinePass
+ ; CHECK-O23SZ-NEXT: Running pass: MergedLoadStoreMotionPass
+ ; CHECK-O23SZ-NEXT: Running pass: GVNPass
+ ; CHECK-O23SZ-NEXT: Running analysis: MemoryDependenceAnalysis
+diff --git a/llvm/test/Other/new-pm-thinlto-postlink-samplepgo-defaults.ll b/llvm/test/Other/new-pm-thinlto-postlink-samplepgo-defaults.ll
+index daf3141a1f2c..78914d1c23b2 100644
+--- a/llvm/test/Other/new-pm-thinlto-postlink-samplepgo-defaults.ll
++++ b/llvm/test/Other/new-pm-thinlto-postlink-samplepgo-defaults.ll
+@@ -130,7 +130,6 @@
+ ; CHECK-O-NEXT: Running pass: LoopDeletionPass
+ ; CHECK-O-NEXT: Running pass: LoopFullUnrollPass
+ ; CHECK-O-NEXT: Running pass: SROAPass on foo
+-; CHECK-O23SZ-NEXT: Running pass: VectorCombinePass
+ ; CHECK-O23SZ-NEXT: Running pass: MergedLoadStoreMotionPass
+ ; CHECK-O23SZ-NEXT: Running pass: GVNPass
+ ; CHECK-O23SZ-NEXT: Running analysis: MemoryDependenceAnalysis
+diff --git a/llvm/test/Other/new-pm-thinlto-prelink-pgo-defaults.ll b/llvm/test/Other/new-pm-thinlto-prelink-pgo-defaults.ll
+index bfe80902f806..5b62ba39add3 100644
+--- a/llvm/test/Other/new-pm-thinlto-prelink-pgo-defaults.ll
++++ b/llvm/test/Other/new-pm-thinlto-prelink-pgo-defaults.ll
+@@ -160,7 +160,6 @@
+ ; CHECK-O-NEXT: Running pass: LoopDeletionPass
+ ; CHECK-O-NEXT: Running pass: LoopFullUnrollPass
+ ; CHECK-O-NEXT: Running pass: SROAPass on foo
+-; CHECK-O23SZ-NEXT: Running pass: VectorCombinePass
+ ; CHECK-O23SZ-NEXT: Running pass: MergedLoadStoreMotionPass
+ ; CHECK-O23SZ-NEXT: Running pass: GVNPass
+ ; CHECK-O23SZ-NEXT: Running analysis: MemoryDependenceAnalysis
+diff --git a/llvm/test/Other/new-pm-thinlto-prelink-samplepgo-defaults.ll b/llvm/test/Other/new-pm-thinlto-prelink-samplepgo-defaults.ll
+index c7daf7aa46b1..17475423d696 100644
+--- a/llvm/test/Other/new-pm-thinlto-prelink-samplepgo-defaults.ll
++++ b/llvm/test/Other/new-pm-thinlto-prelink-samplepgo-defaults.ll
+@@ -124,7 +124,6 @@
+ ; CHECK-O-NEXT: Running pass: IndVarSimplifyPass
+ ; CHECK-O-NEXT: Running pass: LoopDeletionPass
+ ; CHECK-O-NEXT: Running pass: SROAPass on foo
+-; CHECK-O23SZ-NEXT: Running pass: VectorCombinePass
+ ; CHECK-O23SZ-NEXT: Running pass: MergedLoadStoreMotionPass
+ ; CHECK-O23SZ-NEXT: Running pass: GVNPass
+ ; CHECK-O23SZ-NEXT: Running analysis: MemoryDependenceAnalysis
+diff --git a/llvm/test/Transforms/PhaseOrdering/X86/vec-load-combine.ll b/llvm/test/Transforms/PhaseOrdering/X86/vec-load-combine.ll
+index 77cbc70ff369..dd7164febea4 100644
+--- a/llvm/test/Transforms/PhaseOrdering/X86/vec-load-combine.ll
++++ b/llvm/test/Transforms/PhaseOrdering/X86/vec-load-combine.ll
+@@ -12,13 +12,20 @@ $getAt = comdat any
+ define dso_local noundef <4 x float> @ConvertVectors_ByRef(ptr noundef nonnull align 16 dereferenceable(16) %0) #0 {
+ ; SSE-LABEL: @ConvertVectors_ByRef(
+ ; SSE-NEXT: [[TMP2:%.*]] = load <4 x float>, ptr [[TMP0:%.*]], align 16
+-; SSE-NEXT: [[TMP3:%.*]] = shufflevector <4 x float> [[TMP2]], <4 x float> poison, <4 x i32> <i32 0, i32 1, i32 2, i32 2>
+-; SSE-NEXT: ret <4 x float> [[TMP3]]
++; SSE-NEXT: [[TMP3:%.*]] = getelementptr inbounds [4 x float], ptr [[TMP0]], i64 0, i64 1
++; SSE-NEXT: [[TMP4:%.*]] = load <2 x float>, ptr [[TMP3]], align 4
++; SSE-NEXT: [[TMP5:%.*]] = shufflevector <2 x float> [[TMP4]], <2 x float> poison, <4 x i32> <i32 0, i32 1, i32 undef, i32 undef>
++; SSE-NEXT: [[TMP6:%.*]] = shufflevector <4 x float> [[TMP2]], <4 x float> [[TMP5]], <4 x i32> <i32 0, i32 4, i32 5, i32 undef>
++; SSE-NEXT: [[TMP7:%.*]] = shufflevector <4 x float> [[TMP6]], <4 x float> [[TMP5]], <4 x i32> <i32 0, i32 1, i32 2, i32 5>
++; SSE-NEXT: ret <4 x float> [[TMP7]]
+ ;
+ ; AVX-LABEL: @ConvertVectors_ByRef(
+ ; AVX-NEXT: [[TMP2:%.*]] = load <4 x float>, ptr [[TMP0:%.*]], align 16
+-; AVX-NEXT: [[TMP3:%.*]] = shufflevector <4 x float> [[TMP2]], <4 x float> poison, <4 x i32> <i32 0, i32 1, i32 2, i32 2>
+-; AVX-NEXT: ret <4 x float> [[TMP3]]
++; AVX-NEXT: [[TMP3:%.*]] = getelementptr inbounds [4 x float], ptr [[TMP0]], i64 0, i64 2
++; AVX-NEXT: [[TMP4:%.*]] = load float, ptr [[TMP3]], align 8
++; AVX-NEXT: [[TMP5:%.*]] = insertelement <4 x float> [[TMP2]], float [[TMP4]], i64 2
++; AVX-NEXT: [[TMP6:%.*]] = insertelement <4 x float> [[TMP5]], float [[TMP4]], i64 3
++; AVX-NEXT: ret <4 x float> [[TMP6]]
+ ;
+ %2 = alloca ptr, align 8
+ %3 = alloca <4 x float>, align 16
+--
+2.39.0.1.g6739ec1790
+
diff --git a/build/build-clang/revert-llvmorg-16-init-11301-g163bb6d64e5f_clang_18.patch b/build/build-clang/revert-llvmorg-16-init-11301-g163bb6d64e5f_clang_18.patch
new file mode 100644
index 0000000000..6449fe14bc
--- /dev/null
+++ b/build/build-clang/revert-llvmorg-16-init-11301-g163bb6d64e5f_clang_18.patch
@@ -0,0 +1,183 @@
+From cf00b30288c4c81b2c6a5af01c38f236148777a0 Mon Sep 17 00:00:00 2001
+From: Mike Hommey <mh@glandium.org>
+Date: Tue, 28 Mar 2023 06:13:36 +0900
+Subject: [PATCH] Revert "[Passes][VectorCombine] enable early run generally
+ and try load folds"
+
+This reverts commit 163bb6d64e5f1220777c3ec2a8b58c0666a74d91.
+It causes various reftest regressions.
+---
+ llvm/lib/Passes/PassBuilderPipelines.cpp | 7 ++++---
+ llvm/lib/Transforms/Vectorize/VectorCombine.cpp | 8 ++------
+ llvm/test/Other/new-pm-defaults.ll | 2 +-
+ .../Other/new-pm-thinlto-postlink-defaults.ll | 1 -
+ .../Other/new-pm-thinlto-postlink-pgo-defaults.ll | 1 -
+ .../new-pm-thinlto-postlink-samplepgo-defaults.ll | 1 -
+ .../Other/new-pm-thinlto-prelink-pgo-defaults.ll | 1 -
+ .../new-pm-thinlto-prelink-samplepgo-defaults.ll | 1 -
+ .../PhaseOrdering/X86/vec-load-combine.ll | 15 +++++++++++----
+ 9 files changed, 18 insertions(+), 19 deletions(-)
+
+diff --git a/llvm/lib/Passes/PassBuilderPipelines.cpp b/llvm/lib/Passes/PassBuilderPipelines.cpp
+index eed29c25714b..b925448cd6c0 100644
+--- a/llvm/lib/Passes/PassBuilderPipelines.cpp
++++ b/llvm/lib/Passes/PassBuilderPipelines.cpp
+@@ -611,9 +611,10 @@ PassBuilder::buildFunctionSimplificationPipeline(OptimizationLevel Level,
+ // Delete small array after loop unroll.
+ FPM.addPass(SROAPass(SROAOptions::ModifyCFG));
+
+- // Try vectorization/scalarization transforms that are both improvements
+- // themselves and can allow further folds with GVN and InstCombine.
+- FPM.addPass(VectorCombinePass(/*TryEarlyFoldsOnly=*/true));
++ // The matrix extension can introduce large vector operations early, which can
++ // benefit from running vector-combine early on.
++ if (EnableMatrix)
++ FPM.addPass(VectorCombinePass(/*TryEarlyFoldsOnly=*/true));
+
+ // Eliminate redundancies.
+ FPM.addPass(MergedLoadStoreMotionPass());
+diff --git a/llvm/lib/Transforms/Vectorize/VectorCombine.cpp b/llvm/lib/Transforms/Vectorize/VectorCombine.cpp
+index 2e489757ebc1..810a9f92bb7a 100644
+--- a/llvm/lib/Transforms/Vectorize/VectorCombine.cpp
++++ b/llvm/lib/Transforms/Vectorize/VectorCombine.cpp
+@@ -1715,23 +1715,6 @@ bool VectorCombine::run() {
+ bool IsFixedVectorType = isa<FixedVectorType>(I.getType());
+ auto Opcode = I.getOpcode();
+
+- // These folds should be beneficial regardless of when this pass is run
+- // in the optimization pipeline.
+- // The type checking is for run-time efficiency. We can avoid wasting time
+- // dispatching to folding functions if there's no chance of matching.
+- if (IsFixedVectorType) {
+- switch (Opcode) {
+- case Instruction::InsertElement:
+- MadeChange |= vectorizeLoadInsert(I);
+- break;
+- case Instruction::ShuffleVector:
+- MadeChange |= widenSubvectorLoad(I);
+- break;
+- default:
+- break;
+- }
+- }
+-
+ // This transform works with scalable and fixed vectors
+ // TODO: Identify and allow other scalable transforms
+ if (isa<VectorType>(I.getType())) {
+@@ -1753,9 +1736,11 @@ bool VectorCombine::run() {
+ if (IsFixedVectorType) {
+ switch (Opcode) {
+ case Instruction::InsertElement:
++ MadeChange |= vectorizeLoadInsert(I);
+ MadeChange |= foldInsExtFNeg(I);
+ break;
+ case Instruction::ShuffleVector:
++ MadeChange |= widenSubvectorLoad(I);
+ MadeChange |= foldShuffleOfBinops(I);
+ MadeChange |= foldSelectShuffle(I);
+ break;
+diff --git a/llvm/test/Other/new-pm-defaults.ll b/llvm/test/Other/new-pm-defaults.ll
+index 13612c3bb459..5f84d28af4a6 100644
+--- a/llvm/test/Other/new-pm-defaults.ll
++++ b/llvm/test/Other/new-pm-defaults.ll
+@@ -186,7 +186,7 @@
+ ; CHECK-O-NEXT: Running pass: LoopFullUnrollPass
+ ; CHECK-EP-LOOP-END-NEXT: Running pass: NoOpLoopPass
+ ; CHECK-O-NEXT: Running pass: SROAPass on foo
+-; CHECK-O23SZ-NEXT: Running pass: VectorCombinePass
++; CHECK-MATRIX: Running pass: VectorCombinePass
+ ; CHECK-O23SZ-NEXT: Running pass: MergedLoadStoreMotionPass
+ ; CHECK-O23SZ-NEXT: Running pass: GVNPass
+ ; CHECK-O23SZ-NEXT: Running analysis: MemoryDependenceAnalysis
+diff --git a/llvm/test/Other/new-pm-thinlto-postlink-defaults.ll b/llvm/test/Other/new-pm-thinlto-postlink-defaults.ll
+index 3f5d2d5b153d..ea07128c9f6a 100644
+--- a/llvm/test/Other/new-pm-thinlto-postlink-defaults.ll
++++ b/llvm/test/Other/new-pm-thinlto-postlink-defaults.ll
+@@ -159,7 +159,6 @@
+ ; CHECK-O-NEXT: Running pass: LoopDeletionPass
+ ; CHECK-O-NEXT: Running pass: LoopFullUnrollPass
+ ; CHECK-O-NEXT: Running pass: SROAPass on foo
+-; CHECK-O23SZ-NEXT: Running pass: VectorCombinePass
+ ; CHECK-O23SZ-NEXT: Running pass: MergedLoadStoreMotionPass
+ ; CHECK-O23SZ-NEXT: Running pass: GVNPass
+ ; CHECK-O23SZ-NEXT: Running analysis: MemoryDependenceAnalysis
+diff --git a/llvm/test/Other/new-pm-thinlto-postlink-pgo-defaults.ll b/llvm/test/Other/new-pm-thinlto-postlink-pgo-defaults.ll
+index 29021ceace54..43e943cb6011 100644
+--- a/llvm/test/Other/new-pm-thinlto-postlink-pgo-defaults.ll
++++ b/llvm/test/Other/new-pm-thinlto-postlink-pgo-defaults.ll
+@@ -121,7 +121,6 @@
+ ; CHECK-O-NEXT: Running pass: LoopDeletionPass
+ ; CHECK-O-NEXT: Running pass: LoopFullUnrollPass
+ ; CHECK-O-NEXT: Running pass: SROAPass on foo
+-; CHECK-O23SZ-NEXT: Running pass: VectorCombinePass
+ ; CHECK-O23SZ-NEXT: Running pass: MergedLoadStoreMotionPass
+ ; CHECK-O23SZ-NEXT: Running pass: GVNPass
+ ; CHECK-O23SZ-NEXT: Running analysis: MemoryDependenceAnalysis
+diff --git a/llvm/test/Other/new-pm-thinlto-postlink-samplepgo-defaults.ll b/llvm/test/Other/new-pm-thinlto-postlink-samplepgo-defaults.ll
+index daf3141a1f2c..78914d1c23b2 100644
+--- a/llvm/test/Other/new-pm-thinlto-postlink-samplepgo-defaults.ll
++++ b/llvm/test/Other/new-pm-thinlto-postlink-samplepgo-defaults.ll
+@@ -130,7 +130,6 @@
+ ; CHECK-O-NEXT: Running pass: LoopDeletionPass
+ ; CHECK-O-NEXT: Running pass: LoopFullUnrollPass
+ ; CHECK-O-NEXT: Running pass: SROAPass on foo
+-; CHECK-O23SZ-NEXT: Running pass: VectorCombinePass
+ ; CHECK-O23SZ-NEXT: Running pass: MergedLoadStoreMotionPass
+ ; CHECK-O23SZ-NEXT: Running pass: GVNPass
+ ; CHECK-O23SZ-NEXT: Running analysis: MemoryDependenceAnalysis
+diff --git a/llvm/test/Other/new-pm-thinlto-prelink-pgo-defaults.ll b/llvm/test/Other/new-pm-thinlto-prelink-pgo-defaults.ll
+index bfe80902f806..5b62ba39add3 100644
+--- a/llvm/test/Other/new-pm-thinlto-prelink-pgo-defaults.ll
++++ b/llvm/test/Other/new-pm-thinlto-prelink-pgo-defaults.ll
+@@ -160,7 +160,6 @@
+ ; CHECK-O-NEXT: Running pass: LoopDeletionPass
+ ; CHECK-O-NEXT: Running pass: LoopFullUnrollPass
+ ; CHECK-O-NEXT: Running pass: SROAPass on foo
+-; CHECK-O23SZ-NEXT: Running pass: VectorCombinePass
+ ; CHECK-O23SZ-NEXT: Running pass: MergedLoadStoreMotionPass
+ ; CHECK-O23SZ-NEXT: Running pass: GVNPass
+ ; CHECK-O23SZ-NEXT: Running analysis: MemoryDependenceAnalysis
+diff --git a/llvm/test/Other/new-pm-thinlto-prelink-samplepgo-defaults.ll b/llvm/test/Other/new-pm-thinlto-prelink-samplepgo-defaults.ll
+index c7daf7aa46b1..17475423d696 100644
+--- a/llvm/test/Other/new-pm-thinlto-prelink-samplepgo-defaults.ll
++++ b/llvm/test/Other/new-pm-thinlto-prelink-samplepgo-defaults.ll
+@@ -124,7 +124,6 @@
+ ; CHECK-O-NEXT: Running pass: IndVarSimplifyPass
+ ; CHECK-O-NEXT: Running pass: LoopDeletionPass
+ ; CHECK-O-NEXT: Running pass: SROAPass on foo
+-; CHECK-O23SZ-NEXT: Running pass: VectorCombinePass
+ ; CHECK-O23SZ-NEXT: Running pass: MergedLoadStoreMotionPass
+ ; CHECK-O23SZ-NEXT: Running pass: GVNPass
+ ; CHECK-O23SZ-NEXT: Running analysis: MemoryDependenceAnalysis
+diff --git a/llvm/test/Transforms/PhaseOrdering/X86/vec-load-combine.ll b/llvm/test/Transforms/PhaseOrdering/X86/vec-load-combine.ll
+index 77cbc70ff369..dd7164febea4 100644
+--- a/llvm/test/Transforms/PhaseOrdering/X86/vec-load-combine.ll
++++ b/llvm/test/Transforms/PhaseOrdering/X86/vec-load-combine.ll
+@@ -12,13 +12,20 @@ $getAt = comdat any
+ define dso_local noundef <4 x float> @ConvertVectors_ByRef(ptr noundef nonnull align 16 dereferenceable(16) %0) #0 {
+ ; SSE-LABEL: @ConvertVectors_ByRef(
+ ; SSE-NEXT: [[TMP2:%.*]] = load <4 x float>, ptr [[TMP0:%.*]], align 16
+-; SSE-NEXT: [[TMP3:%.*]] = shufflevector <4 x float> [[TMP2]], <4 x float> poison, <4 x i32> <i32 0, i32 1, i32 2, i32 2>
+-; SSE-NEXT: ret <4 x float> [[TMP3]]
++; SSE-NEXT: [[TMP3:%.*]] = getelementptr inbounds [4 x float], ptr [[TMP0]], i64 0, i64 1
++; SSE-NEXT: [[TMP4:%.*]] = load <2 x float>, ptr [[TMP3]], align 4
++; SSE-NEXT: [[TMP5:%.*]] = shufflevector <2 x float> [[TMP4]], <2 x float> poison, <4 x i32> <i32 0, i32 1, i32 undef, i32 undef>
++; SSE-NEXT: [[TMP6:%.*]] = shufflevector <4 x float> [[TMP2]], <4 x float> [[TMP5]], <4 x i32> <i32 0, i32 4, i32 5, i32 undef>
++; SSE-NEXT: [[TMP7:%.*]] = shufflevector <4 x float> [[TMP6]], <4 x float> [[TMP5]], <4 x i32> <i32 0, i32 1, i32 2, i32 5>
++; SSE-NEXT: ret <4 x float> [[TMP7]]
+ ;
+ ; AVX-LABEL: @ConvertVectors_ByRef(
+ ; AVX-NEXT: [[TMP2:%.*]] = load <4 x float>, ptr [[TMP0:%.*]], align 16
+-; AVX-NEXT: [[TMP3:%.*]] = shufflevector <4 x float> [[TMP2]], <4 x float> poison, <4 x i32> <i32 0, i32 1, i32 2, i32 2>
+-; AVX-NEXT: ret <4 x float> [[TMP3]]
++; AVX-NEXT: [[TMP3:%.*]] = getelementptr inbounds [4 x float], ptr [[TMP0]], i64 0, i64 2
++; AVX-NEXT: [[TMP4:%.*]] = load float, ptr [[TMP3]], align 8
++; AVX-NEXT: [[TMP5:%.*]] = insertelement <4 x float> [[TMP2]], float [[TMP4]], i64 2
++; AVX-NEXT: [[TMP6:%.*]] = insertelement <4 x float> [[TMP5]], float [[TMP4]], i64 3
++; AVX-NEXT: ret <4 x float> [[TMP6]]
+ ;
+ %2 = alloca ptr, align 8
+ %3 = alloca <4 x float>, align 16
+--
+2.39.0.1.g6739ec1790
+
diff --git a/build/build-clang/revert-llvmorg-17-init-4120-g02e8eb1a438b.patch b/build/build-clang/revert-llvmorg-17-init-4120-g02e8eb1a438b.patch
new file mode 100644
index 0000000000..63e59ee68b
--- /dev/null
+++ b/build/build-clang/revert-llvmorg-17-init-4120-g02e8eb1a438b.patch
@@ -0,0 +1,118 @@
+From 2836e92ea557be53fcd91e38cb05a989ad0167e9 Mon Sep 17 00:00:00 2001
+From: Mike Hommey <mh@glandium.org>
+Date: Wed, 8 Mar 2023 14:44:58 +0900
+Subject: [PATCH] Revert "Split getCompileUnitFor{Data,Code}Address."
+
+This reverts commit 02e8eb1a438bdb1dc9a97aea75a8c9c748048039, which
+applies on top of cead4eceb01b935fae07bf4a7e91911b344d2fec, that we
+revert too.
+---
+ .../llvm/DebugInfo/DWARF/DWARFContext.h | 11 +--------
+ llvm/lib/DebugInfo/DWARF/DWARFContext.cpp | 23 ++++++++-----------
+ 2 files changed, 11 insertions(+), 23 deletions(-)
+
+diff --git a/llvm/include/llvm/DebugInfo/DWARF/DWARFContext.h b/llvm/include/llvm/DebugInfo/DWARF/DWARFContext.h
+index 4eba79a7215f..df903b967ef6 100644
+--- a/llvm/include/llvm/DebugInfo/DWARF/DWARFContext.h
++++ b/llvm/include/llvm/DebugInfo/DWARF/DWARFContext.h
+@@ -445,16 +445,7 @@ public:
+ /// address.
+ /// TODO: change input parameter from "uint64_t Address"
+ /// into "SectionedAddress Address"
+- DWARFCompileUnit *getCompileUnitForCodeAddress(uint64_t Address);
+-
+- /// Return the compile unit which contains data with the provided address.
+- /// Note: This is more expensive than `getCompileUnitForAddress`, as if
+- /// `Address` isn't found in the CU ranges (which is cheap), then it falls
+- /// back to an expensive O(n) walk of all CU's looking for data that spans the
+- /// address.
+- /// TODO: change input parameter from "uint64_t Address" into
+- /// "SectionedAddress Address"
+- DWARFCompileUnit *getCompileUnitForDataAddress(uint64_t Address);
++ DWARFCompileUnit *getCompileUnitForAddress(uint64_t Address);
+
+ /// Returns whether CU/TU should be populated manually. TU Index populated
+ /// manually only for DWARF5.
+diff --git a/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp b/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
+index f648ef8ff770..dd86144d16e0 100644
+--- a/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
++++ b/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
+@@ -1118,17 +1118,14 @@ DWARFCompileUnit *DWARFContext::getCompileUnitForOffset(uint64_t Offset) {
+ NormalUnits.getUnitForOffset(Offset));
+ }
+
+-DWARFCompileUnit *DWARFContext::getCompileUnitForCodeAddress(uint64_t Address) {
+- uint64_t CUOffset = getDebugAranges()->findAddress(Address);
+- return getCompileUnitForOffset(CUOffset);
+-}
+-
+-DWARFCompileUnit *DWARFContext::getCompileUnitForDataAddress(uint64_t Address) {
++DWARFCompileUnit *DWARFContext::getCompileUnitForAddress(uint64_t Address) {
++ // First, get the offset of the compile unit.
+ uint64_t CUOffset = getDebugAranges()->findAddress(Address);
++ // Retrieve the compile unit.
+ if (DWARFCompileUnit *OffsetCU = getCompileUnitForOffset(CUOffset))
+ return OffsetCU;
+
+- // Global variables are often missed by the above search, for one of two
++ // Global variables are often not found by the above search, for one of two
+ // reasons:
+ // 1. .debug_aranges may not include global variables. On clang, it seems we
+ // put the globals in the aranges, but this isn't true for gcc.
+@@ -1149,7 +1146,7 @@ DWARFCompileUnit *DWARFContext::getCompileUnitForDataAddress(uint64_t Address) {
+ DWARFContext::DIEsForAddress DWARFContext::getDIEsForAddress(uint64_t Address) {
+ DIEsForAddress Result;
+
+- DWARFCompileUnit *CU = getCompileUnitForCodeAddress(Address);
++ DWARFCompileUnit *CU = getCompileUnitForAddress(Address);
+ if (!CU)
+ return Result;
+
+@@ -1300,7 +1297,7 @@ void DWARFContext::addLocalsForDie(DWARFCompileUnit *CU, DWARFDie Subprogram,
+ std::vector<DILocal>
+ DWARFContext::getLocalsForAddress(object::SectionedAddress Address) {
+ std::vector<DILocal> Result;
+- DWARFCompileUnit *CU = getCompileUnitForCodeAddress(Address.Address);
++ DWARFCompileUnit *CU = getCompileUnitForAddress(Address.Address);
+ if (!CU)
+ return Result;
+
+@@ -1313,7 +1310,7 @@ DWARFContext::getLocalsForAddress(object::SectionedAddress Address) {
+ DILineInfo DWARFContext::getLineInfoForAddress(object::SectionedAddress Address,
+ DILineInfoSpecifier Spec) {
+ DILineInfo Result;
+- DWARFCompileUnit *CU = getCompileUnitForCodeAddress(Address.Address);
++ DWARFCompileUnit *CU = getCompileUnitForAddress(Address.Address);
+ if (!CU)
+ return Result;
+
+@@ -1334,7 +1331,7 @@ DILineInfo DWARFContext::getLineInfoForAddress(object::SectionedAddress Address,
+ DILineInfo
+ DWARFContext::getLineInfoForDataAddress(object::SectionedAddress Address) {
+ DILineInfo Result;
+- DWARFCompileUnit *CU = getCompileUnitForDataAddress(Address.Address);
++ DWARFCompileUnit *CU = getCompileUnitForAddress(Address.Address);
+ if (!CU)
+ return Result;
+
+@@ -1349,7 +1346,7 @@ DWARFContext::getLineInfoForDataAddress(object::SectionedAddress Address) {
+ DILineInfoTable DWARFContext::getLineInfoForAddressRange(
+ object::SectionedAddress Address, uint64_t Size, DILineInfoSpecifier Spec) {
+ DILineInfoTable Lines;
+- DWARFCompileUnit *CU = getCompileUnitForCodeAddress(Address.Address);
++ DWARFCompileUnit *CU = getCompileUnitForAddress(Address.Address);
+ if (!CU)
+ return Lines;
+
+@@ -1405,7 +1402,7 @@ DWARFContext::getInliningInfoForAddress(object::SectionedAddress Address,
+ DILineInfoSpecifier Spec) {
+ DIInliningInfo InliningInfo;
+
+- DWARFCompileUnit *CU = getCompileUnitForCodeAddress(Address.Address);
++ DWARFCompileUnit *CU = getCompileUnitForAddress(Address.Address);
+ if (!CU)
+ return InliningInfo;
+
+--
+2.39.0.1.g6739ec1790
+
diff --git a/build/build-clang/revert-llvmorg-17-init-4120-g02e8eb1a438b_clang_18.patch b/build/build-clang/revert-llvmorg-17-init-4120-g02e8eb1a438b_clang_18.patch
new file mode 100644
index 0000000000..098c410790
--- /dev/null
+++ b/build/build-clang/revert-llvmorg-17-init-4120-g02e8eb1a438b_clang_18.patch
@@ -0,0 +1,115 @@
+From 2836e92ea557be53fcd91e38cb05a989ad0167e9 Mon Sep 17 00:00:00 2001
+From: Mike Hommey <mh@glandium.org>
+Date: Wed, 8 Mar 2023 14:44:58 +0900
+Subject: [PATCH] Revert "Split getCompileUnitFor{Data,Code}Address."
+
+This reverts commit 02e8eb1a438bdb1dc9a97aea75a8c9c748048039, which
+applies on top of cead4eceb01b935fae07bf4a7e91911b344d2fec, that we
+revert too.
+---
+ .../llvm/DebugInfo/DWARF/DWARFContext.h | 11 +--------
+ llvm/lib/DebugInfo/DWARF/DWARFContext.cpp | 23 ++++++++-----------
+ 2 files changed, 11 insertions(+), 23 deletions(-)
+
+diff --git a/llvm/include/llvm/DebugInfo/DWARF/DWARFContext.h b/llvm/include/llvm/DebugInfo/DWARF/DWARFContext.h
+index 4bd8394e6b4e..3f49fadc2b98 100644
+--- a/llvm/include/llvm/DebugInfo/DWARF/DWARFContext.h
++++ b/llvm/include/llvm/DebugInfo/DWARF/DWARFContext.h
+@@ -459,16 +459,7 @@ public:
+ /// address.
+ /// TODO: change input parameter from "uint64_t Address"
+ /// into "SectionedAddress Address"
+- DWARFCompileUnit *getCompileUnitForCodeAddress(uint64_t Address);
+-
+- /// Return the compile unit which contains data with the provided address.
+- /// Note: This is more expensive than `getCompileUnitForAddress`, as if
+- /// `Address` isn't found in the CU ranges (which is cheap), then it falls
+- /// back to an expensive O(n) walk of all CU's looking for data that spans the
+- /// address.
+- /// TODO: change input parameter from "uint64_t Address" into
+- /// "SectionedAddress Address"
+- DWARFCompileUnit *getCompileUnitForDataAddress(uint64_t Address);
++ DWARFCompileUnit *getCompileUnitForAddress(uint64_t Address);
+
+ /// Returns whether CU/TU should be populated manually. TU Index populated
+ /// manually only for DWARF5.
+diff --git a/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp b/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
+index a45ed0e56553..692304ac6774 100644
+--- a/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
++++ b/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
+@@ -1492,17 +1492,14 @@ DWARFCompileUnit *DWARFContext::getCompileUnitForOffset(uint64_t Offset) {
+ State->getNormalUnits().getUnitForOffset(Offset));
+ }
+
+-DWARFCompileUnit *DWARFContext::getCompileUnitForCodeAddress(uint64_t Address) {
+- uint64_t CUOffset = getDebugAranges()->findAddress(Address);
+- return getCompileUnitForOffset(CUOffset);
+-}
+-
+-DWARFCompileUnit *DWARFContext::getCompileUnitForDataAddress(uint64_t Address) {
++DWARFCompileUnit *DWARFContext::getCompileUnitForAddress(uint64_t Address) {
++ // First, get the offset of the compile unit.
+ uint64_t CUOffset = getDebugAranges()->findAddress(Address);
++ // Retrieve the compile unit.
+ if (DWARFCompileUnit *OffsetCU = getCompileUnitForOffset(CUOffset))
+ return OffsetCU;
+
+- // Global variables are often missed by the above search, for one of two
++ // Global variables are often not found by the above search, for one of two
+ // reasons:
+ // 1. .debug_aranges may not include global variables. On clang, it seems we
+ // put the globals in the aranges, but this isn't true for gcc.
+@@ -1523,7 +1520,7 @@ DWARFCompileUnit *DWARFContext::getCompileUnitForDataAddress(uint64_t Address) {
+ bool CheckDWO) {
+ DIEsForAddress Result;
+
+- DWARFCompileUnit *CU = getCompileUnitForCodeAddress(Address);
++ DWARFCompileUnit *CU = getCompileUnitForAddress(Address);
+ if (!CU)
+ return Result;
+
+@@ -1674,7 +1671,7 @@ void DWARFContext::addLocalsForDie(DWARFCompileUnit *CU, DWARFDie Subprogram,
+ std::vector<DILocal>
+ DWARFContext::getLocalsForAddress(object::SectionedAddress Address) {
+ std::vector<DILocal> Result;
+- DWARFCompileUnit *CU = getCompileUnitForCodeAddress(Address.Address);
++ DWARFCompileUnit *CU = getCompileUnitForAddress(Address.Address);
+ if (!CU)
+ return Result;
+
+@@ -1687,7 +1684,7 @@ DWARFContext::getLocalsForAddress(object::SectionedAddress Address) {
+ DILineInfo DWARFContext::getLineInfoForAddress(object::SectionedAddress Address,
+ DILineInfoSpecifier Spec) {
+ DILineInfo Result;
+- DWARFCompileUnit *CU = getCompileUnitForCodeAddress(Address.Address);
++ DWARFCompileUnit *CU = getCompileUnitForAddress(Address.Address);
+ if (!CU)
+ return Result;
+
+@@ -1708,7 +1705,7 @@ DILineInfo DWARFContext::getLineInfoForAddress(object::SectionedAddress Address,
+ DILineInfo
+ DWARFContext::getLineInfoForDataAddress(object::SectionedAddress Address) {
+ DILineInfo Result;
+- DWARFCompileUnit *CU = getCompileUnitForDataAddress(Address.Address);
++ DWARFCompileUnit *CU = getCompileUnitForAddress(Address.Address);
+ if (!CU)
+ return Result;
+
+@@ -1723,7 +1720,7 @@ DWARFContext::getLineInfoForDataAddress(object::SectionedAddress Address) {
+ DILineInfoTable DWARFContext::getLineInfoForAddressRange(
+ object::SectionedAddress Address, uint64_t Size, DILineInfoSpecifier Spec) {
+ DILineInfoTable Lines;
+- DWARFCompileUnit *CU = getCompileUnitForCodeAddress(Address.Address);
++ DWARFCompileUnit *CU = getCompileUnitForAddress(Address.Address);
+ if (!CU)
+ return Lines;
+
+@@ -1779,7 +1776,7 @@ DWARFContext::getInliningInfoForAddress(object::SectionedAddress Address,
+ DILineInfoSpecifier Spec) {
+ DIInliningInfo InliningInfo;
+
+- DWARFCompileUnit *CU = getCompileUnitForCodeAddress(Address.Address);
++ DWARFCompileUnit *CU = getCompileUnitForAddress(Address.Address);
+ if (!CU)
+ return InliningInfo;
+
diff --git a/build/build-clang/revert-llvmorg-18-init-6188-gc649f29c24c9.patch b/build/build-clang/revert-llvmorg-18-init-6188-gc649f29c24c9.patch
new file mode 100644
index 0000000000..290c65f4b5
--- /dev/null
+++ b/build/build-clang/revert-llvmorg-18-init-6188-gc649f29c24c9.patch
@@ -0,0 +1,466 @@
+From c3994286d37f4273d6d7a4cb578828d64a25a341 Mon Sep 17 00:00:00 2001
+From: Mike Hommey <mh@glandium.org>
+Date: Wed, 20 Sep 2023 10:08:22 +0900
+Subject: [PATCH 3/3] Revert "[llvm-nm] Add --line-numbers flag"
+
+This reverts commit c649f29c24c9fc1502d8d53e0c96c3d24b31de1a because it
+depends on cead4eceb01b935fae07bf4a7e91911b344d2fec, which we revert.
+---
+ llvm/docs/CommandGuide/llvm-nm.rst | 6 -
+ llvm/test/tools/llvm-nm/X86/line-numbers.test | 240 ------------------
+ llvm/tools/llvm-nm/CMakeLists.txt | 1 -
+ llvm/tools/llvm-nm/Opts.td | 2 -
+ llvm/tools/llvm-nm/llvm-nm.cpp | 92 +------
+ 6 files changed, 5 insertions(+), 339 deletions(-)
+ delete mode 100644 llvm/test/tools/llvm-nm/X86/line-numbers.test
+
+diff --git a/llvm/docs/CommandGuide/llvm-nm.rst b/llvm/docs/CommandGuide/llvm-nm.rst
+index 7067bb0a29a1..4b1290a15665 100644
+--- a/llvm/docs/CommandGuide/llvm-nm.rst
++++ b/llvm/docs/CommandGuide/llvm-nm.rst
+@@ -190,12 +190,6 @@ OPTIONS
+
+ Print just the symbol names. Alias for `--format=just-symbols``.
+
+-.. option:: --line-numbers, -l
+-
+- Use debugging information to print the filenames and line numbers where
+- symbols are defined. Undefined symbols have the location of their first
+- relocation printed instead.
+-
+ .. option:: -m
+
+ Use Darwin format. Alias for ``--format=darwin``.
+diff --git a/llvm/test/tools/llvm-nm/X86/line-numbers.test b/llvm/test/tools/llvm-nm/X86/line-numbers.test
+deleted file mode 100644
+index 4b9817ab5c62..000000000000
+--- a/llvm/test/tools/llvm-nm/X86/line-numbers.test
++++ /dev/null
+@@ -1,240 +0,0 @@
+-## Check that printing line numbers isn't attempted for files like bitcode,
+-## which have symbols but limited/no section or debug info.
+-# RUN: llvm-nm --line-numbers %p/Inputs/test.IRobj-x86_64 | FileCheck %s --check-prefix=BITCODE --match-full-lines --implicit-check-not={{.}}
+-# BITCODE: ---------------- S _global_const
+-# BITCODE-NEXT: ---------------- D _global_data
+-# BITCODE-NEXT: ---------------- T _global_func
+-# BITCODE-NEXT: ---------------- S _hidden_const
+-# BITCODE-NEXT: ---------------- D _hidden_data
+-# BITCODE-NEXT: ---------------- T _hidden_func
+-# BITCODE-NEXT: ---------------- s _static_const
+-# BITCODE-NEXT: ---------------- d _static_data
+-# BITCODE-NEXT: ---------------- t _static_func
+-
+-## Check that various symbol types can use debug information if available to
+-## print line numbers, and if unavailable, don't print anything erroneous. The
+-## specific cases checked are given by the symbol names below. Other test cases
+-## place requirements on the contents of the whole file, so they are kept out
+-## of main.o.
+-# RUN: rm -rf %t
+-# RUN: split-file %s %t
+-# RUN: llvm-mc -g --filetype=obj %t/main.s -o %t/main.o
+-# RUN: llvm-nm -l %t/main.o | FileCheck %s --match-full-lines --implicit-check-not={{.}}
+-# RUN: llvm-nm --line-numbers %t/main.o | FileCheck %s --match-full-lines --implicit-check-not={{.}}
+-
+-# CHECK: 0000000000001234 a absolute_symbol
+-# CHECK-NEXT: 0000000000000000 d data_no_dwarf
+-# CHECK-NEXT: 0000000000000000 T defined_global_function [[FILENAME:.*main.s]]:4
+-# CHECK-NEXT: 0000000000000001 t defined_local_function [[FILENAME]]:7
+-# CHECK-NEXT: 0000000000000000 t function_no_dwarf
+-# CHECK-NEXT: U undef1 [[FILENAME]]:12
+-# CHECK-NEXT: U undef2 [[FILENAME]]:14
+-# CHECK-NEXT: U undef_no_reloc
+-# CHECK-NEXT: 0000000000000002 t undefined_references [[FILENAME]]:12
+-
+-## Check that in the absence of DWARF in the whole object, no line number
+-## information is printed.
+-# RUN: llvm-mc --filetype=obj %t/main.s -o %t/no-dwarf.o
+-# RUN: llvm-nm -l %t/no-dwarf.o | FileCheck %s --check-prefix=NO-DWARF --match-full-lines --implicit-check-not={{.}}
+-
+-# NO-DWARF: 0000000000001234 a absolute_symbol
+-# NO-DWARF-NEXT: 0000000000000000 d data_no_dwarf
+-# NO-DWARF-NEXT: 0000000000000000 T defined_global_function
+-# NO-DWARF-NEXT: 0000000000000001 t defined_local_function
+-# NO-DWARF-NEXT: 0000000000000000 t function_no_dwarf
+-# NO-DWARF-NEXT: U undef1
+-# NO-DWARF-NEXT: U undef2
+-# NO-DWARF-NEXT: U undef_no_reloc
+-# NO-DWARF-NEXT: 0000000000000002 t undefined_references
+-
+-## Check that printing line numbers for undefined values is not attempted in
+-## the absence of any relocation section.
+-# RUN: llvm-mc --filetype=obj %t/undef-no-reloc-sections.s -o %t/undef-no-reloc-sections.o
+-# RUN: llvm-nm --line-numbers %t/undef-no-reloc-sections.o | FileCheck %s --check-prefix=UNDEF-NO-RELOC-SECTIONS --match-full-lines --implicit-check-not={{.}}
+-
+-# UNDEF-NO-RELOC-SECTIONS: U undef
+-
+-## Check that printing line numbers for undefined values does not include
+-## relocations for non-text sections. This is broken out of main.s to ensure
+-## that the data relocation for undef comes first.
+-# RUN: llvm-mc -g --filetype=obj %t/undef-data-reloc.s -o %t/undef-data-reloc.o
+-# RUN: llvm-nm --line-numbers %t/undef-data-reloc.o | FileCheck %s --check-prefix=UNDEF-DATA-RELOC --match-full-lines --implicit-check-not={{.}}
+-
+-# UNDEF-DATA-RELOC: 0000000000000000 r data_reloc
+-# UNDEF-DATA-RELOC-NEXT: U undef
+-
+-## Check that line numbers can be printed for data definitions. These are broken
+-## out of main.s since their DWARF cannot be generated with llvm-mc -g.
+-# RUN: llvm-mc -g --filetype=obj %t/data-dwarf.s -o %t/data-dwarf.o
+-# RUN: llvm-nm --line-numbers %t/data-dwarf.o | FileCheck %s --check-prefix=DATA-DWARF --match-full-lines --implicit-check-not={{.}}
+-
+-# DATA-DWARF: 0000000000000000 D defined_data /tmp/tmp.c:1
+-
+-#--- main.s
+-.text
+-.globl defined_global_function
+-defined_global_function:
+- ret
+-
+-defined_local_function:
+- ret
+-
+-absolute_symbol = 0x1234
+-
+-undefined_references:
+- nop
+- .long undef1
+- nop
+- .long undef2
+- ret
+-
+-# Note: llvm-mc -g produces no DWARF for data.
+-.data
+-data_no_dwarf:
+- .byte 0
+-
+-.globl undef_no_reloc
+-
+-# Note: llvm-mc -g does not produce DWARF for non-SHF_ALLOC sections.
+-.section no_alloc_text,"x",@progbits
+-function_no_dwarf:
+- ret
+-
+-#--- undef-no-reloc-sections.s
+-.globl undef
+-
+-#--- undef-data-reloc.s
+-.globl undef
+-.rodata
+-data_reloc:
+- .long undef
+-
+-#--- data-dwarf.s
+-# char defined_data = 42
+- .text
+- .file "tmp.c"
+- .file 0 "/tmp" "/tmp/tmp.c" md5 0x39602a53b15a32d6a622ca86936e88d7
+- .file 1 "tmp.c" md5 0x39602a53b15a32d6a622ca86936e88d7
+- .type defined_data,@object # @defined_data
+- .data
+- .globl defined_data
+-defined_data:
+- .byte 42 # 0x2a
+- .size defined_data, 1
+-
+- .section .debug_abbrev,"",@progbits
+- .byte 1 # Abbreviation Code
+- .byte 17 # DW_TAG_compile_unit
+- .byte 1 # DW_CHILDREN_yes
+- .byte 37 # DW_AT_producer
+- .byte 37 # DW_FORM_strx1
+- .byte 19 # DW_AT_language
+- .byte 5 # DW_FORM_data2
+- .byte 3 # DW_AT_name
+- .byte 37 # DW_FORM_strx1
+- .byte 114 # DW_AT_str_offsets_base
+- .byte 23 # DW_FORM_sec_offset
+- .byte 16 # DW_AT_stmt_list
+- .byte 23 # DW_FORM_sec_offset
+- .byte 27 # DW_AT_comp_dir
+- .byte 37 # DW_FORM_strx1
+- .byte 115 # DW_AT_addr_base
+- .byte 23 # DW_FORM_sec_offset
+- .byte 0 # EOM(1)
+- .byte 0 # EOM(2)
+- .byte 2 # Abbreviation Code
+- .byte 52 # DW_TAG_variable
+- .byte 0 # DW_CHILDREN_no
+- .byte 3 # DW_AT_name
+- .byte 37 # DW_FORM_strx1
+- .byte 73 # DW_AT_type
+- .byte 19 # DW_FORM_ref4
+- .byte 63 # DW_AT_external
+- .byte 25 # DW_FORM_flag_present
+- .byte 58 # DW_AT_decl_file
+- .byte 11 # DW_FORM_data1
+- .byte 59 # DW_AT_decl_line
+- .byte 11 # DW_FORM_data1
+- .byte 2 # DW_AT_location
+- .byte 24 # DW_FORM_exprloc
+- .byte 0 # EOM(1)
+- .byte 0 # EOM(2)
+- .byte 3 # Abbreviation Code
+- .byte 36 # DW_TAG_base_type
+- .byte 0 # DW_CHILDREN_no
+- .byte 3 # DW_AT_name
+- .byte 37 # DW_FORM_strx1
+- .byte 62 # DW_AT_encoding
+- .byte 11 # DW_FORM_data1
+- .byte 11 # DW_AT_byte_size
+- .byte 11 # DW_FORM_data1
+- .byte 0 # EOM(1)
+- .byte 0 # EOM(2)
+- .byte 0 # EOM(3)
+- .section .debug_info,"",@progbits
+-.Lcu_begin0:
+- .long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit
+-.Ldebug_info_start0:
+- .short 5 # DWARF version number
+- .byte 1 # DWARF Unit Type
+- .byte 8 # Address Size (in bytes)
+- .long .debug_abbrev # Offset Into Abbrev. Section
+- .byte 1 # Abbrev [1] 0xc:0x22 DW_TAG_compile_unit
+- .byte 0 # DW_AT_producer
+- .short 12 # DW_AT_language
+- .byte 1 # DW_AT_name
+- .long .Lstr_offsets_base0 # DW_AT_str_offsets_base
+- .long .Lline_table_start0 # DW_AT_stmt_list
+- .byte 2 # DW_AT_comp_dir
+- .long .Laddr_table_base0 # DW_AT_addr_base
+- .byte 2 # Abbrev [2] 0x1e:0xb DW_TAG_variable
+- .byte 3 # DW_AT_name
+- .long 41 # DW_AT_type
+- # DW_AT_external
+- .byte 1 # DW_AT_decl_file
+- .byte 1 # DW_AT_decl_line
+- .byte 2 # DW_AT_location
+- .byte 161
+- .byte 0
+- .byte 3 # Abbrev [3] 0x29:0x4 DW_TAG_base_type
+- .byte 4 # DW_AT_name
+- .byte 6 # DW_AT_encoding
+- .byte 1 # DW_AT_byte_size
+- .byte 0 # End Of Children Mark
+-.Ldebug_info_end0:
+- .section .debug_str_offsets,"",@progbits
+- .long 24 # Length of String Offsets Set
+- .short 5
+- .short 0
+-.Lstr_offsets_base0:
+- .section .debug_str,"MS",@progbits,1
+-.Linfo_string0:
+- .asciz "Debian clang version 14.0.6" # string offset=0
+-.Linfo_string1:
+- .asciz "/tmp/tmp.c" # string offset=28
+-.Linfo_string2:
+- .asciz "/tmp" # string offset=39
+-.Linfo_string3:
+- .asciz "defined_data" # string offset=44
+-.Linfo_string4:
+- .asciz "char" # string offset=57
+- .section .debug_str_offsets,"",@progbits
+- .long .Linfo_string0
+- .long .Linfo_string1
+- .long .Linfo_string2
+- .long .Linfo_string3
+- .long .Linfo_string4
+- .section .debug_addr,"",@progbits
+- .long .Ldebug_addr_end0-.Ldebug_addr_start0 # Length of contribution
+-.Ldebug_addr_start0:
+- .short 5 # DWARF version number
+- .byte 8 # Address size
+- .byte 0 # Segment selector size
+-.Laddr_table_base0:
+- .quad defined_data
+-.Ldebug_addr_end0:
+- .ident "Debian clang version 14.0.6"
+- .section ".note.GNU-stack","",@progbits
+- .addrsig
+- .section .debug_line,"",@progbits
+-.Lline_table_start0:
+diff --git a/llvm/tools/llvm-nm/CMakeLists.txt b/llvm/tools/llvm-nm/CMakeLists.txt
+index 5191e138d1c0..ec04f1e9d234 100644
+--- a/llvm/tools/llvm-nm/CMakeLists.txt
++++ b/llvm/tools/llvm-nm/CMakeLists.txt
+@@ -8,7 +8,6 @@ set(LLVM_LINK_COMPONENTS
+ Object
+ Option
+ Support
+- Symbolize
+ TargetParser
+ TextAPI
+ )
+diff --git a/llvm/tools/llvm-nm/Opts.td b/llvm/tools/llvm-nm/Opts.td
+index 04d9f5db5cf8..60ac134269b3 100644
+--- a/llvm/tools/llvm-nm/Opts.td
++++ b/llvm/tools/llvm-nm/Opts.td
+@@ -22,7 +22,6 @@ def export_symbols : FF<"export-symbols", "Export symbol list for all inputs">;
+ def extern_only : FF<"extern-only", "Show only external symbols">;
+ defm format : Eq<"format", "Specify output format: bsd (default), posix, sysv, darwin, just-symbols">, MetaVarName<"<format>">;
+ def help : FF<"help", "Display this help">;
+-def line_numbers : FF<"line-numbers", "Use debugging information to print symbols' filenames and line numbers">;
+ def no_llvm_bc : FF<"no-llvm-bc", "Disable LLVM bitcode reader">;
+ def no_sort : FF<"no-sort", "Show symbols in order encountered">;
+ def no_weak : FF<"no-weak", "Show only non-weak symbols">;
+@@ -68,7 +67,6 @@ def : JoinedOrSeparate<["-"], "f">, HelpText<"Alias for --format">, Alias<format
+ def : F<"h", "Alias for --help">, Alias<help>;
+ def : F<"g", "Alias for --extern-only">, Alias<extern_only>;
+ def : F<"j", "Alias for --format=just-symbols">, Alias<format_EQ>, AliasArgs<["just-symbols"]>;
+-def : F<"l", "Alias for --line-numbers">, Alias<line_numbers>;
+ def : F<"m", "Alias for --format=darwin">, Alias<format_EQ>, AliasArgs<["darwin"]>;
+ def : F<"M", "Deprecated alias for --print-armap">, Alias<print_armap>, Flags<[HelpHidden]>;
+ def : F<"n", "Alias for --numeric-sort">, Alias<numeric_sort>;
+diff --git a/llvm/tools/llvm-nm/llvm-nm.cpp b/llvm/tools/llvm-nm/llvm-nm.cpp
+index 051fa3e5bfa5..9a9e8bd146bb 100644
+--- a/llvm/tools/llvm-nm/llvm-nm.cpp
++++ b/llvm/tools/llvm-nm/llvm-nm.cpp
+@@ -19,7 +19,6 @@
+ #include "llvm/BinaryFormat/COFF.h"
+ #include "llvm/BinaryFormat/MachO.h"
+ #include "llvm/BinaryFormat/XCOFF.h"
+-#include "llvm/DebugInfo/Symbolize/Symbolize.h"
+ #include "llvm/Demangle/Demangle.h"
+ #include "llvm/IR/Function.h"
+ #include "llvm/IR/LLVMContext.h"
+@@ -98,7 +97,6 @@ static bool Demangle;
+ static bool DynamicSyms;
+ static bool ExportSymbols;
+ static bool ExternalOnly;
+-static bool LineNumbers;
+ static OutputFormatTy OutputFormat;
+ static bool NoLLVMBitcode;
+ static bool NoSort;
+@@ -553,6 +551,8 @@ static void darwinPrintSymbol(SymbolicFile &Obj, const NMSymbol &S,
+ }
+ }
+ }
++
++ outs() << "\n";
+ }
+
+ // Table that maps Darwin's Mach-O stab constants to strings to allow printing.
+@@ -689,88 +689,9 @@ static void printExportSymbolList(const std::vector<NMSymbol> &SymbolList) {
+ }
+ }
+
+-static void printLineNumbers(symbolize::LLVMSymbolizer &Symbolizer,
+- const NMSymbol &S) {
+- const auto *Obj = dyn_cast<ObjectFile>(S.Sym.getObject());
+- if (!Obj)
+- return;
+- const SymbolRef Sym(S.Sym);
+- uint64_t SectionIndex = object::SectionedAddress::UndefSection;
+- section_iterator Sec = cantFail(Sym.getSection());
+- if (Sec != Obj->section_end())
+- SectionIndex = Sec->getIndex();
+- object::SectionedAddress Address = {cantFail(Sym.getAddress()), SectionIndex};
+-
+- std::string FileName;
+- uint32_t Line;
+- switch (S.TypeChar) {
+- // For undefined symbols, find the first relocation for that symbol with a
+- // line number.
+- case 'U': {
+- for (const SectionRef RelocsSec : Obj->sections()) {
+- if (RelocsSec.relocations().empty())
+- continue;
+- SectionRef TextSec = *cantFail(RelocsSec.getRelocatedSection());
+- if (!TextSec.isText())
+- continue;
+- for (const RelocationRef R : RelocsSec.relocations()) {
+- if (R.getSymbol() != Sym)
+- continue;
+- Expected<DILineInfo> ResOrErr = Symbolizer.symbolizeCode(
+- *Obj, {TextSec.getAddress() + R.getOffset(), SectionIndex});
+- if (!ResOrErr) {
+- error(ResOrErr.takeError(), Obj->getFileName());
+- return;
+- }
+- if (ResOrErr->FileName == DILineInfo::BadString)
+- return;
+- FileName = std::move(ResOrErr->FileName);
+- Line = ResOrErr->Line;
+- break;
+- }
+- if (!FileName.empty())
+- break;
+- }
+- if (FileName.empty())
+- return;
+- break;
+- }
+- case 't':
+- case 'T': {
+- Expected<DILineInfo> ResOrErr = Symbolizer.symbolizeCode(*Obj, Address);
+- if (!ResOrErr) {
+- error(ResOrErr.takeError(), Obj->getFileName());
+- return;
+- }
+- if (ResOrErr->FileName == DILineInfo::BadString)
+- return;
+- FileName = std::move(ResOrErr->FileName);
+- Line = ResOrErr->Line;
+- break;
+- }
+- default: {
+- Expected<DIGlobal> ResOrErr = Symbolizer.symbolizeData(*Obj, Address);
+- if (!ResOrErr) {
+- error(ResOrErr.takeError(), Obj->getFileName());
+- return;
+- }
+- if (ResOrErr->DeclFile.empty())
+- return;
+- FileName = std::move(ResOrErr->DeclFile);
+- Line = ResOrErr->DeclLine;
+- break;
+- }
+- }
+- outs() << '\t' << FileName << ':' << Line;
+-}
+-
+ static void printSymbolList(SymbolicFile &Obj,
+ std::vector<NMSymbol> &SymbolList, bool printName,
+ StringRef ArchiveName, StringRef ArchitectureName) {
+- std::optional<symbolize::LLVMSymbolizer> Symbolizer;
+- if (LineNumbers)
+- Symbolizer.emplace();
+-
+ if (!PrintFileName) {
+ if ((OutputFormat == bsd || OutputFormat == posix ||
+ OutputFormat == just_symbols) &&
+@@ -877,7 +798,7 @@ static void printSymbolList(SymbolicFile &Obj,
+ printFormat);
+ } else if (OutputFormat == posix) {
+ outs() << Name << " " << S.TypeChar << " " << SymbolAddrStr << " "
+- << (MachO ? "0" : SymbolSizeStr);
++ << (MachO ? "0" : SymbolSizeStr) << "\n";
+ } else if (OutputFormat == bsd || (OutputFormat == darwin && !MachO)) {
+ if (PrintAddress)
+ outs() << SymbolAddrStr << ' ';
+@@ -898,14 +819,12 @@ static void printSymbolList(SymbolicFile &Obj,
+ } else
+ outs() << S.IndirectName << ")";
+ }
++ outs() << "\n";
+ } else if (OutputFormat == sysv) {
+ outs() << left_justify(Name, 20) << "|" << SymbolAddrStr << "| "
+ << S.TypeChar << " |" << right_justify(S.TypeName, 18) << "|"
+- << SymbolSizeStr << "| |" << S.SectionName;
++ << SymbolSizeStr << "| |" << S.SectionName << "\n";
+ }
+- if (LineNumbers)
+- printLineNumbers(*Symbolizer, S);
+- outs() << '\n';
+ }
+
+ SymbolList.clear();
+@@ -2496,7 +2415,6 @@ int llvm_nm_main(int argc, char **argv, const llvm::ToolContext &) {
+ else
+ error("--format value should be one of: bsd, posix, sysv, darwin, "
+ "just-symbols");
+- LineNumbers = Args.hasArg(OPT_line_numbers);
+ NoLLVMBitcode = Args.hasArg(OPT_no_llvm_bc);
+ NoSort = Args.hasArg(OPT_no_sort);
+ NoWeakSymbols = Args.hasArg(OPT_no_weak);
+--
+2.41.0.3.g1cb8d410ac
+
diff --git a/build/build-clang/revert-llvmorg-18-init-6193-gb88cffeafd39.patch b/build/build-clang/revert-llvmorg-18-init-6193-gb88cffeafd39.patch
new file mode 100644
index 0000000000..a3ad8e0ed3
--- /dev/null
+++ b/build/build-clang/revert-llvmorg-18-init-6193-gb88cffeafd39.patch
@@ -0,0 +1,63 @@
+From be338a0b7be5040a7814d10d424f1555604cce7c Mon Sep 17 00:00:00 2001
+From: Mike Hommey <mh@glandium.org>
+Date: Wed, 20 Sep 2023 10:08:21 +0900
+Subject: [PATCH 2/3] Revert "Explicitly set triple on line-numbers.test"
+
+This reverts commit b88cffeafd393d54f85feb641c4f8fd4fdb73fe4 because it
+depends on c649f29c24c9fc1502d8d53e0c96c3d24b31de1a which we revert.
+---
+ llvm/test/tools/llvm-nm/X86/line-numbers.test | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/llvm/test/tools/llvm-nm/X86/line-numbers.test b/llvm/test/tools/llvm-nm/X86/line-numbers.test
+index 4acda8afb2a4..4b9817ab5c62 100644
+--- a/llvm/test/tools/llvm-nm/X86/line-numbers.test
++++ b/llvm/test/tools/llvm-nm/X86/line-numbers.test
+@@ -18,7 +18,7 @@
+ ## of main.o.
+ # RUN: rm -rf %t
+ # RUN: split-file %s %t
+-# RUN: llvm-mc -g --filetype=obj -triple=x86_64-pc-linux %t/main.s -o %t/main.o
++# RUN: llvm-mc -g --filetype=obj %t/main.s -o %t/main.o
+ # RUN: llvm-nm -l %t/main.o | FileCheck %s --match-full-lines --implicit-check-not={{.}}
+ # RUN: llvm-nm --line-numbers %t/main.o | FileCheck %s --match-full-lines --implicit-check-not={{.}}
+
+@@ -34,7 +34,7 @@
+
+ ## Check that in the absence of DWARF in the whole object, no line number
+ ## information is printed.
+-# RUN: llvm-mc --filetype=obj %t/main.s -triple=x86_64-pc-linux -o %t/no-dwarf.o
++# RUN: llvm-mc --filetype=obj %t/main.s -o %t/no-dwarf.o
+ # RUN: llvm-nm -l %t/no-dwarf.o | FileCheck %s --check-prefix=NO-DWARF --match-full-lines --implicit-check-not={{.}}
+
+ # NO-DWARF: 0000000000001234 a absolute_symbol
+@@ -49,7 +49,7 @@
+
+ ## Check that printing line numbers for undefined values is not attempted in
+ ## the absence of any relocation section.
+-# RUN: llvm-mc --filetype=obj %t/undef-no-reloc-sections.s -triple=x86_64-pc-linux -o %t/undef-no-reloc-sections.o
++# RUN: llvm-mc --filetype=obj %t/undef-no-reloc-sections.s -o %t/undef-no-reloc-sections.o
+ # RUN: llvm-nm --line-numbers %t/undef-no-reloc-sections.o | FileCheck %s --check-prefix=UNDEF-NO-RELOC-SECTIONS --match-full-lines --implicit-check-not={{.}}
+
+ # UNDEF-NO-RELOC-SECTIONS: U undef
+@@ -57,7 +57,7 @@
+ ## Check that printing line numbers for undefined values does not include
+ ## relocations for non-text sections. This is broken out of main.s to ensure
+ ## that the data relocation for undef comes first.
+-# RUN: llvm-mc -g --filetype=obj %t/undef-data-reloc.s -triple=x86_64-pc-linux -o %t/undef-data-reloc.o
++# RUN: llvm-mc -g --filetype=obj %t/undef-data-reloc.s -o %t/undef-data-reloc.o
+ # RUN: llvm-nm --line-numbers %t/undef-data-reloc.o | FileCheck %s --check-prefix=UNDEF-DATA-RELOC --match-full-lines --implicit-check-not={{.}}
+
+ # UNDEF-DATA-RELOC: 0000000000000000 r data_reloc
+@@ -65,7 +65,7 @@
+
+ ## Check that line numbers can be printed for data definitions. These are broken
+ ## out of main.s since their DWARF cannot be generated with llvm-mc -g.
+-# RUN: llvm-mc -g --filetype=obj %t/data-dwarf.s -triple=x86_64-pc-linux -o %t/data-dwarf.o
++# RUN: llvm-mc -g --filetype=obj %t/data-dwarf.s -o %t/data-dwarf.o
+ # RUN: llvm-nm --line-numbers %t/data-dwarf.o | FileCheck %s --check-prefix=DATA-DWARF --match-full-lines --implicit-check-not={{.}}
+
+ # DATA-DWARF: 0000000000000000 D defined_data /tmp/tmp.c:1
+--
+2.41.0.3.g1cb8d410ac
+
diff --git a/build/build-clang/revert-llvmorg-18-init-6208-g2baf4a06ef06.patch b/build/build-clang/revert-llvmorg-18-init-6208-g2baf4a06ef06.patch
new file mode 100644
index 0000000000..ba2116d4ba
--- /dev/null
+++ b/build/build-clang/revert-llvmorg-18-init-6208-g2baf4a06ef06.patch
@@ -0,0 +1,28 @@
+From 9d81bf8d2e457540b8bd93859baef79a043c8482 Mon Sep 17 00:00:00 2001
+From: Mike Hommey <mh@glandium.org>
+Date: Wed, 20 Sep 2023 10:08:13 +0900
+Subject: [PATCH 1/3] Revert "Fix test added in D150987 to account for
+ different path separators which was causing the test to fail on Windows."
+
+This reverts commit 2baf4a06ef06c51c2ef09f981f204983b0f8082c because it
+depends on c649f29c24c9fc1502d8d53e0c96c3d24b31de1a which we revert.
+---
+ llvm/test/tools/llvm-nm/X86/line-numbers.test | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/llvm/test/tools/llvm-nm/X86/line-numbers.test b/llvm/test/tools/llvm-nm/X86/line-numbers.test
+index e254df67f955..4acda8afb2a4 100644
+--- a/llvm/test/tools/llvm-nm/X86/line-numbers.test
++++ b/llvm/test/tools/llvm-nm/X86/line-numbers.test
+@@ -68,7 +68,7 @@
+ # RUN: llvm-mc -g --filetype=obj %t/data-dwarf.s -triple=x86_64-pc-linux -o %t/data-dwarf.o
+ # RUN: llvm-nm --line-numbers %t/data-dwarf.o | FileCheck %s --check-prefix=DATA-DWARF --match-full-lines --implicit-check-not={{.}}
+
+-# DATA-DWARF: 0000000000000000 D defined_data /tmp{{\\|/}}tmp.c:1
++# DATA-DWARF: 0000000000000000 D defined_data /tmp/tmp.c:1
+
+ #--- main.s
+ .text
+--
+2.41.0.3.g1cb8d410ac
+
diff --git a/build/build-clang/skip-3-stages.json b/build/build-clang/skip-3-stages.json
new file mode 100644
index 0000000000..79b1bf193f
--- /dev/null
+++ b/build/build-clang/skip-3-stages.json
@@ -0,0 +1,6 @@
+{
+ "skip_stages": "3",
+ "cc": "{MOZ_FETCHES_DIR}/clang/bin/clang",
+ "cxx": "{MOZ_FETCHES_DIR}/clang/bin/clang++",
+ "as": "{MOZ_FETCHES_DIR}/clang/bin/clang"
+}
diff --git a/build/build-clang/skip-stage-1-win64.json b/build/build-clang/skip-stage-1-win64.json
new file mode 100644
index 0000000000..8dee151003
--- /dev/null
+++ b/build/build-clang/skip-stage-1-win64.json
@@ -0,0 +1,7 @@
+{
+ "skip_stages": "1",
+ "cc": "{MOZ_FETCHES_DIR}/clang/bin/clang-cl.exe",
+ "cxx": "{MOZ_FETCHES_DIR}/clang/bin/clang-cl.exe",
+ "ml": "{MOZ_FETCHES_DIR}/clang/bin/clang-cl.exe",
+ "lib": "{MOZ_FETCHES_DIR}/clang/bin/llvm-lib.exe"
+}
diff --git a/build/build-clang/skip-stage-1.json b/build/build-clang/skip-stage-1.json
new file mode 100644
index 0000000000..aa1101b13b
--- /dev/null
+++ b/build/build-clang/skip-stage-1.json
@@ -0,0 +1,6 @@
+{
+ "skip_stages": "1",
+ "cc": "{MOZ_FETCHES_DIR}/clang/bin/clang",
+ "cxx": "{MOZ_FETCHES_DIR}/clang/bin/clang++",
+ "as": "{MOZ_FETCHES_DIR}/clang/bin/clang"
+}
diff --git a/build/build-clang/unpoison-thread-stacks_clang_10.patch b/build/build-clang/unpoison-thread-stacks_clang_10.patch
new file mode 100644
index 0000000000..563fa1d7bf
--- /dev/null
+++ b/build/build-clang/unpoison-thread-stacks_clang_10.patch
@@ -0,0 +1,64 @@
+[winasan] Unpoison the stack in NtTerminateThread
+
+In long-running builds we've seen some ASan complaints during thread creation
+that we suspect are due to leftover poisoning from previous threads whose stacks
+occupied that memory. This patch adds a hook that unpoisons the stack just
+before the NtTerminateThread syscall.
+
+Differential Revision: https://reviews.llvm.org/D52091
+
+** Update for clang 9 ** : After some backouts, this patch eventually landed
+upstream in a different form, as the TLS handler `asan_thread_exit`, but that
+variant causes failures in our test suite, so revert the TLS handler in favor of
+the interceptor approach from the first patch.
+
+diff --git a/compiler-rt/lib/asan/asan_win.cpp b/compiler-rt/lib/asan/asan_win.cpp
+index 417892aaedd..5fe86db44f4 100644
+--- a/compiler-rt/lib/asan/asan_win.cpp
++++ b/compiler-rt/lib/asan/asan_win.cpp
+@@ -154,6 +154,14 @@ INTERCEPTOR_WINAPI(HANDLE, CreateThread, LPSECURITY_ATTRIBUTES security,
+ thr_flags, tid);
+ }
+
++INTERCEPTOR_WINAPI(void, NtTerminateThread, void *rcx) {
++ // Unpoison the terminating thread's stack because the memory may be re-used.
++ NT_TIB *tib = (NT_TIB *)NtCurrentTeb();
++ uptr stackSize = (uptr)tib->StackBase - (uptr)tib->StackLimit;
++ __asan_unpoison_memory_region(tib->StackLimit, stackSize);
++ return REAL(NtTerminateThread(rcx));
++}
++
+ // }}}
+
+ namespace __asan {
+@@ -168,7 +176,9 @@ void InitializePlatformInterceptors() {
+
+ ASAN_INTERCEPT_FUNC(CreateThread);
+ ASAN_INTERCEPT_FUNC(SetUnhandledExceptionFilter);
+-
++ CHECK(::__interception::OverrideFunction("NtTerminateThread",
++ (uptr)WRAP(NtTerminateThread),
++ (uptr *)&REAL(NtTerminateThread)));
+ #ifdef _WIN64
+ ASAN_INTERCEPT_FUNC(__C_specific_handler);
+ #else
+@@ -380,19 +390,6 @@ __declspec(allocate(".CRT$XLAB")) void(NTAPI *__asan_tls_init)(
+ void *, unsigned long, void *) = asan_thread_init;
+ #endif
+
+-static void NTAPI asan_thread_exit(void *module, DWORD reason, void *reserved) {
+- if (reason == DLL_THREAD_DETACH) {
+- // Unpoison the thread's stack because the memory may be re-used.
+- NT_TIB *tib = (NT_TIB *)NtCurrentTeb();
+- uptr stackSize = (uptr)tib->StackBase - (uptr)tib->StackLimit;
+- __asan_unpoison_memory_region(tib->StackLimit, stackSize);
+- }
+-}
+-
+-#pragma section(".CRT$XLY", long, read)
+-__declspec(allocate(".CRT$XLY")) void(NTAPI *__asan_tls_exit)(
+- void *, unsigned long, void *) = asan_thread_exit;
+-
+ WIN_FORCE_LINK(__asan_dso_reg_hook)
+
+ // }}}
diff --git a/build/build-clang/win64-ret-null-on-commitment-limit_clang_14.patch b/build/build-clang/win64-ret-null-on-commitment-limit_clang_14.patch
new file mode 100644
index 0000000000..23b001bc68
--- /dev/null
+++ b/build/build-clang/win64-ret-null-on-commitment-limit_clang_14.patch
@@ -0,0 +1,14 @@
+diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_win.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_win.cpp
+index 7c84cdc22ce4..e13fff03489e 100644
+--- a/compiler-rt/lib/sanitizer_common/sanitizer_win.cpp
++++ b/compiler-rt/lib/sanitizer_common/sanitizer_win.cpp
+@@ -157,7 +157,8 @@ void UnmapOrDie(void *addr, uptr size) {
+ static void *ReturnNullptrOnOOMOrDie(uptr size, const char *mem_type,
+ const char *mmap_type) {
+ error_t last_error = GetLastError();
+- if (last_error == ERROR_NOT_ENOUGH_MEMORY)
++ if (last_error == ERROR_NOT_ENOUGH_MEMORY ||
++ last_error == ERROR_COMMITMENT_LIMIT)
+ return nullptr;
+ ReportMmapFailureAndDie(size, mem_type, mmap_type, last_error);
+ }
diff --git a/build/build-clang/win64.json b/build/build-clang/win64.json
new file mode 100644
index 0000000000..9d4dcc589e
--- /dev/null
+++ b/build/build-clang/win64.json
@@ -0,0 +1,7 @@
+{
+ "target": "x86_64-pc-windows-msvc",
+ "cc": "{MOZ_FETCHES_DIR}/clang/bin/clang-cl",
+ "cxx": "{MOZ_FETCHES_DIR}/clang/bin/clang-cl",
+ "ml": "{MOZ_FETCHES_DIR}/clang/bin/clang-cl",
+ "lib": "{MOZ_FETCHES_DIR}/clang/bin/llvm-lib"
+}