Coverage Report

Created: 2024-01-17 10:31

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