diff options
Diffstat (limited to 'contrib/llvm/tools/clang/lib/Driver/ToolChains/Linux.cpp')
-rw-r--r-- | contrib/llvm/tools/clang/lib/Driver/ToolChains/Linux.cpp | 120 |
1 files changed, 101 insertions, 19 deletions
diff --git a/contrib/llvm/tools/clang/lib/Driver/ToolChains/Linux.cpp b/contrib/llvm/tools/clang/lib/Driver/ToolChains/Linux.cpp index 1301cdf114ae..d27f994d32ab 100644 --- a/contrib/llvm/tools/clang/lib/Driver/ToolChains/Linux.cpp +++ b/contrib/llvm/tools/clang/lib/Driver/ToolChains/Linux.cpp @@ -11,6 +11,7 @@ #include "Arch/ARM.h" #include "Arch/Mips.h" #include "Arch/PPC.h" +#include "Arch/RISCV.h" #include "CommonArgs.h" #include "clang/Basic/VirtualFileSystem.h" #include "clang/Config/config.h" @@ -21,6 +22,7 @@ #include "llvm/Option/ArgList.h" #include "llvm/ProfileData/InstrProf.h" #include "llvm/Support/Path.h" +#include "llvm/Support/ScopedPrinter.h" #include <system_error> using namespace clang::driver; @@ -30,7 +32,7 @@ using namespace llvm::opt; using tools::addPathIfExists; -/// \brief Get our best guess at the multiarch triple for a target. +/// Get our best guess at the multiarch triple for a target. /// /// Debian-based systems are starting to use a multiarch setup where they use /// a target-triple directory in the library and header search paths. @@ -41,6 +43,7 @@ static std::string getMultiarchTriple(const Driver &D, StringRef SysRoot) { llvm::Triple::EnvironmentType TargetEnvironment = TargetTriple.getEnvironment(); + bool IsAndroid = TargetTriple.isAndroid(); // For most architectures, just use whatever we have rather than trying to be // clever. @@ -54,7 +57,9 @@ static std::string getMultiarchTriple(const Driver &D, // regardless of what the actual target triple is. case llvm::Triple::arm: case llvm::Triple::thumb: - if (TargetEnvironment == llvm::Triple::GNUEABIHF) { + if (IsAndroid) { + return "arm-linux-androideabi"; + } else if (TargetEnvironment == llvm::Triple::GNUEABIHF) { if (D.getVFS().exists(SysRoot + "/lib/arm-linux-gnueabihf")) return "arm-linux-gnueabihf"; } else { @@ -73,16 +78,22 @@ static std::string getMultiarchTriple(const Driver &D, } break; case llvm::Triple::x86: + if (IsAndroid) + return "i686-linux-android"; if (D.getVFS().exists(SysRoot + "/lib/i386-linux-gnu")) return "i386-linux-gnu"; break; case llvm::Triple::x86_64: + if (IsAndroid) + return "x86_64-linux-android"; // We don't want this for x32, otherwise it will match x86_64 libs if (TargetEnvironment != llvm::Triple::GNUX32 && D.getVFS().exists(SysRoot + "/lib/x86_64-linux-gnu")) return "x86_64-linux-gnu"; break; case llvm::Triple::aarch64: + if (IsAndroid) + return "aarch64-linux-android"; if (D.getVFS().exists(SysRoot + "/lib/aarch64-linux-gnu")) return "aarch64-linux-gnu"; break; @@ -95,6 +106,8 @@ static std::string getMultiarchTriple(const Driver &D, return "mips-linux-gnu"; break; case llvm::Triple::mipsel: + if (IsAndroid) + return "mipsel-linux-android"; if (D.getVFS().exists(SysRoot + "/lib/mipsel-linux-gnu")) return "mipsel-linux-gnu"; break; @@ -105,6 +118,8 @@ static std::string getMultiarchTriple(const Driver &D, return "mips64-linux-gnuabi64"; break; case llvm::Triple::mips64el: + if (IsAndroid) + return "mips64el-linux-android"; if (D.getVFS().exists(SysRoot + "/lib/mips64el-linux-gnu")) return "mips64el-linux-gnu"; if (D.getVFS().exists(SysRoot + "/lib/mips64el-linux-gnuabi64")) @@ -141,7 +156,7 @@ static std::string getMultiarchTriple(const Driver &D, } static StringRef getOSLibDir(const llvm::Triple &Triple, const ArgList &Args) { - if (tools::isMipsArch(Triple.getArch())) { + if (Triple.isMIPS()) { if (Triple.isAndroid()) { StringRef CPUName; StringRef ABIName; @@ -176,6 +191,9 @@ static StringRef getOSLibDir(const llvm::Triple &Triple, const ArgList &Args) { Triple.getEnvironment() == llvm::Triple::GNUX32) return "libx32"; + if (Triple.getArch() == llvm::Triple::riscv32) + return "lib32"; + return Triple.isArch32Bit() ? "lib" : "lib64"; } @@ -220,12 +238,23 @@ Linux::Linux(const Driver &D, const llvm::Triple &Triple, const ArgList &Args) ExtraOpts.push_back("relro"); } + if (GCCInstallation.getParentLibPath().find("opt/rh/devtoolset") != + StringRef::npos) + // With devtoolset on RHEL, we want to add a bin directory that is relative + // to the detected gcc install, because if we are using devtoolset gcc then + // we want to use other tools from devtoolset (e.g. ld) instead of the + // standard system tools. + PPaths.push_back(Twine(GCCInstallation.getParentLibPath() + + "/../bin").str()); + if (Arch == llvm::Triple::arm || Arch == llvm::Triple::thumb) ExtraOpts.push_back("-X"); const bool IsAndroid = Triple.isAndroid(); - const bool IsMips = tools::isMipsArch(Arch); + const bool IsMips = Triple.isMIPS(); const bool IsHexagon = Arch == llvm::Triple::hexagon; + const bool IsRISCV = + Arch == llvm::Triple::riscv32 || Arch == llvm::Triple::riscv64; if (IsMips && !SysRoot.empty()) ExtraOpts.push_back("--sysroot=" + SysRoot); @@ -331,8 +360,28 @@ Linux::Linux(const Driver &D, const llvm::Triple &Triple, const ArgList &Args) addPathIfExists(D, SysRoot + "/lib/" + MultiarchTriple, Paths); addPathIfExists(D, SysRoot + "/lib/../" + OSLibDir, Paths); + + if (IsAndroid) { + // Android sysroots contain a library directory for each supported OS + // version as well as some unversioned libraries in the usual multiarch + // directory. + unsigned Major; + unsigned Minor; + unsigned Micro; + Triple.getEnvironmentVersion(Major, Minor, Micro); + addPathIfExists(D, + SysRoot + "/usr/lib/" + MultiarchTriple + "/" + + llvm::to_string(Major), + Paths); + } + addPathIfExists(D, SysRoot + "/usr/lib/" + MultiarchTriple, Paths); addPathIfExists(D, SysRoot + "/usr/lib/../" + OSLibDir, Paths); + if (IsRISCV) { + StringRef ABIName = tools::riscv::getRISCVABI(Args, Triple); + addPathIfExists(D, SysRoot + "/" + OSLibDir + "/" + ABIName, Paths); + 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. @@ -389,7 +438,16 @@ std::string Linux::computeSysRoot() const { if (!getDriver().SysRoot.empty()) return getDriver().SysRoot; - if (!GCCInstallation.isValid() || !tools::isMipsArch(getTriple().getArch())) + if (getTriple().isAndroid()) { + // Android toolchains typically include a sysroot at ../sysroot relative to + // the clang binary. + const StringRef ClangDir = getDriver().getInstalledDir(); + std::string AndroidSysRootPath = (ClangDir + "/../sysroot").str(); + if (getVFS().exists(AndroidSysRootPath)) + return AndroidSysRootPath; + } + + if (!GCCInstallation.isValid() || !getTriple().isMIPS()) return std::string(); // Standalone MIPS toolchains use different names for sysroot folder @@ -481,8 +539,6 @@ std::string Linux::getDynamicLinker(const ArgList &Args) const { case llvm::Triple::mipsel: case llvm::Triple::mips64: case llvm::Triple::mips64el: { - bool LE = (Triple.getArch() == llvm::Triple::mipsel) || - (Triple.getArch() == llvm::Triple::mips64el); bool IsNaN2008 = tools::mips::isNaN2008(Args, Triple); LibDir = "lib" + tools::mips::getMipsABILibSuffix(Args, Triple); @@ -491,7 +547,8 @@ std::string Linux::getDynamicLinker(const ArgList &Args) const { Loader = IsNaN2008 ? "ld-uClibc-mipsn8.so.0" : "ld-uClibc.so.0"; else if (!Triple.hasEnvironment() && Triple.getVendor() == llvm::Triple::VendorType::MipsTechnologies) - Loader = LE ? "ld-musl-mipsel.so.1" : "ld-musl-mips.so.1"; + Loader = + Triple.isLittleEndian() ? "ld-musl-mipsel.so.1" : "ld-musl-mips.so.1"; else Loader = IsNaN2008 ? "ld-linux-mipsn8.so.1" : "ld.so.1"; @@ -511,6 +568,18 @@ std::string Linux::getDynamicLinker(const ArgList &Args) const { Loader = (tools::ppc::hasPPCAbiArg(Args, "elfv1")) ? "ld64.so.1" : "ld64.so.2"; break; + case llvm::Triple::riscv32: { + StringRef ABIName = tools::riscv::getRISCVABI(Args, Triple); + LibDir = "lib"; + Loader = ("ld-linux-riscv32-" + ABIName + ".so.1").str(); + break; + } + case llvm::Triple::riscv64: { + StringRef ABIName = tools::riscv::getRISCVABI(Args, Triple); + LibDir = "lib"; + Loader = ("ld-linux-riscv64-" + ABIName + ".so.1").str(); + break; + } case llvm::Triple::sparc: case llvm::Triple::sparcel: LibDir = "lib"; @@ -694,6 +763,14 @@ void Linux::AddClangSystemIncludeArgs(const ArgList &DriverArgs, default: break; } + + const std::string AndroidMultiarchIncludeDir = + std::string("/usr/include/") + + getMultiarchTriple(D, getTriple(), SysRoot); + const StringRef AndroidMultiarchIncludeDirs[] = {AndroidMultiarchIncludeDir}; + if (getTriple().isAndroid()) + MultiarchIncludeDirs = AndroidMultiarchIncludeDirs; + for (StringRef Dir : MultiarchIncludeDirs) { if (D.getVFS().exists(SysRoot + Dir)) { addExternCSystemInclude(DriverArgs, CC1Args, SysRoot + Dir); @@ -731,21 +808,24 @@ static std::string DetectLibcxxIncludePath(StringRef base) { return MaxVersion ? (base + "/" + MaxVersionString).str() : ""; } -std::string Linux::findLibCxxIncludePath() const { +void Linux::addLibCxxIncludePaths(const llvm::opt::ArgList &DriverArgs, + llvm::opt::ArgStringList &CC1Args) const { + const std::string& SysRoot = computeSysRoot(); const std::string LibCXXIncludePathCandidates[] = { + DetectLibcxxIncludePath(getDriver().ResourceDir + "/include/c++"), DetectLibcxxIncludePath(getDriver().Dir + "/../include/c++"), // If this is a development, non-installed, clang, libcxx will // not be found at ../include/c++ but it likely to be found at // one of the following two locations: - DetectLibcxxIncludePath(getDriver().SysRoot + "/usr/local/include/c++"), - DetectLibcxxIncludePath(getDriver().SysRoot + "/usr/include/c++") }; + DetectLibcxxIncludePath(SysRoot + "/usr/local/include/c++"), + DetectLibcxxIncludePath(SysRoot + "/usr/include/c++") }; for (const auto &IncludePath : LibCXXIncludePathCandidates) { if (IncludePath.empty() || !getVFS().exists(IncludePath)) continue; // Use the first candidate that exists. - return IncludePath; + addSystemInclude(DriverArgs, CC1Args, IncludePath); + return; } - return ""; } void Linux::addLibStdCxxIncludePaths(const llvm::opt::ArgList &DriverArgs, @@ -823,8 +903,8 @@ bool Linux::isPIEDefault() const { SanitizerMask Linux::getSupportedSanitizers() const { const bool IsX86 = getTriple().getArch() == llvm::Triple::x86; const bool IsX86_64 = getTriple().getArch() == llvm::Triple::x86_64; - const bool IsMIPS64 = getTriple().getArch() == llvm::Triple::mips64 || - getTriple().getArch() == llvm::Triple::mips64el; + const bool IsMIPS = getTriple().isMIPS32(); + const bool IsMIPS64 = getTriple().isMIPS64(); const bool IsPowerPC64 = getTriple().getArch() == llvm::Triple::ppc64 || getTriple().getArch() == llvm::Triple::ppc64le; const bool IsAArch64 = getTriple().getArch() == llvm::Triple::aarch64 || @@ -838,6 +918,7 @@ SanitizerMask Linux::getSupportedSanitizers() const { Res |= SanitizerKind::Fuzzer; Res |= SanitizerKind::FuzzerNoLink; Res |= SanitizerKind::KernelAddress; + Res |= SanitizerKind::Memory; Res |= SanitizerKind::Vptr; Res |= SanitizerKind::SafeStack; if (IsX86_64 || IsMIPS64 || IsAArch64) @@ -846,16 +927,17 @@ SanitizerMask Linux::getSupportedSanitizers() const { Res |= SanitizerKind::Leak; if (IsX86_64 || IsMIPS64 || IsAArch64 || IsPowerPC64) Res |= SanitizerKind::Thread; - if (IsX86_64 || IsMIPS64 || IsPowerPC64 || IsAArch64) - Res |= SanitizerKind::Memory; if (IsX86_64 || IsMIPS64) Res |= SanitizerKind::Efficiency; if (IsX86 || IsX86_64) Res |= SanitizerKind::Function; - if (IsX86_64 || IsMIPS64 || IsAArch64 || IsX86 || IsArmArch) + if (IsX86_64 || IsMIPS64 || IsAArch64 || IsX86 || IsMIPS || IsArmArch || + IsPowerPC64) Res |= SanitizerKind::Scudo; - if (IsAArch64) + if (IsX86_64 || IsAArch64) { Res |= SanitizerKind::HWAddress; + Res |= SanitizerKind::KernelHWAddress; + } return Res; } |