diff options
Diffstat (limited to 'clang/lib/Driver/ToolChains.cpp')
-rw-r--r-- | clang/lib/Driver/ToolChains.cpp | 85 |
1 files changed, 59 insertions, 26 deletions
diff --git a/clang/lib/Driver/ToolChains.cpp b/clang/lib/Driver/ToolChains.cpp index 79290219c7f..2f1420e943f 100644 --- a/clang/lib/Driver/ToolChains.cpp +++ b/clang/lib/Driver/ToolChains.cpp @@ -4037,69 +4037,102 @@ std::string Linux::getDynamicLinker(const ArgList &Args) const { const llvm::Triple::ArchType Arch = getArch(); const llvm::Triple &Triple = getTriple(); + const enum Distro Distro = DetectDistro(getDriver(), Arch); + if (Triple.isAndroid()) return Triple.isArch64Bit() ? "/system/bin/linker64" : "/system/bin/linker"; + std::string LibDir; + std::string Loader; + switch (Arch) { - default: llvm_unreachable("unsupported architecture"); + default: + llvm_unreachable("unsupported architecture"); case llvm::Triple::aarch64: - return "/lib/ld-linux-aarch64.so.1"; + LibDir = "lib"; + Loader = "ld-linux-aarch64.so.1"; + break; case llvm::Triple::aarch64_be: - return "/lib/ld-linux-aarch64_be.so.1"; + LibDir = "lib"; + Loader = "ld-linux-aarch64_be.so.1"; + break; case llvm::Triple::arm: case llvm::Triple::thumb: case llvm::Triple::armeb: case llvm::Triple::thumbeb: { - const bool IsHardFloat = + const bool HF = Triple.getEnvironment() == llvm::Triple::GNUEABIHF || tools::arm::getARMFloatABI(*this, Args) == tools::arm::FloatABI::Hard; - return IsHardFloat ? "/lib/ld-linux-armhf.so.3" : "/lib/ld-linux.so.3"; + LibDir = "lib"; + Loader = HF ? "ld-linux-armhf.so.3" : "ld-linux.so.3"; + break; } case llvm::Triple::mips: case llvm::Triple::mipsel: case llvm::Triple::mips64: case llvm::Triple::mips64el: { - bool IsNaN2008 = tools::mips::isNaN2008(Args, Triple); 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); - std::string LibDir = - "/lib" + tools::mips::getMipsABILibSuffix(Args, Triple); - StringRef LibName; if (tools::mips::isUCLibc(Args)) - LibName = IsNaN2008 ? "ld-uClibc-mipsn8.so.0" : "ld-uClibc.so.0"; + Loader = IsNaN2008 ? "ld-uClibc-mipsn8.so.0" : "ld-uClibc.so.0"; else if (!Triple.hasEnvironment() && Triple.getVendor() == llvm::Triple::VendorType::MipsTechnologies) - LibName = LE ? "ld-musl-mipsel.so.1" : "ld-musl-mips.so.1"; + Loader = LE ? "ld-musl-mipsel.so.1" : "ld-musl-mips.so.1"; else - LibName = IsNaN2008 ? "ld-linux-mipsn8.so.1" : "ld.so.1"; + Loader = IsNaN2008 ? "ld-linux-mipsn8.so.1" : "ld.so.1"; - return (LibDir + "/" + LibName).str(); + break; } case llvm::Triple::ppc: - return "/lib/ld.so.1"; + LibDir = "lib"; + Loader = "ld.so.1"; + break; case llvm::Triple::ppc64: - return (tools::ppc::hasPPCAbiArg(Args, "elfv2")) ? "/lib64/ld64.so.2" - : "/lib64/ld64.so.1"; + LibDir = "lib64"; + Loader = + (tools::ppc::hasPPCAbiArg(Args, "elfv2")) ? "ld64.so.2" : "ld64.so.1"; + break; case llvm::Triple::ppc64le: - return (tools::ppc::hasPPCAbiArg(Args, "elfv1")) ? "/lib64/ld64.so.1" - : "/lib64/ld64.so.2"; + LibDir = "lib64"; + Loader = + (tools::ppc::hasPPCAbiArg(Args, "elfv1")) ? "ld64.so.1" : "ld64.so.2"; + break; case llvm::Triple::sparc: case llvm::Triple::sparcel: - return "/lib/ld-linux.so.2"; + LibDir = "lib"; + Loader = "ld-linux.so.2"; + break; case llvm::Triple::sparcv9: - return "/lib64/ld-linux.so.2"; + LibDir = "lib64"; + Loader = "ld-linux.so.2"; + break; case llvm::Triple::systemz: - return "/lib/ld64.so.1"; + LibDir = "lib"; + Loader = "ld64.so.1"; + break; case llvm::Triple::x86: - return "/lib/ld-linux.so.2"; - case llvm::Triple::x86_64: - return (Triple.getEnvironment() == llvm::Triple::GNUX32) - ? "/libx32/ld-linux-x32.so.2" - : "/lib64/ld-linux-x86-64.so.2"; + LibDir = "lib"; + Loader = "ld-linux.so.2"; + break; + case llvm::Triple::x86_64: { + bool X32 = Triple.getEnvironment() == llvm::Triple::GNUX32; + + LibDir = X32 ? "libx32" : "lib64"; + Loader = X32 ? "ld-linux-x32.so.2" : "ld-linux-x86-64.so.2"; + break; } + } + + if (Distro == Exherbo && (Triple.getVendor() == llvm::Triple::UnknownVendor || + Triple.getVendor() == llvm::Triple::PC)) + return "/usr/" + Triple.str() + "/lib/" + Loader; + return "/" + LibDir + "/" + Loader; } void Linux::AddClangSystemIncludeArgs(const ArgList &DriverArgs, |