1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | #include "Linux.h" |
10 | #include "Arch/ARM.h" |
11 | #include "Arch/Mips.h" |
12 | #include "Arch/PPC.h" |
13 | #include "Arch/RISCV.h" |
14 | #include "CommonArgs.h" |
15 | #include "clang/Config/config.h" |
16 | #include "clang/Driver/Distro.h" |
17 | #include "clang/Driver/Driver.h" |
18 | #include "clang/Driver/Options.h" |
19 | #include "clang/Driver/SanitizerArgs.h" |
20 | #include "llvm/Option/ArgList.h" |
21 | #include "llvm/ProfileData/InstrProf.h" |
22 | #include "llvm/Support/Path.h" |
23 | #include "llvm/Support/ScopedPrinter.h" |
24 | #include "llvm/Support/VirtualFileSystem.h" |
25 | #include <system_error> |
26 | |
27 | using namespace clang::driver; |
28 | using namespace clang::driver::toolchains; |
29 | using namespace clang; |
30 | using namespace llvm::opt; |
31 | |
32 | using tools::addPathIfExists; |
33 | |
34 | |
35 | |
36 | |
37 | |
38 | |
39 | |
40 | static std::string getMultiarchTriple(const Driver &D, |
41 | const llvm::Triple &TargetTriple, |
42 | StringRef SysRoot) { |
43 | llvm::Triple::EnvironmentType TargetEnvironment = |
44 | TargetTriple.getEnvironment(); |
45 | bool IsAndroid = TargetTriple.isAndroid(); |
46 | bool IsMipsR6 = TargetTriple.getSubArch() == llvm::Triple::MipsSubArch_r6; |
47 | |
48 | |
49 | |
50 | switch (TargetTriple.getArch()) { |
51 | default: |
52 | break; |
53 | |
54 | |
55 | |
56 | |
57 | |
58 | case llvm::Triple::arm: |
59 | case llvm::Triple::thumb: |
60 | if (IsAndroid) { |
61 | return "arm-linux-androideabi"; |
62 | } else if (TargetEnvironment == llvm::Triple::GNUEABIHF) { |
63 | if (D.getVFS().exists(SysRoot + "/lib/arm-linux-gnueabihf")) |
64 | return "arm-linux-gnueabihf"; |
65 | } else { |
66 | if (D.getVFS().exists(SysRoot + "/lib/arm-linux-gnueabi")) |
67 | return "arm-linux-gnueabi"; |
68 | } |
69 | break; |
70 | case llvm::Triple::armeb: |
71 | case llvm::Triple::thumbeb: |
72 | if (TargetEnvironment == llvm::Triple::GNUEABIHF) { |
73 | if (D.getVFS().exists(SysRoot + "/lib/armeb-linux-gnueabihf")) |
74 | return "armeb-linux-gnueabihf"; |
75 | } else { |
76 | if (D.getVFS().exists(SysRoot + "/lib/armeb-linux-gnueabi")) |
77 | return "armeb-linux-gnueabi"; |
78 | } |
79 | break; |
80 | case llvm::Triple::x86: |
81 | if (IsAndroid) |
82 | return "i686-linux-android"; |
83 | if (D.getVFS().exists(SysRoot + "/lib/i386-linux-gnu")) |
84 | return "i386-linux-gnu"; |
85 | break; |
86 | case llvm::Triple::x86_64: |
87 | if (IsAndroid) |
88 | return "x86_64-linux-android"; |
89 | |
90 | if (TargetEnvironment != llvm::Triple::GNUX32 && |
91 | D.getVFS().exists(SysRoot + "/lib/x86_64-linux-gnu")) |
92 | return "x86_64-linux-gnu"; |
93 | break; |
94 | case llvm::Triple::aarch64: |
95 | if (IsAndroid) |
96 | return "aarch64-linux-android"; |
97 | if (D.getVFS().exists(SysRoot + "/lib/aarch64-linux-gnu")) |
98 | return "aarch64-linux-gnu"; |
99 | break; |
100 | case llvm::Triple::aarch64_be: |
101 | if (D.getVFS().exists(SysRoot + "/lib/aarch64_be-linux-gnu")) |
102 | return "aarch64_be-linux-gnu"; |
103 | break; |
104 | case llvm::Triple::mips: { |
105 | std::string Arch = IsMipsR6 ? "mipsisa32r6" : "mips"; |
106 | if (D.getVFS().exists(SysRoot + "/lib/" + Arch + "-linux-gnu")) |
107 | return Arch + "-linux-gnu"; |
108 | break; |
109 | } |
110 | case llvm::Triple::mipsel: { |
111 | if (IsAndroid) |
112 | return "mipsel-linux-android"; |
113 | std::string Arch = IsMipsR6 ? "mipsisa32r6el" : "mipsel"; |
114 | if (D.getVFS().exists(SysRoot + "/lib/" + Arch + "-linux-gnu")) |
115 | return Arch + "-linux-gnu"; |
116 | break; |
117 | } |
118 | case llvm::Triple::mips64: { |
119 | std::string Arch = IsMipsR6 ? "mipsisa64r6" : "mips64"; |
120 | std::string ABI = llvm::Triple::getEnvironmentTypeName(TargetEnvironment); |
121 | if (D.getVFS().exists(SysRoot + "/lib/" + Arch + "-linux-" + ABI)) |
122 | return Arch + "-linux-" + ABI; |
123 | break; |
124 | } |
125 | case llvm::Triple::mips64el: { |
126 | if (IsAndroid) |
127 | return "mips64el-linux-android"; |
128 | std::string Arch = IsMipsR6 ? "mipsisa64r6el" : "mips64el"; |
129 | std::string ABI = llvm::Triple::getEnvironmentTypeName(TargetEnvironment); |
130 | if (D.getVFS().exists(SysRoot + "/lib/" + Arch + "-linux-" + ABI)) |
131 | return Arch + "-linux-" + ABI; |
132 | break; |
133 | } |
134 | case llvm::Triple::ppc: |
135 | if (D.getVFS().exists(SysRoot + "/lib/powerpc-linux-gnuspe")) |
136 | return "powerpc-linux-gnuspe"; |
137 | if (D.getVFS().exists(SysRoot + "/lib/powerpc-linux-gnu")) |
138 | return "powerpc-linux-gnu"; |
139 | break; |
140 | case llvm::Triple::ppc64: |
141 | if (D.getVFS().exists(SysRoot + "/lib/powerpc64-linux-gnu")) |
142 | return "powerpc64-linux-gnu"; |
143 | break; |
144 | case llvm::Triple::ppc64le: |
145 | if (D.getVFS().exists(SysRoot + "/lib/powerpc64le-linux-gnu")) |
146 | return "powerpc64le-linux-gnu"; |
147 | break; |
148 | case llvm::Triple::sparc: |
149 | if (D.getVFS().exists(SysRoot + "/lib/sparc-linux-gnu")) |
150 | return "sparc-linux-gnu"; |
151 | break; |
152 | case llvm::Triple::sparcv9: |
153 | if (D.getVFS().exists(SysRoot + "/lib/sparc64-linux-gnu")) |
154 | return "sparc64-linux-gnu"; |
155 | break; |
156 | case llvm::Triple::systemz: |
157 | if (D.getVFS().exists(SysRoot + "/lib/s390x-linux-gnu")) |
158 | return "s390x-linux-gnu"; |
159 | break; |
160 | } |
161 | return TargetTriple.str(); |
162 | } |
163 | |
164 | static StringRef getOSLibDir(const llvm::Triple &Triple, const ArgList &Args) { |
165 | if (Triple.isMIPS()) { |
166 | if (Triple.isAndroid()) { |
167 | StringRef CPUName; |
168 | StringRef ABIName; |
169 | tools::mips::getMipsCPUAndABI(Args, Triple, CPUName, ABIName); |
170 | if (CPUName == "mips32r6") |
171 | return "libr6"; |
172 | if (CPUName == "mips32r2") |
173 | return "libr2"; |
174 | } |
175 | |
176 | |
177 | |
178 | if (tools::mips::hasMipsAbiArg(Args, "n32")) |
179 | return "lib32"; |
180 | return Triple.isArch32Bit() ? "lib" : "lib64"; |
181 | } |
182 | |
183 | |
184 | |
185 | |
186 | |
187 | |
188 | |
189 | |
190 | |
191 | |
192 | if (Triple.getArch() == llvm::Triple::x86 || |
193 | Triple.getArch() == llvm::Triple::ppc) |
194 | return "lib32"; |
195 | |
196 | if (Triple.getArch() == llvm::Triple::x86_64 && |
197 | Triple.getEnvironment() == llvm::Triple::GNUX32) |
198 | return "libx32"; |
199 | |
200 | if (Triple.getArch() == llvm::Triple::riscv32) |
201 | return "lib32"; |
202 | |
203 | return Triple.isArch32Bit() ? "lib" : "lib64"; |
204 | } |
205 | |
206 | static void addMultilibsFilePaths(const Driver &D, const MultilibSet &Multilibs, |
207 | const Multilib &Multilib, |
208 | StringRef InstallPath, |
209 | ToolChain::path_list &Paths) { |
210 | if (const auto &PathsCallback = Multilibs.filePathsCallback()) |
211 | for (const auto &Path : PathsCallback(Multilib)) |
212 | addPathIfExists(D, InstallPath + Path, Paths); |
213 | } |
214 | |
215 | Linux::Linux(const Driver &D, const llvm::Triple &Triple, const ArgList &Args) |
216 | : Generic_ELF(D, Triple, Args) { |
217 | GCCInstallation.init(Triple, Args); |
218 | Multilibs = GCCInstallation.getMultilibs(); |
219 | SelectedMultilib = GCCInstallation.getMultilib(); |
220 | llvm::Triple::ArchType Arch = Triple.getArch(); |
221 | std::string SysRoot = computeSysRoot(); |
222 | |
223 | |
224 | |
225 | |
226 | |
227 | |
228 | |
229 | |
230 | |
231 | ToolChain::path_list &PPaths = getProgramPaths(); |
232 | PPaths.push_back(Twine(GCCInstallation.getParentLibPath() + "/../" + |
233 | GCCInstallation.getTriple().str() + "/bin") |
234 | .str()); |
235 | |
236 | Distro Distro(D.getVFS()); |
237 | |
238 | if (Distro.IsAlpineLinux() || Triple.isAndroid()) { |
239 | ExtraOpts.push_back("-z"); |
240 | ExtraOpts.push_back("now"); |
241 | } |
242 | |
243 | if (Distro.IsOpenSUSE() || Distro.IsUbuntu() || Distro.IsAlpineLinux() || |
244 | Triple.isAndroid()) { |
245 | ExtraOpts.push_back("-z"); |
246 | ExtraOpts.push_back("relro"); |
247 | } |
248 | |
249 | |
250 | |
251 | |
252 | if (Triple.isAArch64() && Triple.isAndroid()) { |
253 | ExtraOpts.push_back("-z"); |
254 | ExtraOpts.push_back("max-page-size=4096"); |
255 | } |
256 | |
257 | if (GCCInstallation.getParentLibPath().find("opt/rh/devtoolset") != |
258 | StringRef::npos) |
259 | |
260 | |
261 | |
262 | |
263 | PPaths.push_back(Twine(GCCInstallation.getParentLibPath() + |
264 | "/../bin").str()); |
265 | |
266 | if (Arch == llvm::Triple::arm || Arch == llvm::Triple::thumb) |
267 | ExtraOpts.push_back("-X"); |
268 | |
269 | const bool IsAndroid = Triple.isAndroid(); |
270 | const bool IsMips = Triple.isMIPS(); |
271 | const bool IsHexagon = Arch == llvm::Triple::hexagon; |
272 | const bool IsRISCV = |
273 | Arch == llvm::Triple::riscv32 || Arch == llvm::Triple::riscv64; |
274 | |
275 | if (IsMips && !SysRoot.empty()) |
276 | ExtraOpts.push_back("--sysroot=" + SysRoot); |
277 | |
278 | |
279 | |
280 | |
281 | |
282 | |
283 | |
284 | if (!IsMips && !IsHexagon) { |
285 | if (Distro.IsRedhat() || Distro.IsOpenSUSE() || Distro.IsAlpineLinux() || |
286 | (Distro.IsUbuntu() && Distro >= Distro::UbuntuMaverick) || |
287 | (IsAndroid && !Triple.isAndroidVersionLT(23))) |
288 | ExtraOpts.push_back("--hash-style=gnu"); |
289 | |
290 | if (Distro.IsDebian() || Distro.IsOpenSUSE() || |
291 | Distro == Distro::UbuntuLucid || Distro == Distro::UbuntuJaunty || |
292 | Distro == Distro::UbuntuKarmic || |
293 | (IsAndroid && Triple.isAndroidVersionLT(23))) |
294 | ExtraOpts.push_back("--hash-style=both"); |
295 | } |
296 | |
297 | if (Distro.IsRedhat() && Distro != Distro::RHEL5 && Distro != Distro::RHEL6) |
298 | ExtraOpts.push_back("--no-add-needed"); |
299 | |
300 | #ifdef ENABLE_LINKER_BUILD_ID |
301 | ExtraOpts.push_back("--build-id"); |
302 | #endif |
303 | |
304 | if (IsAndroid || Distro.IsOpenSUSE()) |
305 | ExtraOpts.push_back("--enable-new-dtags"); |
306 | |
307 | |
308 | |
309 | |
310 | |
311 | |
312 | path_list &Paths = getFilePaths(); |
313 | |
314 | const std::string OSLibDir = getOSLibDir(Triple, Args); |
315 | const std::string MultiarchTriple = getMultiarchTriple(D, Triple, SysRoot); |
316 | |
317 | |
318 | if (GCCInstallation.isValid()) { |
319 | const llvm::Triple &GCCTriple = GCCInstallation.getTriple(); |
320 | const std::string &LibPath = GCCInstallation.getParentLibPath(); |
321 | |
322 | |
323 | addMultilibsFilePaths(D, Multilibs, SelectedMultilib, |
324 | GCCInstallation.getInstallPath(), Paths); |
325 | |
326 | |
327 | |
328 | addPathIfExists(D, GCCInstallation.getInstallPath() + SelectedMultilib.gccSuffix(), |
329 | Paths); |
330 | |
331 | |
332 | |
333 | |
334 | |
335 | |
336 | |
337 | |
338 | |
339 | |
340 | |
341 | |
342 | |
343 | |
344 | |
345 | |
346 | |
347 | |
348 | |
349 | addPathIfExists(D, LibPath + "/../" + GCCTriple.str() + "/lib/../" + |
350 | OSLibDir + SelectedMultilib.osSuffix(), |
351 | Paths); |
352 | |
353 | |
354 | |
355 | |
356 | |
357 | |
358 | |
359 | |
360 | |
361 | |
362 | if (StringRef(LibPath).startswith(SysRoot)) { |
363 | addPathIfExists(D, LibPath + "/" + MultiarchTriple, Paths); |
364 | addPathIfExists(D, LibPath + "/../" + OSLibDir, Paths); |
365 | } |
366 | } |
367 | |
368 | |
369 | |
370 | |
371 | |
372 | |
373 | if (StringRef(D.Dir).startswith(SysRoot)) { |
374 | addPathIfExists(D, D.Dir + "/../lib/" + MultiarchTriple, Paths); |
375 | addPathIfExists(D, D.Dir + "/../" + OSLibDir, Paths); |
376 | } |
377 | |
378 | addPathIfExists(D, SysRoot + "/lib/" + MultiarchTriple, Paths); |
379 | addPathIfExists(D, SysRoot + "/lib/../" + OSLibDir, Paths); |
380 | |
381 | if (IsAndroid) { |
382 | |
383 | |
384 | |
385 | unsigned Major; |
386 | unsigned Minor; |
387 | unsigned Micro; |
388 | Triple.getEnvironmentVersion(Major, Minor, Micro); |
389 | addPathIfExists(D, |
390 | SysRoot + "/usr/lib/" + MultiarchTriple + "/" + |
391 | llvm::to_string(Major), |
392 | Paths); |
393 | } |
394 | |
395 | addPathIfExists(D, SysRoot + "/usr/lib/" + MultiarchTriple, Paths); |
396 | |
397 | |
398 | |
399 | if (Triple.getVendor() == llvm::Triple::OpenEmbedded && |
400 | Triple.isArch64Bit()) |
401 | addPathIfExists(D, SysRoot + "/usr/" + OSLibDir, Paths); |
402 | else |
403 | addPathIfExists(D, SysRoot + "/usr/lib/../" + OSLibDir, Paths); |
404 | if (IsRISCV) { |
405 | StringRef ABIName = tools::riscv::getRISCVABI(Args, Triple); |
406 | addPathIfExists(D, SysRoot + "/" + OSLibDir + "/" + ABIName, Paths); |
407 | addPathIfExists(D, SysRoot + "/usr/" + OSLibDir + "/" + ABIName, Paths); |
408 | } |
409 | |
410 | |
411 | |
412 | if (GCCInstallation.isValid()) { |
413 | addPathIfExists(D, |
414 | SysRoot + "/usr/lib/" + GCCInstallation.getTriple().str() + |
415 | "/../../" + OSLibDir, |
416 | Paths); |
417 | |
418 | |
419 | Multilib BiarchSibling; |
420 | if (GCCInstallation.getBiarchSibling(BiarchSibling)) { |
421 | addPathIfExists(D, GCCInstallation.getInstallPath() + |
422 | BiarchSibling.gccSuffix(), |
423 | Paths); |
424 | } |
425 | |
426 | |
427 | |
428 | const std::string &LibPath = GCCInstallation.getParentLibPath(); |
429 | const llvm::Triple &GCCTriple = GCCInstallation.getTriple(); |
430 | const Multilib &Multilib = GCCInstallation.getMultilib(); |
431 | addPathIfExists(D, LibPath + "/../" + GCCTriple.str() + "/lib" + |
432 | Multilib.osSuffix(), |
433 | Paths); |
434 | |
435 | |
436 | |
437 | if (StringRef(LibPath).startswith(SysRoot)) |
438 | addPathIfExists(D, LibPath, Paths); |
439 | } |
440 | |
441 | |
442 | |
443 | |
444 | |
445 | |
446 | if (StringRef(D.Dir).startswith(SysRoot)) |
447 | addPathIfExists(D, D.Dir + "/../lib", Paths); |
448 | |
449 | addPathIfExists(D, SysRoot + "/lib", Paths); |
450 | addPathIfExists(D, SysRoot + "/usr/lib", Paths); |
451 | } |
452 | |
453 | ToolChain::CXXStdlibType Linux::GetDefaultCXXStdlibType() const { |
454 | if (getTriple().isAndroid()) |
455 | return ToolChain::CST_Libcxx; |
456 | return ToolChain::CST_Libstdcxx; |
457 | } |
458 | |
459 | bool Linux::HasNativeLLVMSupport() const { return true; } |
460 | |
461 | Tool *Linux::buildLinker() const { return new tools::gnutools::Linker(*this); } |
462 | |
463 | Tool *Linux::buildAssembler() const { |
464 | return new tools::gnutools::Assembler(*this); |
465 | } |
466 | |
467 | std::string Linux::computeSysRoot() const { |
468 | if (!getDriver().SysRoot.empty()) |
469 | return getDriver().SysRoot; |
470 | |
471 | if (getTriple().isAndroid()) { |
472 | |
473 | |
474 | const StringRef ClangDir = getDriver().getInstalledDir(); |
475 | std::string AndroidSysRootPath = (ClangDir + "/../sysroot").str(); |
476 | if (getVFS().exists(AndroidSysRootPath)) |
477 | return AndroidSysRootPath; |
478 | } |
479 | |
480 | if (!GCCInstallation.isValid() || !getTriple().isMIPS()) |
481 | return std::string(); |
482 | |
483 | |
484 | |
485 | |
486 | |
487 | const StringRef InstallDir = GCCInstallation.getInstallPath(); |
488 | const StringRef TripleStr = GCCInstallation.getTriple().str(); |
489 | const Multilib &Multilib = GCCInstallation.getMultilib(); |
490 | |
491 | std::string Path = |
492 | (InstallDir + "/../../../../" + TripleStr + "/libc" + Multilib.osSuffix()) |
493 | .str(); |
494 | |
495 | if (getVFS().exists(Path)) |
496 | return Path; |
497 | |
498 | Path = (InstallDir + "/../../../../sysroot" + Multilib.osSuffix()).str(); |
499 | |
500 | if (getVFS().exists(Path)) |
501 | return Path; |
502 | |
503 | return std::string(); |
504 | } |
505 | |
506 | std::string Linux::getDynamicLinker(const ArgList &Args) const { |
507 | const llvm::Triple::ArchType Arch = getArch(); |
508 | const llvm::Triple &Triple = getTriple(); |
509 | |
510 | const Distro Distro(getDriver().getVFS()); |
511 | |
512 | if (Triple.isAndroid()) |
513 | return Triple.isArch64Bit() ? "/system/bin/linker64" : "/system/bin/linker"; |
514 | |
515 | if (Triple.isMusl()) { |
516 | std::string ArchName; |
517 | bool IsArm = false; |
518 | |
519 | switch (Arch) { |
520 | case llvm::Triple::arm: |
521 | case llvm::Triple::thumb: |
522 | ArchName = "arm"; |
523 | IsArm = true; |
524 | break; |
525 | case llvm::Triple::armeb: |
526 | case llvm::Triple::thumbeb: |
527 | ArchName = "armeb"; |
528 | IsArm = true; |
529 | break; |
530 | default: |
531 | ArchName = Triple.getArchName().str(); |
532 | } |
533 | if (IsArm && |
534 | (Triple.getEnvironment() == llvm::Triple::MuslEABIHF || |
535 | tools::arm::getARMFloatABI(*this, Args) == tools::arm::FloatABI::Hard)) |
536 | ArchName += "hf"; |
537 | |
538 | return "/lib/ld-musl-" + ArchName + ".so.1"; |
539 | } |
540 | |
541 | std::string LibDir; |
542 | std::string Loader; |
543 | |
544 | switch (Arch) { |
545 | default: |
546 | llvm_unreachable("unsupported architecture"); |
547 | |
548 | case llvm::Triple::aarch64: |
549 | LibDir = "lib"; |
550 | Loader = "ld-linux-aarch64.so.1"; |
551 | break; |
552 | case llvm::Triple::aarch64_be: |
553 | LibDir = "lib"; |
554 | Loader = "ld-linux-aarch64_be.so.1"; |
555 | break; |
556 | case llvm::Triple::arm: |
557 | case llvm::Triple::thumb: |
558 | case llvm::Triple::armeb: |
559 | case llvm::Triple::thumbeb: { |
560 | const bool HF = |
561 | Triple.getEnvironment() == llvm::Triple::GNUEABIHF || |
562 | tools::arm::getARMFloatABI(*this, Args) == tools::arm::FloatABI::Hard; |
563 | |
564 | LibDir = "lib"; |
565 | Loader = HF ? "ld-linux-armhf.so.3" : "ld-linux.so.3"; |
566 | break; |
567 | } |
568 | case llvm::Triple::mips: |
569 | case llvm::Triple::mipsel: |
570 | case llvm::Triple::mips64: |
571 | case llvm::Triple::mips64el: { |
572 | bool IsNaN2008 = tools::mips::isNaN2008(Args, Triple); |
573 | |
574 | LibDir = "lib" + tools::mips::getMipsABILibSuffix(Args, Triple); |
575 | |
576 | if (tools::mips::isUCLibc(Args)) |
577 | Loader = IsNaN2008 ? "ld-uClibc-mipsn8.so.0" : "ld-uClibc.so.0"; |
578 | else if (!Triple.hasEnvironment() && |
579 | Triple.getVendor() == llvm::Triple::VendorType::MipsTechnologies) |
580 | Loader = |
581 | Triple.isLittleEndian() ? "ld-musl-mipsel.so.1" : "ld-musl-mips.so.1"; |
582 | else |
583 | Loader = IsNaN2008 ? "ld-linux-mipsn8.so.1" : "ld.so.1"; |
584 | |
585 | break; |
586 | } |
587 | case llvm::Triple::ppc: |
588 | LibDir = "lib"; |
589 | Loader = "ld.so.1"; |
590 | break; |
591 | case llvm::Triple::ppc64: |
592 | LibDir = "lib64"; |
593 | Loader = |
594 | (tools::ppc::hasPPCAbiArg(Args, "elfv2")) ? "ld64.so.2" : "ld64.so.1"; |
595 | break; |
596 | case llvm::Triple::ppc64le: |
597 | LibDir = "lib64"; |
598 | Loader = |
599 | (tools::ppc::hasPPCAbiArg(Args, "elfv1")) ? "ld64.so.1" : "ld64.so.2"; |
600 | break; |
601 | case llvm::Triple::riscv32: { |
602 | StringRef ABIName = tools::riscv::getRISCVABI(Args, Triple); |
603 | LibDir = "lib"; |
604 | Loader = ("ld-linux-riscv32-" + ABIName + ".so.1").str(); |
605 | break; |
606 | } |
607 | case llvm::Triple::riscv64: { |
608 | StringRef ABIName = tools::riscv::getRISCVABI(Args, Triple); |
609 | LibDir = "lib"; |
610 | Loader = ("ld-linux-riscv64-" + ABIName + ".so.1").str(); |
611 | break; |
612 | } |
613 | case llvm::Triple::sparc: |
614 | case llvm::Triple::sparcel: |
615 | LibDir = "lib"; |
616 | Loader = "ld-linux.so.2"; |
617 | break; |
618 | case llvm::Triple::sparcv9: |
619 | LibDir = "lib64"; |
620 | Loader = "ld-linux.so.2"; |
621 | break; |
622 | case llvm::Triple::systemz: |
623 | LibDir = "lib"; |
624 | Loader = "ld64.so.1"; |
625 | break; |
626 | case llvm::Triple::x86: |
627 | LibDir = "lib"; |
628 | Loader = "ld-linux.so.2"; |
629 | break; |
630 | case llvm::Triple::x86_64: { |
631 | bool X32 = Triple.getEnvironment() == llvm::Triple::GNUX32; |
632 | |
633 | LibDir = X32 ? "libx32" : "lib64"; |
634 | Loader = X32 ? "ld-linux-x32.so.2" : "ld-linux-x86-64.so.2"; |
635 | break; |
636 | } |
637 | } |
638 | |
639 | if (Distro == Distro::Exherbo && (Triple.getVendor() == llvm::Triple::UnknownVendor || |
640 | Triple.getVendor() == llvm::Triple::PC)) |
641 | return "/usr/" + Triple.str() + "/lib/" + Loader; |
642 | return "/" + LibDir + "/" + Loader; |
643 | } |
644 | |
645 | void Linux::AddClangSystemIncludeArgs(const ArgList &DriverArgs, |
646 | ArgStringList &CC1Args) const { |
647 | const Driver &D = getDriver(); |
648 | std::string SysRoot = computeSysRoot(); |
649 | |
650 | if (DriverArgs.hasArg(clang::driver::options::OPT_nostdinc)) |
651 | return; |
652 | |
653 | if (!DriverArgs.hasArg(options::OPT_nostdlibinc)) |
654 | addSystemInclude(DriverArgs, CC1Args, SysRoot + "/usr/local/include"); |
655 | |
656 | if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) { |
657 | SmallString<128> P(D.ResourceDir); |
658 | llvm::sys::path::append(P, "include"); |
659 | addSystemInclude(DriverArgs, CC1Args, P); |
660 | } |
661 | |
662 | if (DriverArgs.hasArg(options::OPT_nostdlibinc)) |
663 | return; |
664 | |
665 | |
666 | StringRef CIncludeDirs(C_INCLUDE_DIRS); |
667 | if (CIncludeDirs != "") { |
668 | SmallVector<StringRef, 5> dirs; |
669 | CIncludeDirs.split(dirs, ":"); |
670 | for (StringRef dir : dirs) { |
671 | StringRef Prefix = |
672 | llvm::sys::path::is_absolute(dir) ? StringRef(SysRoot) : ""; |
673 | addExternCSystemInclude(DriverArgs, CC1Args, Prefix + dir); |
674 | } |
675 | return; |
676 | } |
677 | |
678 | |
679 | |
680 | |
681 | |
682 | if (GCCInstallation.isValid()) { |
683 | const auto &Callback = Multilibs.includeDirsCallback(); |
684 | if (Callback) { |
685 | for (const auto &Path : Callback(GCCInstallation.getMultilib())) |
686 | addExternCSystemIncludeIfExists( |
687 | DriverArgs, CC1Args, GCCInstallation.getInstallPath() + Path); |
688 | } |
689 | } |
690 | |
691 | |
692 | const StringRef X86_64MultiarchIncludeDirs[] = { |
693 | "/usr/include/x86_64-linux-gnu", |
694 | |
695 | |
696 | |
697 | |
698 | "/usr/include/i686-linux-gnu/64", "/usr/include/i486-linux-gnu/64"}; |
699 | const StringRef X86MultiarchIncludeDirs[] = { |
700 | "/usr/include/i386-linux-gnu", |
701 | |
702 | |
703 | |
704 | |
705 | "/usr/include/x86_64-linux-gnu/32", "/usr/include/i686-linux-gnu", |
706 | "/usr/include/i486-linux-gnu"}; |
707 | const StringRef AArch64MultiarchIncludeDirs[] = { |
708 | "/usr/include/aarch64-linux-gnu"}; |
709 | const StringRef ARMMultiarchIncludeDirs[] = { |
710 | "/usr/include/arm-linux-gnueabi"}; |
711 | const StringRef ARMHFMultiarchIncludeDirs[] = { |
712 | "/usr/include/arm-linux-gnueabihf"}; |
713 | const StringRef ARMEBMultiarchIncludeDirs[] = { |
714 | "/usr/include/armeb-linux-gnueabi"}; |
715 | const StringRef ARMEBHFMultiarchIncludeDirs[] = { |
716 | "/usr/include/armeb-linux-gnueabihf"}; |
717 | const StringRef MIPSMultiarchIncludeDirs[] = {"/usr/include/mips-linux-gnu"}; |
718 | const StringRef MIPSELMultiarchIncludeDirs[] = { |
719 | "/usr/include/mipsel-linux-gnu"}; |
720 | const StringRef MIPS64MultiarchIncludeDirs[] = { |
721 | "/usr/include/mips64-linux-gnuabi64"}; |
722 | const StringRef MIPS64ELMultiarchIncludeDirs[] = { |
723 | "/usr/include/mips64el-linux-gnuabi64"}; |
724 | const StringRef MIPSN32MultiarchIncludeDirs[] = { |
725 | "/usr/include/mips64-linux-gnuabin32"}; |
726 | const StringRef MIPSN32ELMultiarchIncludeDirs[] = { |
727 | "/usr/include/mips64el-linux-gnuabin32"}; |
728 | const StringRef MIPSR6MultiarchIncludeDirs[] = { |
729 | "/usr/include/mipsisa32-linux-gnu"}; |
730 | const StringRef MIPSR6ELMultiarchIncludeDirs[] = { |
731 | "/usr/include/mipsisa32r6el-linux-gnu"}; |
732 | const StringRef MIPS64R6MultiarchIncludeDirs[] = { |
733 | "/usr/include/mipsisa64r6-linux-gnuabi64"}; |
734 | const StringRef MIPS64R6ELMultiarchIncludeDirs[] = { |
735 | "/usr/include/mipsisa64r6el-linux-gnuabi64"}; |
736 | const StringRef MIPSN32R6MultiarchIncludeDirs[] = { |
737 | "/usr/include/mipsisa64r6-linux-gnuabin32"}; |
738 | const StringRef MIPSN32R6ELMultiarchIncludeDirs[] = { |
739 | "/usr/include/mipsisa64r6el-linux-gnuabin32"}; |
740 | const StringRef PPCMultiarchIncludeDirs[] = { |
741 | "/usr/include/powerpc-linux-gnu", |
742 | "/usr/include/powerpc-linux-gnuspe"}; |
743 | const StringRef PPC64MultiarchIncludeDirs[] = { |
744 | "/usr/include/powerpc64-linux-gnu"}; |
745 | const StringRef PPC64LEMultiarchIncludeDirs[] = { |
746 | "/usr/include/powerpc64le-linux-gnu"}; |
747 | const StringRef SparcMultiarchIncludeDirs[] = { |
748 | "/usr/include/sparc-linux-gnu"}; |
749 | const StringRef Sparc64MultiarchIncludeDirs[] = { |
750 | "/usr/include/sparc64-linux-gnu"}; |
751 | const StringRef SYSTEMZMultiarchIncludeDirs[] = { |
752 | "/usr/include/s390x-linux-gnu"}; |
753 | ArrayRef<StringRef> MultiarchIncludeDirs; |
754 | switch (getTriple().getArch()) { |
755 | case llvm::Triple::x86_64: |
756 | MultiarchIncludeDirs = X86_64MultiarchIncludeDirs; |
757 | break; |
758 | case llvm::Triple::x86: |
759 | MultiarchIncludeDirs = X86MultiarchIncludeDirs; |
760 | break; |
761 | case llvm::Triple::aarch64: |
762 | case llvm::Triple::aarch64_be: |
763 | MultiarchIncludeDirs = AArch64MultiarchIncludeDirs; |
764 | break; |
765 | case llvm::Triple::arm: |
766 | case llvm::Triple::thumb: |
767 | if (getTriple().getEnvironment() == llvm::Triple::GNUEABIHF) |
768 | MultiarchIncludeDirs = ARMHFMultiarchIncludeDirs; |
769 | else |
770 | MultiarchIncludeDirs = ARMMultiarchIncludeDirs; |
771 | break; |
772 | case llvm::Triple::armeb: |
773 | case llvm::Triple::thumbeb: |
774 | if (getTriple().getEnvironment() == llvm::Triple::GNUEABIHF) |
775 | MultiarchIncludeDirs = ARMEBHFMultiarchIncludeDirs; |
776 | else |
777 | MultiarchIncludeDirs = ARMEBMultiarchIncludeDirs; |
778 | break; |
779 | case llvm::Triple::mips: |
780 | if (getTriple().getSubArch() == llvm::Triple::MipsSubArch_r6) |
781 | MultiarchIncludeDirs = MIPSR6MultiarchIncludeDirs; |
782 | else |
783 | MultiarchIncludeDirs = MIPSMultiarchIncludeDirs; |
784 | break; |
785 | case llvm::Triple::mipsel: |
786 | if (getTriple().getSubArch() == llvm::Triple::MipsSubArch_r6) |
787 | MultiarchIncludeDirs = MIPSR6ELMultiarchIncludeDirs; |
788 | else |
789 | MultiarchIncludeDirs = MIPSELMultiarchIncludeDirs; |
790 | break; |
791 | case llvm::Triple::mips64: |
792 | if (getTriple().getSubArch() == llvm::Triple::MipsSubArch_r6) |
793 | if (getTriple().getEnvironment() == llvm::Triple::GNUABIN32) |
794 | MultiarchIncludeDirs = MIPSN32R6MultiarchIncludeDirs; |
795 | else |
796 | MultiarchIncludeDirs = MIPS64R6MultiarchIncludeDirs; |
797 | else if (getTriple().getEnvironment() == llvm::Triple::GNUABIN32) |
798 | MultiarchIncludeDirs = MIPSN32MultiarchIncludeDirs; |
799 | else |
800 | MultiarchIncludeDirs = MIPS64MultiarchIncludeDirs; |
801 | break; |
802 | case llvm::Triple::mips64el: |
803 | if (getTriple().getSubArch() == llvm::Triple::MipsSubArch_r6) |
804 | if (getTriple().getEnvironment() == llvm::Triple::GNUABIN32) |
805 | MultiarchIncludeDirs = MIPSN32R6ELMultiarchIncludeDirs; |
806 | else |
807 | MultiarchIncludeDirs = MIPS64R6ELMultiarchIncludeDirs; |
808 | else if (getTriple().getEnvironment() == llvm::Triple::GNUABIN32) |
809 | MultiarchIncludeDirs = MIPSN32ELMultiarchIncludeDirs; |
810 | else |
811 | MultiarchIncludeDirs = MIPS64ELMultiarchIncludeDirs; |
812 | break; |
813 | case llvm::Triple::ppc: |
814 | MultiarchIncludeDirs = PPCMultiarchIncludeDirs; |
815 | break; |
816 | case llvm::Triple::ppc64: |
817 | MultiarchIncludeDirs = PPC64MultiarchIncludeDirs; |
818 | break; |
819 | case llvm::Triple::ppc64le: |
820 | MultiarchIncludeDirs = PPC64LEMultiarchIncludeDirs; |
821 | break; |
822 | case llvm::Triple::sparc: |
823 | MultiarchIncludeDirs = SparcMultiarchIncludeDirs; |
824 | break; |
825 | case llvm::Triple::sparcv9: |
826 | MultiarchIncludeDirs = Sparc64MultiarchIncludeDirs; |
827 | break; |
828 | case llvm::Triple::systemz: |
829 | MultiarchIncludeDirs = SYSTEMZMultiarchIncludeDirs; |
830 | break; |
831 | default: |
832 | break; |
833 | } |
834 | |
835 | const std::string AndroidMultiarchIncludeDir = |
836 | std::string("/usr/include/") + |
837 | getMultiarchTriple(D, getTriple(), SysRoot); |
838 | const StringRef AndroidMultiarchIncludeDirs[] = {AndroidMultiarchIncludeDir}; |
839 | if (getTriple().isAndroid()) |
840 | MultiarchIncludeDirs = AndroidMultiarchIncludeDirs; |
841 | |
842 | for (StringRef Dir : MultiarchIncludeDirs) { |
843 | if (D.getVFS().exists(SysRoot + Dir)) { |
844 | addExternCSystemInclude(DriverArgs, CC1Args, SysRoot + Dir); |
845 | break; |
846 | } |
847 | } |
848 | |
849 | if (getTriple().getOS() == llvm::Triple::RTEMS) |
850 | return; |
851 | |
852 | |
853 | |
854 | |
855 | addExternCSystemInclude(DriverArgs, CC1Args, SysRoot + "/include"); |
856 | |
857 | addExternCSystemInclude(DriverArgs, CC1Args, SysRoot + "/usr/include"); |
858 | } |
859 | |
860 | static std::string DetectLibcxxIncludePath(StringRef base) { |
861 | std::error_code EC; |
862 | int MaxVersion = 0; |
863 | std::string MaxVersionString = ""; |
864 | for (llvm::sys::fs::directory_iterator LI(base, EC), LE; !EC && LI != LE; |
865 | LI = LI.increment(EC)) { |
866 | StringRef VersionText = llvm::sys::path::filename(LI->path()); |
867 | int Version; |
868 | if (VersionText[0] == 'v' && |
869 | !VersionText.slice(1, StringRef::npos).getAsInteger(10, Version)) { |
870 | if (Version > MaxVersion) { |
871 | MaxVersion = Version; |
872 | MaxVersionString = VersionText; |
873 | } |
874 | } |
875 | } |
876 | return MaxVersion ? (base + "/" + MaxVersionString).str() : ""; |
877 | } |
878 | |
879 | void Linux::addLibCxxIncludePaths(const llvm::opt::ArgList &DriverArgs, |
880 | llvm::opt::ArgStringList &CC1Args) const { |
881 | const std::string& SysRoot = computeSysRoot(); |
882 | const std::string LibCXXIncludePathCandidates[] = { |
883 | DetectLibcxxIncludePath(getDriver().ResourceDir + "/include/c++"), |
884 | DetectLibcxxIncludePath(getDriver().Dir + "/../include/c++"), |
885 | |
886 | |
887 | |
888 | DetectLibcxxIncludePath(SysRoot + "/usr/local/include/c++"), |
889 | DetectLibcxxIncludePath(SysRoot + "/usr/include/c++") }; |
890 | for (const auto &IncludePath : LibCXXIncludePathCandidates) { |
891 | if (IncludePath.empty() || !getVFS().exists(IncludePath)) |
892 | continue; |
893 | |
894 | addSystemInclude(DriverArgs, CC1Args, IncludePath); |
895 | return; |
896 | } |
897 | } |
898 | |
899 | void Linux::addLibStdCxxIncludePaths(const llvm::opt::ArgList &DriverArgs, |
900 | llvm::opt::ArgStringList &CC1Args) const { |
901 | |
902 | |
903 | if (!GCCInstallation.isValid()) |
904 | return; |
905 | |
906 | |
907 | |
908 | |
909 | StringRef LibDir = GCCInstallation.getParentLibPath(); |
910 | StringRef InstallDir = GCCInstallation.getInstallPath(); |
911 | StringRef TripleStr = GCCInstallation.getTriple().str(); |
912 | const Multilib &Multilib = GCCInstallation.getMultilib(); |
913 | const std::string GCCMultiarchTriple = getMultiarchTriple( |
914 | getDriver(), GCCInstallation.getTriple(), getDriver().SysRoot); |
915 | const std::string TargetMultiarchTriple = |
916 | getMultiarchTriple(getDriver(), getTriple(), getDriver().SysRoot); |
917 | const GCCVersion &Version = GCCInstallation.getVersion(); |
918 | |
919 | |
920 | if (addLibStdCXXIncludePaths(LibDir.str() + "/../include", |
921 | "/c++/" + Version.Text, TripleStr, |
922 | GCCMultiarchTriple, TargetMultiarchTriple, |
923 | Multilib.includeSuffix(), DriverArgs, CC1Args)) |
924 | return; |
925 | |
926 | |
927 | |
928 | const std::string LibStdCXXIncludePathCandidates[] = { |
929 | |
930 | |
931 | InstallDir.str() + "/include/g++-v" + Version.Text, |
932 | InstallDir.str() + "/include/g++-v" + Version.MajorStr + "." + |
933 | Version.MinorStr, |
934 | InstallDir.str() + "/include/g++-v" + Version.MajorStr, |
935 | |
936 | LibDir.str() + "/../" + TripleStr.str() + "/include/c++/" + Version.Text, |
937 | |
938 | |
939 | LibDir.str() + "/../include/c++", |
940 | |
941 | |
942 | LibDir.str() + "/../include/g++", |
943 | }; |
944 | |
945 | for (const auto &IncludePath : LibStdCXXIncludePathCandidates) { |
946 | if (addLibStdCXXIncludePaths(IncludePath, "", TripleStr, |
947 | "", |
948 | "", |
949 | Multilib.includeSuffix(), DriverArgs, CC1Args)) |
950 | break; |
951 | } |
952 | } |
953 | |
954 | void Linux::AddCudaIncludeArgs(const ArgList &DriverArgs, |
955 | ArgStringList &CC1Args) const { |
956 | CudaInstallation.AddCudaIncludeArgs(DriverArgs, CC1Args); |
957 | } |
958 | |
959 | void Linux::AddIAMCUIncludeArgs(const ArgList &DriverArgs, |
960 | ArgStringList &CC1Args) const { |
961 | if (GCCInstallation.isValid()) { |
962 | CC1Args.push_back("-isystem"); |
963 | CC1Args.push_back(DriverArgs.MakeArgString( |
964 | GCCInstallation.getParentLibPath() + "/../" + |
965 | GCCInstallation.getTriple().str() + "/include")); |
966 | } |
967 | } |
968 | |
969 | bool Linux::isPIEDefault() const { |
970 | return (getTriple().isAndroid() && !getTriple().isAndroidVersionLT(16)) || |
971 | getTriple().isMusl() || getSanitizerArgs().requiresPIE(); |
972 | } |
973 | |
974 | bool Linux::isNoExecStackDefault() const { |
975 | return getTriple().isAndroid(); |
976 | } |
977 | |
978 | bool Linux::IsMathErrnoDefault() const { |
979 | if (getTriple().isAndroid()) |
980 | return false; |
981 | return Generic_ELF::IsMathErrnoDefault(); |
982 | } |
983 | |
984 | SanitizerMask Linux::getSupportedSanitizers() const { |
985 | const bool IsX86 = getTriple().getArch() == llvm::Triple::x86; |
986 | const bool IsX86_64 = getTriple().getArch() == llvm::Triple::x86_64; |
987 | const bool IsMIPS = getTriple().isMIPS32(); |
988 | const bool IsMIPS64 = getTriple().isMIPS64(); |
989 | const bool IsPowerPC64 = getTriple().getArch() == llvm::Triple::ppc64 || |
990 | getTriple().getArch() == llvm::Triple::ppc64le; |
991 | const bool IsAArch64 = getTriple().getArch() == llvm::Triple::aarch64 || |
992 | getTriple().getArch() == llvm::Triple::aarch64_be; |
993 | const bool IsArmArch = getTriple().getArch() == llvm::Triple::arm || |
994 | getTriple().getArch() == llvm::Triple::thumb || |
995 | getTriple().getArch() == llvm::Triple::armeb || |
996 | getTriple().getArch() == llvm::Triple::thumbeb; |
997 | SanitizerMask Res = ToolChain::getSupportedSanitizers(); |
998 | Res |= SanitizerKind::Address; |
999 | Res |= SanitizerKind::Fuzzer; |
1000 | Res |= SanitizerKind::FuzzerNoLink; |
1001 | Res |= SanitizerKind::KernelAddress; |
1002 | Res |= SanitizerKind::Memory; |
1003 | Res |= SanitizerKind::Vptr; |
1004 | Res |= SanitizerKind::SafeStack; |
1005 | if (IsX86_64 || IsMIPS64 || IsAArch64) |
1006 | Res |= SanitizerKind::DataFlow; |
1007 | if (IsX86_64 || IsMIPS64 || IsAArch64 || IsX86 || IsArmArch || IsPowerPC64) |
1008 | Res |= SanitizerKind::Leak; |
1009 | if (IsX86_64 || IsMIPS64 || IsAArch64 || IsPowerPC64) |
1010 | Res |= SanitizerKind::Thread; |
1011 | if (IsX86_64) |
1012 | Res |= SanitizerKind::KernelMemory; |
1013 | if (IsX86 || IsX86_64) |
1014 | Res |= SanitizerKind::Function; |
1015 | if (IsX86_64 || IsMIPS64 || IsAArch64 || IsX86 || IsMIPS || IsArmArch || |
1016 | IsPowerPC64) |
1017 | Res |= SanitizerKind::Scudo; |
1018 | if (IsX86_64 || IsAArch64) { |
1019 | Res |= SanitizerKind::HWAddress; |
1020 | Res |= SanitizerKind::KernelHWAddress; |
1021 | } |
1022 | return Res; |
1023 | } |
1024 | |
1025 | void Linux::addProfileRTLibs(const llvm::opt::ArgList &Args, |
1026 | llvm::opt::ArgStringList &CmdArgs) const { |
1027 | if (!needsProfileRT(Args)) return; |
1028 | |
1029 | |
1030 | |
1031 | if ((!Args.hasArg(options::OPT_coverage)) && (!Args.hasArg(options::OPT_ftest_coverage))) |
1032 | CmdArgs.push_back(Args.MakeArgString( |
1033 | Twine("-u", llvm::getInstrProfRuntimeHookVarName()))); |
1034 | ToolChain::addProfileRTLibs(Args, CmdArgs); |
1035 | } |
1036 | |