forked from OSchip/llvm-project
[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 llvm-svn: 324296
This commit is contained in:
parent
9198efceb8
commit
85da0f6fb5
|
@ -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);
|
||||
|
||||
|
|
|
@ -323,13 +323,23 @@ static StringRef getArchNameForCompilerRTLib(const ToolChain &TC,
|
|||
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::getCompilerRTArgString(const llvm::opt::ArgList &Args,
|
|||
|
||||
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();
|
||||
}
|
||||
|
|
|
@ -508,9 +508,9 @@ static void addSanitizerRuntime(const ToolChain &TC, const ArgList &Args,
|
|||
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 ToolChain &TC, const ArgList &Args,
|
|||
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 ToolChain &TC, const ArgList &Args,
|
|||
// 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)
|
||||
|
|
|
@ -92,24 +92,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")));
|
||||
|
@ -165,6 +189,17 @@ Solaris::Solaris(const Driver &D, const llvm::Triple &Triple,
|
|||
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);
|
||||
}
|
||||
|
|
|
@ -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:
|
||||
|
|
Loading…
Reference in New Issue