[PATCH] Add compiler support for dynamic Asan runtime
Yury Gribov
tetra2005 at gmail.com
Thu Mar 20 09:41:27 PDT 2014
Based on Alexey's comments. Tests still tbd.
Hi kcc, eugenis, samsonov,
http://llvm-reviews.chandlerc.com/D3043
CHANGE SINCE LAST DIFF
http://llvm-reviews.chandlerc.com/D3043?vs=7935&id=7990#toc
Files:
include/clang/Driver/Options.td
include/clang/Driver/SanitizerArgs.h
lib/Driver/SanitizerArgs.cpp
lib/Driver/Tools.cpp
Index: include/clang/Driver/Options.td
===================================================================
--- include/clang/Driver/Options.td
+++ include/clang/Driver/Options.td
@@ -359,6 +359,7 @@
HelpText<"Enable Apple gcc-compatible #pragma pack handling">;
def faddress_sanitizer : Flag<["-"], "faddress-sanitizer">, Group<f_Group>;
def fno_address_sanitizer : Flag<["-"], "fno-address-sanitizer">, Group<f_Group>;
+def shared_libasan : Flag<["-"], "shared-libasan">;
def fthread_sanitizer : Flag<["-"], "fthread-sanitizer">, Group<f_Group>;
def fno_thread_sanitizer : Flag<["-"], "fno-thread-sanitizer">, Group<f_Group>;
def fasm : Flag<["-"], "fasm">, Group<f_Group>;
Index: include/clang/Driver/SanitizerArgs.h
===================================================================
--- include/clang/Driver/SanitizerArgs.h
+++ include/clang/Driver/SanitizerArgs.h
@@ -51,13 +51,15 @@
bool MsanTrackOrigins;
bool AsanZeroBaseShadow;
bool UbsanTrapOnError;
+ bool AsanSharedRuntime;
public:
SanitizerArgs();
/// Parses the sanitizer arguments from an argument list.
SanitizerArgs(const ToolChain &TC, const llvm::opt::ArgList &Args);
bool needsAsanRt() const { return Kind & NeedsAsanRt; }
+ bool needsSharedAsanRt() const { return AsanSharedRuntime; }
bool needsTsanRt() const { return Kind & NeedsTsanRt; }
bool needsMsanRt() const { return Kind & NeedsMsanRt; }
bool needsLeakDetection() const { return Kind & NeedsLeakDetection; }
Index: lib/Driver/SanitizerArgs.cpp
===================================================================
--- lib/Driver/SanitizerArgs.cpp
+++ lib/Driver/SanitizerArgs.cpp
@@ -26,6 +26,7 @@
MsanTrackOrigins = false;
AsanZeroBaseShadow = false;
UbsanTrapOnError = false;
+ AsanSharedRuntime = false;
}
SanitizerArgs::SanitizerArgs() {
@@ -168,9 +169,12 @@
Args.hasFlag(options::OPT_fsanitize_memory_track_origins,
options::OPT_fno_sanitize_memory_track_origins,
/* Default */false);
- if (NeedsAsan)
+
+ if (NeedsAsan) {
+ AsanSharedRuntime = Args.hasArg(options::OPT_shared_libasan);
AsanZeroBaseShadow =
(TC.getTriple().getEnvironment() == llvm::Triple::Android);
+ }
}
void SanitizerArgs::addArgs(const llvm::opt::ArgList &Args,
Index: lib/Driver/Tools.cpp
===================================================================
--- lib/Driver/Tools.cpp
+++ lib/Driver/Tools.cpp
@@ -1809,57 +1809,87 @@
static void addSanitizerRTLinkFlags(
const ToolChain &TC, const ArgList &Args, ArgStringList &CmdArgs,
const StringRef Sanitizer, bool BeforeLibStdCXX,
- bool ExportSymbols = true) {
+ bool ExportSymbols = true,
+ bool NeedsSharedRT = false) {
+ bool Executable = !Args.hasArg(options::OPT_shared);
+
// 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"));
+ Twine("libclang_rt.") + Sanitizer + "-" +
+ getArchNameForCompilerRTLib(TC) +
+ (NeedsSharedRT ? "-dynamic.so" : ".a"));
+ SmallString<128> LibSanitizerPreinit = getCompilerRTLibDir(TC);
+ llvm::sys::path::append(LibSanitizerPreinit,
+ Twine("libclang_rt." + Sanitizer + "-" +
+ getArchNameForCompilerRTLib(TC) +
+ "-preinit.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
// new' and 'operator delete' symbols. We take the extreme (but simple)
- // strategy of inserting it at the front of the link command. It also
- // needs to be forced to end up in the executable, so wrap it in
- // whole-archive.
- SmallVector<const char *, 3> LibSanitizerArgs;
- LibSanitizerArgs.push_back("-whole-archive");
- LibSanitizerArgs.push_back(Args.MakeArgString(LibSanitizer));
- LibSanitizerArgs.push_back("-no-whole-archive");
+ // strategy of inserting it at the front of the link command.
- CmdArgs.insert(BeforeLibStdCXX ? CmdArgs.begin() : CmdArgs.end(),
- LibSanitizerArgs.begin(), LibSanitizerArgs.end());
+ SmallVector<const char *, 4> LibSanitizerArgs;
- CmdArgs.push_back("-lpthread");
- CmdArgs.push_back("-lrt");
- CmdArgs.push_back("-ldl");
- CmdArgs.push_back("-lm");
-
- // If possible, use a dynamic symbols file to export the symbols from the
- // runtime library. If we can't do so, use -export-dynamic instead to export
- // all symbols from the binary.
- if (ExportSymbols) {
- if (llvm::sys::fs::exists(LibSanitizer + ".syms"))
- CmdArgs.push_back(
- Args.MakeArgString("--dynamic-list=" + LibSanitizer + ".syms"));
- else
- CmdArgs.push_back("-export-dynamic");
+ if (Executable) {
+ // Force initialization code to end up in the executable
+ // by wrapping it in whole-archive.
+ LibSanitizerArgs.push_back("-whole-archive");
+ LibSanitizerArgs.push_back(Args.MakeArgString(LibSanitizerPreinit));
+ LibSanitizerArgs.push_back("-no-whole-archive");
+
+ if (NeedsSharedRT) {
+ LibSanitizerArgs.push_back(Args.MakeArgString(LibSanitizer));
+ } else {
+ // Force static runtime to end up in the executable
+ // by wrapping it in whole-archive.
+ LibSanitizerArgs.push_back("-whole-archive");
+ LibSanitizerArgs.push_back(Args.MakeArgString(LibSanitizer));
+ LibSanitizerArgs.push_back("-no-whole-archive");
+
+ // If possible, use a dynamic symbols file to export the symbols from the
+ // runtime library. If we can't do so, use -export-dynamic instead to export
+ // all symbols from the binary.
+ if (ExportSymbols) {
+ if (llvm::sys::fs::exists(LibSanitizer + ".syms"))
+ CmdArgs.push_back(
+ Args.MakeArgString("--dynamic-list=" + LibSanitizer + ".syms"));
+ else
+ CmdArgs.push_back("-export-dynamic");
+ }
+ }
+ } else {
+ if (NeedsSharedRT)
+ LibSanitizerArgs.push_back(Args.MakeArgString(LibSanitizer));
}
+
+ CmdArgs.insert(BeforeLibStdCXX ? CmdArgs.begin() : CmdArgs.end(),
+ LibSanitizerArgs.begin(), LibSanitizerArgs.end());
}
/// 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 addAsanRT(const ToolChain &TC, const ArgList &Args,
- ArgStringList &CmdArgs) {
+ ArgStringList &CmdArgs, bool NeedsSharedRT) {
if (TC.getTriple().getEnvironment() == llvm::Triple::Android) {
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))
- addSanitizerRTLinkFlags(TC, Args, CmdArgs, "asan", true);
+ addSanitizerRTLinkFlags(TC, Args, CmdArgs, "asan", true, true, NeedsSharedRT);
+
+ bool Executable = !Args.hasArg(options::OPT_shared);
+ if (Executable && !NeedsSharedRT) {
+ // FIXME: this is not quite portable but we shouldn't force user
+ // to manually include these silly libs.
+ CmdArgs.push_back("-lpthread");
+ CmdArgs.push_back("-lrt");
+ CmdArgs.push_back("-ldl");
+ CmdArgs.push_back("-lm");
+ }
}
}
@@ -1921,7 +1951,7 @@
Sanitize.needsAsanRt() || Sanitize.needsTsanRt() ||
Sanitize.needsMsanRt() || Sanitize.needsLsanRt());
if (Sanitize.needsAsanRt())
- addAsanRT(TC, Args, CmdArgs);
+ addAsanRT(TC, Args, CmdArgs, Sanitize.needsSharedAsanRt());
if (Sanitize.needsTsanRt())
addTsanRT(TC, Args, CmdArgs);
if (Sanitize.needsMsanRt())
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D3043.3.patch
Type: text/x-patch
Size: 8124 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20140320/a9e12331/attachment.bin>
More information about the llvm-commits
mailing list