1e5dd7070Spatrick //===--- Linux.h - Linux ToolChain Implementations --------------*- C++ -*-===//
2e5dd7070Spatrick //
3e5dd7070Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4e5dd7070Spatrick // See https://llvm.org/LICENSE.txt for license information.
5e5dd7070Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6e5dd7070Spatrick //
7e5dd7070Spatrick //===----------------------------------------------------------------------===//
8e5dd7070Spatrick 
9e5dd7070Spatrick #include "Linux.h"
10e5dd7070Spatrick #include "Arch/ARM.h"
11*12c85518Srobert #include "Arch/LoongArch.h"
12e5dd7070Spatrick #include "Arch/Mips.h"
13e5dd7070Spatrick #include "Arch/PPC.h"
14e5dd7070Spatrick #include "Arch/RISCV.h"
15e5dd7070Spatrick #include "CommonArgs.h"
16e5dd7070Spatrick #include "clang/Config/config.h"
17e5dd7070Spatrick #include "clang/Driver/Distro.h"
18e5dd7070Spatrick #include "clang/Driver/Driver.h"
19e5dd7070Spatrick #include "clang/Driver/Options.h"
20e5dd7070Spatrick #include "clang/Driver/SanitizerArgs.h"
21e5dd7070Spatrick #include "llvm/Option/ArgList.h"
22e5dd7070Spatrick #include "llvm/ProfileData/InstrProf.h"
23e5dd7070Spatrick #include "llvm/Support/Path.h"
24e5dd7070Spatrick #include "llvm/Support/ScopedPrinter.h"
25e5dd7070Spatrick #include "llvm/Support/VirtualFileSystem.h"
26e5dd7070Spatrick #include <system_error>
27e5dd7070Spatrick 
28e5dd7070Spatrick using namespace clang::driver;
29e5dd7070Spatrick using namespace clang::driver::toolchains;
30e5dd7070Spatrick using namespace clang;
31e5dd7070Spatrick using namespace llvm::opt;
32e5dd7070Spatrick 
33e5dd7070Spatrick using tools::addPathIfExists;
34e5dd7070Spatrick 
35e5dd7070Spatrick /// Get our best guess at the multiarch triple for a target.
36e5dd7070Spatrick ///
37e5dd7070Spatrick /// Debian-based systems are starting to use a multiarch setup where they use
38e5dd7070Spatrick /// a target-triple directory in the library and header search paths.
39e5dd7070Spatrick /// Unfortunately, this triple does not align with the vanilla target triple,
40e5dd7070Spatrick /// so we provide a rough mapping here.
getMultiarchTriple(const Driver & D,const llvm::Triple & TargetTriple,StringRef SysRoot) const41e5dd7070Spatrick std::string Linux::getMultiarchTriple(const Driver &D,
42e5dd7070Spatrick                                       const llvm::Triple &TargetTriple,
43e5dd7070Spatrick                                       StringRef SysRoot) const {
44e5dd7070Spatrick   llvm::Triple::EnvironmentType TargetEnvironment =
45e5dd7070Spatrick       TargetTriple.getEnvironment();
46e5dd7070Spatrick   bool IsAndroid = TargetTriple.isAndroid();
47e5dd7070Spatrick   bool IsMipsR6 = TargetTriple.getSubArch() == llvm::Triple::MipsSubArch_r6;
48e5dd7070Spatrick   bool IsMipsN32Abi = TargetTriple.getEnvironment() == llvm::Triple::GNUABIN32;
49e5dd7070Spatrick 
50e5dd7070Spatrick   // For most architectures, just use whatever we have rather than trying to be
51e5dd7070Spatrick   // clever.
52e5dd7070Spatrick   switch (TargetTriple.getArch()) {
53e5dd7070Spatrick   default:
54e5dd7070Spatrick     break;
55e5dd7070Spatrick 
56e5dd7070Spatrick   // We use the existence of '/lib/<triple>' as a directory to detect some
57e5dd7070Spatrick   // common linux triples that don't quite match the Clang triple for both
58e5dd7070Spatrick   // 32-bit and 64-bit targets. Multiarch fixes its install triples to these
59e5dd7070Spatrick   // regardless of what the actual target triple is.
60e5dd7070Spatrick   case llvm::Triple::arm:
61e5dd7070Spatrick   case llvm::Triple::thumb:
62a9ac8606Spatrick     if (IsAndroid)
63e5dd7070Spatrick       return "arm-linux-androideabi";
64a9ac8606Spatrick     if (TargetEnvironment == llvm::Triple::GNUEABIHF)
65e5dd7070Spatrick       return "arm-linux-gnueabihf";
66e5dd7070Spatrick     return "arm-linux-gnueabi";
67e5dd7070Spatrick   case llvm::Triple::armeb:
68e5dd7070Spatrick   case llvm::Triple::thumbeb:
69a9ac8606Spatrick     if (TargetEnvironment == llvm::Triple::GNUEABIHF)
70e5dd7070Spatrick       return "armeb-linux-gnueabihf";
71e5dd7070Spatrick     return "armeb-linux-gnueabi";
72e5dd7070Spatrick   case llvm::Triple::x86:
73e5dd7070Spatrick     if (IsAndroid)
74e5dd7070Spatrick       return "i686-linux-android";
75e5dd7070Spatrick     return "i386-linux-gnu";
76e5dd7070Spatrick   case llvm::Triple::x86_64:
77e5dd7070Spatrick     if (IsAndroid)
78e5dd7070Spatrick       return "x86_64-linux-android";
79a9ac8606Spatrick     if (TargetEnvironment == llvm::Triple::GNUX32)
80a9ac8606Spatrick       return "x86_64-linux-gnux32";
81e5dd7070Spatrick     return "x86_64-linux-gnu";
82e5dd7070Spatrick   case llvm::Triple::aarch64:
83e5dd7070Spatrick     if (IsAndroid)
84e5dd7070Spatrick       return "aarch64-linux-android";
85e5dd7070Spatrick     return "aarch64-linux-gnu";
86e5dd7070Spatrick   case llvm::Triple::aarch64_be:
87e5dd7070Spatrick     return "aarch64_be-linux-gnu";
88a9ac8606Spatrick 
89a9ac8606Spatrick   case llvm::Triple::m68k:
90a9ac8606Spatrick     return "m68k-linux-gnu";
91a9ac8606Spatrick 
92a9ac8606Spatrick   case llvm::Triple::mips:
93a9ac8606Spatrick     return IsMipsR6 ? "mipsisa32r6-linux-gnu" : "mips-linux-gnu";
94a9ac8606Spatrick   case llvm::Triple::mipsel:
95e5dd7070Spatrick     if (IsAndroid)
96e5dd7070Spatrick       return "mipsel-linux-android";
97a9ac8606Spatrick     return IsMipsR6 ? "mipsisa32r6el-linux-gnu" : "mipsel-linux-gnu";
98e5dd7070Spatrick   case llvm::Triple::mips64: {
99e5dd7070Spatrick     std::string MT = std::string(IsMipsR6 ? "mipsisa64r6" : "mips64") +
100e5dd7070Spatrick                      "-linux-" + (IsMipsN32Abi ? "gnuabin32" : "gnuabi64");
101*12c85518Srobert     if (D.getVFS().exists(concat(SysRoot, "/lib", MT)))
102e5dd7070Spatrick       return MT;
103*12c85518Srobert     if (D.getVFS().exists(concat(SysRoot, "/lib/mips64-linux-gnu")))
104e5dd7070Spatrick       return "mips64-linux-gnu";
105e5dd7070Spatrick     break;
106e5dd7070Spatrick   }
107e5dd7070Spatrick   case llvm::Triple::mips64el: {
108e5dd7070Spatrick     if (IsAndroid)
109e5dd7070Spatrick       return "mips64el-linux-android";
110e5dd7070Spatrick     std::string MT = std::string(IsMipsR6 ? "mipsisa64r6el" : "mips64el") +
111e5dd7070Spatrick                      "-linux-" + (IsMipsN32Abi ? "gnuabin32" : "gnuabi64");
112*12c85518Srobert     if (D.getVFS().exists(concat(SysRoot, "/lib", MT)))
113e5dd7070Spatrick       return MT;
114*12c85518Srobert     if (D.getVFS().exists(concat(SysRoot, "/lib/mips64el-linux-gnu")))
115e5dd7070Spatrick       return "mips64el-linux-gnu";
116e5dd7070Spatrick     break;
117e5dd7070Spatrick   }
118e5dd7070Spatrick   case llvm::Triple::ppc:
119*12c85518Srobert     if (D.getVFS().exists(concat(SysRoot, "/lib/powerpc-linux-gnuspe")))
120e5dd7070Spatrick       return "powerpc-linux-gnuspe";
121e5dd7070Spatrick     return "powerpc-linux-gnu";
122a9ac8606Spatrick   case llvm::Triple::ppcle:
123a9ac8606Spatrick     return "powerpcle-linux-gnu";
124e5dd7070Spatrick   case llvm::Triple::ppc64:
125e5dd7070Spatrick     return "powerpc64-linux-gnu";
126e5dd7070Spatrick   case llvm::Triple::ppc64le:
127e5dd7070Spatrick     return "powerpc64le-linux-gnu";
128*12c85518Srobert   case llvm::Triple::riscv64:
129*12c85518Srobert     return "riscv64-linux-gnu";
130e5dd7070Spatrick   case llvm::Triple::sparc:
131e5dd7070Spatrick     return "sparc-linux-gnu";
132e5dd7070Spatrick   case llvm::Triple::sparcv9:
133e5dd7070Spatrick     return "sparc64-linux-gnu";
134e5dd7070Spatrick   case llvm::Triple::systemz:
135e5dd7070Spatrick     return "s390x-linux-gnu";
136e5dd7070Spatrick   }
137e5dd7070Spatrick   return TargetTriple.str();
138e5dd7070Spatrick }
139e5dd7070Spatrick 
getOSLibDir(const llvm::Triple & Triple,const ArgList & Args)140e5dd7070Spatrick static StringRef getOSLibDir(const llvm::Triple &Triple, const ArgList &Args) {
141e5dd7070Spatrick   if (Triple.isMIPS()) {
142e5dd7070Spatrick     if (Triple.isAndroid()) {
143e5dd7070Spatrick       StringRef CPUName;
144e5dd7070Spatrick       StringRef ABIName;
145e5dd7070Spatrick       tools::mips::getMipsCPUAndABI(Args, Triple, CPUName, ABIName);
146e5dd7070Spatrick       if (CPUName == "mips32r6")
147e5dd7070Spatrick         return "libr6";
148e5dd7070Spatrick       if (CPUName == "mips32r2")
149e5dd7070Spatrick         return "libr2";
150e5dd7070Spatrick     }
151e5dd7070Spatrick     // lib32 directory has a special meaning on MIPS targets.
152e5dd7070Spatrick     // It contains N32 ABI binaries. Use this folder if produce
153e5dd7070Spatrick     // code for N32 ABI only.
154e5dd7070Spatrick     if (tools::mips::hasMipsAbiArg(Args, "n32"))
155e5dd7070Spatrick       return "lib32";
156e5dd7070Spatrick     return Triple.isArch32Bit() ? "lib" : "lib64";
157e5dd7070Spatrick   }
158e5dd7070Spatrick 
159a9ac8606Spatrick   // It happens that only x86, PPC and SPARC use the 'lib32' variant of
160a9ac8606Spatrick   // oslibdir, and using that variant while targeting other architectures causes
161a9ac8606Spatrick   // problems because the libraries are laid out in shared system roots that
162a9ac8606Spatrick   // can't cope with a 'lib32' library search path being considered. So we only
163a9ac8606Spatrick   // enable them when we know we may need it.
164e5dd7070Spatrick   //
165e5dd7070Spatrick   // FIXME: This is a bit of a hack. We should really unify this code for
166e5dd7070Spatrick   // reasoning about oslibdir spellings with the lib dir spellings in the
167e5dd7070Spatrick   // GCCInstallationDetector, but that is a more significant refactoring.
168a9ac8606Spatrick   if (Triple.getArch() == llvm::Triple::x86 || Triple.isPPC32() ||
169a9ac8606Spatrick       Triple.getArch() == llvm::Triple::sparc)
170e5dd7070Spatrick     return "lib32";
171e5dd7070Spatrick 
172a9ac8606Spatrick   if (Triple.getArch() == llvm::Triple::x86_64 && Triple.isX32())
173e5dd7070Spatrick     return "libx32";
174e5dd7070Spatrick 
175e5dd7070Spatrick   if (Triple.getArch() == llvm::Triple::riscv32)
176e5dd7070Spatrick     return "lib32";
177e5dd7070Spatrick 
178e5dd7070Spatrick   return Triple.isArch32Bit() ? "lib" : "lib64";
179e5dd7070Spatrick }
180e5dd7070Spatrick 
Linux(const Driver & D,const llvm::Triple & Triple,const ArgList & Args)181e5dd7070Spatrick Linux::Linux(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)
182e5dd7070Spatrick     : Generic_ELF(D, Triple, Args) {
183e5dd7070Spatrick   GCCInstallation.init(Triple, Args);
184e5dd7070Spatrick   Multilibs = GCCInstallation.getMultilibs();
185e5dd7070Spatrick   SelectedMultilib = GCCInstallation.getMultilib();
186e5dd7070Spatrick   llvm::Triple::ArchType Arch = Triple.getArch();
187e5dd7070Spatrick   std::string SysRoot = computeSysRoot();
188e5dd7070Spatrick   ToolChain::path_list &PPaths = getProgramPaths();
189ec727ea7Spatrick 
190ec727ea7Spatrick   Generic_GCC::PushPPaths(PPaths);
191e5dd7070Spatrick 
192e5dd7070Spatrick   Distro Distro(D.getVFS(), Triple);
193e5dd7070Spatrick 
194e5dd7070Spatrick   if (Distro.IsAlpineLinux() || Triple.isAndroid()) {
195e5dd7070Spatrick     ExtraOpts.push_back("-z");
196e5dd7070Spatrick     ExtraOpts.push_back("now");
197e5dd7070Spatrick   }
198e5dd7070Spatrick 
199e5dd7070Spatrick   if (Distro.IsOpenSUSE() || Distro.IsUbuntu() || Distro.IsAlpineLinux() ||
200e5dd7070Spatrick       Triple.isAndroid()) {
201e5dd7070Spatrick     ExtraOpts.push_back("-z");
202e5dd7070Spatrick     ExtraOpts.push_back("relro");
203e5dd7070Spatrick   }
204e5dd7070Spatrick 
205ec727ea7Spatrick   // Android ARM/AArch64 use max-page-size=4096 to reduce VMA usage. Note, lld
206ec727ea7Spatrick   // from 11 onwards default max-page-size to 65536 for both ARM and AArch64.
207ec727ea7Spatrick   if ((Triple.isARM() || Triple.isAArch64()) && Triple.isAndroid()) {
208e5dd7070Spatrick     ExtraOpts.push_back("-z");
209e5dd7070Spatrick     ExtraOpts.push_back("max-page-size=4096");
210e5dd7070Spatrick   }
211e5dd7070Spatrick 
212*12c85518Srobert   if (GCCInstallation.getParentLibPath().contains("opt/rh/"))
213e5dd7070Spatrick     // With devtoolset on RHEL, we want to add a bin directory that is relative
214e5dd7070Spatrick     // to the detected gcc install, because if we are using devtoolset gcc then
215e5dd7070Spatrick     // we want to use other tools from devtoolset (e.g. ld) instead of the
216e5dd7070Spatrick     // standard system tools.
217e5dd7070Spatrick     PPaths.push_back(Twine(GCCInstallation.getParentLibPath() +
218e5dd7070Spatrick                      "/../bin").str());
219e5dd7070Spatrick 
220e5dd7070Spatrick   if (Arch == llvm::Triple::arm || Arch == llvm::Triple::thumb)
221e5dd7070Spatrick     ExtraOpts.push_back("-X");
222e5dd7070Spatrick 
223e5dd7070Spatrick   const bool IsAndroid = Triple.isAndroid();
224e5dd7070Spatrick   const bool IsMips = Triple.isMIPS();
225e5dd7070Spatrick   const bool IsHexagon = Arch == llvm::Triple::hexagon;
226e5dd7070Spatrick   const bool IsRISCV = Triple.isRISCV();
227*12c85518Srobert   const bool IsCSKY = Triple.isCSKY();
228e5dd7070Spatrick 
229*12c85518Srobert   if (IsCSKY)
230*12c85518Srobert     SysRoot = SysRoot + SelectedMultilib.osSuffix();
231*12c85518Srobert 
232*12c85518Srobert   if ((IsMips || IsCSKY) && !SysRoot.empty())
233e5dd7070Spatrick     ExtraOpts.push_back("--sysroot=" + SysRoot);
234e5dd7070Spatrick 
235e5dd7070Spatrick   // Do not use 'gnu' hash style for Mips targets because .gnu.hash
236e5dd7070Spatrick   // and the MIPS ABI require .dynsym to be sorted in different ways.
237e5dd7070Spatrick   // .gnu.hash needs symbols to be grouped by hash code whereas the MIPS
238e5dd7070Spatrick   // ABI requires a mapping between the GOT and the symbol table.
239e5dd7070Spatrick   // Android loader does not support .gnu.hash until API 23.
240e5dd7070Spatrick   // Hexagon linker/loader does not support .gnu.hash
241e5dd7070Spatrick   if (!IsMips && !IsHexagon) {
242*12c85518Srobert     if (Distro.IsOpenSUSE() || Distro == Distro::UbuntuLucid ||
243*12c85518Srobert         Distro == Distro::UbuntuJaunty || Distro == Distro::UbuntuKarmic ||
244e5dd7070Spatrick         (IsAndroid && Triple.isAndroidVersionLT(23)))
245e5dd7070Spatrick       ExtraOpts.push_back("--hash-style=both");
246*12c85518Srobert     else
247*12c85518Srobert       ExtraOpts.push_back("--hash-style=gnu");
248e5dd7070Spatrick   }
249e5dd7070Spatrick 
250e5dd7070Spatrick #ifdef ENABLE_LINKER_BUILD_ID
251e5dd7070Spatrick   ExtraOpts.push_back("--build-id");
252e5dd7070Spatrick #endif
253e5dd7070Spatrick 
254e5dd7070Spatrick   // The selection of paths to try here is designed to match the patterns which
255e5dd7070Spatrick   // the GCC driver itself uses, as this is part of the GCC-compatible driver.
256e5dd7070Spatrick   // This was determined by running GCC in a fake filesystem, creating all
257e5dd7070Spatrick   // possible permutations of these directories, and seeing which ones it added
258e5dd7070Spatrick   // to the link paths.
259e5dd7070Spatrick   path_list &Paths = getFilePaths();
260e5dd7070Spatrick 
261ec727ea7Spatrick   const std::string OSLibDir = std::string(getOSLibDir(Triple, Args));
262e5dd7070Spatrick   const std::string MultiarchTriple = getMultiarchTriple(D, Triple, SysRoot);
263e5dd7070Spatrick 
264*12c85518Srobert   // mips32: Debian multilib, we use /libo32, while in other case, /lib is
265*12c85518Srobert   // used. We need add both libo32 and /lib.
266*12c85518Srobert   if (Arch == llvm::Triple::mips || Arch == llvm::Triple::mipsel) {
267*12c85518Srobert     Generic_GCC::AddMultilibPaths(D, SysRoot, "libo32", MultiarchTriple, Paths);
268*12c85518Srobert     addPathIfExists(D, concat(SysRoot, "/libo32"), Paths);
269*12c85518Srobert     addPathIfExists(D, concat(SysRoot, "/usr/libo32"), Paths);
270*12c85518Srobert   }
271ec727ea7Spatrick   Generic_GCC::AddMultilibPaths(D, SysRoot, OSLibDir, MultiarchTriple, Paths);
272e5dd7070Spatrick 
273*12c85518Srobert   addPathIfExists(D, concat(SysRoot, "/lib", MultiarchTriple), Paths);
274*12c85518Srobert   addPathIfExists(D, concat(SysRoot, "/lib/..", OSLibDir), Paths);
275e5dd7070Spatrick 
276e5dd7070Spatrick   if (IsAndroid) {
277e5dd7070Spatrick     // Android sysroots contain a library directory for each supported OS
278e5dd7070Spatrick     // version as well as some unversioned libraries in the usual multiarch
279e5dd7070Spatrick     // directory.
280*12c85518Srobert     addPathIfExists(
281*12c85518Srobert         D,
282*12c85518Srobert         concat(SysRoot, "/usr/lib", MultiarchTriple,
283*12c85518Srobert                llvm::to_string(Triple.getEnvironmentVersion().getMajor())),
284e5dd7070Spatrick         Paths);
285e5dd7070Spatrick   }
286e5dd7070Spatrick 
287*12c85518Srobert   addPathIfExists(D, concat(SysRoot, "/usr/lib", MultiarchTriple), Paths);
288e5dd7070Spatrick   // 64-bit OpenEmbedded sysroots may not have a /usr/lib dir. So they cannot
289e5dd7070Spatrick   // find /usr/lib64 as it is referenced as /usr/lib/../lib64. So we handle
290e5dd7070Spatrick   // this here.
291e5dd7070Spatrick   if (Triple.getVendor() == llvm::Triple::OpenEmbedded &&
292e5dd7070Spatrick       Triple.isArch64Bit())
293*12c85518Srobert     addPathIfExists(D, concat(SysRoot, "/usr", OSLibDir), Paths);
294e5dd7070Spatrick   else
295*12c85518Srobert     addPathIfExists(D, concat(SysRoot, "/usr/lib/..", OSLibDir), Paths);
296e5dd7070Spatrick   if (IsRISCV) {
297e5dd7070Spatrick     StringRef ABIName = tools::riscv::getRISCVABI(Args, Triple);
298*12c85518Srobert     addPathIfExists(D, concat(SysRoot, "/", OSLibDir, ABIName), Paths);
299*12c85518Srobert     addPathIfExists(D, concat(SysRoot, "/usr", OSLibDir, ABIName), Paths);
300e5dd7070Spatrick   }
301e5dd7070Spatrick 
302ec727ea7Spatrick   Generic_GCC::AddMultiarchPaths(D, SysRoot, OSLibDir, Paths);
303e5dd7070Spatrick 
304*12c85518Srobert   // The deprecated -DLLVM_ENABLE_PROJECTS=libcxx configuration installs
305*12c85518Srobert   // libc++.so in D.Dir+"/../lib/". Detect this path.
306*12c85518Srobert   // TODO Remove once LLVM_ENABLE_PROJECTS=libcxx is unsupported.
307*12c85518Srobert   if (StringRef(D.Dir).startswith(SysRoot) &&
308*12c85518Srobert       D.getVFS().exists(D.Dir + "/../lib/libc++.so"))
309e5dd7070Spatrick     addPathIfExists(D, D.Dir + "/../lib", Paths);
310e5dd7070Spatrick 
311*12c85518Srobert   addPathIfExists(D, concat(SysRoot, "/lib"), Paths);
312*12c85518Srobert   addPathIfExists(D, concat(SysRoot, "/usr/lib"), Paths);
313e5dd7070Spatrick }
314e5dd7070Spatrick 
GetDefaultRuntimeLibType() const315a9ac8606Spatrick ToolChain::RuntimeLibType Linux::GetDefaultRuntimeLibType() const {
316a9ac8606Spatrick   if (getTriple().isAndroid())
317a9ac8606Spatrick     return ToolChain::RLT_CompilerRT;
318a9ac8606Spatrick   return Generic_ELF::GetDefaultRuntimeLibType();
319a9ac8606Spatrick }
320a9ac8606Spatrick 
GetDefaultDwarfVersion() const321*12c85518Srobert unsigned Linux::GetDefaultDwarfVersion() const {
322*12c85518Srobert   if (getTriple().isAndroid())
323*12c85518Srobert     return 4;
324*12c85518Srobert   return ToolChain::GetDefaultDwarfVersion();
325*12c85518Srobert }
326*12c85518Srobert 
GetDefaultCXXStdlibType() const327e5dd7070Spatrick ToolChain::CXXStdlibType Linux::GetDefaultCXXStdlibType() const {
328e5dd7070Spatrick   if (getTriple().isAndroid())
329e5dd7070Spatrick     return ToolChain::CST_Libcxx;
330e5dd7070Spatrick   return ToolChain::CST_Libstdcxx;
331e5dd7070Spatrick }
332e5dd7070Spatrick 
HasNativeLLVMSupport() const333e5dd7070Spatrick bool Linux::HasNativeLLVMSupport() const { return true; }
334e5dd7070Spatrick 
buildLinker() const335e5dd7070Spatrick Tool *Linux::buildLinker() const { return new tools::gnutools::Linker(*this); }
336e5dd7070Spatrick 
buildStaticLibTool() const337ec727ea7Spatrick Tool *Linux::buildStaticLibTool() const {
338ec727ea7Spatrick   return new tools::gnutools::StaticLibTool(*this);
339ec727ea7Spatrick }
340ec727ea7Spatrick 
buildAssembler() const341e5dd7070Spatrick Tool *Linux::buildAssembler() const {
342e5dd7070Spatrick   return new tools::gnutools::Assembler(*this);
343e5dd7070Spatrick }
344e5dd7070Spatrick 
computeSysRoot() const345e5dd7070Spatrick std::string Linux::computeSysRoot() const {
346e5dd7070Spatrick   if (!getDriver().SysRoot.empty())
347e5dd7070Spatrick     return getDriver().SysRoot;
348e5dd7070Spatrick 
349e5dd7070Spatrick   if (getTriple().isAndroid()) {
350e5dd7070Spatrick     // Android toolchains typically include a sysroot at ../sysroot relative to
351e5dd7070Spatrick     // the clang binary.
352e5dd7070Spatrick     const StringRef ClangDir = getDriver().getInstalledDir();
353e5dd7070Spatrick     std::string AndroidSysRootPath = (ClangDir + "/../sysroot").str();
354e5dd7070Spatrick     if (getVFS().exists(AndroidSysRootPath))
355e5dd7070Spatrick       return AndroidSysRootPath;
356e5dd7070Spatrick   }
357e5dd7070Spatrick 
358*12c85518Srobert   if (getTriple().isCSKY()) {
359*12c85518Srobert     // CSKY toolchains use different names for sysroot folder.
360*12c85518Srobert     if (!GCCInstallation.isValid())
361*12c85518Srobert       return std::string();
362*12c85518Srobert     // GCCInstallation.getInstallPath() =
363*12c85518Srobert     //   $GCCToolchainPath/lib/gcc/csky-linux-gnuabiv2/6.3.0
364*12c85518Srobert     // Path = $GCCToolchainPath/csky-linux-gnuabiv2/libc
365*12c85518Srobert     std::string Path = (GCCInstallation.getInstallPath() + "/../../../../" +
366*12c85518Srobert                         GCCInstallation.getTriple().str() + "/libc")
367*12c85518Srobert                            .str();
368*12c85518Srobert     if (getVFS().exists(Path))
369*12c85518Srobert       return Path;
370*12c85518Srobert     return std::string();
371*12c85518Srobert   }
372*12c85518Srobert 
373e5dd7070Spatrick   if (!GCCInstallation.isValid() || !getTriple().isMIPS())
374e5dd7070Spatrick     return std::string();
375e5dd7070Spatrick 
376e5dd7070Spatrick   // Standalone MIPS toolchains use different names for sysroot folder
377e5dd7070Spatrick   // and put it into different places. Here we try to check some known
378e5dd7070Spatrick   // variants.
379e5dd7070Spatrick 
380e5dd7070Spatrick   const StringRef InstallDir = GCCInstallation.getInstallPath();
381e5dd7070Spatrick   const StringRef TripleStr = GCCInstallation.getTriple().str();
382e5dd7070Spatrick   const Multilib &Multilib = GCCInstallation.getMultilib();
383e5dd7070Spatrick 
384e5dd7070Spatrick   std::string Path =
385e5dd7070Spatrick       (InstallDir + "/../../../../" + TripleStr + "/libc" + Multilib.osSuffix())
386e5dd7070Spatrick           .str();
387e5dd7070Spatrick 
388e5dd7070Spatrick   if (getVFS().exists(Path))
389e5dd7070Spatrick     return Path;
390e5dd7070Spatrick 
391e5dd7070Spatrick   Path = (InstallDir + "/../../../../sysroot" + Multilib.osSuffix()).str();
392e5dd7070Spatrick 
393e5dd7070Spatrick   if (getVFS().exists(Path))
394e5dd7070Spatrick     return Path;
395e5dd7070Spatrick 
396e5dd7070Spatrick   return std::string();
397e5dd7070Spatrick }
398e5dd7070Spatrick 
getDynamicLinker(const ArgList & Args) const399e5dd7070Spatrick std::string Linux::getDynamicLinker(const ArgList &Args) const {
400e5dd7070Spatrick   const llvm::Triple::ArchType Arch = getArch();
401e5dd7070Spatrick   const llvm::Triple &Triple = getTriple();
402e5dd7070Spatrick 
403e5dd7070Spatrick   const Distro Distro(getDriver().getVFS(), Triple);
404e5dd7070Spatrick 
405e5dd7070Spatrick   if (Triple.isAndroid())
406e5dd7070Spatrick     return Triple.isArch64Bit() ? "/system/bin/linker64" : "/system/bin/linker";
407e5dd7070Spatrick 
408e5dd7070Spatrick   if (Triple.isMusl()) {
409e5dd7070Spatrick     std::string ArchName;
410e5dd7070Spatrick     bool IsArm = false;
411e5dd7070Spatrick 
412e5dd7070Spatrick     switch (Arch) {
413e5dd7070Spatrick     case llvm::Triple::arm:
414e5dd7070Spatrick     case llvm::Triple::thumb:
415e5dd7070Spatrick       ArchName = "arm";
416e5dd7070Spatrick       IsArm = true;
417e5dd7070Spatrick       break;
418e5dd7070Spatrick     case llvm::Triple::armeb:
419e5dd7070Spatrick     case llvm::Triple::thumbeb:
420e5dd7070Spatrick       ArchName = "armeb";
421e5dd7070Spatrick       IsArm = true;
422e5dd7070Spatrick       break;
423a9ac8606Spatrick     case llvm::Triple::x86:
424a9ac8606Spatrick       ArchName = "i386";
425a9ac8606Spatrick       break;
426a9ac8606Spatrick     case llvm::Triple::x86_64:
427a9ac8606Spatrick       ArchName = Triple.isX32() ? "x32" : Triple.getArchName().str();
428a9ac8606Spatrick       break;
429e5dd7070Spatrick     default:
430e5dd7070Spatrick       ArchName = Triple.getArchName().str();
431e5dd7070Spatrick     }
432e5dd7070Spatrick     if (IsArm &&
433e5dd7070Spatrick         (Triple.getEnvironment() == llvm::Triple::MuslEABIHF ||
434e5dd7070Spatrick          tools::arm::getARMFloatABI(*this, Args) == tools::arm::FloatABI::Hard))
435e5dd7070Spatrick       ArchName += "hf";
436*12c85518Srobert     if (Arch == llvm::Triple::ppc &&
437*12c85518Srobert         Triple.getSubArch() == llvm::Triple::PPCSubArch_spe)
438*12c85518Srobert       ArchName = "powerpc-sf";
439e5dd7070Spatrick 
440e5dd7070Spatrick     return "/lib/ld-musl-" + ArchName + ".so.1";
441e5dd7070Spatrick   }
442e5dd7070Spatrick 
443e5dd7070Spatrick   std::string LibDir;
444e5dd7070Spatrick   std::string Loader;
445e5dd7070Spatrick 
446e5dd7070Spatrick   switch (Arch) {
447e5dd7070Spatrick   default:
448e5dd7070Spatrick     llvm_unreachable("unsupported architecture");
449e5dd7070Spatrick 
450e5dd7070Spatrick   case llvm::Triple::aarch64:
451e5dd7070Spatrick     LibDir = "lib";
452e5dd7070Spatrick     Loader = "ld-linux-aarch64.so.1";
453e5dd7070Spatrick     break;
454e5dd7070Spatrick   case llvm::Triple::aarch64_be:
455e5dd7070Spatrick     LibDir = "lib";
456e5dd7070Spatrick     Loader = "ld-linux-aarch64_be.so.1";
457e5dd7070Spatrick     break;
458e5dd7070Spatrick   case llvm::Triple::arm:
459e5dd7070Spatrick   case llvm::Triple::thumb:
460e5dd7070Spatrick   case llvm::Triple::armeb:
461e5dd7070Spatrick   case llvm::Triple::thumbeb: {
462e5dd7070Spatrick     const bool HF =
463e5dd7070Spatrick         Triple.getEnvironment() == llvm::Triple::GNUEABIHF ||
464e5dd7070Spatrick         tools::arm::getARMFloatABI(*this, Args) == tools::arm::FloatABI::Hard;
465e5dd7070Spatrick 
466e5dd7070Spatrick     LibDir = "lib";
467e5dd7070Spatrick     Loader = HF ? "ld-linux-armhf.so.3" : "ld-linux.so.3";
468e5dd7070Spatrick     break;
469e5dd7070Spatrick   }
470*12c85518Srobert   case llvm::Triple::loongarch32: {
471*12c85518Srobert     LibDir = "lib32";
472*12c85518Srobert     Loader =
473*12c85518Srobert         ("ld-linux-loongarch-" +
474*12c85518Srobert          tools::loongarch::getLoongArchABI(getDriver(), Args, Triple) + ".so.1")
475*12c85518Srobert             .str();
476*12c85518Srobert     break;
477*12c85518Srobert   }
478*12c85518Srobert   case llvm::Triple::loongarch64: {
479*12c85518Srobert     LibDir = "lib64";
480*12c85518Srobert     Loader =
481*12c85518Srobert         ("ld-linux-loongarch-" +
482*12c85518Srobert          tools::loongarch::getLoongArchABI(getDriver(), Args, Triple) + ".so.1")
483*12c85518Srobert             .str();
484*12c85518Srobert     break;
485*12c85518Srobert   }
486a9ac8606Spatrick   case llvm::Triple::m68k:
487a9ac8606Spatrick     LibDir = "lib";
488a9ac8606Spatrick     Loader = "ld.so.1";
489a9ac8606Spatrick     break;
490e5dd7070Spatrick   case llvm::Triple::mips:
491e5dd7070Spatrick   case llvm::Triple::mipsel:
492e5dd7070Spatrick   case llvm::Triple::mips64:
493e5dd7070Spatrick   case llvm::Triple::mips64el: {
494*12c85518Srobert     bool IsNaN2008 = tools::mips::isNaN2008(getDriver(), Args, Triple);
495e5dd7070Spatrick 
496e5dd7070Spatrick     LibDir = "lib" + tools::mips::getMipsABILibSuffix(Args, Triple);
497e5dd7070Spatrick 
498e5dd7070Spatrick     if (tools::mips::isUCLibc(Args))
499e5dd7070Spatrick       Loader = IsNaN2008 ? "ld-uClibc-mipsn8.so.0" : "ld-uClibc.so.0";
500e5dd7070Spatrick     else if (!Triple.hasEnvironment() &&
501e5dd7070Spatrick              Triple.getVendor() == llvm::Triple::VendorType::MipsTechnologies)
502e5dd7070Spatrick       Loader =
503e5dd7070Spatrick           Triple.isLittleEndian() ? "ld-musl-mipsel.so.1" : "ld-musl-mips.so.1";
504e5dd7070Spatrick     else
505e5dd7070Spatrick       Loader = IsNaN2008 ? "ld-linux-mipsn8.so.1" : "ld.so.1";
506e5dd7070Spatrick 
507e5dd7070Spatrick     break;
508e5dd7070Spatrick   }
509e5dd7070Spatrick   case llvm::Triple::ppc:
510e5dd7070Spatrick     LibDir = "lib";
511e5dd7070Spatrick     Loader = "ld.so.1";
512e5dd7070Spatrick     break;
513a9ac8606Spatrick   case llvm::Triple::ppcle:
514a9ac8606Spatrick     LibDir = "lib";
515a9ac8606Spatrick     Loader = "ld.so.1";
516a9ac8606Spatrick     break;
517e5dd7070Spatrick   case llvm::Triple::ppc64:
518e5dd7070Spatrick     LibDir = "lib64";
519e5dd7070Spatrick     Loader =
520e5dd7070Spatrick         (tools::ppc::hasPPCAbiArg(Args, "elfv2")) ? "ld64.so.2" : "ld64.so.1";
521e5dd7070Spatrick     break;
522e5dd7070Spatrick   case llvm::Triple::ppc64le:
523e5dd7070Spatrick     LibDir = "lib64";
524e5dd7070Spatrick     Loader =
525e5dd7070Spatrick         (tools::ppc::hasPPCAbiArg(Args, "elfv1")) ? "ld64.so.1" : "ld64.so.2";
526e5dd7070Spatrick     break;
527e5dd7070Spatrick   case llvm::Triple::riscv32: {
528e5dd7070Spatrick     StringRef ABIName = tools::riscv::getRISCVABI(Args, Triple);
529e5dd7070Spatrick     LibDir = "lib";
530e5dd7070Spatrick     Loader = ("ld-linux-riscv32-" + ABIName + ".so.1").str();
531e5dd7070Spatrick     break;
532e5dd7070Spatrick   }
533e5dd7070Spatrick   case llvm::Triple::riscv64: {
534e5dd7070Spatrick     StringRef ABIName = tools::riscv::getRISCVABI(Args, Triple);
535e5dd7070Spatrick     LibDir = "lib";
536e5dd7070Spatrick     Loader = ("ld-linux-riscv64-" + ABIName + ".so.1").str();
537e5dd7070Spatrick     break;
538e5dd7070Spatrick   }
539e5dd7070Spatrick   case llvm::Triple::sparc:
540e5dd7070Spatrick   case llvm::Triple::sparcel:
541e5dd7070Spatrick     LibDir = "lib";
542e5dd7070Spatrick     Loader = "ld-linux.so.2";
543e5dd7070Spatrick     break;
544e5dd7070Spatrick   case llvm::Triple::sparcv9:
545e5dd7070Spatrick     LibDir = "lib64";
546e5dd7070Spatrick     Loader = "ld-linux.so.2";
547e5dd7070Spatrick     break;
548e5dd7070Spatrick   case llvm::Triple::systemz:
549e5dd7070Spatrick     LibDir = "lib";
550e5dd7070Spatrick     Loader = "ld64.so.1";
551e5dd7070Spatrick     break;
552e5dd7070Spatrick   case llvm::Triple::x86:
553e5dd7070Spatrick     LibDir = "lib";
554e5dd7070Spatrick     Loader = "ld-linux.so.2";
555e5dd7070Spatrick     break;
556e5dd7070Spatrick   case llvm::Triple::x86_64: {
557a9ac8606Spatrick     bool X32 = Triple.isX32();
558e5dd7070Spatrick 
559e5dd7070Spatrick     LibDir = X32 ? "libx32" : "lib64";
560e5dd7070Spatrick     Loader = X32 ? "ld-linux-x32.so.2" : "ld-linux-x86-64.so.2";
561e5dd7070Spatrick     break;
562e5dd7070Spatrick   }
563ec727ea7Spatrick   case llvm::Triple::ve:
564ec727ea7Spatrick     return "/opt/nec/ve/lib/ld-linux-ve.so.1";
565*12c85518Srobert   case llvm::Triple::csky: {
566*12c85518Srobert     LibDir = "lib";
567*12c85518Srobert     Loader = "ld.so.1";
568*12c85518Srobert     break;
569*12c85518Srobert   }
570e5dd7070Spatrick   }
571e5dd7070Spatrick 
572e5dd7070Spatrick   if (Distro == Distro::Exherbo &&
573e5dd7070Spatrick       (Triple.getVendor() == llvm::Triple::UnknownVendor ||
574e5dd7070Spatrick        Triple.getVendor() == llvm::Triple::PC))
575e5dd7070Spatrick     return "/usr/" + Triple.str() + "/lib/" + Loader;
576e5dd7070Spatrick   return "/" + LibDir + "/" + Loader;
577e5dd7070Spatrick }
578e5dd7070Spatrick 
AddClangSystemIncludeArgs(const ArgList & DriverArgs,ArgStringList & CC1Args) const579e5dd7070Spatrick void Linux::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
580e5dd7070Spatrick                                       ArgStringList &CC1Args) const {
581e5dd7070Spatrick   const Driver &D = getDriver();
582e5dd7070Spatrick   std::string SysRoot = computeSysRoot();
583e5dd7070Spatrick 
584e5dd7070Spatrick   if (DriverArgs.hasArg(clang::driver::options::OPT_nostdinc))
585e5dd7070Spatrick     return;
586e5dd7070Spatrick 
587a9ac8606Spatrick   // Add 'include' in the resource directory, which is similar to
588a9ac8606Spatrick   // GCC_INCLUDE_DIR (private headers) in GCC. Note: the include directory
589a9ac8606Spatrick   // contains some files conflicting with system /usr/include. musl systems
590a9ac8606Spatrick   // prefer the /usr/include copies which are more relevant.
591e5dd7070Spatrick   SmallString<128> ResourceDirInclude(D.ResourceDir);
592e5dd7070Spatrick   llvm::sys::path::append(ResourceDirInclude, "include");
593e5dd7070Spatrick   if (!DriverArgs.hasArg(options::OPT_nobuiltininc) &&
594e5dd7070Spatrick       (!getTriple().isMusl() || DriverArgs.hasArg(options::OPT_nostdlibinc)))
595e5dd7070Spatrick     addSystemInclude(DriverArgs, CC1Args, ResourceDirInclude);
596e5dd7070Spatrick 
597e5dd7070Spatrick   if (DriverArgs.hasArg(options::OPT_nostdlibinc))
598e5dd7070Spatrick     return;
599e5dd7070Spatrick 
600a9ac8606Spatrick   // LOCAL_INCLUDE_DIR
601*12c85518Srobert   addSystemInclude(DriverArgs, CC1Args, concat(SysRoot, "/usr/local/include"));
602a9ac8606Spatrick   // TOOL_INCLUDE_DIR
603a9ac8606Spatrick   AddMultilibIncludeArgs(DriverArgs, CC1Args);
604a9ac8606Spatrick 
605e5dd7070Spatrick   // Check for configure-time C include directories.
606e5dd7070Spatrick   StringRef CIncludeDirs(C_INCLUDE_DIRS);
607e5dd7070Spatrick   if (CIncludeDirs != "") {
608e5dd7070Spatrick     SmallVector<StringRef, 5> dirs;
609e5dd7070Spatrick     CIncludeDirs.split(dirs, ":");
610e5dd7070Spatrick     for (StringRef dir : dirs) {
611e5dd7070Spatrick       StringRef Prefix =
612ec727ea7Spatrick           llvm::sys::path::is_absolute(dir) ? "" : StringRef(SysRoot);
613e5dd7070Spatrick       addExternCSystemInclude(DriverArgs, CC1Args, Prefix + dir);
614e5dd7070Spatrick     }
615e5dd7070Spatrick     return;
616e5dd7070Spatrick   }
617e5dd7070Spatrick 
618a9ac8606Spatrick   // On systems using multiarch and Android, add /usr/include/$triple before
619a9ac8606Spatrick   // /usr/include.
620a9ac8606Spatrick   std::string MultiarchIncludeDir = getMultiarchTriple(D, getTriple(), SysRoot);
621a9ac8606Spatrick   if (!MultiarchIncludeDir.empty() &&
622*12c85518Srobert       D.getVFS().exists(concat(SysRoot, "/usr/include", MultiarchIncludeDir)))
623*12c85518Srobert     addExternCSystemInclude(
624*12c85518Srobert         DriverArgs, CC1Args,
625*12c85518Srobert         concat(SysRoot, "/usr/include", MultiarchIncludeDir));
626e5dd7070Spatrick 
627e5dd7070Spatrick   if (getTriple().getOS() == llvm::Triple::RTEMS)
628e5dd7070Spatrick     return;
629e5dd7070Spatrick 
630e5dd7070Spatrick   // Add an include of '/include' directly. This isn't provided by default by
631e5dd7070Spatrick   // system GCCs, but is often used with cross-compiling GCCs, and harmless to
632e5dd7070Spatrick   // add even when Clang is acting as-if it were a system compiler.
633*12c85518Srobert   addExternCSystemInclude(DriverArgs, CC1Args, concat(SysRoot, "/include"));
634e5dd7070Spatrick 
635*12c85518Srobert   addExternCSystemInclude(DriverArgs, CC1Args, concat(SysRoot, "/usr/include"));
636e5dd7070Spatrick 
637e5dd7070Spatrick   if (!DriverArgs.hasArg(options::OPT_nobuiltininc) && getTriple().isMusl())
638e5dd7070Spatrick     addSystemInclude(DriverArgs, CC1Args, ResourceDirInclude);
639e5dd7070Spatrick }
640e5dd7070Spatrick 
addLibStdCxxIncludePaths(const llvm::opt::ArgList & DriverArgs,llvm::opt::ArgStringList & CC1Args) const641e5dd7070Spatrick void Linux::addLibStdCxxIncludePaths(const llvm::opt::ArgList &DriverArgs,
642e5dd7070Spatrick                                      llvm::opt::ArgStringList &CC1Args) const {
643e5dd7070Spatrick   // We need a detected GCC installation on Linux to provide libstdc++'s
644e5dd7070Spatrick   // headers in odd Linuxish places.
645e5dd7070Spatrick   if (!GCCInstallation.isValid())
646e5dd7070Spatrick     return;
647e5dd7070Spatrick 
648a9ac8606Spatrick   // Detect Debian g++-multiarch-incdir.diff.
649e5dd7070Spatrick   StringRef TripleStr = GCCInstallation.getTriple().str();
650a9ac8606Spatrick   StringRef DebianMultiarch =
651a9ac8606Spatrick       GCCInstallation.getTriple().getArch() == llvm::Triple::x86
652a9ac8606Spatrick           ? "i386-linux-gnu"
653a9ac8606Spatrick           : TripleStr;
654a9ac8606Spatrick 
655a9ac8606Spatrick   // Try generic GCC detection first.
656a9ac8606Spatrick   if (Generic_GCC::addGCCLibStdCxxIncludePaths(DriverArgs, CC1Args,
657a9ac8606Spatrick                                                DebianMultiarch))
658a9ac8606Spatrick     return;
659a9ac8606Spatrick 
660a9ac8606Spatrick   StringRef LibDir = GCCInstallation.getParentLibPath();
661e5dd7070Spatrick   const Multilib &Multilib = GCCInstallation.getMultilib();
662e5dd7070Spatrick   const GCCVersion &Version = GCCInstallation.getVersion();
663e5dd7070Spatrick 
664e5dd7070Spatrick   const std::string LibStdCXXIncludePathCandidates[] = {
665e5dd7070Spatrick       // Android standalone toolchain has C++ headers in yet another place.
666e5dd7070Spatrick       LibDir.str() + "/../" + TripleStr.str() + "/include/c++/" + Version.Text,
667e5dd7070Spatrick       // Freescale SDK C++ headers are directly in <sysroot>/usr/include/c++,
668e5dd7070Spatrick       // without a subdirectory corresponding to the gcc version.
669e5dd7070Spatrick       LibDir.str() + "/../include/c++",
670e5dd7070Spatrick       // Cray's gcc installation puts headers under "g++" without a
671e5dd7070Spatrick       // version suffix.
672e5dd7070Spatrick       LibDir.str() + "/../include/g++",
673e5dd7070Spatrick   };
674e5dd7070Spatrick 
675e5dd7070Spatrick   for (const auto &IncludePath : LibStdCXXIncludePathCandidates) {
676a9ac8606Spatrick     if (addLibStdCXXIncludePaths(IncludePath, TripleStr,
677e5dd7070Spatrick                                  Multilib.includeSuffix(), DriverArgs, CC1Args))
678e5dd7070Spatrick       break;
679e5dd7070Spatrick   }
680e5dd7070Spatrick }
681e5dd7070Spatrick 
AddCudaIncludeArgs(const ArgList & DriverArgs,ArgStringList & CC1Args) const682e5dd7070Spatrick void Linux::AddCudaIncludeArgs(const ArgList &DriverArgs,
683e5dd7070Spatrick                                ArgStringList &CC1Args) const {
684e5dd7070Spatrick   CudaInstallation.AddCudaIncludeArgs(DriverArgs, CC1Args);
685e5dd7070Spatrick }
686e5dd7070Spatrick 
AddHIPIncludeArgs(const ArgList & DriverArgs,ArgStringList & CC1Args) const687ec727ea7Spatrick void Linux::AddHIPIncludeArgs(const ArgList &DriverArgs,
688ec727ea7Spatrick                               ArgStringList &CC1Args) const {
689ec727ea7Spatrick   RocmInstallation.AddHIPIncludeArgs(DriverArgs, CC1Args);
690ec727ea7Spatrick }
691ec727ea7Spatrick 
AddHIPRuntimeLibArgs(const ArgList & Args,ArgStringList & CmdArgs) const692*12c85518Srobert void Linux::AddHIPRuntimeLibArgs(const ArgList &Args,
693*12c85518Srobert                                  ArgStringList &CmdArgs) const {
694*12c85518Srobert   CmdArgs.push_back(
695*12c85518Srobert       Args.MakeArgString(StringRef("-L") + RocmInstallation.getLibPath()));
696*12c85518Srobert 
697*12c85518Srobert   if (Args.hasFlag(options::OPT_offload_add_rpath,
698*12c85518Srobert                    options::OPT_no_offload_add_rpath, false))
699*12c85518Srobert     CmdArgs.append(
700*12c85518Srobert         {"-rpath", Args.MakeArgString(RocmInstallation.getLibPath())});
701*12c85518Srobert 
702*12c85518Srobert   CmdArgs.push_back("-lamdhip64");
703*12c85518Srobert }
704*12c85518Srobert 
AddIAMCUIncludeArgs(const ArgList & DriverArgs,ArgStringList & CC1Args) const705e5dd7070Spatrick void Linux::AddIAMCUIncludeArgs(const ArgList &DriverArgs,
706e5dd7070Spatrick                                 ArgStringList &CC1Args) const {
707e5dd7070Spatrick   if (GCCInstallation.isValid()) {
708e5dd7070Spatrick     CC1Args.push_back("-isystem");
709e5dd7070Spatrick     CC1Args.push_back(DriverArgs.MakeArgString(
710e5dd7070Spatrick         GCCInstallation.getParentLibPath() + "/../" +
711e5dd7070Spatrick         GCCInstallation.getTriple().str() + "/include"));
712e5dd7070Spatrick   }
713e5dd7070Spatrick }
714e5dd7070Spatrick 
isPIEDefault(const llvm::opt::ArgList & Args) const715*12c85518Srobert bool Linux::isPIEDefault(const llvm::opt::ArgList &Args) const {
716*12c85518Srobert   return CLANG_DEFAULT_PIE_ON_LINUX || getTriple().isAndroid() ||
717*12c85518Srobert          getTriple().isMusl() || getSanitizerArgs(Args).requiresPIE();
718e5dd7070Spatrick }
719e5dd7070Spatrick 
IsAArch64OutlineAtomicsDefault(const ArgList & Args) const720a9ac8606Spatrick bool Linux::IsAArch64OutlineAtomicsDefault(const ArgList &Args) const {
721a9ac8606Spatrick   // Outline atomics for AArch64 are supported by compiler-rt
722a9ac8606Spatrick   // and libgcc since 9.3.1
723a9ac8606Spatrick   assert(getTriple().isAArch64() && "expected AArch64 target!");
724a9ac8606Spatrick   ToolChain::RuntimeLibType RtLib = GetRuntimeLibType(Args);
725a9ac8606Spatrick   if (RtLib == ToolChain::RLT_CompilerRT)
726a9ac8606Spatrick     return true;
727a9ac8606Spatrick   assert(RtLib == ToolChain::RLT_Libgcc && "unexpected runtime library type!");
728a9ac8606Spatrick   if (GCCInstallation.getVersion().isOlderThan(9, 3, 1))
729a9ac8606Spatrick     return false;
730a9ac8606Spatrick   return true;
731a9ac8606Spatrick }
732a9ac8606Spatrick 
IsMathErrnoDefault() const733e5dd7070Spatrick bool Linux::IsMathErrnoDefault() const {
734*12c85518Srobert   if (getTriple().isAndroid() || getTriple().isMusl())
735e5dd7070Spatrick     return false;
736e5dd7070Spatrick   return Generic_ELF::IsMathErrnoDefault();
737e5dd7070Spatrick }
738e5dd7070Spatrick 
getSupportedSanitizers() const739e5dd7070Spatrick SanitizerMask Linux::getSupportedSanitizers() const {
740e5dd7070Spatrick   const bool IsX86 = getTriple().getArch() == llvm::Triple::x86;
741e5dd7070Spatrick   const bool IsX86_64 = getTriple().getArch() == llvm::Triple::x86_64;
742e5dd7070Spatrick   const bool IsMIPS = getTriple().isMIPS32();
743e5dd7070Spatrick   const bool IsMIPS64 = getTriple().isMIPS64();
744e5dd7070Spatrick   const bool IsPowerPC64 = getTriple().getArch() == llvm::Triple::ppc64 ||
745e5dd7070Spatrick                            getTriple().getArch() == llvm::Triple::ppc64le;
746e5dd7070Spatrick   const bool IsAArch64 = getTriple().getArch() == llvm::Triple::aarch64 ||
747e5dd7070Spatrick                          getTriple().getArch() == llvm::Triple::aarch64_be;
748e5dd7070Spatrick   const bool IsArmArch = getTriple().getArch() == llvm::Triple::arm ||
749e5dd7070Spatrick                          getTriple().getArch() == llvm::Triple::thumb ||
750e5dd7070Spatrick                          getTriple().getArch() == llvm::Triple::armeb ||
751e5dd7070Spatrick                          getTriple().getArch() == llvm::Triple::thumbeb;
752*12c85518Srobert   const bool IsLoongArch64 = getTriple().getArch() == llvm::Triple::loongarch64;
753a9ac8606Spatrick   const bool IsRISCV64 = getTriple().getArch() == llvm::Triple::riscv64;
754ec727ea7Spatrick   const bool IsSystemZ = getTriple().getArch() == llvm::Triple::systemz;
755*12c85518Srobert   const bool IsHexagon = getTriple().getArch() == llvm::Triple::hexagon;
756e5dd7070Spatrick   SanitizerMask Res = ToolChain::getSupportedSanitizers();
757e5dd7070Spatrick   Res |= SanitizerKind::Address;
758e5dd7070Spatrick   Res |= SanitizerKind::PointerCompare;
759e5dd7070Spatrick   Res |= SanitizerKind::PointerSubtract;
760e5dd7070Spatrick   Res |= SanitizerKind::Fuzzer;
761e5dd7070Spatrick   Res |= SanitizerKind::FuzzerNoLink;
762e5dd7070Spatrick   Res |= SanitizerKind::KernelAddress;
763e5dd7070Spatrick   Res |= SanitizerKind::Memory;
764e5dd7070Spatrick   Res |= SanitizerKind::Vptr;
765e5dd7070Spatrick   Res |= SanitizerKind::SafeStack;
766e5dd7070Spatrick   if (IsX86_64 || IsMIPS64 || IsAArch64)
767e5dd7070Spatrick     Res |= SanitizerKind::DataFlow;
768ec727ea7Spatrick   if (IsX86_64 || IsMIPS64 || IsAArch64 || IsX86 || IsArmArch || IsPowerPC64 ||
769*12c85518Srobert       IsRISCV64 || IsSystemZ || IsHexagon || IsLoongArch64)
770e5dd7070Spatrick     Res |= SanitizerKind::Leak;
771*12c85518Srobert   if (IsX86_64 || IsMIPS64 || IsAArch64 || IsPowerPC64 || IsSystemZ ||
772*12c85518Srobert       IsLoongArch64)
773e5dd7070Spatrick     Res |= SanitizerKind::Thread;
774e5dd7070Spatrick   if (IsX86_64)
775e5dd7070Spatrick     Res |= SanitizerKind::KernelMemory;
776e5dd7070Spatrick   if (IsX86 || IsX86_64)
777e5dd7070Spatrick     Res |= SanitizerKind::Function;
778e5dd7070Spatrick   if (IsX86_64 || IsMIPS64 || IsAArch64 || IsX86 || IsMIPS || IsArmArch ||
779*12c85518Srobert       IsPowerPC64 || IsHexagon || IsLoongArch64)
780e5dd7070Spatrick     Res |= SanitizerKind::Scudo;
781*12c85518Srobert   if (IsX86_64 || IsAArch64 || IsRISCV64) {
782e5dd7070Spatrick     Res |= SanitizerKind::HWAddress;
783*12c85518Srobert   }
784*12c85518Srobert   if (IsX86_64 || IsAArch64) {
785e5dd7070Spatrick     Res |= SanitizerKind::KernelHWAddress;
786e5dd7070Spatrick   }
787e5dd7070Spatrick   return Res;
788e5dd7070Spatrick }
789e5dd7070Spatrick 
addProfileRTLibs(const llvm::opt::ArgList & Args,llvm::opt::ArgStringList & CmdArgs) const790e5dd7070Spatrick void Linux::addProfileRTLibs(const llvm::opt::ArgList &Args,
791e5dd7070Spatrick                              llvm::opt::ArgStringList &CmdArgs) const {
792ec727ea7Spatrick   // Add linker option -u__llvm_profile_runtime to cause runtime
793e5dd7070Spatrick   // initialization module to be linked in.
794ec727ea7Spatrick   if (needsProfileRT(Args))
795e5dd7070Spatrick     CmdArgs.push_back(Args.MakeArgString(
796e5dd7070Spatrick         Twine("-u", llvm::getInstrProfRuntimeHookVarName())));
797e5dd7070Spatrick   ToolChain::addProfileRTLibs(Args, CmdArgs);
798e5dd7070Spatrick }
799389bb291Spatrick 
800ec727ea7Spatrick llvm::DenormalMode
getDefaultDenormalModeForType(const llvm::opt::ArgList & DriverArgs,const JobAction & JA,const llvm::fltSemantics * FPType) const801ec727ea7Spatrick Linux::getDefaultDenormalModeForType(const llvm::opt::ArgList &DriverArgs,
802ec727ea7Spatrick                                      const JobAction &JA,
803ec727ea7Spatrick                                      const llvm::fltSemantics *FPType) const {
804ec727ea7Spatrick   switch (getTriple().getArch()) {
805ec727ea7Spatrick   case llvm::Triple::x86:
806ec727ea7Spatrick   case llvm::Triple::x86_64: {
807ec727ea7Spatrick     std::string Unused;
808ec727ea7Spatrick     // DAZ and FTZ are turned on in crtfastmath.o
809ec727ea7Spatrick     if (!DriverArgs.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles) &&
810ec727ea7Spatrick         isFastMathRuntimeAvailable(DriverArgs, Unused))
811ec727ea7Spatrick       return llvm::DenormalMode::getPreserveSign();
812ec727ea7Spatrick     return llvm::DenormalMode::getIEEE();
813ec727ea7Spatrick   }
814ec727ea7Spatrick   default:
815ec727ea7Spatrick     return llvm::DenormalMode::getIEEE();
816ec727ea7Spatrick   }
817ec727ea7Spatrick }
818ec727ea7Spatrick 
addExtraOpts(llvm::opt::ArgStringList & CmdArgs) const819389bb291Spatrick void Linux::addExtraOpts(llvm::opt::ArgStringList &CmdArgs) const {
820389bb291Spatrick   for (const auto &Opt : ExtraOpts)
821389bb291Spatrick     CmdArgs.push_back(Opt.c_str());
822389bb291Spatrick }
823*12c85518Srobert 
getDefaultLinker() const824*12c85518Srobert const char *Linux::getDefaultLinker() const {
825*12c85518Srobert   if (getTriple().isAndroid())
826*12c85518Srobert     return "ld.lld";
827*12c85518Srobert   return Generic_ELF::getDefaultLinker();
828*12c85518Srobert }
829