xref: /freebsd-src/contrib/llvm-project/clang/lib/Driver/ToolChains/Linux.cpp (revision d686ce931cab72612a9e1ada9fe99d65e11a32a3)
10b57cec5SDimitry Andric //===--- Linux.h - Linux ToolChain Implementations --------------*- C++ -*-===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric 
90b57cec5SDimitry Andric #include "Linux.h"
100b57cec5SDimitry Andric #include "Arch/ARM.h"
11bdd1243dSDimitry Andric #include "Arch/LoongArch.h"
120b57cec5SDimitry Andric #include "Arch/Mips.h"
130b57cec5SDimitry Andric #include "Arch/PPC.h"
140b57cec5SDimitry Andric #include "Arch/RISCV.h"
150b57cec5SDimitry Andric #include "CommonArgs.h"
160b57cec5SDimitry Andric #include "clang/Config/config.h"
170b57cec5SDimitry Andric #include "clang/Driver/Distro.h"
180b57cec5SDimitry Andric #include "clang/Driver/Driver.h"
190b57cec5SDimitry Andric #include "clang/Driver/Options.h"
200b57cec5SDimitry Andric #include "clang/Driver/SanitizerArgs.h"
210b57cec5SDimitry Andric #include "llvm/Option/ArgList.h"
220b57cec5SDimitry Andric #include "llvm/ProfileData/InstrProf.h"
230b57cec5SDimitry Andric #include "llvm/Support/Path.h"
240b57cec5SDimitry Andric #include "llvm/Support/ScopedPrinter.h"
250b57cec5SDimitry Andric #include "llvm/Support/VirtualFileSystem.h"
260b57cec5SDimitry Andric #include <system_error>
270b57cec5SDimitry Andric 
280b57cec5SDimitry Andric using namespace clang::driver;
290b57cec5SDimitry Andric using namespace clang::driver::toolchains;
300b57cec5SDimitry Andric using namespace clang;
310b57cec5SDimitry Andric using namespace llvm::opt;
320b57cec5SDimitry Andric 
330b57cec5SDimitry Andric using tools::addPathIfExists;
340b57cec5SDimitry Andric 
350b57cec5SDimitry Andric /// Get our best guess at the multiarch triple for a target.
360b57cec5SDimitry Andric ///
370b57cec5SDimitry Andric /// Debian-based systems are starting to use a multiarch setup where they use
380b57cec5SDimitry Andric /// a target-triple directory in the library and header search paths.
390b57cec5SDimitry Andric /// Unfortunately, this triple does not align with the vanilla target triple,
400b57cec5SDimitry Andric /// so we provide a rough mapping here.
41480093f4SDimitry Andric std::string Linux::getMultiarchTriple(const Driver &D,
420b57cec5SDimitry Andric                                       const llvm::Triple &TargetTriple,
43480093f4SDimitry Andric                                       StringRef SysRoot) const {
440b57cec5SDimitry Andric   llvm::Triple::EnvironmentType TargetEnvironment =
450b57cec5SDimitry Andric       TargetTriple.getEnvironment();
460b57cec5SDimitry Andric   bool IsAndroid = TargetTriple.isAndroid();
470b57cec5SDimitry Andric   bool IsMipsR6 = TargetTriple.getSubArch() == llvm::Triple::MipsSubArch_r6;
480b57cec5SDimitry Andric   bool IsMipsN32Abi = TargetTriple.getEnvironment() == llvm::Triple::GNUABIN32;
490b57cec5SDimitry Andric 
500b57cec5SDimitry Andric   // For most architectures, just use whatever we have rather than trying to be
510b57cec5SDimitry Andric   // clever.
520b57cec5SDimitry Andric   switch (TargetTriple.getArch()) {
530b57cec5SDimitry Andric   default:
540b57cec5SDimitry Andric     break;
550b57cec5SDimitry Andric 
560b57cec5SDimitry Andric   // We use the existence of '/lib/<triple>' as a directory to detect some
570b57cec5SDimitry Andric   // common linux triples that don't quite match the Clang triple for both
580b57cec5SDimitry Andric   // 32-bit and 64-bit targets. Multiarch fixes its install triples to these
590b57cec5SDimitry Andric   // regardless of what the actual target triple is.
600b57cec5SDimitry Andric   case llvm::Triple::arm:
610b57cec5SDimitry Andric   case llvm::Triple::thumb:
62fe6060f1SDimitry Andric     if (IsAndroid)
630b57cec5SDimitry Andric       return "arm-linux-androideabi";
64297eecfbSDimitry Andric     if (TargetEnvironment == llvm::Triple::GNUEABIHF ||
65297eecfbSDimitry Andric         TargetEnvironment == llvm::Triple::MuslEABIHF ||
66297eecfbSDimitry Andric         TargetEnvironment == llvm::Triple::EABIHF)
670b57cec5SDimitry Andric       return "arm-linux-gnueabihf";
680b57cec5SDimitry Andric     return "arm-linux-gnueabi";
690b57cec5SDimitry Andric   case llvm::Triple::armeb:
700b57cec5SDimitry Andric   case llvm::Triple::thumbeb:
71297eecfbSDimitry Andric     if (TargetEnvironment == llvm::Triple::GNUEABIHF ||
72297eecfbSDimitry Andric         TargetEnvironment == llvm::Triple::MuslEABIHF ||
73297eecfbSDimitry Andric         TargetEnvironment == llvm::Triple::EABIHF)
740b57cec5SDimitry Andric       return "armeb-linux-gnueabihf";
750b57cec5SDimitry Andric     return "armeb-linux-gnueabi";
760b57cec5SDimitry Andric   case llvm::Triple::x86:
770b57cec5SDimitry Andric     if (IsAndroid)
780b57cec5SDimitry Andric       return "i686-linux-android";
790b57cec5SDimitry Andric     return "i386-linux-gnu";
800b57cec5SDimitry Andric   case llvm::Triple::x86_64:
810b57cec5SDimitry Andric     if (IsAndroid)
820b57cec5SDimitry Andric       return "x86_64-linux-android";
83fe6060f1SDimitry Andric     if (TargetEnvironment == llvm::Triple::GNUX32)
84fe6060f1SDimitry Andric       return "x86_64-linux-gnux32";
850b57cec5SDimitry Andric     return "x86_64-linux-gnu";
860b57cec5SDimitry Andric   case llvm::Triple::aarch64:
870b57cec5SDimitry Andric     if (IsAndroid)
880b57cec5SDimitry Andric       return "aarch64-linux-android";
890fca6ea1SDimitry Andric     if (hasEffectiveTriple() &&
900fca6ea1SDimitry Andric         getEffectiveTriple().getEnvironment() == llvm::Triple::PAuthTest)
910fca6ea1SDimitry Andric       return "aarch64-linux-pauthtest";
920b57cec5SDimitry Andric     return "aarch64-linux-gnu";
930b57cec5SDimitry Andric   case llvm::Triple::aarch64_be:
940b57cec5SDimitry Andric     return "aarch64_be-linux-gnu";
95fe6060f1SDimitry Andric 
9606c3fb27SDimitry Andric   case llvm::Triple::loongarch64: {
9706c3fb27SDimitry Andric     const char *Libc;
9806c3fb27SDimitry Andric     const char *FPFlavor;
9906c3fb27SDimitry Andric 
10006c3fb27SDimitry Andric     if (TargetTriple.isGNUEnvironment()) {
10106c3fb27SDimitry Andric       Libc = "gnu";
10206c3fb27SDimitry Andric     } else if (TargetTriple.isMusl()) {
10306c3fb27SDimitry Andric       Libc = "musl";
10406c3fb27SDimitry Andric     } else {
10506c3fb27SDimitry Andric       return TargetTriple.str();
10606c3fb27SDimitry Andric     }
10706c3fb27SDimitry Andric 
10806c3fb27SDimitry Andric     switch (TargetEnvironment) {
10906c3fb27SDimitry Andric     default:
11006c3fb27SDimitry Andric       return TargetTriple.str();
11106c3fb27SDimitry Andric     case llvm::Triple::GNUSF:
11206c3fb27SDimitry Andric       FPFlavor = "sf";
11306c3fb27SDimitry Andric       break;
11406c3fb27SDimitry Andric     case llvm::Triple::GNUF32:
11506c3fb27SDimitry Andric       FPFlavor = "f32";
11606c3fb27SDimitry Andric       break;
11706c3fb27SDimitry Andric     case llvm::Triple::GNU:
11806c3fb27SDimitry Andric     case llvm::Triple::GNUF64:
11906c3fb27SDimitry Andric       // This was going to be "f64" in an earlier Toolchain Conventions
12006c3fb27SDimitry Andric       // revision, but starting from Feb 2023 the F64 ABI variants are
12106c3fb27SDimitry Andric       // unmarked in their canonical forms.
12206c3fb27SDimitry Andric       FPFlavor = "";
12306c3fb27SDimitry Andric       break;
12406c3fb27SDimitry Andric     }
12506c3fb27SDimitry Andric 
12606c3fb27SDimitry Andric     return (Twine("loongarch64-linux-") + Libc + FPFlavor).str();
12706c3fb27SDimitry Andric   }
12806c3fb27SDimitry Andric 
129fe6060f1SDimitry Andric   case llvm::Triple::m68k:
130fe6060f1SDimitry Andric     return "m68k-linux-gnu";
131fe6060f1SDimitry Andric 
132fe6060f1SDimitry Andric   case llvm::Triple::mips:
133fe6060f1SDimitry Andric     return IsMipsR6 ? "mipsisa32r6-linux-gnu" : "mips-linux-gnu";
134fe6060f1SDimitry Andric   case llvm::Triple::mipsel:
135fe6060f1SDimitry Andric     return IsMipsR6 ? "mipsisa32r6el-linux-gnu" : "mipsel-linux-gnu";
1360b57cec5SDimitry Andric   case llvm::Triple::mips64: {
1370b57cec5SDimitry Andric     std::string MT = std::string(IsMipsR6 ? "mipsisa64r6" : "mips64") +
1380b57cec5SDimitry Andric                      "-linux-" + (IsMipsN32Abi ? "gnuabin32" : "gnuabi64");
13981ad6265SDimitry Andric     if (D.getVFS().exists(concat(SysRoot, "/lib", MT)))
1400b57cec5SDimitry Andric       return MT;
14181ad6265SDimitry Andric     if (D.getVFS().exists(concat(SysRoot, "/lib/mips64-linux-gnu")))
1420b57cec5SDimitry Andric       return "mips64-linux-gnu";
1430b57cec5SDimitry Andric     break;
1440b57cec5SDimitry Andric   }
1450b57cec5SDimitry Andric   case llvm::Triple::mips64el: {
1460b57cec5SDimitry Andric     std::string MT = std::string(IsMipsR6 ? "mipsisa64r6el" : "mips64el") +
1470b57cec5SDimitry Andric                      "-linux-" + (IsMipsN32Abi ? "gnuabin32" : "gnuabi64");
14881ad6265SDimitry Andric     if (D.getVFS().exists(concat(SysRoot, "/lib", MT)))
1490b57cec5SDimitry Andric       return MT;
15081ad6265SDimitry Andric     if (D.getVFS().exists(concat(SysRoot, "/lib/mips64el-linux-gnu")))
1510b57cec5SDimitry Andric       return "mips64el-linux-gnu";
1520b57cec5SDimitry Andric     break;
1530b57cec5SDimitry Andric   }
1540b57cec5SDimitry Andric   case llvm::Triple::ppc:
15581ad6265SDimitry Andric     if (D.getVFS().exists(concat(SysRoot, "/lib/powerpc-linux-gnuspe")))
1560b57cec5SDimitry Andric       return "powerpc-linux-gnuspe";
1570b57cec5SDimitry Andric     return "powerpc-linux-gnu";
158e8d8bef9SDimitry Andric   case llvm::Triple::ppcle:
159e8d8bef9SDimitry Andric     return "powerpcle-linux-gnu";
1600b57cec5SDimitry Andric   case llvm::Triple::ppc64:
1610b57cec5SDimitry Andric     return "powerpc64-linux-gnu";
1620b57cec5SDimitry Andric   case llvm::Triple::ppc64le:
1630b57cec5SDimitry Andric     return "powerpc64le-linux-gnu";
16481ad6265SDimitry Andric   case llvm::Triple::riscv64:
16506c3fb27SDimitry Andric     if (IsAndroid)
16606c3fb27SDimitry Andric       return "riscv64-linux-android";
16781ad6265SDimitry Andric     return "riscv64-linux-gnu";
1680b57cec5SDimitry Andric   case llvm::Triple::sparc:
1690b57cec5SDimitry Andric     return "sparc-linux-gnu";
1700b57cec5SDimitry Andric   case llvm::Triple::sparcv9:
1710b57cec5SDimitry Andric     return "sparc64-linux-gnu";
1720b57cec5SDimitry Andric   case llvm::Triple::systemz:
1730b57cec5SDimitry Andric     return "s390x-linux-gnu";
1740b57cec5SDimitry Andric   }
1750b57cec5SDimitry Andric   return TargetTriple.str();
1760b57cec5SDimitry Andric }
1770b57cec5SDimitry Andric 
1780b57cec5SDimitry Andric static StringRef getOSLibDir(const llvm::Triple &Triple, const ArgList &Args) {
1790b57cec5SDimitry Andric   if (Triple.isMIPS()) {
1800b57cec5SDimitry Andric     if (Triple.isAndroid()) {
1810b57cec5SDimitry Andric       StringRef CPUName;
1820b57cec5SDimitry Andric       StringRef ABIName;
1830b57cec5SDimitry Andric       tools::mips::getMipsCPUAndABI(Args, Triple, CPUName, ABIName);
1840b57cec5SDimitry Andric       if (CPUName == "mips32r6")
1850b57cec5SDimitry Andric         return "libr6";
1860b57cec5SDimitry Andric       if (CPUName == "mips32r2")
1870b57cec5SDimitry Andric         return "libr2";
1880b57cec5SDimitry Andric     }
1890b57cec5SDimitry Andric     // lib32 directory has a special meaning on MIPS targets.
1900b57cec5SDimitry Andric     // It contains N32 ABI binaries. Use this folder if produce
1910b57cec5SDimitry Andric     // code for N32 ABI only.
1920b57cec5SDimitry Andric     if (tools::mips::hasMipsAbiArg(Args, "n32"))
1930b57cec5SDimitry Andric       return "lib32";
1940b57cec5SDimitry Andric     return Triple.isArch32Bit() ? "lib" : "lib64";
1950b57cec5SDimitry Andric   }
1960b57cec5SDimitry Andric 
197e8d8bef9SDimitry Andric   // It happens that only x86, PPC and SPARC use the 'lib32' variant of
198e8d8bef9SDimitry Andric   // oslibdir, and using that variant while targeting other architectures causes
199e8d8bef9SDimitry Andric   // problems because the libraries are laid out in shared system roots that
200e8d8bef9SDimitry Andric   // can't cope with a 'lib32' library search path being considered. So we only
201e8d8bef9SDimitry Andric   // enable them when we know we may need it.
2020b57cec5SDimitry Andric   //
2030b57cec5SDimitry Andric   // FIXME: This is a bit of a hack. We should really unify this code for
2040b57cec5SDimitry Andric   // reasoning about oslibdir spellings with the lib dir spellings in the
2050b57cec5SDimitry Andric   // GCCInstallationDetector, but that is a more significant refactoring.
206e8d8bef9SDimitry Andric   if (Triple.getArch() == llvm::Triple::x86 || Triple.isPPC32() ||
207e8d8bef9SDimitry Andric       Triple.getArch() == llvm::Triple::sparc)
2080b57cec5SDimitry Andric     return "lib32";
2090b57cec5SDimitry Andric 
210fe6060f1SDimitry Andric   if (Triple.getArch() == llvm::Triple::x86_64 && Triple.isX32())
2110b57cec5SDimitry Andric     return "libx32";
2120b57cec5SDimitry Andric 
2130b57cec5SDimitry Andric   if (Triple.getArch() == llvm::Triple::riscv32)
2140b57cec5SDimitry Andric     return "lib32";
2150b57cec5SDimitry Andric 
2160b57cec5SDimitry Andric   return Triple.isArch32Bit() ? "lib" : "lib64";
2170b57cec5SDimitry Andric }
2180b57cec5SDimitry Andric 
2190b57cec5SDimitry Andric Linux::Linux(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)
2200b57cec5SDimitry Andric     : Generic_ELF(D, Triple, Args) {
2210b57cec5SDimitry Andric   GCCInstallation.init(Triple, Args);
2220b57cec5SDimitry Andric   Multilibs = GCCInstallation.getMultilibs();
22306c3fb27SDimitry Andric   SelectedMultilibs.assign({GCCInstallation.getMultilib()});
2240b57cec5SDimitry Andric   llvm::Triple::ArchType Arch = Triple.getArch();
2250b57cec5SDimitry Andric   std::string SysRoot = computeSysRoot();
2260b57cec5SDimitry Andric   ToolChain::path_list &PPaths = getProgramPaths();
2275ffd83dbSDimitry Andric 
2285ffd83dbSDimitry Andric   Generic_GCC::PushPPaths(PPaths);
2290b57cec5SDimitry Andric 
230480093f4SDimitry Andric   Distro Distro(D.getVFS(), Triple);
2310b57cec5SDimitry Andric 
2320b57cec5SDimitry Andric   if (Distro.IsAlpineLinux() || Triple.isAndroid()) {
2330b57cec5SDimitry Andric     ExtraOpts.push_back("-z");
2340b57cec5SDimitry Andric     ExtraOpts.push_back("now");
2350b57cec5SDimitry Andric   }
2360b57cec5SDimitry Andric 
2370b57cec5SDimitry Andric   if (Distro.IsOpenSUSE() || Distro.IsUbuntu() || Distro.IsAlpineLinux() ||
2380b57cec5SDimitry Andric       Triple.isAndroid()) {
2390b57cec5SDimitry Andric     ExtraOpts.push_back("-z");
2400b57cec5SDimitry Andric     ExtraOpts.push_back("relro");
2410b57cec5SDimitry Andric   }
2420b57cec5SDimitry Andric 
2430fca6ea1SDimitry Andric   // Note, lld from 11 onwards default max-page-size to 65536 for both ARM and
2440fca6ea1SDimitry Andric   // AArch64.
2450fca6ea1SDimitry Andric   if (Triple.isAndroid()) {
2460fca6ea1SDimitry Andric     if (Triple.isARM()) {
2470fca6ea1SDimitry Andric       // Android ARM uses max-page-size=4096 to reduce VMA usage.
2480b57cec5SDimitry Andric       ExtraOpts.push_back("-z");
2490b57cec5SDimitry Andric       ExtraOpts.push_back("max-page-size=4096");
2500fca6ea1SDimitry Andric     } else if (Triple.isAArch64() || Triple.getArch() == llvm::Triple::x86_64) {
2510fca6ea1SDimitry Andric       // Android AArch64 uses max-page-size=16384 to support 4k/16k page sizes.
2520fca6ea1SDimitry Andric       // Android emulates a 16k page size for app testing on x86_64 machines.
2530fca6ea1SDimitry Andric       ExtraOpts.push_back("-z");
2540fca6ea1SDimitry Andric       ExtraOpts.push_back("max-page-size=16384");
2550fca6ea1SDimitry Andric     }
2560b57cec5SDimitry Andric   }
2570b57cec5SDimitry Andric 
258349cc55cSDimitry Andric   if (GCCInstallation.getParentLibPath().contains("opt/rh/"))
2590b57cec5SDimitry Andric     // With devtoolset on RHEL, we want to add a bin directory that is relative
2600b57cec5SDimitry Andric     // to the detected gcc install, because if we are using devtoolset gcc then
2610b57cec5SDimitry Andric     // we want to use other tools from devtoolset (e.g. ld) instead of the
2620b57cec5SDimitry Andric     // standard system tools.
2630b57cec5SDimitry Andric     PPaths.push_back(Twine(GCCInstallation.getParentLibPath() +
2640b57cec5SDimitry Andric                      "/../bin").str());
2650b57cec5SDimitry Andric 
2660b57cec5SDimitry Andric   if (Arch == llvm::Triple::arm || Arch == llvm::Triple::thumb)
2670b57cec5SDimitry Andric     ExtraOpts.push_back("-X");
2680b57cec5SDimitry Andric 
2690b57cec5SDimitry Andric   const bool IsAndroid = Triple.isAndroid();
2700b57cec5SDimitry Andric   const bool IsMips = Triple.isMIPS();
2710b57cec5SDimitry Andric   const bool IsHexagon = Arch == llvm::Triple::hexagon;
2720b57cec5SDimitry Andric   const bool IsRISCV = Triple.isRISCV();
27381ad6265SDimitry Andric   const bool IsCSKY = Triple.isCSKY();
2740b57cec5SDimitry Andric 
27506c3fb27SDimitry Andric   if (IsCSKY && !SelectedMultilibs.empty())
27606c3fb27SDimitry Andric     SysRoot = SysRoot + SelectedMultilibs.back().osSuffix();
27781ad6265SDimitry Andric 
27881ad6265SDimitry Andric   if ((IsMips || IsCSKY) && !SysRoot.empty())
2790b57cec5SDimitry Andric     ExtraOpts.push_back("--sysroot=" + SysRoot);
2800b57cec5SDimitry Andric 
2810b57cec5SDimitry Andric   // Do not use 'gnu' hash style for Mips targets because .gnu.hash
2820b57cec5SDimitry Andric   // and the MIPS ABI require .dynsym to be sorted in different ways.
2830b57cec5SDimitry Andric   // .gnu.hash needs symbols to be grouped by hash code whereas the MIPS
2840b57cec5SDimitry Andric   // ABI requires a mapping between the GOT and the symbol table.
2850b57cec5SDimitry Andric   // Android loader does not support .gnu.hash until API 23.
2860b57cec5SDimitry Andric   // Hexagon linker/loader does not support .gnu.hash
2870b57cec5SDimitry Andric   if (!IsMips && !IsHexagon) {
288bdd1243dSDimitry Andric     if (Distro.IsOpenSUSE() || Distro == Distro::UbuntuLucid ||
289bdd1243dSDimitry Andric         Distro == Distro::UbuntuJaunty || Distro == Distro::UbuntuKarmic ||
2900b57cec5SDimitry Andric         (IsAndroid && Triple.isAndroidVersionLT(23)))
2910b57cec5SDimitry Andric       ExtraOpts.push_back("--hash-style=both");
292bdd1243dSDimitry Andric     else
293bdd1243dSDimitry Andric       ExtraOpts.push_back("--hash-style=gnu");
2940b57cec5SDimitry Andric   }
2950b57cec5SDimitry Andric 
2960b57cec5SDimitry Andric #ifdef ENABLE_LINKER_BUILD_ID
2970b57cec5SDimitry Andric   ExtraOpts.push_back("--build-id");
2980b57cec5SDimitry Andric #endif
2990b57cec5SDimitry Andric 
3000b57cec5SDimitry Andric   // The selection of paths to try here is designed to match the patterns which
3010b57cec5SDimitry Andric   // the GCC driver itself uses, as this is part of the GCC-compatible driver.
3020b57cec5SDimitry Andric   // This was determined by running GCC in a fake filesystem, creating all
3030b57cec5SDimitry Andric   // possible permutations of these directories, and seeing which ones it added
3040b57cec5SDimitry Andric   // to the link paths.
3050b57cec5SDimitry Andric   path_list &Paths = getFilePaths();
3060b57cec5SDimitry Andric 
3075ffd83dbSDimitry Andric   const std::string OSLibDir = std::string(getOSLibDir(Triple, Args));
3080b57cec5SDimitry Andric   const std::string MultiarchTriple = getMultiarchTriple(D, Triple, SysRoot);
3090b57cec5SDimitry Andric 
310349cc55cSDimitry Andric   // mips32: Debian multilib, we use /libo32, while in other case, /lib is
311349cc55cSDimitry Andric   // used. We need add both libo32 and /lib.
312349cc55cSDimitry Andric   if (Arch == llvm::Triple::mips || Arch == llvm::Triple::mipsel) {
313349cc55cSDimitry Andric     Generic_GCC::AddMultilibPaths(D, SysRoot, "libo32", MultiarchTriple, Paths);
31481ad6265SDimitry Andric     addPathIfExists(D, concat(SysRoot, "/libo32"), Paths);
31581ad6265SDimitry Andric     addPathIfExists(D, concat(SysRoot, "/usr/libo32"), Paths);
316349cc55cSDimitry Andric   }
3175ffd83dbSDimitry Andric   Generic_GCC::AddMultilibPaths(D, SysRoot, OSLibDir, MultiarchTriple, Paths);
3180b57cec5SDimitry Andric 
31981ad6265SDimitry Andric   addPathIfExists(D, concat(SysRoot, "/lib", MultiarchTriple), Paths);
32081ad6265SDimitry Andric   addPathIfExists(D, concat(SysRoot, "/lib/..", OSLibDir), Paths);
3210b57cec5SDimitry Andric 
3220b57cec5SDimitry Andric   if (IsAndroid) {
3230b57cec5SDimitry Andric     // Android sysroots contain a library directory for each supported OS
3240b57cec5SDimitry Andric     // version as well as some unversioned libraries in the usual multiarch
3250b57cec5SDimitry Andric     // directory.
3260eae32dcSDimitry Andric     addPathIfExists(
3270eae32dcSDimitry Andric         D,
32881ad6265SDimitry Andric         concat(SysRoot, "/usr/lib", MultiarchTriple,
32981ad6265SDimitry Andric                llvm::to_string(Triple.getEnvironmentVersion().getMajor())),
3300b57cec5SDimitry Andric         Paths);
3310b57cec5SDimitry Andric   }
3320b57cec5SDimitry Andric 
33381ad6265SDimitry Andric   addPathIfExists(D, concat(SysRoot, "/usr/lib", MultiarchTriple), Paths);
3340b57cec5SDimitry Andric   // 64-bit OpenEmbedded sysroots may not have a /usr/lib dir. So they cannot
3350b57cec5SDimitry Andric   // find /usr/lib64 as it is referenced as /usr/lib/../lib64. So we handle
3360b57cec5SDimitry Andric   // this here.
3370b57cec5SDimitry Andric   if (Triple.getVendor() == llvm::Triple::OpenEmbedded &&
3380b57cec5SDimitry Andric       Triple.isArch64Bit())
33981ad6265SDimitry Andric     addPathIfExists(D, concat(SysRoot, "/usr", OSLibDir), Paths);
3400b57cec5SDimitry Andric   else
34181ad6265SDimitry Andric     addPathIfExists(D, concat(SysRoot, "/usr/lib/..", OSLibDir), Paths);
3420b57cec5SDimitry Andric   if (IsRISCV) {
3430b57cec5SDimitry Andric     StringRef ABIName = tools::riscv::getRISCVABI(Args, Triple);
34481ad6265SDimitry Andric     addPathIfExists(D, concat(SysRoot, "/", OSLibDir, ABIName), Paths);
34581ad6265SDimitry Andric     addPathIfExists(D, concat(SysRoot, "/usr", OSLibDir, ABIName), Paths);
3460b57cec5SDimitry Andric   }
3470b57cec5SDimitry Andric 
3485ffd83dbSDimitry Andric   Generic_GCC::AddMultiarchPaths(D, SysRoot, OSLibDir, Paths);
3490b57cec5SDimitry Andric 
35081ad6265SDimitry Andric   addPathIfExists(D, concat(SysRoot, "/lib"), Paths);
35181ad6265SDimitry Andric   addPathIfExists(D, concat(SysRoot, "/usr/lib"), Paths);
3520b57cec5SDimitry Andric }
3530b57cec5SDimitry Andric 
354fe6060f1SDimitry Andric ToolChain::RuntimeLibType Linux::GetDefaultRuntimeLibType() const {
355fe6060f1SDimitry Andric   if (getTriple().isAndroid())
356fe6060f1SDimitry Andric     return ToolChain::RLT_CompilerRT;
357fe6060f1SDimitry Andric   return Generic_ELF::GetDefaultRuntimeLibType();
358fe6060f1SDimitry Andric }
359fe6060f1SDimitry Andric 
36004eeddc0SDimitry Andric unsigned Linux::GetDefaultDwarfVersion() const {
36104eeddc0SDimitry Andric   if (getTriple().isAndroid())
36204eeddc0SDimitry Andric     return 4;
36304eeddc0SDimitry Andric   return ToolChain::GetDefaultDwarfVersion();
36404eeddc0SDimitry Andric }
36504eeddc0SDimitry Andric 
3660b57cec5SDimitry Andric ToolChain::CXXStdlibType Linux::GetDefaultCXXStdlibType() const {
3670b57cec5SDimitry Andric   if (getTriple().isAndroid())
3680b57cec5SDimitry Andric     return ToolChain::CST_Libcxx;
3690b57cec5SDimitry Andric   return ToolChain::CST_Libstdcxx;
3700b57cec5SDimitry Andric }
3710b57cec5SDimitry Andric 
3720b57cec5SDimitry Andric bool Linux::HasNativeLLVMSupport() const { return true; }
3730b57cec5SDimitry Andric 
3740b57cec5SDimitry Andric Tool *Linux::buildLinker() const { return new tools::gnutools::Linker(*this); }
3750b57cec5SDimitry Andric 
3765ffd83dbSDimitry Andric Tool *Linux::buildStaticLibTool() const {
3775ffd83dbSDimitry Andric   return new tools::gnutools::StaticLibTool(*this);
3785ffd83dbSDimitry Andric }
3795ffd83dbSDimitry Andric 
3800b57cec5SDimitry Andric Tool *Linux::buildAssembler() const {
3810b57cec5SDimitry Andric   return new tools::gnutools::Assembler(*this);
3820b57cec5SDimitry Andric }
3830b57cec5SDimitry Andric 
3840b57cec5SDimitry Andric std::string Linux::computeSysRoot() const {
3850b57cec5SDimitry Andric   if (!getDriver().SysRoot.empty())
3860b57cec5SDimitry Andric     return getDriver().SysRoot;
3870b57cec5SDimitry Andric 
3880b57cec5SDimitry Andric   if (getTriple().isAndroid()) {
3890b57cec5SDimitry Andric     // Android toolchains typically include a sysroot at ../sysroot relative to
3900b57cec5SDimitry Andric     // the clang binary.
3910fca6ea1SDimitry Andric     const StringRef ClangDir = getDriver().Dir;
3920b57cec5SDimitry Andric     std::string AndroidSysRootPath = (ClangDir + "/../sysroot").str();
3930b57cec5SDimitry Andric     if (getVFS().exists(AndroidSysRootPath))
3940b57cec5SDimitry Andric       return AndroidSysRootPath;
3950b57cec5SDimitry Andric   }
3960b57cec5SDimitry Andric 
39781ad6265SDimitry Andric   if (getTriple().isCSKY()) {
39881ad6265SDimitry Andric     // CSKY toolchains use different names for sysroot folder.
39981ad6265SDimitry Andric     if (!GCCInstallation.isValid())
40081ad6265SDimitry Andric       return std::string();
40181ad6265SDimitry Andric     // GCCInstallation.getInstallPath() =
40281ad6265SDimitry Andric     //   $GCCToolchainPath/lib/gcc/csky-linux-gnuabiv2/6.3.0
40381ad6265SDimitry Andric     // Path = $GCCToolchainPath/csky-linux-gnuabiv2/libc
40481ad6265SDimitry Andric     std::string Path = (GCCInstallation.getInstallPath() + "/../../../../" +
40581ad6265SDimitry Andric                         GCCInstallation.getTriple().str() + "/libc")
40681ad6265SDimitry Andric                            .str();
40781ad6265SDimitry Andric     if (getVFS().exists(Path))
40881ad6265SDimitry Andric       return Path;
40981ad6265SDimitry Andric     return std::string();
41081ad6265SDimitry Andric   }
41181ad6265SDimitry Andric 
4120b57cec5SDimitry Andric   if (!GCCInstallation.isValid() || !getTriple().isMIPS())
4130b57cec5SDimitry Andric     return std::string();
4140b57cec5SDimitry Andric 
4150b57cec5SDimitry Andric   // Standalone MIPS toolchains use different names for sysroot folder
4160b57cec5SDimitry Andric   // and put it into different places. Here we try to check some known
4170b57cec5SDimitry Andric   // variants.
4180b57cec5SDimitry Andric 
4190b57cec5SDimitry Andric   const StringRef InstallDir = GCCInstallation.getInstallPath();
4200b57cec5SDimitry Andric   const StringRef TripleStr = GCCInstallation.getTriple().str();
4210b57cec5SDimitry Andric   const Multilib &Multilib = GCCInstallation.getMultilib();
4220b57cec5SDimitry Andric 
4230b57cec5SDimitry Andric   std::string Path =
4240b57cec5SDimitry Andric       (InstallDir + "/../../../../" + TripleStr + "/libc" + Multilib.osSuffix())
4250b57cec5SDimitry Andric           .str();
4260b57cec5SDimitry Andric 
4270b57cec5SDimitry Andric   if (getVFS().exists(Path))
4280b57cec5SDimitry Andric     return Path;
4290b57cec5SDimitry Andric 
4300b57cec5SDimitry Andric   Path = (InstallDir + "/../../../../sysroot" + Multilib.osSuffix()).str();
4310b57cec5SDimitry Andric 
4320b57cec5SDimitry Andric   if (getVFS().exists(Path))
4330b57cec5SDimitry Andric     return Path;
4340b57cec5SDimitry Andric 
4350b57cec5SDimitry Andric   return std::string();
4360b57cec5SDimitry Andric }
4370b57cec5SDimitry Andric 
4380b57cec5SDimitry Andric std::string Linux::getDynamicLinker(const ArgList &Args) const {
4390b57cec5SDimitry Andric   const llvm::Triple::ArchType Arch = getArch();
4400b57cec5SDimitry Andric   const llvm::Triple &Triple = getTriple();
4410b57cec5SDimitry Andric 
442480093f4SDimitry Andric   const Distro Distro(getDriver().getVFS(), Triple);
4430b57cec5SDimitry Andric 
44406c3fb27SDimitry Andric   if (Triple.isAndroid()) {
44506c3fb27SDimitry Andric     if (getSanitizerArgs(Args).needsHwasanRt() &&
44606c3fb27SDimitry Andric         !Triple.isAndroidVersionLT(34) && Triple.isArch64Bit()) {
44706c3fb27SDimitry Andric       // On Android 14 and newer, there is a special linker_hwasan64 that
44806c3fb27SDimitry Andric       // allows to run HWASan binaries on non-HWASan system images. This
44906c3fb27SDimitry Andric       // is also available on HWASan system images, so we can just always
45006c3fb27SDimitry Andric       // use that instead.
45106c3fb27SDimitry Andric       return "/system/bin/linker_hwasan64";
45206c3fb27SDimitry Andric     }
4530b57cec5SDimitry Andric     return Triple.isArch64Bit() ? "/system/bin/linker64" : "/system/bin/linker";
45406c3fb27SDimitry Andric   }
4550b57cec5SDimitry Andric   if (Triple.isMusl()) {
4560b57cec5SDimitry Andric     std::string ArchName;
4570b57cec5SDimitry Andric     bool IsArm = false;
4580b57cec5SDimitry Andric 
4590b57cec5SDimitry Andric     switch (Arch) {
4600b57cec5SDimitry Andric     case llvm::Triple::arm:
4610b57cec5SDimitry Andric     case llvm::Triple::thumb:
4620b57cec5SDimitry Andric       ArchName = "arm";
4630b57cec5SDimitry Andric       IsArm = true;
4640b57cec5SDimitry Andric       break;
4650b57cec5SDimitry Andric     case llvm::Triple::armeb:
4660b57cec5SDimitry Andric     case llvm::Triple::thumbeb:
4670b57cec5SDimitry Andric       ArchName = "armeb";
4680b57cec5SDimitry Andric       IsArm = true;
4690b57cec5SDimitry Andric       break;
470fe6060f1SDimitry Andric     case llvm::Triple::x86:
471fe6060f1SDimitry Andric       ArchName = "i386";
472fe6060f1SDimitry Andric       break;
473fe6060f1SDimitry Andric     case llvm::Triple::x86_64:
474fe6060f1SDimitry Andric       ArchName = Triple.isX32() ? "x32" : Triple.getArchName().str();
475fe6060f1SDimitry Andric       break;
4760b57cec5SDimitry Andric     default:
4770b57cec5SDimitry Andric       ArchName = Triple.getArchName().str();
4780b57cec5SDimitry Andric     }
4790b57cec5SDimitry Andric     if (IsArm &&
4800b57cec5SDimitry Andric         (Triple.getEnvironment() == llvm::Triple::MuslEABIHF ||
4810b57cec5SDimitry Andric          tools::arm::getARMFloatABI(*this, Args) == tools::arm::FloatABI::Hard))
4820b57cec5SDimitry Andric       ArchName += "hf";
4834824e7fdSDimitry Andric     if (Arch == llvm::Triple::ppc &&
4844824e7fdSDimitry Andric         Triple.getSubArch() == llvm::Triple::PPCSubArch_spe)
4854824e7fdSDimitry Andric       ArchName = "powerpc-sf";
4860b57cec5SDimitry Andric 
4870b57cec5SDimitry Andric     return "/lib/ld-musl-" + ArchName + ".so.1";
4880b57cec5SDimitry Andric   }
4890b57cec5SDimitry Andric 
4900b57cec5SDimitry Andric   std::string LibDir;
4910b57cec5SDimitry Andric   std::string Loader;
4920b57cec5SDimitry Andric 
4930b57cec5SDimitry Andric   switch (Arch) {
4940b57cec5SDimitry Andric   default:
4950b57cec5SDimitry Andric     llvm_unreachable("unsupported architecture");
4960b57cec5SDimitry Andric 
4970b57cec5SDimitry Andric   case llvm::Triple::aarch64:
4980b57cec5SDimitry Andric     LibDir = "lib";
4990b57cec5SDimitry Andric     Loader = "ld-linux-aarch64.so.1";
5000b57cec5SDimitry Andric     break;
5010b57cec5SDimitry Andric   case llvm::Triple::aarch64_be:
5020b57cec5SDimitry Andric     LibDir = "lib";
5030b57cec5SDimitry Andric     Loader = "ld-linux-aarch64_be.so.1";
5040b57cec5SDimitry Andric     break;
5050b57cec5SDimitry Andric   case llvm::Triple::arm:
5060b57cec5SDimitry Andric   case llvm::Triple::thumb:
5070b57cec5SDimitry Andric   case llvm::Triple::armeb:
5080b57cec5SDimitry Andric   case llvm::Triple::thumbeb: {
5090b57cec5SDimitry Andric     const bool HF =
5100b57cec5SDimitry Andric         Triple.getEnvironment() == llvm::Triple::GNUEABIHF ||
511*d686ce93SDimitry Andric         Triple.getEnvironment() == llvm::Triple::GNUEABIHFT64 ||
5120b57cec5SDimitry Andric         tools::arm::getARMFloatABI(*this, Args) == tools::arm::FloatABI::Hard;
5130b57cec5SDimitry Andric 
5140b57cec5SDimitry Andric     LibDir = "lib";
5150b57cec5SDimitry Andric     Loader = HF ? "ld-linux-armhf.so.3" : "ld-linux.so.3";
5160b57cec5SDimitry Andric     break;
5170b57cec5SDimitry Andric   }
518bdd1243dSDimitry Andric   case llvm::Triple::loongarch32: {
519bdd1243dSDimitry Andric     LibDir = "lib32";
520bdd1243dSDimitry Andric     Loader =
521bdd1243dSDimitry Andric         ("ld-linux-loongarch-" +
522bdd1243dSDimitry Andric          tools::loongarch::getLoongArchABI(getDriver(), Args, Triple) + ".so.1")
523bdd1243dSDimitry Andric             .str();
524bdd1243dSDimitry Andric     break;
525bdd1243dSDimitry Andric   }
526bdd1243dSDimitry Andric   case llvm::Triple::loongarch64: {
527bdd1243dSDimitry Andric     LibDir = "lib64";
528bdd1243dSDimitry Andric     Loader =
529bdd1243dSDimitry Andric         ("ld-linux-loongarch-" +
530bdd1243dSDimitry Andric          tools::loongarch::getLoongArchABI(getDriver(), Args, Triple) + ".so.1")
531bdd1243dSDimitry Andric             .str();
532bdd1243dSDimitry Andric     break;
533bdd1243dSDimitry Andric   }
534fe6060f1SDimitry Andric   case llvm::Triple::m68k:
535fe6060f1SDimitry Andric     LibDir = "lib";
536fe6060f1SDimitry Andric     Loader = "ld.so.1";
537fe6060f1SDimitry Andric     break;
5380b57cec5SDimitry Andric   case llvm::Triple::mips:
5390b57cec5SDimitry Andric   case llvm::Triple::mipsel:
5400b57cec5SDimitry Andric   case llvm::Triple::mips64:
5410b57cec5SDimitry Andric   case llvm::Triple::mips64el: {
542349cc55cSDimitry Andric     bool IsNaN2008 = tools::mips::isNaN2008(getDriver(), Args, Triple);
5430b57cec5SDimitry Andric 
5440b57cec5SDimitry Andric     LibDir = "lib" + tools::mips::getMipsABILibSuffix(Args, Triple);
5450b57cec5SDimitry Andric 
5460b57cec5SDimitry Andric     if (tools::mips::isUCLibc(Args))
5470b57cec5SDimitry Andric       Loader = IsNaN2008 ? "ld-uClibc-mipsn8.so.0" : "ld-uClibc.so.0";
5480b57cec5SDimitry Andric     else if (!Triple.hasEnvironment() &&
5490b57cec5SDimitry Andric              Triple.getVendor() == llvm::Triple::VendorType::MipsTechnologies)
5500b57cec5SDimitry Andric       Loader =
5510b57cec5SDimitry Andric           Triple.isLittleEndian() ? "ld-musl-mipsel.so.1" : "ld-musl-mips.so.1";
5520b57cec5SDimitry Andric     else
5530b57cec5SDimitry Andric       Loader = IsNaN2008 ? "ld-linux-mipsn8.so.1" : "ld.so.1";
5540b57cec5SDimitry Andric 
5550b57cec5SDimitry Andric     break;
5560b57cec5SDimitry Andric   }
5570b57cec5SDimitry Andric   case llvm::Triple::ppc:
5580b57cec5SDimitry Andric     LibDir = "lib";
5590b57cec5SDimitry Andric     Loader = "ld.so.1";
5600b57cec5SDimitry Andric     break;
561e8d8bef9SDimitry Andric   case llvm::Triple::ppcle:
562e8d8bef9SDimitry Andric     LibDir = "lib";
563e8d8bef9SDimitry Andric     Loader = "ld.so.1";
564e8d8bef9SDimitry Andric     break;
5650b57cec5SDimitry Andric   case llvm::Triple::ppc64:
5660b57cec5SDimitry Andric     LibDir = "lib64";
5670b57cec5SDimitry Andric     Loader =
5680b57cec5SDimitry Andric         (tools::ppc::hasPPCAbiArg(Args, "elfv2")) ? "ld64.so.2" : "ld64.so.1";
5690b57cec5SDimitry Andric     break;
5700b57cec5SDimitry Andric   case llvm::Triple::ppc64le:
5710b57cec5SDimitry Andric     LibDir = "lib64";
5720b57cec5SDimitry Andric     Loader =
5730b57cec5SDimitry Andric         (tools::ppc::hasPPCAbiArg(Args, "elfv1")) ? "ld64.so.1" : "ld64.so.2";
5740b57cec5SDimitry Andric     break;
5750fca6ea1SDimitry Andric   case llvm::Triple::riscv32:
5760b57cec5SDimitry Andric   case llvm::Triple::riscv64: {
5770fca6ea1SDimitry Andric     StringRef ArchName = llvm::Triple::getArchTypeName(Arch);
5780b57cec5SDimitry Andric     StringRef ABIName = tools::riscv::getRISCVABI(Args, Triple);
5790b57cec5SDimitry Andric     LibDir = "lib";
5800fca6ea1SDimitry Andric     Loader = ("ld-linux-" + ArchName + "-" + ABIName + ".so.1").str();
5810b57cec5SDimitry Andric     break;
5820b57cec5SDimitry Andric   }
5830b57cec5SDimitry Andric   case llvm::Triple::sparc:
5840b57cec5SDimitry Andric   case llvm::Triple::sparcel:
5850b57cec5SDimitry Andric     LibDir = "lib";
5860b57cec5SDimitry Andric     Loader = "ld-linux.so.2";
5870b57cec5SDimitry Andric     break;
5880b57cec5SDimitry Andric   case llvm::Triple::sparcv9:
5890b57cec5SDimitry Andric     LibDir = "lib64";
5900b57cec5SDimitry Andric     Loader = "ld-linux.so.2";
5910b57cec5SDimitry Andric     break;
5920b57cec5SDimitry Andric   case llvm::Triple::systemz:
5930b57cec5SDimitry Andric     LibDir = "lib";
5940b57cec5SDimitry Andric     Loader = "ld64.so.1";
5950b57cec5SDimitry Andric     break;
5960b57cec5SDimitry Andric   case llvm::Triple::x86:
5970b57cec5SDimitry Andric     LibDir = "lib";
5980b57cec5SDimitry Andric     Loader = "ld-linux.so.2";
5990b57cec5SDimitry Andric     break;
6000b57cec5SDimitry Andric   case llvm::Triple::x86_64: {
601fe6060f1SDimitry Andric     bool X32 = Triple.isX32();
6020b57cec5SDimitry Andric 
6030b57cec5SDimitry Andric     LibDir = X32 ? "libx32" : "lib64";
6040b57cec5SDimitry Andric     Loader = X32 ? "ld-linux-x32.so.2" : "ld-linux-x86-64.so.2";
6050b57cec5SDimitry Andric     break;
6060b57cec5SDimitry Andric   }
6075ffd83dbSDimitry Andric   case llvm::Triple::ve:
6085ffd83dbSDimitry Andric     return "/opt/nec/ve/lib/ld-linux-ve.so.1";
60981ad6265SDimitry Andric   case llvm::Triple::csky: {
61081ad6265SDimitry Andric     LibDir = "lib";
61181ad6265SDimitry Andric     Loader = "ld.so.1";
61281ad6265SDimitry Andric     break;
61381ad6265SDimitry Andric   }
6140b57cec5SDimitry Andric   }
6150b57cec5SDimitry Andric 
6160b57cec5SDimitry Andric   if (Distro == Distro::Exherbo &&
6170b57cec5SDimitry Andric       (Triple.getVendor() == llvm::Triple::UnknownVendor ||
6180b57cec5SDimitry Andric        Triple.getVendor() == llvm::Triple::PC))
6190b57cec5SDimitry Andric     return "/usr/" + Triple.str() + "/lib/" + Loader;
6200b57cec5SDimitry Andric   return "/" + LibDir + "/" + Loader;
6210b57cec5SDimitry Andric }
6220b57cec5SDimitry Andric 
6230b57cec5SDimitry Andric void Linux::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
6240b57cec5SDimitry Andric                                       ArgStringList &CC1Args) const {
6250b57cec5SDimitry Andric   const Driver &D = getDriver();
6260b57cec5SDimitry Andric   std::string SysRoot = computeSysRoot();
6270b57cec5SDimitry Andric 
6280b57cec5SDimitry Andric   if (DriverArgs.hasArg(clang::driver::options::OPT_nostdinc))
6290b57cec5SDimitry Andric     return;
6300b57cec5SDimitry Andric 
631fe6060f1SDimitry Andric   // Add 'include' in the resource directory, which is similar to
632fe6060f1SDimitry Andric   // GCC_INCLUDE_DIR (private headers) in GCC. Note: the include directory
633fe6060f1SDimitry Andric   // contains some files conflicting with system /usr/include. musl systems
634fe6060f1SDimitry Andric   // prefer the /usr/include copies which are more relevant.
635c14a5a88SDimitry Andric   SmallString<128> ResourceDirInclude(D.ResourceDir);
636c14a5a88SDimitry Andric   llvm::sys::path::append(ResourceDirInclude, "include");
637c14a5a88SDimitry Andric   if (!DriverArgs.hasArg(options::OPT_nobuiltininc) &&
638c14a5a88SDimitry Andric       (!getTriple().isMusl() || DriverArgs.hasArg(options::OPT_nostdlibinc)))
639c14a5a88SDimitry Andric     addSystemInclude(DriverArgs, CC1Args, ResourceDirInclude);
6400b57cec5SDimitry Andric 
6410b57cec5SDimitry Andric   if (DriverArgs.hasArg(options::OPT_nostdlibinc))
6420b57cec5SDimitry Andric     return;
6430b57cec5SDimitry Andric 
644fe6060f1SDimitry Andric   // LOCAL_INCLUDE_DIR
64581ad6265SDimitry Andric   addSystemInclude(DriverArgs, CC1Args, concat(SysRoot, "/usr/local/include"));
646fe6060f1SDimitry Andric   // TOOL_INCLUDE_DIR
647fe6060f1SDimitry Andric   AddMultilibIncludeArgs(DriverArgs, CC1Args);
648fe6060f1SDimitry Andric 
6490b57cec5SDimitry Andric   // Check for configure-time C include directories.
6500b57cec5SDimitry Andric   StringRef CIncludeDirs(C_INCLUDE_DIRS);
6510b57cec5SDimitry Andric   if (CIncludeDirs != "") {
6520b57cec5SDimitry Andric     SmallVector<StringRef, 5> dirs;
6530b57cec5SDimitry Andric     CIncludeDirs.split(dirs, ":");
6540b57cec5SDimitry Andric     for (StringRef dir : dirs) {
6550b57cec5SDimitry Andric       StringRef Prefix =
6565ffd83dbSDimitry Andric           llvm::sys::path::is_absolute(dir) ? "" : StringRef(SysRoot);
6570b57cec5SDimitry Andric       addExternCSystemInclude(DriverArgs, CC1Args, Prefix + dir);
6580b57cec5SDimitry Andric     }
6590b57cec5SDimitry Andric     return;
6600b57cec5SDimitry Andric   }
6610b57cec5SDimitry Andric 
662fe6060f1SDimitry Andric   // On systems using multiarch and Android, add /usr/include/$triple before
663fe6060f1SDimitry Andric   // /usr/include.
664fe6060f1SDimitry Andric   std::string MultiarchIncludeDir = getMultiarchTriple(D, getTriple(), SysRoot);
665fe6060f1SDimitry Andric   if (!MultiarchIncludeDir.empty() &&
66681ad6265SDimitry Andric       D.getVFS().exists(concat(SysRoot, "/usr/include", MultiarchIncludeDir)))
66781ad6265SDimitry Andric     addExternCSystemInclude(
66881ad6265SDimitry Andric         DriverArgs, CC1Args,
66981ad6265SDimitry Andric         concat(SysRoot, "/usr/include", MultiarchIncludeDir));
6700b57cec5SDimitry Andric 
6710b57cec5SDimitry Andric   if (getTriple().getOS() == llvm::Triple::RTEMS)
6720b57cec5SDimitry Andric     return;
6730b57cec5SDimitry Andric 
6740b57cec5SDimitry Andric   // Add an include of '/include' directly. This isn't provided by default by
6750b57cec5SDimitry Andric   // system GCCs, but is often used with cross-compiling GCCs, and harmless to
6760b57cec5SDimitry Andric   // add even when Clang is acting as-if it were a system compiler.
67781ad6265SDimitry Andric   addExternCSystemInclude(DriverArgs, CC1Args, concat(SysRoot, "/include"));
6780b57cec5SDimitry Andric 
67981ad6265SDimitry Andric   addExternCSystemInclude(DriverArgs, CC1Args, concat(SysRoot, "/usr/include"));
680c14a5a88SDimitry Andric 
681c14a5a88SDimitry Andric   if (!DriverArgs.hasArg(options::OPT_nobuiltininc) && getTriple().isMusl())
682c14a5a88SDimitry Andric     addSystemInclude(DriverArgs, CC1Args, ResourceDirInclude);
6830b57cec5SDimitry Andric }
6840b57cec5SDimitry Andric 
6850b57cec5SDimitry Andric void Linux::addLibStdCxxIncludePaths(const llvm::opt::ArgList &DriverArgs,
6860b57cec5SDimitry Andric                                      llvm::opt::ArgStringList &CC1Args) const {
6870b57cec5SDimitry Andric   // We need a detected GCC installation on Linux to provide libstdc++'s
688480093f4SDimitry Andric   // headers in odd Linuxish places.
6890b57cec5SDimitry Andric   if (!GCCInstallation.isValid())
6900b57cec5SDimitry Andric     return;
6910b57cec5SDimitry Andric 
692fe6060f1SDimitry Andric   // Detect Debian g++-multiarch-incdir.diff.
6930b57cec5SDimitry Andric   StringRef TripleStr = GCCInstallation.getTriple().str();
694fe6060f1SDimitry Andric   StringRef DebianMultiarch =
695fe6060f1SDimitry Andric       GCCInstallation.getTriple().getArch() == llvm::Triple::x86
696fe6060f1SDimitry Andric           ? "i386-linux-gnu"
697fe6060f1SDimitry Andric           : TripleStr;
698fe6060f1SDimitry Andric 
699fe6060f1SDimitry Andric   // Try generic GCC detection first.
700fe6060f1SDimitry Andric   if (Generic_GCC::addGCCLibStdCxxIncludePaths(DriverArgs, CC1Args,
701fe6060f1SDimitry Andric                                                DebianMultiarch))
702fe6060f1SDimitry Andric     return;
703fe6060f1SDimitry Andric 
704fe6060f1SDimitry Andric   StringRef LibDir = GCCInstallation.getParentLibPath();
7050b57cec5SDimitry Andric   const Multilib &Multilib = GCCInstallation.getMultilib();
7060b57cec5SDimitry Andric   const GCCVersion &Version = GCCInstallation.getVersion();
7070b57cec5SDimitry Andric 
7080b57cec5SDimitry Andric   const std::string LibStdCXXIncludePathCandidates[] = {
7090b57cec5SDimitry Andric       // Android standalone toolchain has C++ headers in yet another place.
7100b57cec5SDimitry Andric       LibDir.str() + "/../" + TripleStr.str() + "/include/c++/" + Version.Text,
7110b57cec5SDimitry Andric       // Freescale SDK C++ headers are directly in <sysroot>/usr/include/c++,
7120b57cec5SDimitry Andric       // without a subdirectory corresponding to the gcc version.
7130b57cec5SDimitry Andric       LibDir.str() + "/../include/c++",
7140b57cec5SDimitry Andric       // Cray's gcc installation puts headers under "g++" without a
7150b57cec5SDimitry Andric       // version suffix.
7160b57cec5SDimitry Andric       LibDir.str() + "/../include/g++",
7170b57cec5SDimitry Andric   };
7180b57cec5SDimitry Andric 
7190b57cec5SDimitry Andric   for (const auto &IncludePath : LibStdCXXIncludePathCandidates) {
720fe6060f1SDimitry Andric     if (addLibStdCXXIncludePaths(IncludePath, TripleStr,
7210b57cec5SDimitry Andric                                  Multilib.includeSuffix(), DriverArgs, CC1Args))
7220b57cec5SDimitry Andric       break;
7230b57cec5SDimitry Andric   }
7240b57cec5SDimitry Andric }
7250b57cec5SDimitry Andric 
7260b57cec5SDimitry Andric void Linux::AddCudaIncludeArgs(const ArgList &DriverArgs,
7270b57cec5SDimitry Andric                                ArgStringList &CC1Args) const {
72806c3fb27SDimitry Andric   CudaInstallation->AddCudaIncludeArgs(DriverArgs, CC1Args);
7290b57cec5SDimitry Andric }
7300b57cec5SDimitry Andric 
7315ffd83dbSDimitry Andric void Linux::AddHIPIncludeArgs(const ArgList &DriverArgs,
7325ffd83dbSDimitry Andric                               ArgStringList &CC1Args) const {
73306c3fb27SDimitry Andric   RocmInstallation->AddHIPIncludeArgs(DriverArgs, CC1Args);
7345ffd83dbSDimitry Andric }
7355ffd83dbSDimitry Andric 
73681ad6265SDimitry Andric void Linux::AddHIPRuntimeLibArgs(const ArgList &Args,
73781ad6265SDimitry Andric                                  ArgStringList &CmdArgs) const {
738bdd1243dSDimitry Andric   CmdArgs.push_back(
73906c3fb27SDimitry Andric       Args.MakeArgString(StringRef("-L") + RocmInstallation->getLibPath()));
740bdd1243dSDimitry Andric 
74106c3fb27SDimitry Andric   if (Args.hasFlag(options::OPT_frtlib_add_rpath,
74206c3fb27SDimitry Andric                    options::OPT_fno_rtlib_add_rpath, false))
74381ad6265SDimitry Andric     CmdArgs.append(
74406c3fb27SDimitry Andric         {"-rpath", Args.MakeArgString(RocmInstallation->getLibPath())});
74581ad6265SDimitry Andric 
74681ad6265SDimitry Andric   CmdArgs.push_back("-lamdhip64");
74781ad6265SDimitry Andric }
74881ad6265SDimitry Andric 
7490b57cec5SDimitry Andric void Linux::AddIAMCUIncludeArgs(const ArgList &DriverArgs,
7500b57cec5SDimitry Andric                                 ArgStringList &CC1Args) const {
7510b57cec5SDimitry Andric   if (GCCInstallation.isValid()) {
7520b57cec5SDimitry Andric     CC1Args.push_back("-isystem");
7530b57cec5SDimitry Andric     CC1Args.push_back(DriverArgs.MakeArgString(
7540b57cec5SDimitry Andric         GCCInstallation.getParentLibPath() + "/../" +
7550b57cec5SDimitry Andric         GCCInstallation.getTriple().str() + "/include"));
7560b57cec5SDimitry Andric   }
7570b57cec5SDimitry Andric }
7580b57cec5SDimitry Andric 
759349cc55cSDimitry Andric bool Linux::isPIEDefault(const llvm::opt::ArgList &Args) const {
760bdd1243dSDimitry Andric   return CLANG_DEFAULT_PIE_ON_LINUX || getTriple().isAndroid() ||
761bdd1243dSDimitry Andric          getTriple().isMusl() || getSanitizerArgs(Args).requiresPIE();
7620b57cec5SDimitry Andric }
7630b57cec5SDimitry Andric 
764fe6060f1SDimitry Andric bool Linux::IsAArch64OutlineAtomicsDefault(const ArgList &Args) const {
765fe6060f1SDimitry Andric   // Outline atomics for AArch64 are supported by compiler-rt
766fe6060f1SDimitry Andric   // and libgcc since 9.3.1
767fe6060f1SDimitry Andric   assert(getTriple().isAArch64() && "expected AArch64 target!");
768fe6060f1SDimitry Andric   ToolChain::RuntimeLibType RtLib = GetRuntimeLibType(Args);
769fe6060f1SDimitry Andric   if (RtLib == ToolChain::RLT_CompilerRT)
770fe6060f1SDimitry Andric     return true;
771fe6060f1SDimitry Andric   assert(RtLib == ToolChain::RLT_Libgcc && "unexpected runtime library type!");
772fe6060f1SDimitry Andric   if (GCCInstallation.getVersion().isOlderThan(9, 3, 1))
773fe6060f1SDimitry Andric     return false;
774fe6060f1SDimitry Andric   return true;
775fe6060f1SDimitry Andric }
776fe6060f1SDimitry Andric 
7770b57cec5SDimitry Andric bool Linux::IsMathErrnoDefault() const {
7781838bd0fSDimitry Andric   if (getTriple().isAndroid() || getTriple().isMusl())
7790b57cec5SDimitry Andric     return false;
7800b57cec5SDimitry Andric   return Generic_ELF::IsMathErrnoDefault();
7810b57cec5SDimitry Andric }
7820b57cec5SDimitry Andric 
7830b57cec5SDimitry Andric SanitizerMask Linux::getSupportedSanitizers() const {
7840b57cec5SDimitry Andric   const bool IsX86 = getTriple().getArch() == llvm::Triple::x86;
7850b57cec5SDimitry Andric   const bool IsX86_64 = getTriple().getArch() == llvm::Triple::x86_64;
7860b57cec5SDimitry Andric   const bool IsMIPS = getTriple().isMIPS32();
7870b57cec5SDimitry Andric   const bool IsMIPS64 = getTriple().isMIPS64();
7880b57cec5SDimitry Andric   const bool IsPowerPC64 = getTriple().getArch() == llvm::Triple::ppc64 ||
7890b57cec5SDimitry Andric                            getTriple().getArch() == llvm::Triple::ppc64le;
7900b57cec5SDimitry Andric   const bool IsAArch64 = getTriple().getArch() == llvm::Triple::aarch64 ||
7910b57cec5SDimitry Andric                          getTriple().getArch() == llvm::Triple::aarch64_be;
7920b57cec5SDimitry Andric   const bool IsArmArch = getTriple().getArch() == llvm::Triple::arm ||
7930b57cec5SDimitry Andric                          getTriple().getArch() == llvm::Triple::thumb ||
7940b57cec5SDimitry Andric                          getTriple().getArch() == llvm::Triple::armeb ||
7950b57cec5SDimitry Andric                          getTriple().getArch() == llvm::Triple::thumbeb;
796bdd1243dSDimitry Andric   const bool IsLoongArch64 = getTriple().getArch() == llvm::Triple::loongarch64;
797fe6060f1SDimitry Andric   const bool IsRISCV64 = getTriple().getArch() == llvm::Triple::riscv64;
7985ffd83dbSDimitry Andric   const bool IsSystemZ = getTriple().getArch() == llvm::Triple::systemz;
799349cc55cSDimitry Andric   const bool IsHexagon = getTriple().getArch() == llvm::Triple::hexagon;
8000b57cec5SDimitry Andric   SanitizerMask Res = ToolChain::getSupportedSanitizers();
8010b57cec5SDimitry Andric   Res |= SanitizerKind::Address;
8020b57cec5SDimitry Andric   Res |= SanitizerKind::PointerCompare;
8030b57cec5SDimitry Andric   Res |= SanitizerKind::PointerSubtract;
8040b57cec5SDimitry Andric   Res |= SanitizerKind::Fuzzer;
8050b57cec5SDimitry Andric   Res |= SanitizerKind::FuzzerNoLink;
8060b57cec5SDimitry Andric   Res |= SanitizerKind::KernelAddress;
8070b57cec5SDimitry Andric   Res |= SanitizerKind::Memory;
8080b57cec5SDimitry Andric   Res |= SanitizerKind::Vptr;
8090b57cec5SDimitry Andric   Res |= SanitizerKind::SafeStack;
81006c3fb27SDimitry Andric   if (IsX86_64 || IsMIPS64 || IsAArch64 || IsLoongArch64)
8110b57cec5SDimitry Andric     Res |= SanitizerKind::DataFlow;
8125ffd83dbSDimitry Andric   if (IsX86_64 || IsMIPS64 || IsAArch64 || IsX86 || IsArmArch || IsPowerPC64 ||
813bdd1243dSDimitry Andric       IsRISCV64 || IsSystemZ || IsHexagon || IsLoongArch64)
8140b57cec5SDimitry Andric     Res |= SanitizerKind::Leak;
815bdd1243dSDimitry Andric   if (IsX86_64 || IsMIPS64 || IsAArch64 || IsPowerPC64 || IsSystemZ ||
8165f757f3fSDimitry Andric       IsLoongArch64 || IsRISCV64)
8170b57cec5SDimitry Andric     Res |= SanitizerKind::Thread;
8180fca6ea1SDimitry Andric   if (IsX86_64 || IsSystemZ || IsPowerPC64)
8190b57cec5SDimitry Andric     Res |= SanitizerKind::KernelMemory;
8200b57cec5SDimitry Andric   if (IsX86_64 || IsMIPS64 || IsAArch64 || IsX86 || IsMIPS || IsArmArch ||
82106c3fb27SDimitry Andric       IsPowerPC64 || IsHexagon || IsLoongArch64 || IsRISCV64)
8220b57cec5SDimitry Andric     Res |= SanitizerKind::Scudo;
823bdd1243dSDimitry Andric   if (IsX86_64 || IsAArch64 || IsRISCV64) {
8240b57cec5SDimitry Andric     Res |= SanitizerKind::HWAddress;
825bdd1243dSDimitry Andric   }
826bdd1243dSDimitry Andric   if (IsX86_64 || IsAArch64) {
8270b57cec5SDimitry Andric     Res |= SanitizerKind::KernelHWAddress;
8280b57cec5SDimitry Andric   }
8290fca6ea1SDimitry Andric   if (IsX86_64)
8300fca6ea1SDimitry Andric     Res |= SanitizerKind::NumericalStability;
8310fca6ea1SDimitry Andric 
83206c3fb27SDimitry Andric   // Work around "Cannot represent a difference across sections".
83306c3fb27SDimitry Andric   if (getTriple().getArch() == llvm::Triple::ppc64)
83406c3fb27SDimitry Andric     Res &= ~SanitizerKind::Function;
8350b57cec5SDimitry Andric   return Res;
8360b57cec5SDimitry Andric }
8370b57cec5SDimitry Andric 
8380b57cec5SDimitry Andric void Linux::addProfileRTLibs(const llvm::opt::ArgList &Args,
8390b57cec5SDimitry Andric                              llvm::opt::ArgStringList &CmdArgs) const {
8405ffd83dbSDimitry Andric   // Add linker option -u__llvm_profile_runtime to cause runtime
8410b57cec5SDimitry Andric   // initialization module to be linked in.
8425ffd83dbSDimitry Andric   if (needsProfileRT(Args))
8430b57cec5SDimitry Andric     CmdArgs.push_back(Args.MakeArgString(
8440b57cec5SDimitry Andric         Twine("-u", llvm::getInstrProfRuntimeHookVarName())));
8450b57cec5SDimitry Andric   ToolChain::addProfileRTLibs(Args, CmdArgs);
8460b57cec5SDimitry Andric }
847d65cd7a5SDimitry Andric 
848d65cd7a5SDimitry Andric void Linux::addExtraOpts(llvm::opt::ArgStringList &CmdArgs) const {
849d65cd7a5SDimitry Andric   for (const auto &Opt : ExtraOpts)
850d65cd7a5SDimitry Andric     CmdArgs.push_back(Opt.c_str());
851d65cd7a5SDimitry Andric }
852bdd1243dSDimitry Andric 
853bdd1243dSDimitry Andric const char *Linux::getDefaultLinker() const {
854bdd1243dSDimitry Andric   if (getTriple().isAndroid())
855bdd1243dSDimitry Andric     return "ld.lld";
856bdd1243dSDimitry Andric   return Generic_ELF::getDefaultLinker();
857bdd1243dSDimitry Andric }
858