aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Driver/ToolChains/Linux.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2019-01-19 10:04:05 +0000
committerDimitry Andric <dim@FreeBSD.org>2019-01-19 10:04:05 +0000
commit676fbe8105eeb6ff4bb2ed261cb212fcfdbe7b63 (patch)
tree02a1ac369cb734d0abfa5000dd86e5b7797e6a74 /lib/Driver/ToolChains/Linux.cpp
parentc7e70c433efc6953dc3888b9fbf9f3512d7da2b0 (diff)
downloadsrc-676fbe8105eeb6ff4bb2ed261cb212fcfdbe7b63.tar.gz
src-676fbe8105eeb6ff4bb2ed261cb212fcfdbe7b63.zip
Vendor import of clang trunk r351319 (just before the release_80 branchvendor/clang/clang-trunk-r351319
Notes
Notes: svn path=/vendor/clang/dist/; revision=343173 svn path=/vendor/clang/clang-trunk-r351319/; revision=343174; tag=vendor/clang/clang-trunk-r351319
Diffstat (limited to 'lib/Driver/ToolChains/Linux.cpp')
-rw-r--r--lib/Driver/ToolChains/Linux.cpp147
1 files changed, 110 insertions, 37 deletions
diff --git a/lib/Driver/ToolChains/Linux.cpp b/lib/Driver/ToolChains/Linux.cpp
index f8f36239180c..65ab9b2daf54 100644
--- a/lib/Driver/ToolChains/Linux.cpp
+++ b/lib/Driver/ToolChains/Linux.cpp
@@ -13,7 +13,6 @@
#include "Arch/PPC.h"
#include "Arch/RISCV.h"
#include "CommonArgs.h"
-#include "clang/Basic/VirtualFileSystem.h"
#include "clang/Config/config.h"
#include "clang/Driver/Distro.h"
#include "clang/Driver/Driver.h"
@@ -23,6 +22,7 @@
#include "llvm/ProfileData/InstrProf.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/ScopedPrinter.h"
+#include "llvm/Support/VirtualFileSystem.h"
#include <system_error>
using namespace clang::driver;
@@ -44,6 +44,7 @@ static std::string getMultiarchTriple(const Driver &D,
llvm::Triple::EnvironmentType TargetEnvironment =
TargetTriple.getEnvironment();
bool IsAndroid = TargetTriple.isAndroid();
+ bool IsMipsR6 = TargetTriple.getSubArch() == llvm::Triple::MipsSubArch_r6;
// For most architectures, just use whatever we have rather than trying to be
// clever.
@@ -101,30 +102,36 @@ static std::string getMultiarchTriple(const Driver &D,
if (D.getVFS().exists(SysRoot + "/lib/aarch64_be-linux-gnu"))
return "aarch64_be-linux-gnu";
break;
- case llvm::Triple::mips:
- if (D.getVFS().exists(SysRoot + "/lib/mips-linux-gnu"))
- return "mips-linux-gnu";
+ case llvm::Triple::mips: {
+ std::string Arch = IsMipsR6 ? "mipsisa32r6" : "mips";
+ if (D.getVFS().exists(SysRoot + "/lib/" + Arch + "-linux-gnu"))
+ return Arch + "-linux-gnu";
break;
- case llvm::Triple::mipsel:
+ }
+ case llvm::Triple::mipsel: {
if (IsAndroid)
return "mipsel-linux-android";
- if (D.getVFS().exists(SysRoot + "/lib/mipsel-linux-gnu"))
- return "mipsel-linux-gnu";
+ std::string Arch = IsMipsR6 ? "mipsisa32r6el" : "mipsel";
+ if (D.getVFS().exists(SysRoot + "/lib/" + Arch + "-linux-gnu"))
+ return Arch + "-linux-gnu";
break;
- case llvm::Triple::mips64:
- if (D.getVFS().exists(SysRoot + "/lib/mips64-linux-gnu"))
- return "mips64-linux-gnu";
- if (D.getVFS().exists(SysRoot + "/lib/mips64-linux-gnuabi64"))
- return "mips64-linux-gnuabi64";
+ }
+ 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;
break;
- case llvm::Triple::mips64el:
+ }
+ 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"))
- return "mips64el-linux-gnuabi64";
+ 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;
break;
+ }
case llvm::Triple::ppc:
if (D.getVFS().exists(SysRoot + "/lib/powerpc-linux-gnuspe"))
return "powerpc-linux-gnuspe";
@@ -210,6 +217,7 @@ Linux::Linux(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)
: Generic_ELF(D, Triple, Args) {
GCCInstallation.init(Triple, Args);
Multilibs = GCCInstallation.getMultilibs();
+ SelectedMultilib = GCCInstallation.getMultilib();
llvm::Triple::ArchType Arch = Triple.getArch();
std::string SysRoot = computeSysRoot();
@@ -228,16 +236,25 @@ Linux::Linux(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)
Distro Distro(D.getVFS());
- if (Distro.IsAlpineLinux()) {
+ if (Distro.IsAlpineLinux() || Triple.isAndroid()) {
ExtraOpts.push_back("-z");
ExtraOpts.push_back("now");
}
- if (Distro.IsOpenSUSE() || Distro.IsUbuntu() || Distro.IsAlpineLinux()) {
+ if (Distro.IsOpenSUSE() || Distro.IsUbuntu() || Distro.IsAlpineLinux() ||
+ Triple.isAndroid()) {
ExtraOpts.push_back("-z");
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()) {
+ ExtraOpts.push_back("-z");
+ ExtraOpts.push_back("max-page-size=4096");
+ }
+
if (GCCInstallation.getParentLibPath().find("opt/rh/devtoolset") !=
StringRef::npos)
// With devtoolset on RHEL, we want to add a bin directory that is relative
@@ -263,15 +280,18 @@ Linux::Linux(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)
// and the MIPS ABI require .dynsym to be sorted in different ways.
// .gnu.hash needs symbols to be grouped by hash code whereas the MIPS
// ABI requires a mapping between the GOT and the symbol table.
- // Android loader does not support .gnu.hash.
+ // Android loader does not support .gnu.hash until API 23.
// Hexagon linker/loader does not support .gnu.hash
- if (!IsMips && !IsAndroid && !IsHexagon) {
+ if (!IsMips && !IsHexagon) {
if (Distro.IsRedhat() || Distro.IsOpenSUSE() || Distro.IsAlpineLinux() ||
- (Distro.IsUbuntu() && Distro >= Distro::UbuntuMaverick))
+ (Distro.IsUbuntu() && Distro >= Distro::UbuntuMaverick) ||
+ (IsAndroid && !Triple.isAndroidVersionLT(23)))
ExtraOpts.push_back("--hash-style=gnu");
- if (Distro.IsDebian() || Distro.IsOpenSUSE() || Distro == Distro::UbuntuLucid ||
- Distro == Distro::UbuntuJaunty || Distro == Distro::UbuntuKarmic)
+ if (Distro.IsDebian() || Distro.IsOpenSUSE() ||
+ Distro == Distro::UbuntuLucid || Distro == Distro::UbuntuJaunty ||
+ Distro == Distro::UbuntuKarmic ||
+ (IsAndroid && Triple.isAndroidVersionLT(23)))
ExtraOpts.push_back("--hash-style=both");
}
@@ -299,16 +319,14 @@ Linux::Linux(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)
if (GCCInstallation.isValid()) {
const llvm::Triple &GCCTriple = GCCInstallation.getTriple();
const std::string &LibPath = GCCInstallation.getParentLibPath();
- const Multilib &Multilib = GCCInstallation.getMultilib();
- const MultilibSet &Multilibs = GCCInstallation.getMultilibs();
// Add toolchain / multilib specific file paths.
- addMultilibsFilePaths(D, Multilibs, Multilib,
+ 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() + Multilib.gccSuffix(),
+ addPathIfExists(D, GCCInstallation.getInstallPath() + SelectedMultilib.gccSuffix(),
Paths);
// GCC cross compiling toolchains will install target libraries which ship
@@ -330,7 +348,7 @@ Linux::Linux(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)
// 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 + Multilib.osSuffix(),
+ OSLibDir + SelectedMultilib.osSuffix(),
Paths);
// If the GCC installation we found is inside of the sysroot, we want to
@@ -433,6 +451,12 @@ Linux::Linux(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)
addPathIfExists(D, SysRoot + "/usr/lib", Paths);
}
+ToolChain::CXXStdlibType Linux::GetDefaultCXXStdlibType() const {
+ if (getTriple().isAndroid())
+ return ToolChain::CST_Libcxx;
+ return ToolChain::CST_Libstdcxx;
+}
+
bool Linux::HasNativeLLVMSupport() const { return true; }
Tool *Linux::buildLinker() const { return new tools::gnutools::Linker(*this); }
@@ -695,12 +719,28 @@ void Linux::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
const StringRef MIPSELMultiarchIncludeDirs[] = {
"/usr/include/mipsel-linux-gnu"};
const StringRef MIPS64MultiarchIncludeDirs[] = {
- "/usr/include/mips64-linux-gnu", "/usr/include/mips64-linux-gnuabi64"};
+ "/usr/include/mips64-linux-gnuabi64"};
const StringRef MIPS64ELMultiarchIncludeDirs[] = {
- "/usr/include/mips64el-linux-gnu",
"/usr/include/mips64el-linux-gnuabi64"};
+ const StringRef MIPSN32MultiarchIncludeDirs[] = {
+ "/usr/include/mips64-linux-gnuabin32"};
+ const StringRef MIPSN32ELMultiarchIncludeDirs[] = {
+ "/usr/include/mips64el-linux-gnuabin32"};
+ const StringRef MIPSR6MultiarchIncludeDirs[] = {
+ "/usr/include/mipsisa32-linux-gnu"};
+ const StringRef MIPSR6ELMultiarchIncludeDirs[] = {
+ "/usr/include/mipsisa32r6el-linux-gnu"};
+ const StringRef MIPS64R6MultiarchIncludeDirs[] = {
+ "/usr/include/mipsisa64r6-linux-gnuabi64"};
+ const StringRef MIPS64R6ELMultiarchIncludeDirs[] = {
+ "/usr/include/mipsisa64r6el-linux-gnuabi64"};
+ const StringRef MIPSN32R6MultiarchIncludeDirs[] = {
+ "/usr/include/mipsisa64r6-linux-gnuabin32"};
+ const StringRef MIPSN32R6ELMultiarchIncludeDirs[] = {
+ "/usr/include/mipsisa64r6el-linux-gnuabin32"};
const StringRef PPCMultiarchIncludeDirs[] = {
- "/usr/include/powerpc-linux-gnu"};
+ "/usr/include/powerpc-linux-gnu",
+ "/usr/include/powerpc-linux-gnuspe"};
const StringRef PPC64MultiarchIncludeDirs[] = {
"/usr/include/powerpc64-linux-gnu"};
const StringRef PPC64LEMultiarchIncludeDirs[] = {
@@ -738,16 +778,38 @@ void Linux::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
MultiarchIncludeDirs = ARMEBMultiarchIncludeDirs;
break;
case llvm::Triple::mips:
- MultiarchIncludeDirs = MIPSMultiarchIncludeDirs;
+ if (getTriple().getSubArch() == llvm::Triple::MipsSubArch_r6)
+ MultiarchIncludeDirs = MIPSR6MultiarchIncludeDirs;
+ else
+ MultiarchIncludeDirs = MIPSMultiarchIncludeDirs;
break;
case llvm::Triple::mipsel:
- MultiarchIncludeDirs = MIPSELMultiarchIncludeDirs;
+ if (getTriple().getSubArch() == llvm::Triple::MipsSubArch_r6)
+ MultiarchIncludeDirs = MIPSR6ELMultiarchIncludeDirs;
+ else
+ MultiarchIncludeDirs = MIPSELMultiarchIncludeDirs;
break;
case llvm::Triple::mips64:
- MultiarchIncludeDirs = MIPS64MultiarchIncludeDirs;
+ if (getTriple().getSubArch() == llvm::Triple::MipsSubArch_r6)
+ if (getTriple().getEnvironment() == llvm::Triple::GNUABIN32)
+ MultiarchIncludeDirs = MIPSN32R6MultiarchIncludeDirs;
+ else
+ MultiarchIncludeDirs = MIPS64R6MultiarchIncludeDirs;
+ else if (getTriple().getEnvironment() == llvm::Triple::GNUABIN32)
+ MultiarchIncludeDirs = MIPSN32MultiarchIncludeDirs;
+ else
+ MultiarchIncludeDirs = MIPS64MultiarchIncludeDirs;
break;
case llvm::Triple::mips64el:
- MultiarchIncludeDirs = MIPS64ELMultiarchIncludeDirs;
+ if (getTriple().getSubArch() == llvm::Triple::MipsSubArch_r6)
+ if (getTriple().getEnvironment() == llvm::Triple::GNUABIN32)
+ MultiarchIncludeDirs = MIPSN32R6ELMultiarchIncludeDirs;
+ else
+ MultiarchIncludeDirs = MIPS64R6ELMultiarchIncludeDirs;
+ else if (getTriple().getEnvironment() == llvm::Triple::GNUABIN32)
+ MultiarchIncludeDirs = MIPSN32ELMultiarchIncludeDirs;
+ else
+ MultiarchIncludeDirs = MIPS64ELMultiarchIncludeDirs;
break;
case llvm::Triple::ppc:
MultiarchIncludeDirs = PPCMultiarchIncludeDirs;
@@ -876,6 +938,9 @@ void Linux::addLibStdCxxIncludePaths(const llvm::opt::ArgList &DriverArgs,
// Freescale SDK C++ headers are directly in <sysroot>/usr/include/c++,
// without a subdirectory corresponding to the gcc version.
LibDir.str() + "/../include/c++",
+ // Cray's gcc installation puts headers under "g++" without a
+ // version suffix.
+ LibDir.str() + "/../include/g++",
};
for (const auto &IncludePath : LibStdCXXIncludePathCandidates) {
@@ -907,6 +972,12 @@ bool Linux::isPIEDefault() const {
getTriple().isMusl() || getSanitizerArgs().requiresPIE();
}
+bool Linux::IsMathErrnoDefault() const {
+ if (getTriple().isAndroid())
+ return false;
+ return Generic_ELF::IsMathErrnoDefault();
+}
+
SanitizerMask Linux::getSupportedSanitizers() const {
const bool IsX86 = getTriple().getArch() == llvm::Triple::x86;
const bool IsX86_64 = getTriple().getArch() == llvm::Triple::x86_64;
@@ -934,6 +1005,8 @@ SanitizerMask Linux::getSupportedSanitizers() const {
Res |= SanitizerKind::Leak;
if (IsX86_64 || IsMIPS64 || IsAArch64 || IsPowerPC64)
Res |= SanitizerKind::Thread;
+ if (IsX86_64)
+ Res |= SanitizerKind::KernelMemory;
if (IsX86_64 || IsMIPS64)
Res |= SanitizerKind::Efficiency;
if (IsX86 || IsX86_64)
@@ -954,7 +1027,7 @@ 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))
+ 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);