Index: include/clang/Driver/ToolChain.h =================================================================== --- include/clang/Driver/ToolChain.h +++ include/clang/Driver/ToolChain.h @@ -355,6 +355,9 @@ // as OpenMP) to find arch-specific libraries. std::string getArchSpecificLibPath() const; + // Returns part of above. + StringRef getOSLibName() const; + /// needsProfileRT - returns true if instrumentation profile is on. static bool needsProfileRT(const llvm::opt::ArgList &Args); Index: lib/Driver/ToolChain.cpp =================================================================== --- lib/Driver/ToolChain.cpp +++ lib/Driver/ToolChain.cpp @@ -323,13 +323,23 @@ return llvm::Triple::getArchTypeName(TC.getArch()); } +StringRef ToolChain::getOSLibName() const { + switch (Triple.getOS()) { + case llvm::Triple::FreeBSD: + return "freebsd"; + case llvm::Triple::Solaris: + return "sunos"; + default: + return getOS(); + } +} + std::string ToolChain::getCompilerRTPath() const { SmallString<128> Path(getDriver().ResourceDir); if (Triple.isOSUnknown()) { llvm::sys::path::append(Path, "lib"); } else { - StringRef OSLibName = Triple.isOSFreeBSD() ? "freebsd" : getOS(); - llvm::sys::path::append(Path, "lib", OSLibName); + llvm::sys::path::append(Path, "lib", getOSLibName()); } return Path.str(); } @@ -360,8 +370,7 @@ std::string ToolChain::getArchSpecificLibPath() const { SmallString<128> Path(getDriver().ResourceDir); - StringRef OSLibName = getTriple().isOSFreeBSD() ? "freebsd" : getOS(); - llvm::sys::path::append(Path, "lib", OSLibName, + llvm::sys::path::append(Path, "lib", getOSLibName(), llvm::Triple::getArchTypeName(getArch())); return Path.str(); } Index: lib/Driver/ToolChains/CommonArgs.cpp =================================================================== --- lib/Driver/ToolChains/CommonArgs.cpp +++ lib/Driver/ToolChains/CommonArgs.cpp @@ -508,9 +508,9 @@ bool IsShared, bool IsWhole) { // Wrap any static runtimes that must be forced into executable in // whole-archive. - if (IsWhole) CmdArgs.push_back("-whole-archive"); + if (IsWhole) CmdArgs.push_back("--whole-archive"); CmdArgs.push_back(TC.getCompilerRTArgString(Args, Sanitizer, IsShared)); - if (IsWhole) CmdArgs.push_back("-no-whole-archive"); + if (IsWhole) CmdArgs.push_back("--no-whole-archive"); if (IsShared) { addArchSpecificRPath(TC, Args, CmdArgs); @@ -522,6 +522,10 @@ static bool addSanitizerDynamicList(const ToolChain &TC, const ArgList &Args, ArgStringList &CmdArgs, StringRef Sanitizer) { + // Solaris ld defaults to --export-dynamic behaviour but doesn't support + // the option, so don't try to pass it. + if (TC.getTriple().getOS() == llvm::Triple::Solaris) + return true; SmallString<128> SanRT(TC.getCompilerRT(Args, Sanitizer)); if (llvm::sys::fs::exists(SanRT + ".syms")) { CmdArgs.push_back(Args.MakeArgString("--dynamic-list=" + SanRT + ".syms")); @@ -692,7 +696,7 @@ // If there is a static runtime with no dynamic list, force all the symbols // to be dynamic to be sure we export sanitizer interface functions. if (AddExportDynamic) - CmdArgs.push_back("-export-dynamic"); + CmdArgs.push_back("--export-dynamic"); const SanitizerArgs &SanArgs = TC.getSanitizerArgs(); if (SanArgs.hasCrossDsoCfi() && !AddExportDynamic) Index: lib/Driver/ToolChains/Solaris.h =================================================================== --- lib/Driver/ToolChains/Solaris.h +++ lib/Driver/ToolChains/Solaris.h @@ -65,6 +65,7 @@ addLibStdCxxIncludePaths(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args) const override; + SanitizerMask getSupportedSanitizers() const override; unsigned GetDefaultDwarfVersion() const override { return 2; } protected: Index: lib/Driver/ToolChains/Solaris.cpp =================================================================== --- lib/Driver/ToolChains/Solaris.cpp +++ lib/Driver/ToolChains/Solaris.cpp @@ -92,24 +92,48 @@ 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"))); @@ -165,6 +189,17 @@ addPathIfExists(D, D.SysRoot + "/usr/lib" + LibSuffix, Paths); } +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; + } + Res |= SanitizerKind::Vptr; + return Res; +} + Tool *Solaris::buildAssembler() const { return new tools::solaris::Assembler(*this); }