clang: lib/Driver/ToolChains/Linux.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

16#include "clang/Config/config.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

30using namespace clang;

32

34

35

36

37

38

39

40

42 const llvm::Triple &TargetTriple,

43 StringRef SysRoot) const {

44 llvm::Triple::EnvironmentType TargetEnvironment =

45 TargetTriple.getEnvironment();

46 bool IsAndroid = TargetTriple.isAndroid();

47 bool IsMipsR6 = TargetTriple.getSubArch() == llvm::Triple::MipsSubArch_r6;

48 bool IsMipsN32Abi = TargetTriple.getEnvironment() == llvm::Triple::GNUABIN32;

49

50

51

52 switch (TargetTriple.getArch()) {

53 default:

54 break;

55

56

57

58

59

60 case llvm::Triple::arm:

61 case llvm::Triple::thumb:

62 if (IsAndroid)

63 return "arm-linux-androideabi";

64 if (TargetEnvironment == llvm::Triple::GNUEABIHF ||

65 TargetEnvironment == llvm::Triple::MuslEABIHF ||

66 TargetEnvironment == llvm::Triple::EABIHF)

67 return "arm-linux-gnueabihf";

68 return "arm-linux-gnueabi";

69 case llvm::Triple::armeb:

70 case llvm::Triple::thumbeb:

71 if (TargetEnvironment == llvm::Triple::GNUEABIHF ||

72 TargetEnvironment == llvm::Triple::MuslEABIHF ||

73 TargetEnvironment == llvm::Triple::EABIHF)

74 return "armeb-linux-gnueabihf";

75 return "armeb-linux-gnueabi";

76 case llvm::Triple::x86:

77 if (IsAndroid)

78 return "i686-linux-android";

79 return "i386-linux-gnu";

80 case llvm::Triple::x86_64:

81 if (IsAndroid)

82 return "x86_64-linux-android";

83 if (TargetEnvironment == llvm::Triple::GNUX32)

84 return "x86_64-linux-gnux32";

85 return "x86_64-linux-gnu";

86 case llvm::Triple::aarch64:

87 if (IsAndroid)

88 return "aarch64-linux-android";

91 return "aarch64-linux-pauthtest";

92 return "aarch64-linux-gnu";

93 case llvm::Triple::aarch64_be:

94 return "aarch64_be-linux-gnu";

95

96 case llvm::Triple::loongarch64: {

97 const char *Libc;

98 const char *FPFlavor;

99

100 if (TargetTriple.isGNUEnvironment()) {

101 Libc = "gnu";

102 } else if (TargetTriple.isMusl()) {

103 Libc = "musl";

104 } else {

105 return TargetTriple.str();

106 }

107

108 switch (TargetEnvironment) {

109 default:

110 return TargetTriple.str();

111 case llvm::Triple::GNUSF:

112 case llvm::Triple::MuslSF:

113 FPFlavor = "sf";

114 break;

115 case llvm::Triple::GNUF32:

116 case llvm::Triple::MuslF32:

117 FPFlavor = "f32";

118 break;

119 case llvm::Triple::GNU:

120 case llvm::Triple::GNUF64:

121 case llvm::Triple::Musl:

122

123

124

125 FPFlavor = "";

126 break;

127 }

128

129 return (Twine("loongarch64-linux-") + Libc + FPFlavor).str();

130 }

131

132 case llvm::Triple::m68k:

133 return "m68k-linux-gnu";

134

135 case llvm::Triple::mips:

136 return IsMipsR6 ? "mipsisa32r6-linux-gnu" : "mips-linux-gnu";

137 case llvm::Triple::mipsel:

138 return IsMipsR6 ? "mipsisa32r6el-linux-gnu" : "mipsel-linux-gnu";

139 case llvm::Triple::mips64: {

140 std::string MT = std::string(IsMipsR6 ? "mipsisa64r6" : "mips64") +

141 "-linux-" + (IsMipsN32Abi ? "gnuabin32" : "gnuabi64");

142 if (D.getVFS().exists(concat(SysRoot, "/lib", MT)))

143 return MT;

144 if (D.getVFS().exists(concat(SysRoot, "/lib/mips64-linux-gnu")))

145 return "mips64-linux-gnu";

146 break;

147 }

148 case llvm::Triple::mips64el: {

149 std::string MT = std::string(IsMipsR6 ? "mipsisa64r6el" : "mips64el") +

150 "-linux-" + (IsMipsN32Abi ? "gnuabin32" : "gnuabi64");

151 if (D.getVFS().exists(concat(SysRoot, "/lib", MT)))

152 return MT;

153 if (D.getVFS().exists(concat(SysRoot, "/lib/mips64el-linux-gnu")))

154 return "mips64el-linux-gnu";

155 break;

156 }

157 case llvm::Triple::ppc:

158 if (D.getVFS().exists(concat(SysRoot, "/lib/powerpc-linux-gnuspe")))

159 return "powerpc-linux-gnuspe";

160 return "powerpc-linux-gnu";

161 case llvm::Triple::ppcle:

162 return "powerpcle-linux-gnu";

163 case llvm::Triple::ppc64:

164 return "powerpc64-linux-gnu";

165 case llvm::Triple::ppc64le:

166 return "powerpc64le-linux-gnu";

167 case llvm::Triple::riscv64:

168 if (IsAndroid)

169 return "riscv64-linux-android";

170 return "riscv64-linux-gnu";

171 case llvm::Triple::sparc:

172 return "sparc-linux-gnu";

173 case llvm::Triple::sparcv9:

174 return "sparc64-linux-gnu";

175 case llvm::Triple::systemz:

176 return "s390x-linux-gnu";

177 }

178 return TargetTriple.str();

179}

180

181static StringRef getOSLibDir(const llvm::Triple &Triple, const ArgList &Args) {

182 if (Triple.isMIPS()) {

183

184

185

187 return "lib32";

188 return Triple.isArch32Bit() ? "lib" : "lib64";

189 }

190

191

192

193

194

195

196

197

198

199

200 if (Triple.getArch() == llvm::Triple::x86 || Triple.isPPC32() ||

201 Triple.getArch() == llvm::Triple::sparc)

202 return "lib32";

203

204 if (Triple.getArch() == llvm::Triple::x86_64 && Triple.isX32())

205 return "libx32";

206

207 if (Triple.getArch() == llvm::Triple::riscv32)

208 return "lib32";

209

210 return Triple.isArch32Bit() ? "lib" : "lib64";

211}

212

218 llvm::Triple::ArchType Arch = Triple.getArch();

221

223

225

229 }

230

232 Triple.isAndroid()) {

235 }

236

237

238

239 if (Triple.isAndroid()) {

240 if (Triple.isARM()) {

241

243 ExtraOpts.push_back("max-page-size=4096");

244 } else if (Triple.isAArch64() || Triple.getArch() == llvm::Triple::x86_64) {

245

246

248 ExtraOpts.push_back("max-page-size=16384");

249 }

250 if (Triple.isAndroidVersionLT(29)) {

251

252

253

254

255

256 ExtraOpts.push_back("--no-rosegment");

257 }

258 if (!Triple.isAndroidVersionLT(28)) {

259

260

261

262

263

264

265 ExtraOpts.push_back("--use-android-relr-tags");

266 ExtraOpts.push_back("--pack-dyn-relocs=relr");

267 }

268 }

269

271

272

273

274

276 "/../bin").str());

277

278 if (Arch == llvm::Triple::arm || Arch == llvm::Triple::thumb)

280

281 const bool IsAndroid = Triple.isAndroid();

282 const bool IsMips = Triple.isMIPS();

283 const bool IsHexagon = Arch == llvm::Triple::hexagon;

284 const bool IsRISCV = Triple.isRISCV();

285 const bool IsCSKY = Triple.isCSKY();

286

289

290 if ((IsMips || IsCSKY) && !SysRoot.empty())

291 ExtraOpts.push_back("--sysroot=" + SysRoot);

292

293

294

295

296

297

298

299 if (!IsMips && !IsHexagon) {

302 (IsAndroid && Triple.isAndroidVersionLT(23)))

303 ExtraOpts.push_back("--hash-style=both");

304 else

305 ExtraOpts.push_back("--hash-style=gnu");

306 }

307

308#ifdef ENABLE_LINKER_BUILD_ID

309 ExtraOpts.push_back("--build-id");

310#endif

311

312

313

314

315

316

318

319 const std::string OSLibDir = std::string(getOSLibDir(Triple, Args));

320 const std::string MultiarchTriple = getMultiarchTriple(D, Triple, SysRoot);

321

322

323

324 if (Arch == llvm::Triple::mips || Arch == llvm::Triple::mipsel) {

326 addPathIfExists(D, concat(SysRoot, "/libo32"), Paths);

327 addPathIfExists(D, concat(SysRoot, "/usr/libo32"), Paths);

328 }

330

331 addPathIfExists(D, concat(SysRoot, "/lib", MultiarchTriple), Paths);

332 addPathIfExists(D, concat(SysRoot, "/lib/..", OSLibDir), Paths);

333

334 if (IsAndroid) {

335

336

337

338 addPathIfExists(

339 D,

340 concat(SysRoot, "/usr/lib", MultiarchTriple,

341 llvm::to_string(Triple.getEnvironmentVersion().getMajor())),

342 Paths);

343 }

344

345 addPathIfExists(D, concat(SysRoot, "/usr/lib", MultiarchTriple), Paths);

346

347

348

349 if (Triple.getVendor() == llvm::Triple::OpenEmbedded &&

350 Triple.isArch64Bit())

351 addPathIfExists(D, concat(SysRoot, "/usr", OSLibDir), Paths);

352 else

353 addPathIfExists(D, concat(SysRoot, "/usr/lib/..", OSLibDir), Paths);

354 if (IsRISCV) {

356 addPathIfExists(D, concat(SysRoot, "/", OSLibDir, ABIName), Paths);

357 addPathIfExists(D, concat(SysRoot, "/usr", OSLibDir, ABIName), Paths);

358 }

359

361

362 addPathIfExists(D, concat(SysRoot, "/lib"), Paths);

363 addPathIfExists(D, concat(SysRoot, "/usr/lib"), Paths);

364}

365

370}

371

374 return 4;

376}

377

382}

383

385

387

390}

391

394}

395

397 if (getDriver().SysRoot.empty())

399

401

402

404 std::string AndroidSysRootPath = (ClangDir + "/../sysroot").str();

405 if (getVFS().exists(AndroidSysRootPath))

406 return AndroidSysRootPath;

407 }

408

410

412 return std::string();

413

414

415

418 .str();

421 return std::string();

422 }

423

425 return std::string();

426

427

428

429

430

434

435 std::string Path =

436 (InstallDir + "/../../../../" + TripleStr + "/libc" + Multilib.osSuffix())

437 .str();

438

441

443

446

447 return std::string();

448}

449

451 const llvm::Triple::ArchType Arch = getArch();

452 const llvm::Triple &Triple = getTriple();

453

455

456 if (Triple.isAndroid()) {

458 !Triple.isAndroidVersionLT(34) && Triple.isArch64Bit()) {

459

460

461

462

463 return "/system/bin/linker_hwasan64";

464 }

465 return Triple.isArch64Bit() ? "/system/bin/linker64" : "/system/bin/linker";

466 }

467 if (Triple.isMusl()) {

468 std::string ArchName;

469 bool IsArm = false;

470

471 switch (Arch) {

472 case llvm::Triple::arm:

473 case llvm::Triple::thumb:

474 ArchName = "arm";

475 IsArm = true;

476 break;

477 case llvm::Triple::armeb:

478 case llvm::Triple::thumbeb:

479 ArchName = "armeb";

480 IsArm = true;

481 break;

482 case llvm::Triple::x86:

483 ArchName = "i386";

484 break;

485 case llvm::Triple::x86_64:

486 ArchName = Triple.isX32() ? "x32" : Triple.getArchName().str();

487 break;

488 default:

489 ArchName = Triple.getArchName().str();

490 }

491 if (IsArm &&

492 (Triple.getEnvironment() == llvm::Triple::MuslEABIHF ||

494 ArchName += "hf";

495 if (Arch == llvm::Triple::ppc &&

496 Triple.getSubArch() == llvm::Triple::PPCSubArch_spe)

497 ArchName = "powerpc-sf";

498

499 return "/lib/ld-musl-" + ArchName + ".so.1";

500 }

501

502 std::string LibDir;

503 std::string Loader;

504

505 switch (Arch) {

506 default:

507 llvm_unreachable("unsupported architecture");

508

509 case llvm::Triple::aarch64:

510 LibDir = "lib";

511 Loader = "ld-linux-aarch64.so.1";

512 break;

513 case llvm::Triple::aarch64_be:

514 LibDir = "lib";

515 Loader = "ld-linux-aarch64_be.so.1";

516 break;

517 case llvm::Triple::arm:

518 case llvm::Triple::thumb:

519 case llvm::Triple::armeb:

520 case llvm::Triple::thumbeb: {

521 const bool HF =

522 Triple.getEnvironment() == llvm::Triple::GNUEABIHF ||

523 Triple.getEnvironment() == llvm::Triple::GNUEABIHFT64 ||

525

526 LibDir = "lib";

527 Loader = HF ? "ld-linux-armhf.so.3" : "ld-linux.so.3";

528 break;

529 }

530 case llvm::Triple::loongarch32: {

531 LibDir = "lib32";

532 Loader =

533 ("ld-linux-loongarch-" +

535 .str();

536 break;

537 }

538 case llvm::Triple::loongarch64: {

539 LibDir = "lib64";

540 Loader =

541 ("ld-linux-loongarch-" +

543 .str();

544 break;

545 }

546 case llvm::Triple::m68k:

547 LibDir = "lib";

548 Loader = "ld.so.1";

549 break;

550 case llvm::Triple::mips:

551 case llvm::Triple::mipsel:

552 case llvm::Triple::mips64:

553 case llvm::Triple::mips64el: {

555

557

559 Loader = IsNaN2008 ? "ld-uClibc-mipsn8.so.0" : "ld-uClibc.so.0";

560 else if (!Triple.hasEnvironment() &&

561 Triple.getVendor() == llvm::Triple::VendorType::MipsTechnologies)

562 Loader =

563 Triple.isLittleEndian() ? "ld-musl-mipsel.so.1" : "ld-musl-mips.so.1";

564 else

565 Loader = IsNaN2008 ? "ld-linux-mipsn8.so.1" : "ld.so.1";

566

567 break;

568 }

569 case llvm::Triple::ppc:

570 LibDir = "lib";

571 Loader = "ld.so.1";

572 break;

573 case llvm::Triple::ppcle:

574 LibDir = "lib";

575 Loader = "ld.so.1";

576 break;

577 case llvm::Triple::ppc64:

578 LibDir = "lib64";

579 Loader =

581 break;

582 case llvm::Triple::ppc64le:

583 LibDir = "lib64";

584 Loader =

586 break;

587 case llvm::Triple::riscv32:

588 case llvm::Triple::riscv64: {

589 StringRef ArchName = llvm::Triple::getArchTypeName(Arch);

591 LibDir = "lib";

592 Loader = ("ld-linux-" + ArchName + "-" + ABIName + ".so.1").str();

593 break;

594 }

595 case llvm::Triple::sparc:

596 case llvm::Triple::sparcel:

597 LibDir = "lib";

598 Loader = "ld-linux.so.2";

599 break;

600 case llvm::Triple::sparcv9:

601 LibDir = "lib64";

602 Loader = "ld-linux.so.2";

603 break;

604 case llvm::Triple::systemz:

605 LibDir = "lib";

606 Loader = "ld64.so.1";

607 break;

608 case llvm::Triple::x86:

609 LibDir = "lib";

610 Loader = "ld-linux.so.2";

611 break;

612 case llvm::Triple::x86_64: {

613 bool X32 = Triple.isX32();

614

615 LibDir = X32 ? "libx32" : "lib64";

616 Loader = X32 ? "ld-linux-x32.so.2" : "ld-linux-x86-64.so.2";

617 break;

618 }

619 case llvm::Triple::ve:

620 return "/opt/nec/ve/lib/ld-linux-ve.so.1";

621 case llvm::Triple::csky: {

622 LibDir = "lib";

623 Loader = "ld.so.1";

624 break;

625 }

626 }

627

629 (Triple.getVendor() == llvm::Triple::UnknownVendor ||

630 Triple.getVendor() == llvm::Triple::PC))

631 return "/usr/" + Triple.str() + "/lib/" + Loader;

632 return "/" + LibDir + "/" + Loader;

633}

634

636 ArgStringList &CC1Args) const {

639

640 if (DriverArgs.hasArg(clang::driver::options::OPT_nostdinc))

641 return;

642

643

644

645

646

648 llvm::sys::path::append(ResourceDirInclude, "include");

649 if (!DriverArgs.hasArg(options::OPT_nobuiltininc) &&

650 (getTriple().isMusl() || DriverArgs.hasArg(options::OPT_nostdlibinc)))

652

653 if (DriverArgs.hasArg(options::OPT_nostdlibinc))

654 return;

655

656

658

660

661

662 StringRef CIncludeDirs(C_INCLUDE_DIRS);

663 if (CIncludeDirs != "") {

665 CIncludeDirs.split(dirs, ":");

666 for (StringRef dir : dirs) {

667 StringRef Prefix =

668 llvm::sys::path::is_absolute(dir) ? "" : StringRef(SysRoot);

670 }

671 return;

672 }

673

674

675

677 if (!MultiarchIncludeDir.empty() &&

678 D.getVFS().exists(concat(SysRoot, "/usr/include", MultiarchIncludeDir)))

680 DriverArgs, CC1Args,

681 concat(SysRoot, "/usr/include", MultiarchIncludeDir));

682

684 return;

685

686

687

688

690

692

693 if (!DriverArgs.hasArg(options::OPT_nobuiltininc) && getTriple().isMusl())

695}

696

698 llvm::opt::ArgStringList &CC1Args) const {

699

700

702 return;

703

704

706 StringRef DebianMultiarch =

708 ? "i386-linux-gnu"

709 : TripleStr;

710

711

713 DebianMultiarch))

714 return;

715

719

720 const std::string LibStdCXXIncludePathCandidates[] = {

721

722 LibDir.str() + "/../" + TripleStr.str() + "/include/c++/" + Version.Text,

723

724

725 LibDir.str() + "/../include/c++",

726

727

728 LibDir.str() + "/../include/g++",

729 };

730

731 for (const auto &IncludePath : LibStdCXXIncludePathCandidates) {

734 break;

735 }

736}

737

739 ArgStringList &CC1Args) const {

741}

742

744 ArgStringList &CC1Args) const {

746}

747

749 ArgStringList &CmdArgs) const {

750 CmdArgs.push_back(

751 Args.MakeArgString(StringRef("-L") + RocmInstallation->getLibPath()));

752

753 if (Args.hasFlag(options::OPT_frtlib_add_rpath,

754 options::OPT_fno_rtlib_add_rpath, false))

755 CmdArgs.append(

756 {"-rpath", Args.MakeArgString(RocmInstallation->getLibPath())});

757

758 CmdArgs.push_back("-lamdhip64");

759}

760

762 ArgStringList &CC1Args) const {

764 CC1Args.push_back("-isystem");

765 CC1Args.push_back(DriverArgs.MakeArgString(

768 }

769}

770

772 ArgStringList &CC1Args) const {

774}

775

777 return CLANG_DEFAULT_PIE_ON_LINUX || getTriple().isAndroid() ||

779}

780

782

783

784 assert(getTriple().isAArch64() && "expected AArch64 target!");

787 return true;

790 return false;

791 return true;

792}

793

796 return false;

798}

799

801 const bool IsX86 = getTriple().getArch() == llvm::Triple::x86;

802 const bool IsX86_64 = getTriple().getArch() == llvm::Triple::x86_64;

803 const bool IsMIPS = getTriple().isMIPS32();

804 const bool IsMIPS64 = getTriple().isMIPS64();

805 const bool IsPowerPC64 = getTriple().getArch() == llvm::Triple::ppc64 ||

806 getTriple().getArch() == llvm::Triple::ppc64le;

807 const bool IsAArch64 = getTriple().getArch() == llvm::Triple::aarch64 ||

808 getTriple().getArch() == llvm::Triple::aarch64_be;

809 const bool IsArmArch = getTriple().getArch() == llvm::Triple::arm ||

810 getTriple().getArch() == llvm::Triple::thumb ||

811 getTriple().getArch() == llvm::Triple::armeb ||

812 getTriple().getArch() == llvm::Triple::thumbeb;

813 const bool IsLoongArch64 = getTriple().getArch() == llvm::Triple::loongarch64;

814 const bool IsRISCV64 = getTriple().getArch() == llvm::Triple::riscv64;

815 const bool IsSystemZ = getTriple().getArch() == llvm::Triple::systemz;

816 const bool IsHexagon = getTriple().getArch() == llvm::Triple::hexagon;

817 const bool IsAndroid = getTriple().isAndroid();

819 Res |= SanitizerKind::Address;

820 Res |= SanitizerKind::PointerCompare;

821 Res |= SanitizerKind::PointerSubtract;

822 Res |= SanitizerKind::Realtime;

823 Res |= SanitizerKind::Fuzzer;

824 Res |= SanitizerKind::FuzzerNoLink;

825 Res |= SanitizerKind::KernelAddress;

826 Res |= SanitizerKind::Vptr;

827 Res |= SanitizerKind::SafeStack;

828 if (IsX86_64 || IsMIPS64 || IsAArch64 || IsLoongArch64)

829 Res |= SanitizerKind::DataFlow;

830 if (IsX86_64 || IsMIPS64 || IsAArch64 || IsX86 || IsArmArch || IsPowerPC64 ||

831 IsRISCV64 || IsSystemZ || IsHexagon || IsLoongArch64)

832 Res |= SanitizerKind::Leak;

833 if (IsX86_64 || IsMIPS64 || IsAArch64 || IsPowerPC64 || IsSystemZ ||

834 IsLoongArch64 || IsRISCV64)

835 Res |= SanitizerKind::Thread;

836 if (IsX86_64 || IsAArch64)

837 Res |= SanitizerKind::Type;

838 if (IsX86_64 || IsSystemZ || IsPowerPC64)

839 Res |= SanitizerKind::KernelMemory;

840 if (IsX86_64 || IsMIPS64 || IsAArch64 || IsX86 || IsMIPS || IsArmArch ||

841 IsPowerPC64 || IsHexagon || IsLoongArch64 || IsRISCV64)

842 Res |= SanitizerKind::Scudo;

843 if (IsX86_64 || IsAArch64 || IsRISCV64) {

844 Res |= SanitizerKind::HWAddress;

845 }

846 if (IsX86_64 || IsAArch64) {

847 Res |= SanitizerKind::KernelHWAddress;

848 }

849 if (IsX86_64)

850 Res |= SanitizerKind::NumericalStability;

851 if (!IsAndroid)

852 Res |= SanitizerKind::Memory;

853

854

857 return Res;

858}

859

861 llvm::opt::ArgStringList &CmdArgs) const {

862

863

865 CmdArgs.push_back(Args.MakeArgString(

866 Twine("-u", llvm::getInstrProfRuntimeHookVarName())));

868}

869

871 for (const auto &Opt : ExtraOpts)

872 CmdArgs.push_back(Opt.c_str());

873}

874

877 return "ld.lld";

879}

static StringRef getOSLibDir(const llvm::Triple &Triple, const ArgList &Args)

Distro - Helper class for detecting and classifying Linux distributions.

bool IsAlpineLinux() const

Driver - Encapsulate logic for constructing compilation processes from a set of gcc-driver-like comma...

std::string SysRoot

sysroot, if present

std::string Dir

The path the driver executable was in, as invoked from the command line.

This corresponds to a single GCC Multilib, or a segment of one controlled by a command line flag.

const std::string & osSuffix() const

Get the detected os path suffix for the multi-arch target variant.

const std::string & includeSuffix() const

Get the include directory suffix.

The JSON file list parser is used to communicate input to InstallAPI.