Factor adding sanitizer linker flags into a separate function and make it less OS-specific

llvm-svn: 202148
This commit is contained in:
Alexey Samsonov 2014-02-25 12:43:43 +00:00
parent cdac761475
commit ce8ab107ac
1 changed files with 63 additions and 62 deletions

View File

@ -1764,8 +1764,11 @@ static StringRef getArchNameForCompilerRTLib(const ToolChain &TC) {
return TC.getArchName();
}
static StringRef getOSNameForCompilerRTLib(const ToolChain &TC) {
return TC.getOS();
static SmallString<128> getCompilerRTLibDir(const ToolChain &TC) {
// The runtimes are located in the OS-specific resource directory.
SmallString<128> Res(TC.getDriver().ResourceDir);
llvm::sys::path::append(Res, "lib", TC.getOS());
return Res;
}
// This adds the static libclang_rt.arch.a directly to the command line
@ -1773,14 +1776,11 @@ static StringRef getOSNameForCompilerRTLib(const ToolChain &TC) {
// and available, check for possible errors, etc.
static void addClangRTLinux(
const ToolChain &TC, const ArgList &Args, ArgStringList &CmdArgs) {
// The runtime is located in the Linux library directory and has name
// "libclang_rt.<ArchName>.a".
SmallString<128> LibProfile(TC.getDriver().ResourceDir);
llvm::sys::path::append(
LibProfile, "lib", "linux",
SmallString<128> LibClangRT = getCompilerRTLibDir(TC);
llvm::sys::path::append(LibClangRT,
Twine("libclang_rt.") + getArchNameForCompilerRTLib(TC) + ".a");
CmdArgs.push_back(Args.MakeArgString(LibProfile));
CmdArgs.push_back(Args.MakeArgString(LibClangRT));
CmdArgs.push_back("-lgcc_s");
if (TC.getDriver().CCCIsCXX())
CmdArgs.push_back("-lgcc_eh");
@ -1795,27 +1795,22 @@ static void addProfileRT(
Args.hasArg(options::OPT_coverage)))
return;
// The profile runtime is located in the OS-specific resource directory and
// has name "libclang_rt.profile-<ArchName>.a".
SmallString<128> LibProfile(TC.getDriver().ResourceDir);
llvm::sys::path::append(
LibProfile, "lib", getOSNameForCompilerRTLib(TC),
SmallString<128> LibProfile = getCompilerRTLibDir(TC);
llvm::sys::path::append(LibProfile,
Twine("libclang_rt.profile-") + getArchNameForCompilerRTLib(TC) + ".a");
CmdArgs.push_back(Args.MakeArgString(LibProfile));
}
static void addSanitizerRTLinkFlagsLinux(
static void addSanitizerRTLinkFlags(
const ToolChain &TC, const ArgList &Args, ArgStringList &CmdArgs,
const StringRef Sanitizer, bool BeforeLibStdCXX,
bool ExportSymbols = true) {
// Sanitizer runtime is located in the Linux library directory and
// has name "libclang_rt.<Sanitizer>-<ArchName>.a".
SmallString<128> LibSanitizer(TC.getDriver().ResourceDir);
llvm::sys::path::append(
LibSanitizer, "lib", "linux",
(Twine("libclang_rt.") + Sanitizer + "-" +
getArchNameForCompilerRTLib(TC) + ".a"));
// Sanitizer runtime has name "libclang_rt.<Sanitizer>-<ArchName>.a".
SmallString<128> LibSanitizer = getCompilerRTLibDir(TC);
llvm::sys::path::append(LibSanitizer,
(Twine("libclang_rt.") + Sanitizer + "-" +
getArchNameForCompilerRTLib(TC) + ".a"));
// Sanitizer runtime may need to come before -lstdc++ (or -lc++, libstdc++.a,
// etc.) so that the linker picks custom versions of the global 'operator
@ -1850,66 +1845,87 @@ static void addSanitizerRTLinkFlagsLinux(
/// If AddressSanitizer is enabled, add appropriate linker flags (Linux).
/// This needs to be called before we add the C run-time (malloc, etc).
static void addAsanRTLinux(const ToolChain &TC, const ArgList &Args,
ArgStringList &CmdArgs) {
static void addAsanRT(const ToolChain &TC, const ArgList &Args,
ArgStringList &CmdArgs) {
if (TC.getTriple().getEnvironment() == llvm::Triple::Android) {
SmallString<128> LibAsan(TC.getDriver().ResourceDir);
llvm::sys::path::append(LibAsan, "lib", "linux",
(Twine("libclang_rt.asan-") +
getArchNameForCompilerRTLib(TC) + "-android.so"));
SmallString<128> LibAsan = getCompilerRTLibDir(TC);
llvm::sys::path::append(LibAsan,
(Twine("libclang_rt.asan-") +
getArchNameForCompilerRTLib(TC) + "-android.so"));
CmdArgs.insert(CmdArgs.begin(), Args.MakeArgString(LibAsan));
} else {
if (!Args.hasArg(options::OPT_shared))
addSanitizerRTLinkFlagsLinux(TC, Args, CmdArgs, "asan", true);
addSanitizerRTLinkFlags(TC, Args, CmdArgs, "asan", true);
}
}
/// If ThreadSanitizer is enabled, add appropriate linker flags (Linux).
/// This needs to be called before we add the C run-time (malloc, etc).
static void addTsanRTLinux(const ToolChain &TC, const ArgList &Args,
ArgStringList &CmdArgs) {
static void addTsanRT(const ToolChain &TC, const ArgList &Args,
ArgStringList &CmdArgs) {
if (!Args.hasArg(options::OPT_shared))
addSanitizerRTLinkFlagsLinux(TC, Args, CmdArgs, "tsan", true);
addSanitizerRTLinkFlags(TC, Args, CmdArgs, "tsan", true);
}
/// If MemorySanitizer is enabled, add appropriate linker flags (Linux).
/// This needs to be called before we add the C run-time (malloc, etc).
static void addMsanRTLinux(const ToolChain &TC, const ArgList &Args,
ArgStringList &CmdArgs) {
static void addMsanRT(const ToolChain &TC, const ArgList &Args,
ArgStringList &CmdArgs) {
if (!Args.hasArg(options::OPT_shared))
addSanitizerRTLinkFlagsLinux(TC, Args, CmdArgs, "msan", true);
addSanitizerRTLinkFlags(TC, Args, CmdArgs, "msan", true);
}
/// If LeakSanitizer is enabled, add appropriate linker flags (Linux).
/// This needs to be called before we add the C run-time (malloc, etc).
static void addLsanRTLinux(const ToolChain &TC, const ArgList &Args,
ArgStringList &CmdArgs) {
static void addLsanRT(const ToolChain &TC, const ArgList &Args,
ArgStringList &CmdArgs) {
if (!Args.hasArg(options::OPT_shared))
addSanitizerRTLinkFlagsLinux(TC, Args, CmdArgs, "lsan", true);
addSanitizerRTLinkFlags(TC, Args, CmdArgs, "lsan", true);
}
/// If UndefinedBehaviorSanitizer is enabled, add appropriate linker flags
/// (Linux).
static void addUbsanRTLinux(const ToolChain &TC, const ArgList &Args,
ArgStringList &CmdArgs, bool IsCXX,
bool HasOtherSanitizerRt) {
static void addUbsanRT(const ToolChain &TC, const ArgList &Args,
ArgStringList &CmdArgs, bool IsCXX,
bool HasOtherSanitizerRt) {
// Need a copy of sanitizer_common. This could come from another sanitizer
// runtime; if we're not including one, include our own copy.
if (!HasOtherSanitizerRt)
addSanitizerRTLinkFlagsLinux(TC, Args, CmdArgs, "san", true, false);
addSanitizerRTLinkFlags(TC, Args, CmdArgs, "san", true, false);
addSanitizerRTLinkFlagsLinux(TC, Args, CmdArgs, "ubsan", false);
addSanitizerRTLinkFlags(TC, Args, CmdArgs, "ubsan", false);
// Only include the bits of the runtime which need a C++ ABI library if
// we're linking in C++ mode.
if (IsCXX)
addSanitizerRTLinkFlagsLinux(TC, Args, CmdArgs, "ubsan_cxx", false);
addSanitizerRTLinkFlags(TC, Args, CmdArgs, "ubsan_cxx", false);
}
static void addDfsanRTLinux(const ToolChain &TC, const ArgList &Args,
ArgStringList &CmdArgs) {
static void addDfsanRT(const ToolChain &TC, const ArgList &Args,
ArgStringList &CmdArgs) {
if (!Args.hasArg(options::OPT_shared))
addSanitizerRTLinkFlagsLinux(TC, Args, CmdArgs, "dfsan", true);
addSanitizerRTLinkFlags(TC, Args, CmdArgs, "dfsan", true);
}
// Should be called before we add C++ ABI library.
static void addSanitizerRuntimes(const ToolChain &TC, const ArgList &Args,
ArgStringList &CmdArgs) {
const SanitizerArgs &Sanitize = TC.getSanitizerArgs();
const Driver &D = TC.getDriver();
if (Sanitize.needsUbsanRt())
addUbsanRT(TC, Args, CmdArgs, D.CCCIsCXX(),
Sanitize.needsAsanRt() || Sanitize.needsTsanRt() ||
Sanitize.needsMsanRt() || Sanitize.needsLsanRt());
if (Sanitize.needsAsanRt())
addAsanRT(TC, Args, CmdArgs);
if (Sanitize.needsTsanRt())
addTsanRT(TC, Args, CmdArgs);
if (Sanitize.needsMsanRt())
addMsanRT(TC, Args, CmdArgs);
if (Sanitize.needsLsanRt())
addLsanRT(TC, Args, CmdArgs);
if (Sanitize.needsDfsanRt())
addDfsanRT(TC, Args, CmdArgs);
}
static bool shouldUseFramePointerForTarget(const ArgList &Args,
@ -6771,22 +6787,7 @@ void gnutools::Link::ConstructJob(Compilation &C, const JobAction &JA,
AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs);
// Call these before we add the C++ ABI library.
if (Sanitize.needsUbsanRt())
addUbsanRTLinux(getToolChain(), Args, CmdArgs, D.CCCIsCXX(),
Sanitize.needsAsanRt() || Sanitize.needsTsanRt() ||
Sanitize.needsMsanRt() || Sanitize.needsLsanRt());
if (Sanitize.needsAsanRt())
addAsanRTLinux(getToolChain(), Args, CmdArgs);
if (Sanitize.needsTsanRt())
addTsanRTLinux(getToolChain(), Args, CmdArgs);
if (Sanitize.needsMsanRt())
addMsanRTLinux(getToolChain(), Args, CmdArgs);
if (Sanitize.needsLsanRt())
addLsanRTLinux(getToolChain(), Args, CmdArgs);
if (Sanitize.needsDfsanRt())
addDfsanRTLinux(getToolChain(), Args, CmdArgs);
addSanitizerRuntimes(getToolChain(), Args, CmdArgs);
// The profile runtime also needs access to system libraries.
addProfileRT(getToolChain(), Args, CmdArgs);