[PATCH] Add compiler support for dynamic Asan runtime

Yury Gribov tetra2005 at gmail.com
Wed Mar 19 00:27:59 PDT 2014


  Now link shared libs against dynamic runtime.

Hi kcc, eugenis, samsonov,

http://llvm-reviews.chandlerc.com/D3043

CHANGE SINCE LAST DIFF
  http://llvm-reviews.chandlerc.com/D3043?vs=7742&id=7935#toc

Files:
  lib/Driver/Tools.cpp
  lib/Driver/SanitizerArgs.cpp
  include/clang/Driver/Options.td
  include/clang/Driver/SanitizerArgs.h

Index: lib/Driver/Tools.cpp
===================================================================
--- lib/Driver/Tools.cpp
+++ lib/Driver/Tools.cpp
@@ -1809,22 +1809,41 @@
 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;
+  if (NeedsSharedRT) {
+    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;
+  SmallVector<const char *, 4> LibSanitizerArgs;
   LibSanitizerArgs.push_back("-whole-archive");
-  LibSanitizerArgs.push_back(Args.MakeArgString(LibSanitizer));
+  if (NeedsSharedRT) {
+    if (Executable)
+      LibSanitizerArgs.push_back(Args.MakeArgString(LibSanitizerPreinit));
+    LibSanitizerArgs.push_back(Args.MakeArgString(LibSanitizer));
+  } else {
+    if (Executable)
+      LibSanitizerArgs.push_back(Args.MakeArgString(LibSanitizer));
+  }
   LibSanitizerArgs.push_back("-no-whole-archive");
 
   CmdArgs.insert(BeforeLibStdCXX ? CmdArgs.begin() : CmdArgs.end(),
@@ -1838,7 +1857,7 @@
   // 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 (Executable && !NeedsSharedRT && ExportSymbols) {
     if (llvm::sys::fs::exists(LibSanitizer + ".syms"))
       CmdArgs.push_back(
           Args.MakeArgString("--dynamic-list=" + LibSanitizer + ".syms"));
@@ -1850,16 +1869,15 @@
 /// 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);
   }
 }
 
@@ -1921,7 +1939,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())
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,15 @@
       Args.hasFlag(options::OPT_fsanitize_memory_track_origins,
                    options::OPT_fno_sanitize_memory_track_origins,
                    /* Default */false);
-  if (NeedsAsan)
+
+  if (NeedsAsan) {
+    AsanSharedRuntime =
+      Args.hasFlag(options::OPT_shared_libasan,
+                   options::OPT_shared_libasan,
+                   /* Default */false);
     AsanZeroBaseShadow =
         (TC.getTriple().getEnvironment() == llvm::Triple::Android);
+  }
 }
 
 void SanitizerArgs::addArgs(const llvm::opt::ArgList &Args,
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; }
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D3043.2.patch
Type: text/x-patch
Size: 6566 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20140319/61ff086b/attachment.bin>


More information about the llvm-commits mailing list