diff options
Diffstat (limited to 'lib/Driver/ToolChains/Linux.cpp')
-rw-r--r-- | lib/Driver/ToolChains/Linux.cpp | 91 |
1 files changed, 51 insertions, 40 deletions
diff --git a/lib/Driver/ToolChains/Linux.cpp b/lib/Driver/ToolChains/Linux.cpp index 65ab9b2daf54..d900508ad938 100644 --- a/lib/Driver/ToolChains/Linux.cpp +++ b/lib/Driver/ToolChains/Linux.cpp @@ -1,9 +1,8 @@ //===--- Linux.h - Linux ToolChain Implementations --------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// @@ -45,6 +44,7 @@ static std::string getMultiarchTriple(const Driver &D, TargetTriple.getEnvironment(); bool IsAndroid = TargetTriple.isAndroid(); bool IsMipsR6 = TargetTriple.getSubArch() == llvm::Triple::MipsSubArch_r6; + bool IsMipsN32Abi = TargetTriple.getEnvironment() == llvm::Triple::GNUABIN32; // For most architectures, just use whatever we have rather than trying to be // clever. @@ -103,33 +103,37 @@ static std::string getMultiarchTriple(const Driver &D, return "aarch64_be-linux-gnu"; break; case llvm::Triple::mips: { - std::string Arch = IsMipsR6 ? "mipsisa32r6" : "mips"; - if (D.getVFS().exists(SysRoot + "/lib/" + Arch + "-linux-gnu")) - return Arch + "-linux-gnu"; + std::string MT = IsMipsR6 ? "mipsisa32r6-linux-gnu" : "mips-linux-gnu"; + if (D.getVFS().exists(SysRoot + "/lib/" + MT)) + return MT; break; } case llvm::Triple::mipsel: { if (IsAndroid) return "mipsel-linux-android"; - std::string Arch = IsMipsR6 ? "mipsisa32r6el" : "mipsel"; - if (D.getVFS().exists(SysRoot + "/lib/" + Arch + "-linux-gnu")) - return Arch + "-linux-gnu"; + std::string MT = IsMipsR6 ? "mipsisa32r6el-linux-gnu" : "mipsel-linux-gnu"; + if (D.getVFS().exists(SysRoot + "/lib/" + MT)) + return MT; break; } case llvm::Triple::mips64: { - std::string Arch = IsMipsR6 ? "mipsisa64r6" : "mips64"; - std::string ABI = llvm::Triple::getEnvironmentTypeName(TargetEnvironment); - if (D.getVFS().exists(SysRoot + "/lib/" + Arch + "-linux-" + ABI)) - return Arch + "-linux-" + ABI; + std::string MT = std::string(IsMipsR6 ? "mipsisa64r6" : "mips64") + + "-linux-" + (IsMipsN32Abi ? "gnuabin32" : "gnuabi64"); + if (D.getVFS().exists(SysRoot + "/lib/" + MT)) + return MT; + if (D.getVFS().exists(SysRoot + "/lib/mips64-linux-gnu")) + return "mips64-linux-gnu"; break; } case llvm::Triple::mips64el: { if (IsAndroid) return "mips64el-linux-android"; - std::string Arch = IsMipsR6 ? "mipsisa64r6el" : "mips64el"; - std::string ABI = llvm::Triple::getEnvironmentTypeName(TargetEnvironment); - if (D.getVFS().exists(SysRoot + "/lib/" + Arch + "-linux-" + ABI)) - return Arch + "-linux-" + ABI; + std::string MT = std::string(IsMipsR6 ? "mipsisa64r6el" : "mips64el") + + "-linux-" + (IsMipsN32Abi ? "gnuabin32" : "gnuabi64"); + if (D.getVFS().exists(SysRoot + "/lib/" + MT)) + return MT; + if (D.getVFS().exists(SysRoot + "/lib/mips64el-linux-gnu")) + return "mips64el-linux-gnu"; break; } case llvm::Triple::ppc: @@ -230,9 +234,11 @@ Linux::Linux(const Driver &D, const llvm::Triple &Triple, const ArgList &Args) // used to target i386. // FIXME: This seems unlikely to be Linux-specific. ToolChain::path_list &PPaths = getProgramPaths(); - PPaths.push_back(Twine(GCCInstallation.getParentLibPath() + "/../" + - GCCInstallation.getTriple().str() + "/bin") - .str()); + if (GCCInstallation.isValid()) { + PPaths.push_back(Twine(GCCInstallation.getParentLibPath() + "/../" + + GCCInstallation.getTriple().str() + "/bin") + .str()); + } Distro Distro(D.getVFS()); @@ -270,8 +276,7 @@ Linux::Linux(const Driver &D, const llvm::Triple &Triple, const ArgList &Args) const bool IsAndroid = Triple.isAndroid(); const bool IsMips = Triple.isMIPS(); const bool IsHexagon = Arch == llvm::Triple::hexagon; - const bool IsRISCV = - Arch == llvm::Triple::riscv32 || Arch == llvm::Triple::riscv64; + const bool IsRISCV = Triple.isRISCV(); if (IsMips && !SysRoot.empty()) ExtraOpts.push_back("--sysroot=" + SysRoot); @@ -295,9 +300,6 @@ Linux::Linux(const Driver &D, const llvm::Triple &Triple, const ArgList &Args) ExtraOpts.push_back("--hash-style=both"); } - if (Distro.IsRedhat() && Distro != Distro::RHEL5 && Distro != Distro::RHEL6) - ExtraOpts.push_back("--no-add-needed"); - #ifdef ENABLE_LINKER_BUILD_ID ExtraOpts.push_back("--build-id"); #endif @@ -326,8 +328,9 @@ Linux::Linux(const Driver &D, const llvm::Triple &Triple, const ArgList &Args) // Sourcery CodeBench MIPS toolchain holds some libraries under // a biarch-like suffix of the GCC installation. - addPathIfExists(D, GCCInstallation.getInstallPath() + SelectedMultilib.gccSuffix(), - Paths); + 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 @@ -637,8 +640,9 @@ std::string Linux::getDynamicLinker(const ArgList &Args) const { } } - if (Distro == Distro::Exherbo && (Triple.getVendor() == llvm::Triple::UnknownVendor || - Triple.getVendor() == llvm::Triple::PC)) + if (Distro == Distro::Exherbo && + (Triple.getVendor() == llvm::Triple::UnknownVendor || + Triple.getVendor() == llvm::Triple::PC)) return "/usr/" + Triple.str() + "/lib/" + Loader; return "/" + LibDir + "/" + Loader; } @@ -858,12 +862,13 @@ void Linux::AddClangSystemIncludeArgs(const ArgList &DriverArgs, addExternCSystemInclude(DriverArgs, CC1Args, SysRoot + "/usr/include"); } -static std::string DetectLibcxxIncludePath(StringRef base) { +static std::string DetectLibcxxIncludePath(llvm::vfs::FileSystem &vfs, + StringRef base) { std::error_code EC; int MaxVersion = 0; std::string MaxVersionString = ""; - for (llvm::sys::fs::directory_iterator LI(base, EC), LE; !EC && LI != LE; - LI = LI.increment(EC)) { + for (llvm::vfs::directory_iterator LI = vfs.dir_begin(base, EC), LE; + !EC && LI != LE; LI = LI.increment(EC)) { StringRef VersionText = llvm::sys::path::filename(LI->path()); int Version; if (VersionText[0] == 'v' && @@ -881,13 +886,12 @@ 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++"), + DetectLibcxxIncludePath(getVFS(), 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(SysRoot + "/usr/local/include/c++"), - DetectLibcxxIncludePath(SysRoot + "/usr/include/c++") }; + DetectLibcxxIncludePath(getVFS(), SysRoot + "/usr/local/include/c++"), + DetectLibcxxIncludePath(getVFS(), SysRoot + "/usr/include/c++") }; for (const auto &IncludePath : LibCXXIncludePathCandidates) { if (IncludePath.empty() || !getVFS().exists(IncludePath)) continue; @@ -972,6 +976,10 @@ bool Linux::isPIEDefault() const { getTriple().isMusl() || getSanitizerArgs().requiresPIE(); } +bool Linux::isNoExecStackDefault() const { + return getTriple().isAndroid(); +} + bool Linux::IsMathErrnoDefault() const { if (getTriple().isAndroid()) return false; @@ -993,6 +1001,8 @@ SanitizerMask Linux::getSupportedSanitizers() const { getTriple().getArch() == llvm::Triple::thumbeb; SanitizerMask Res = ToolChain::getSupportedSanitizers(); Res |= SanitizerKind::Address; + Res |= SanitizerKind::PointerCompare; + Res |= SanitizerKind::PointerSubtract; Res |= SanitizerKind::Fuzzer; Res |= SanitizerKind::FuzzerNoLink; Res |= SanitizerKind::KernelAddress; @@ -1007,8 +1017,6 @@ SanitizerMask Linux::getSupportedSanitizers() const { Res |= SanitizerKind::Thread; if (IsX86_64) Res |= SanitizerKind::KernelMemory; - if (IsX86_64 || IsMIPS64) - Res |= SanitizerKind::Efficiency; if (IsX86 || IsX86_64) Res |= SanitizerKind::Function; if (IsX86_64 || IsMIPS64 || IsAArch64 || IsX86 || IsMIPS || IsArmArch || @@ -1018,6 +1026,8 @@ SanitizerMask Linux::getSupportedSanitizers() const { Res |= SanitizerKind::HWAddress; Res |= SanitizerKind::KernelHWAddress; } + if (IsAArch64) + Res |= SanitizerKind::MemTag; return Res; } @@ -1027,7 +1037,8 @@ void Linux::addProfileRTLibs(const llvm::opt::ArgList &Args, // Add linker option -u__llvm_runtime_variable to cause runtime // initialization module to be linked in. - if ((!Args.hasArg(options::OPT_coverage)) && (!Args.hasArg(options::OPT_ftest_coverage))) + if ((!Args.hasArg(options::OPT_coverage)) && + (!Args.hasArg(options::OPT_ftest_coverage))) CmdArgs.push_back(Args.MakeArgString( Twine("-u", llvm::getInstrProfRuntimeHookVarName()))); ToolChain::addProfileRTLibs(Args, CmdArgs); |