diff options
Diffstat (limited to 'lib/Driver/ToolChains/Solaris.cpp')
-rw-r--r-- | lib/Driver/ToolChains/Solaris.cpp | 173 |
1 files changed, 131 insertions, 42 deletions
diff --git a/lib/Driver/ToolChains/Solaris.cpp b/lib/Driver/ToolChains/Solaris.cpp index 9fe6e9d520d0..b48edbb08ee6 100644 --- a/lib/Driver/ToolChains/Solaris.cpp +++ b/lib/Driver/ToolChains/Solaris.cpp @@ -71,6 +71,11 @@ void solaris::Linker::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back( Args.MakeArgString(getToolChain().GetFilePath("ld.so.1"))); } + + // libpthread has been folded into libc since Solaris 10, no need to do + // anything for pthreads. Claim argument to avoid warning. + Args.ClaimAllArgs(options::OPT_pthread); + Args.ClaimAllArgs(options::OPT_pthreads); } if (Output.isFilename()) { @@ -92,24 +97,48 @@ void solaris::Linker::ConstructJob(Compilation &C, const JobAction &JA, Args.MakeArgString(getToolChain().GetFilePath("crtbegin.o"))); } + // Provide __start___sancov_guards. Solaris ld doesn't automatically create + // __start_SECNAME labels. + CmdArgs.push_back("--whole-archive"); + CmdArgs.push_back( + getToolChain().getCompilerRTArgString(Args, "sancov_begin", false)); + CmdArgs.push_back("--no-whole-archive"); + getToolChain().AddFilePathLibArgs(Args, CmdArgs); Args.AddAllArgs(CmdArgs, {options::OPT_L, options::OPT_T_Group, options::OPT_e, options::OPT_r}); + bool NeedsSanitizerDeps = addSanitizerRuntimes(getToolChain(), Args, CmdArgs); AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs, JA); if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) { if (getToolChain().ShouldLinkCXXStdlib(Args)) getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs); + if (Args.hasArg(options::OPT_fstack_protector) || + Args.hasArg(options::OPT_fstack_protector_strong) || + Args.hasArg(options::OPT_fstack_protector_all)) { + // Explicitly link ssp libraries, not folded into Solaris libc. + CmdArgs.push_back("-lssp_nonshared"); + CmdArgs.push_back("-lssp"); + } CmdArgs.push_back("-lgcc_s"); CmdArgs.push_back("-lc"); if (!Args.hasArg(options::OPT_shared)) { CmdArgs.push_back("-lgcc"); CmdArgs.push_back("-lm"); } + if (NeedsSanitizerDeps) + linkSanitizerRuntimeDeps(getToolChain(), CmdArgs); } + // Provide __stop___sancov_guards. Solaris ld doesn't automatically create + // __stop_SECNAME labels. + CmdArgs.push_back("--whole-archive"); + CmdArgs.push_back( + getToolChain().getCompilerRTArgString(Args, "sancov_end", false)); + CmdArgs.push_back("--no-whole-archive"); + if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) { CmdArgs.push_back( Args.MakeArgString(getToolChain().GetFilePath("crtend.o"))); @@ -122,6 +151,21 @@ void solaris::Linker::ConstructJob(Compilation &C, const JobAction &JA, C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs)); } +static StringRef getSolarisLibSuffix(const llvm::Triple &Triple) { + switch (Triple.getArch()) { + case llvm::Triple::x86: + case llvm::Triple::sparc: + break; + case llvm::Triple::x86_64: + return "/amd64"; + case llvm::Triple::sparcv9: + return "/sparcv9"; + default: + llvm_unreachable("Unsupported architecture"); + } + return ""; +} + /// Solaris - Solaris tool chain which can call as(1) and ld(1) directly. Solaris::Solaris(const Driver &D, const llvm::Triple &Triple, @@ -130,32 +174,35 @@ Solaris::Solaris(const Driver &D, const llvm::Triple &Triple, GCCInstallation.init(Triple, Args); + StringRef LibSuffix = getSolarisLibSuffix(Triple); path_list &Paths = getFilePaths(); - if (GCCInstallation.isValid()) - addPathIfExists(D, GCCInstallation.getInstallPath(), Paths); + if (GCCInstallation.isValid()) { + // On Solaris gcc uses both an architecture-specific path with triple in it + // as well as a more generic lib path (+arch suffix). + addPathIfExists(D, + GCCInstallation.getInstallPath() + + GCCInstallation.getMultilib().gccSuffix(), + Paths); + addPathIfExists(D, GCCInstallation.getParentLibPath() + LibSuffix, Paths); + } - addPathIfExists(D, getDriver().getInstalledDir(), Paths); - if (getDriver().getInstalledDir() != getDriver().Dir) - addPathIfExists(D, getDriver().Dir, Paths); + // If we are currently running Clang inside of the requested system root, + // add its parent library path to those searched. + if (StringRef(D.Dir).startswith(D.SysRoot)) + addPathIfExists(D, D.Dir + "/../lib", Paths); - addPathIfExists(D, getDriver().SysRoot + getDriver().Dir + "/../lib", Paths); + addPathIfExists(D, D.SysRoot + "/usr/lib" + LibSuffix, Paths); +} - std::string LibPath = "/usr/lib/"; - switch (Triple.getArch()) { - case llvm::Triple::x86: - case llvm::Triple::sparc: - break; - case llvm::Triple::x86_64: - LibPath += "amd64/"; - break; - case llvm::Triple::sparcv9: - LibPath += "sparcv9/"; - break; - default: - llvm_unreachable("Unsupported architecture"); +SanitizerMask Solaris::getSupportedSanitizers() const { + const bool IsX86 = getTriple().getArch() == llvm::Triple::x86; + SanitizerMask Res = ToolChain::getSupportedSanitizers(); + // FIXME: Omit X86_64 until 64-bit support is figured out. + if (IsX86) { + Res |= SanitizerKind::Address; } - - addPathIfExists(D, getDriver().SysRoot + LibPath, Paths); + Res |= SanitizerKind::Vptr; + return Res; } Tool *Solaris::buildAssembler() const { @@ -164,30 +211,72 @@ Tool *Solaris::buildAssembler() const { Tool *Solaris::buildLinker() const { return new tools::solaris::Linker(*this); } -void Solaris::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs, - ArgStringList &CC1Args) const { - if (DriverArgs.hasArg(options::OPT_nostdlibinc) || - DriverArgs.hasArg(options::OPT_nostdincxx)) +void Solaris::AddClangSystemIncludeArgs(const ArgList &DriverArgs, + ArgStringList &CC1Args) const { + const Driver &D = getDriver(); + + if (DriverArgs.hasArg(clang::driver::options::OPT_nostdinc)) + return; + + if (!DriverArgs.hasArg(options::OPT_nostdlibinc)) + addSystemInclude(DriverArgs, CC1Args, D.SysRoot + "/usr/local/include"); + + if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) { + SmallString<128> P(D.ResourceDir); + llvm::sys::path::append(P, "include"); + addSystemInclude(DriverArgs, CC1Args, P); + } + + if (DriverArgs.hasArg(options::OPT_nostdlibinc)) return; - // Include the support directory for things like xlocale and fudged system - // headers. - // FIXME: This is a weird mix of libc++ and libstdc++. We should also be - // checking the value of -stdlib= here and adding the includes for libc++ - // rather than libstdc++ if it's requested. - addSystemInclude(DriverArgs, CC1Args, "/usr/include/c++/v1/support/solaris"); + // Check for configure-time C include directories. + StringRef CIncludeDirs(C_INCLUDE_DIRS); + if (CIncludeDirs != "") { + SmallVector<StringRef, 5> dirs; + CIncludeDirs.split(dirs, ":"); + for (StringRef dir : dirs) { + StringRef Prefix = + llvm::sys::path::is_absolute(dir) ? StringRef(D.SysRoot) : ""; + addExternCSystemInclude(DriverArgs, CC1Args, Prefix + dir); + } + return; + } + // Add include directories specific to the selected multilib set and multilib. if (GCCInstallation.isValid()) { - GCCVersion Version = GCCInstallation.getVersion(); - addSystemInclude(DriverArgs, CC1Args, - getDriver().SysRoot + "/usr/gcc/" + - Version.MajorStr + "." + - Version.MinorStr + - "/include/c++/" + Version.Text); - addSystemInclude(DriverArgs, CC1Args, - getDriver().SysRoot + "/usr/gcc/" + Version.MajorStr + - "." + Version.MinorStr + "/include/c++/" + - Version.Text + "/" + - GCCInstallation.getTriple().str()); + const MultilibSet::IncludeDirsFunc &Callback = + Multilibs.includeDirsCallback(); + if (Callback) { + for (const auto &Path : Callback(GCCInstallation.getMultilib())) + addExternCSystemIncludeIfExists( + DriverArgs, CC1Args, GCCInstallation.getInstallPath() + Path); + } } + + addExternCSystemInclude(DriverArgs, CC1Args, D.SysRoot + "/usr/include"); +} + +void Solaris::addLibStdCxxIncludePaths( + const llvm::opt::ArgList &DriverArgs, + llvm::opt::ArgStringList &CC1Args) const { + // We need a detected GCC installation on Solaris (similar to Linux) + // to provide libstdc++'s headers. + if (!GCCInstallation.isValid()) + return; + + // By default, look for the C++ headers in an include directory adjacent to + // the lib directory of the GCC installation. + // On Solaris this usually looks like /usr/gcc/X.Y/include/c++/X.Y.Z + StringRef LibDir = GCCInstallation.getParentLibPath(); + StringRef TripleStr = GCCInstallation.getTriple().str(); + const Multilib &Multilib = GCCInstallation.getMultilib(); + const GCCVersion &Version = GCCInstallation.getVersion(); + + // The primary search for libstdc++ supports multiarch variants. + addLibStdCXXIncludePaths(LibDir.str() + "/../include", "/c++/" + Version.Text, + TripleStr, + /*GCCMultiarchTriple*/ "", + /*TargetMultiarchTriple*/ "", + Multilib.includeSuffix(), DriverArgs, CC1Args); } |