Author: alekseyshl Date: Mon Feb 5 15:59:13 2018 New Revision: 324296 URL: http://llvm.org/viewvc/llvm-project?rev=324296&view=rev Log: [Sanitizers] Basic Solaris sanitizer support (PR 33274)
Summary: This patch (on top of https://reviews.llvm.org/D35755) provides the clang side necessary to enable the Solaris port of the sanitizers implemented by https://reviews.llvm.org/D40898, https://reviews.llvm.org/D40899, and https://reviews.llvm.org/D40900). A few features of note: * While compiler-rt cmake/base-config-ix.cmake (COMPILER_RT_OS_DIR) places the runtime libs in a tolower(CMAKE_SYSTEM_NAME) directory, clang defaults to the OS part of the target triplet (solaris2.11 in the case at hand). The patch makes them agree on compiler-rt's idea. * While Solaris ld accepts a considerable number of GNU ld options for compatibility, it only does so for the double-dash forms. clang unfortunately is inconsistent here and sometimes uses the double-dash form, sometimes the single-dash one that confuses the hell out of Solaris ld. I've changed the affected places to use the double-dash form that should always work. * As described in https://reviews.llvm.org/D40899, Solaris ld doesn't create the __start___sancov_guards/__stop___sancov_guards labels gld/gold/lld do, so I'm including additional runtime libs into the link that provide them. * One test uses -fstack-protector, but unlike other systems libssp hasn't been folded into Solaris libc, but needs to be linked with separately. * For now, only 32-bit x86 asan is enabled on Solaris. 64-bit x86 should follow, but sparc (which requires additional compiler-rt changes not yet submitted) fails miserably due to a llvmsparc backend limitation: fatal error: error in backend: Function "_ZN7testing8internal16BoolFromGTestEnvEPKcb": over-aligned dynamic alloca not supported. However, inside the gcc tree, Solaris/sparc asan works almost as well as x86. Reviewers: rsmith, alekseyshl Reviewed By: alekseyshl Subscribers: jyknight, fedor.sergeev, cfe-commits Tags: #sanitizers Differential Revision: https://reviews.llvm.org/D40903 Modified: cfe/trunk/include/clang/Driver/ToolChain.h cfe/trunk/lib/Driver/ToolChain.cpp cfe/trunk/lib/Driver/ToolChains/CommonArgs.cpp cfe/trunk/lib/Driver/ToolChains/Solaris.cpp cfe/trunk/lib/Driver/ToolChains/Solaris.h Modified: cfe/trunk/include/clang/Driver/ToolChain.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/ToolChain.h?rev=324296&r1=324295&r2=324296&view=diff ============================================================================== --- cfe/trunk/include/clang/Driver/ToolChain.h (original) +++ cfe/trunk/include/clang/Driver/ToolChain.h Mon Feb 5 15:59:13 2018 @@ -355,6 +355,9 @@ public: // as OpenMP) to find arch-specific libraries. std::string getArchSpecificLibPath() const; + // Returns <OSname> part of above. + StringRef getOSLibName() const; + /// needsProfileRT - returns true if instrumentation profile is on. static bool needsProfileRT(const llvm::opt::ArgList &Args); Modified: cfe/trunk/lib/Driver/ToolChain.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/ToolChain.cpp?rev=324296&r1=324295&r2=324296&view=diff ============================================================================== --- cfe/trunk/lib/Driver/ToolChain.cpp (original) +++ cfe/trunk/lib/Driver/ToolChain.cpp Mon Feb 5 15:59:13 2018 @@ -323,13 +323,23 @@ static StringRef getArchNameForCompilerR 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 @@ const char *ToolChain::getCompilerRTArgS 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(); } Modified: cfe/trunk/lib/Driver/ToolChains/CommonArgs.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/ToolChains/CommonArgs.cpp?rev=324296&r1=324295&r2=324296&view=diff ============================================================================== --- cfe/trunk/lib/Driver/ToolChains/CommonArgs.cpp (original) +++ cfe/trunk/lib/Driver/ToolChains/CommonArgs.cpp Mon Feb 5 15:59:13 2018 @@ -508,9 +508,9 @@ static void addSanitizerRuntime(const To 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 void addSanitizerRuntime(const To 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 @@ bool tools::addSanitizerRuntimes(const T // 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) Modified: cfe/trunk/lib/Driver/ToolChains/Solaris.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/ToolChains/Solaris.cpp?rev=324296&r1=324295&r2=324296&view=diff ============================================================================== --- cfe/trunk/lib/Driver/ToolChains/Solaris.cpp (original) +++ cfe/trunk/lib/Driver/ToolChains/Solaris.cpp Mon Feb 5 15:59:13 2018 @@ -92,24 +92,48 @@ void solaris::Linker::ConstructJob(Compi 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 @@ Solaris::Solaris(const Driver &D, const 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); } Modified: cfe/trunk/lib/Driver/ToolChains/Solaris.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/ToolChains/Solaris.h?rev=324296&r1=324295&r2=324296&view=diff ============================================================================== --- cfe/trunk/lib/Driver/ToolChains/Solaris.h (original) +++ cfe/trunk/lib/Driver/ToolChains/Solaris.h Mon Feb 5 15:59:13 2018 @@ -65,6 +65,7 @@ public: addLibStdCxxIncludePaths(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args) const override; + SanitizerMask getSupportedSanitizers() const override; unsigned GetDefaultDwarfVersion() const override { return 2; } protected: _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits