diff options
Diffstat (limited to 'clang/lib/Driver/ToolChains/Linux.cpp')
-rw-r--r-- | clang/lib/Driver/ToolChains/Linux.cpp | 175 |
1 files changed, 50 insertions, 125 deletions
diff --git a/clang/lib/Driver/ToolChains/Linux.cpp b/clang/lib/Driver/ToolChains/Linux.cpp index bff1ab1009be..180350476c38 100644 --- a/clang/lib/Driver/ToolChains/Linux.cpp +++ b/clang/lib/Driver/ToolChains/Linux.cpp @@ -208,15 +208,6 @@ static StringRef getOSLibDir(const llvm::Triple &Triple, const ArgList &Args) { return Triple.isArch32Bit() ? "lib" : "lib64"; } -static void addMultilibsFilePaths(const Driver &D, const MultilibSet &Multilibs, - const Multilib &Multilib, - StringRef InstallPath, - ToolChain::path_list &Paths) { - if (const auto &PathsCallback = Multilibs.filePathsCallback()) - for (const auto &Path : PathsCallback(Multilib)) - addPathIfExists(D, InstallPath + Path, Paths); -} - Linux::Linux(const Driver &D, const llvm::Triple &Triple, const ArgList &Args) : Generic_ELF(D, Triple, Args) { GCCInstallation.init(Triple, Args); @@ -224,21 +215,9 @@ Linux::Linux(const Driver &D, const llvm::Triple &Triple, const ArgList &Args) SelectedMultilib = GCCInstallation.getMultilib(); llvm::Triple::ArchType Arch = Triple.getArch(); std::string SysRoot = computeSysRoot(); - - // Cross-compiling binutils and GCC installations (vanilla and openSUSE at - // least) put various tools in a triple-prefixed directory off of the parent - // of the GCC installation. We use the GCC triple here to ensure that we end - // up with tools that support the same amount of cross compiling as the - // detected GCC installation. For example, if we find a GCC installation - // targeting x86_64, but it is a bi-arch GCC installation, it can also be - // used to target i386. - // FIXME: This seems unlikely to be Linux-specific. ToolChain::path_list &PPaths = getProgramPaths(); - if (GCCInstallation.isValid()) { - PPaths.push_back(Twine(GCCInstallation.getParentLibPath() + "/../" + - GCCInstallation.getTriple().str() + "/bin") - .str()); - } + + Generic_GCC::PushPPaths(PPaths); Distro Distro(D.getVFS(), Triple); @@ -253,10 +232,9 @@ Linux::Linux(const Driver &D, const llvm::Triple &Triple, const ArgList &Args) ExtraOpts.push_back("relro"); } - // The lld default page size is too large for Aarch64, which produces much - // larger .so files and images for arm64 device targets. Use 4KB page size - // for Android arm64 targets instead. - if (Triple.isAArch64() && Triple.isAndroid()) { + // Android ARM/AArch64 use max-page-size=4096 to reduce VMA usage. Note, lld + // from 11 onwards default max-page-size to 65536 for both ARM and AArch64. + if ((Triple.isARM() || Triple.isAArch64()) && Triple.isAndroid()) { ExtraOpts.push_back("-z"); ExtraOpts.push_back("max-page-size=4096"); } @@ -314,60 +292,10 @@ Linux::Linux(const Driver &D, const llvm::Triple &Triple, const ArgList &Args) // to the link paths. path_list &Paths = getFilePaths(); - const std::string OSLibDir = getOSLibDir(Triple, Args); + const std::string OSLibDir = std::string(getOSLibDir(Triple, Args)); const std::string MultiarchTriple = getMultiarchTriple(D, Triple, SysRoot); - // Add the multilib suffixed paths where they are available. - if (GCCInstallation.isValid()) { - const llvm::Triple &GCCTriple = GCCInstallation.getTriple(); - const std::string &LibPath = GCCInstallation.getParentLibPath(); - - // Add toolchain / multilib specific file paths. - addMultilibsFilePaths(D, Multilibs, SelectedMultilib, - GCCInstallation.getInstallPath(), Paths); - - // Sourcery CodeBench MIPS toolchain holds some libraries under - // a biarch-like suffix of the GCC installation. - addPathIfExists( - D, GCCInstallation.getInstallPath() + SelectedMultilib.gccSuffix(), - Paths); - - // GCC cross compiling toolchains will install target libraries which ship - // as part of the toolchain under <prefix>/<triple>/<libdir> rather than as - // any part of the GCC installation in - // <prefix>/<libdir>/gcc/<triple>/<version>. This decision is somewhat - // debatable, but is the reality today. We need to search this tree even - // when we have a sysroot somewhere else. It is the responsibility of - // whomever is doing the cross build targeting a sysroot using a GCC - // installation that is *not* within the system root to ensure two things: - // - // 1) Any DSOs that are linked in from this tree or from the install path - // above must be present on the system root and found via an - // appropriate rpath. - // 2) There must not be libraries installed into - // <prefix>/<triple>/<libdir> unless they should be preferred over - // those within the system root. - // - // Note that this matches the GCC behavior. See the below comment for where - // Clang diverges from GCC's behavior. - addPathIfExists(D, LibPath + "/../" + GCCTriple.str() + "/lib/../" + - OSLibDir + SelectedMultilib.osSuffix(), - Paths); - - // If the GCC installation we found is inside of the sysroot, we want to - // prefer libraries installed in the parent prefix of the GCC installation. - // It is important to *not* use these paths when the GCC installation is - // outside of the system root as that can pick up unintended libraries. - // This usually happens when there is an external cross compiler on the - // host system, and a more minimal sysroot available that is the target of - // the cross. Note that GCC does include some of these directories in some - // configurations but this seems somewhere between questionable and simply - // a bug. - if (StringRef(LibPath).startswith(SysRoot)) { - addPathIfExists(D, LibPath + "/" + MultiarchTriple, Paths); - addPathIfExists(D, LibPath + "/../" + OSLibDir, Paths); - } - } + Generic_GCC::AddMultilibPaths(D, SysRoot, OSLibDir, MultiarchTriple, Paths); // Similar to the logic for GCC above, if we currently running Clang inside // of the requested system root, add its parent library paths to @@ -411,36 +339,7 @@ Linux::Linux(const Driver &D, const llvm::Triple &Triple, const ArgList &Args) addPathIfExists(D, SysRoot + "/usr/" + OSLibDir + "/" + ABIName, Paths); } - // Try walking via the GCC triple path in case of biarch or multiarch GCC - // installations with strange symlinks. - if (GCCInstallation.isValid()) { - addPathIfExists(D, - SysRoot + "/usr/lib/" + GCCInstallation.getTriple().str() + - "/../../" + OSLibDir, - Paths); - - // Add the 'other' biarch variant path - Multilib BiarchSibling; - if (GCCInstallation.getBiarchSibling(BiarchSibling)) { - addPathIfExists(D, GCCInstallation.getInstallPath() + - BiarchSibling.gccSuffix(), - Paths); - } - - // See comments above on the multilib variant for details of why this is - // included even from outside the sysroot. - const std::string &LibPath = GCCInstallation.getParentLibPath(); - const llvm::Triple &GCCTriple = GCCInstallation.getTriple(); - const Multilib &Multilib = GCCInstallation.getMultilib(); - addPathIfExists(D, LibPath + "/../" + GCCTriple.str() + "/lib" + - Multilib.osSuffix(), - Paths); - - // See comments above on the multilib variant for details of why this is - // only included from within the sysroot. - if (StringRef(LibPath).startswith(SysRoot)) - addPathIfExists(D, LibPath, Paths); - } + Generic_GCC::AddMultiarchPaths(D, SysRoot, OSLibDir, Paths); // Similar to the logic for GCC above, if we are currently running Clang // inside of the requested system root, add its parent library path to those @@ -464,6 +363,10 @@ bool Linux::HasNativeLLVMSupport() const { return true; } Tool *Linux::buildLinker() const { return new tools::gnutools::Linker(*this); } +Tool *Linux::buildStaticLibTool() const { + return new tools::gnutools::StaticLibTool(*this); +} + Tool *Linux::buildAssembler() const { return new tools::gnutools::Assembler(*this); } @@ -638,6 +541,8 @@ std::string Linux::getDynamicLinker(const ArgList &Args) const { Loader = X32 ? "ld-linux-x32.so.2" : "ld-linux-x86-64.so.2"; break; } + case llvm::Triple::ve: + return "/opt/nec/ve/lib/ld-linux-ve.so.1"; } if (Distro == Distro::Exherbo && @@ -674,7 +579,7 @@ void Linux::AddClangSystemIncludeArgs(const ArgList &DriverArgs, CIncludeDirs.split(dirs, ":"); for (StringRef dir : dirs) { StringRef Prefix = - llvm::sys::path::is_absolute(dir) ? StringRef(SysRoot) : ""; + llvm::sys::path::is_absolute(dir) ? "" : StringRef(SysRoot); addExternCSystemInclude(DriverArgs, CC1Args, Prefix + dir); } return; @@ -683,15 +588,7 @@ void Linux::AddClangSystemIncludeArgs(const ArgList &DriverArgs, // Lacking those, try to detect the correct set of system includes for the // target triple. - // Add include directories specific to the selected multilib set and multilib. - if (GCCInstallation.isValid()) { - const auto &Callback = Multilibs.includeDirsCallback(); - if (Callback) { - for (const auto &Path : Callback(GCCInstallation.getMultilib())) - addExternCSystemIncludeIfExists( - DriverArgs, CC1Args, GCCInstallation.getInstallPath() + Path); - } - } + AddMultilibIncludeArgs(DriverArgs, CC1Args); // Implement generic Debian multiarch support. const StringRef X86_64MultiarchIncludeDirs[] = { @@ -906,6 +803,11 @@ void Linux::AddCudaIncludeArgs(const ArgList &DriverArgs, CudaInstallation.AddCudaIncludeArgs(DriverArgs, CC1Args); } +void Linux::AddHIPIncludeArgs(const ArgList &DriverArgs, + ArgStringList &CC1Args) const { + RocmInstallation.AddHIPIncludeArgs(DriverArgs, CC1Args); +} + void Linux::AddIAMCUIncludeArgs(const ArgList &DriverArgs, ArgStringList &CC1Args) const { if (GCCInstallation.isValid()) { @@ -944,6 +846,7 @@ SanitizerMask Linux::getSupportedSanitizers() const { getTriple().getArch() == llvm::Triple::thumb || getTriple().getArch() == llvm::Triple::armeb || getTriple().getArch() == llvm::Triple::thumbeb; + const bool IsSystemZ = getTriple().getArch() == llvm::Triple::systemz; SanitizerMask Res = ToolChain::getSupportedSanitizers(); Res |= SanitizerKind::Address; Res |= SanitizerKind::PointerCompare; @@ -956,7 +859,8 @@ SanitizerMask Linux::getSupportedSanitizers() const { Res |= SanitizerKind::SafeStack; if (IsX86_64 || IsMIPS64 || IsAArch64) Res |= SanitizerKind::DataFlow; - if (IsX86_64 || IsMIPS64 || IsAArch64 || IsX86 || IsArmArch || IsPowerPC64) + if (IsX86_64 || IsMIPS64 || IsAArch64 || IsX86 || IsArmArch || IsPowerPC64 || + IsSystemZ) Res |= SanitizerKind::Leak; if (IsX86_64 || IsMIPS64 || IsAArch64 || IsPowerPC64) Res |= SanitizerKind::Thread; @@ -976,13 +880,34 @@ SanitizerMask Linux::getSupportedSanitizers() const { void Linux::addProfileRTLibs(const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs) const { - if (!needsProfileRT(Args)) return; - - // Add linker option -u__llvm_runtime_variable to cause runtime + // Add linker option -u__llvm_profile_runtime to cause runtime // initialization module to be linked in. - if ((!Args.hasArg(options::OPT_coverage)) && - (!Args.hasArg(options::OPT_ftest_coverage))) + if (needsProfileRT(Args)) CmdArgs.push_back(Args.MakeArgString( Twine("-u", llvm::getInstrProfRuntimeHookVarName()))); ToolChain::addProfileRTLibs(Args, CmdArgs); } + +llvm::DenormalMode +Linux::getDefaultDenormalModeForType(const llvm::opt::ArgList &DriverArgs, + const JobAction &JA, + const llvm::fltSemantics *FPType) const { + switch (getTriple().getArch()) { + case llvm::Triple::x86: + case llvm::Triple::x86_64: { + std::string Unused; + // DAZ and FTZ are turned on in crtfastmath.o + if (!DriverArgs.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles) && + isFastMathRuntimeAvailable(DriverArgs, Unused)) + return llvm::DenormalMode::getPreserveSign(); + return llvm::DenormalMode::getIEEE(); + } + default: + return llvm::DenormalMode::getIEEE(); + } +} + +void Linux::addExtraOpts(llvm::opt::ArgStringList &CmdArgs) const { + for (const auto &Opt : ExtraOpts) + CmdArgs.push_back(Opt.c_str()); +} |