From 2d24dc3d646e589cc684f282476b94be4c458a66 Mon Sep 17 00:00:00 2001 From: Alexey Samsonov Date: Tue, 25 Feb 2014 12:43:43 +0000 Subject: [PATCH] Factor adding sanitizer linker flags into a separate function and make it less OS-specific git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@202148 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Driver/Tools.cpp | 125 ++++++++++++++++++++++--------------------- 1 file changed, 63 insertions(+), 62 deletions(-) diff --git a/lib/Driver/Tools.cpp b/lib/Driver/Tools.cpp index 37b351c38a..371df4b62f 100644 --- a/lib/Driver/Tools.cpp +++ b/lib/Driver/Tools.cpp @@ -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..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-.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.-.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.-.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); -- 2.40.0