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