Attached the new version, PTAL

> +  if (Args.hasArg(options::OPT_faddress_sanitizer)) {
> Please
> use Args.hasFlag(options::OPT_faddress_sanitizer, options::OPT_fno_address_sanitizer,
> false))
Done
>
> and hide the flag checking inside addAsanRTDarwinExe/etc
Then this should be something like "maybeAddAsan...", because this
function is called unconditionally and other devs may think that we
always add ASan.
I've renamed the correspoding Linux function as well.

> +const int AsanIfaceFnsSize = sizeof(AsanIfaceFns) / sizeof(char*);
> +const char *AsanIfaceFns[13] = {
> I would make these function-scope (if we end up needing them).
I've ended up using -undefined dynamic_lookup.
Indeed, if someone has an undefined symbol in this dynamic library,
let him catch this in another compiler mode.
Index: tools/clang/lib/Driver/Tools.cpp
===================================================================
--- tools/clang/lib/Driver/Tools.cpp	(revision 145532)
+++ tools/clang/lib/Driver/Tools.cpp	(working copy)
@@ -1102,8 +1102,8 @@
 
 /// 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 maybeAddAsanRTLinux(const ToolChain &TC, const ArgList &Args,
+                                ArgStringList &CmdArgs) {
   // Add asan linker flags when linking an executable, but not a shared object.
   if (Args.hasArg(options::OPT_shared) ||
       !Args.hasFlag(options::OPT_faddress_sanitizer,
@@ -1121,6 +1121,38 @@
   TC.AddCXXStdlibLibArgs(Args, CmdArgs);
 }
 
+static void maybeAddAsanRTDarwin(const ToolChain &TC, const ArgList &Args,
+                               ArgStringList &CmdArgs) {
+  // Add linker flags only if ASan is on.                             
+  if (!Args.hasFlag(options::OPT_faddress_sanitizer,
+                    options::OPT_fno_address_sanitizer, false)) return;
+
+  if (!Args.hasArg(options::OPT_dynamiclib) &&
+      !Args.hasArg(options::OPT_bundle)) {
+    // Exe case: link with the runtime library.
+
+    // LibAsan is "../lib/clang/linux/ArchName/libclang_rt.asan.a
+    llvm::SmallString<128> LibAsan =
+        llvm::sys::path::parent_path(StringRef(TC.getDriver().Dir));
+    llvm::sys::path::append(
+        LibAsan, "lib", "clang", "darwin", TC.getArchName());
+    llvm::sys::path::append(LibAsan, "libclang_rt.asan.a");
+    CmdArgs.push_back(Args.MakeArgString(LibAsan));
+    CmdArgs.push_back("-lpthread");
+    CmdArgs.push_back("-ldl");
+    CmdArgs.push_back("-framework");
+    CmdArgs.push_back("Foundation");
+    TC.AddCXXStdlibLibArgs(Args, CmdArgs);
+  } else {
+    // Dylib case: treat all undefined functions as dynamic_lookup.
+    // This is needed because after ASan instrumentation the dynamic library
+    // may have calls to ASan interface functions that exist only in the
+    // executable.
+    CmdArgs.push_back("-undefined");
+    CmdArgs.push_back("dynamic_lookup");
+  }
+}
+
 void Clang::ConstructJob(Compilation &C, const JobAction &JA,
                          const InputInfo &Output,
                          const InputInfoList &Inputs,
@@ -3576,6 +3608,9 @@
   }
 
   Args.AddAllArgs(CmdArgs, options::OPT_L);
+ 
+  // Call this before we add the C run-time.
+  maybeAddAsanRTDarwin(getToolChain(), Args, CmdArgs);
 
   if (Args.hasArg(options::OPT_fopenmp))
     // This is more complicated in gcc...
@@ -4490,7 +4525,7 @@
   }
 
   // Call this before we add the C run-time.
-  addAsanRTLinux(getToolChain(), Args, CmdArgs);
+  maybeAddAsanRTLinux(getToolChain(), Args, CmdArgs);
 
   if (!Args.hasArg(options::OPT_nostdlib)) {
     if (Args.hasArg(options::OPT_static))
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to