r176178 - [Sanitizer] Change driver behavior when linking with -fsanitize=thread and -fsanitize=memory. TSan/MSan also provide their versions of new/delete and should use the same strategy as ASan. Share the code that sets linker flags for all sanitizers.

Alexey Samsonov samsonov at google.com
Wed Feb 27 03:14:56 PST 2013


Author: samsonov
Date: Wed Feb 27 05:14:55 2013
New Revision: 176178

URL: http://llvm.org/viewvc/llvm-project?rev=176178&view=rev
Log:
[Sanitizer] Change driver behavior when linking with -fsanitize=thread and -fsanitize=memory. TSan/MSan also provide their versions of new/delete and should use the same strategy as ASan. Share the code that sets linker flags for all sanitizers.

Added:
    cfe/trunk/test/Driver/sanitizer-ld.c
Removed:
    cfe/trunk/test/Driver/asan-ld.c
    cfe/trunk/test/Driver/ubsan-ld.c
Modified:
    cfe/trunk/lib/Driver/Tools.cpp

Modified: cfe/trunk/lib/Driver/Tools.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/Tools.cpp?rev=176178&r1=176177&r2=176178&view=diff
==============================================================================
--- cfe/trunk/lib/Driver/Tools.cpp (original)
+++ cfe/trunk/lib/Driver/Tools.cpp Wed Feb 27 05:14:55 2013
@@ -1568,6 +1568,35 @@ SanitizerArgs::SanitizerArgs(const Drive
                    /* Default */false);
 }
 
+static void addSanitizerRTLinkFlagsLinux(
+    const ToolChain &TC, const ArgList &Args, ArgStringList &CmdArgs,
+    const StringRef Sanitizer, bool BeforeLibStdCXX) {
+  // 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 + "-" + TC.getArchName() + ".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.
+  if (BeforeLibStdCXX) {
+    SmallVector<const char *, 3> PrefixArgs;
+    PrefixArgs.push_back("-whole-archive");
+    PrefixArgs.push_back(Args.MakeArgString(LibSanitizer));
+    PrefixArgs.push_back("-no-whole-archive");
+    CmdArgs.insert(CmdArgs.begin(), PrefixArgs.begin(), PrefixArgs.end());
+  } else {
+    CmdArgs.push_back(Args.MakeArgString(LibSanitizer));
+  }
+  CmdArgs.push_back("-lpthread");
+  CmdArgs.push_back("-ldl");
+  CmdArgs.push_back("-export-dynamic");
+}
+
 /// 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,
@@ -1592,26 +1621,7 @@ static void addAsanRTLinux(const ToolCha
         TC.getDriver().Diag(diag::err_drv_argument_only_allowed_with) <<
             "-fsanitize-address-zero-base-shadow" << "-pie";
       }
-      // LibAsan is "libclang_rt.asan-<ArchName>.a" in the Linux library
-      // resource directory.
-      SmallString<128> LibAsan(TC.getDriver().ResourceDir);
-      llvm::sys::path::append(LibAsan, "lib", "linux",
-                              (Twine("libclang_rt.asan-") +
-                               TC.getArchName() + ".a"));
-      // The ASan runtime needs to come before -lstdc++ (or -lc++, libstdc++.a,
-      // etc.) so that the linker picks ASan's 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> PrefixArgs;
-      PrefixArgs.push_back("-whole-archive");
-      PrefixArgs.push_back(Args.MakeArgString(LibAsan));
-      PrefixArgs.push_back("-no-whole-archive");
-      CmdArgs.insert(CmdArgs.begin(), PrefixArgs.begin(), PrefixArgs.end());
-      CmdArgs.push_back("-lpthread");
-      CmdArgs.push_back("-ldl");
-      CmdArgs.push_back("-export-dynamic");
+      addSanitizerRTLinkFlagsLinux(TC, Args, CmdArgs, "asan", true);
     }
   }
 }
@@ -1624,16 +1634,7 @@ static void addTsanRTLinux(const ToolCha
     if (!Args.hasArg(options::OPT_pie))
       TC.getDriver().Diag(diag::err_drv_argument_only_allowed_with) <<
         "-fsanitize=thread" << "-pie";
-    // LibTsan is "libclang_rt.tsan-<ArchName>.a" in the Linux library
-    // resource directory.
-    SmallString<128> LibTsan(TC.getDriver().ResourceDir);
-    llvm::sys::path::append(LibTsan, "lib", "linux",
-                            (Twine("libclang_rt.tsan-") +
-                             TC.getArchName() + ".a"));
-    CmdArgs.push_back(Args.MakeArgString(LibTsan));
-    CmdArgs.push_back("-lpthread");
-    CmdArgs.push_back("-ldl");
-    CmdArgs.push_back("-export-dynamic");
+    addSanitizerRTLinkFlagsLinux(TC, Args, CmdArgs, "tsan", true);
   }
 }
 
@@ -1645,16 +1646,7 @@ static void addMsanRTLinux(const ToolCha
     if (!Args.hasArg(options::OPT_pie))
       TC.getDriver().Diag(diag::err_drv_argument_only_allowed_with) <<
         "-fsanitize=memory" << "-pie";
-    // LibMsan is "libclang_rt.msan-<ArchName>.a" in the Linux library
-    // resource directory.
-    SmallString<128> LibMsan(TC.getDriver().ResourceDir);
-    llvm::sys::path::append(LibMsan, "lib", "linux",
-                            (Twine("libclang_rt.msan-") +
-                             TC.getArchName() + ".a"));
-    CmdArgs.push_back(Args.MakeArgString(LibMsan));
-    CmdArgs.push_back("-lpthread");
-    CmdArgs.push_back("-ldl");
-    CmdArgs.push_back("-export-dynamic");
+    addSanitizerRTLinkFlagsLinux(TC, Args, CmdArgs, "msan", true);
   }
 }
 
@@ -1662,15 +1654,7 @@ static void addMsanRTLinux(const ToolCha
 /// (Linux).
 static void addUbsanRTLinux(const ToolChain &TC, const ArgList &Args,
                             ArgStringList &CmdArgs) {
-  // LibUbsan is "libclang_rt.ubsan-<ArchName>.a" in the Linux library
-  // resource directory.
-  SmallString<128> LibUbsan(TC.getDriver().ResourceDir);
-  llvm::sys::path::append(LibUbsan, "lib", "linux",
-                          (Twine("libclang_rt.ubsan-") +
-                           TC.getArchName() + ".a"));
-  CmdArgs.push_back(Args.MakeArgString(LibUbsan));
-  CmdArgs.push_back("-lpthread");
-  CmdArgs.push_back("-export-dynamic");
+  addSanitizerRTLinkFlagsLinux(TC, Args, CmdArgs, "ubsan", false);
 }
 
 static bool shouldUseFramePointer(const ArgList &Args,

Removed: cfe/trunk/test/Driver/asan-ld.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Driver/asan-ld.c?rev=176177&view=auto
==============================================================================
--- cfe/trunk/test/Driver/asan-ld.c (original)
+++ cfe/trunk/test/Driver/asan-ld.c (removed)
@@ -1,57 +0,0 @@
-// Test AddressSanitizer ld flags.
-
-// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
-// RUN:     -target i386-unknown-linux -fsanitize=address \
-// RUN:     --sysroot=%S/Inputs/basic_linux_tree \
-// RUN:   | FileCheck --check-prefix=CHECK-LINUX %s
-//
-// CHECK-LINUX: "{{(.*[^-.0-9A-Z_a-z])?}}ld{{(.exe)?}}"
-// CHECK-LINUX-NOT: "-lc"
-// CHECK-LINUX: libclang_rt.asan-i386.a"
-// CHECK-LINUX: "-lpthread"
-// CHECK-LINUX: "-ldl"
-// CHECK-LINUX: "-export-dynamic"
-
-// RUN: %clangxx -no-canonical-prefixes %s -### -o %t.o 2>&1 \
-// RUN:     -target i386-unknown-linux -fsanitize=address \
-// RUN:     --sysroot=%S/Inputs/basic_linux_tree \
-// RUN:   | FileCheck --check-prefix=CHECK-LINUX-CXX %s
-//
-// CHECK-LINUX-CXX: "{{(.*[^-.0-9A-Z_a-z])?}}ld{{(.exe)?}}"
-// CHECK-LINUX-CXX-NOT: "-lc"
-// CHECK-LINUX-CXX: "-whole-archive" "{{.*}}libclang_rt.asan-i386.a" "-no-whole-archive"
-// CHECK-LINUX-CXX: "-lpthread"
-// CHECK-LINUX-CXX: "-ldl"
-// CHECK-LINUX-CXX: "-export-dynamic"
-// CHECK-LINUX-CXX: stdc++
-
-// RUN: %clang -no-canonical-prefixes %s -### -o /dev/null -fsanitize=address \
-// RUN:     -target i386-unknown-linux --sysroot=%S/Inputs/basic_linux_tree \
-// RUN:     -lstdc++ -static 2>&1 \
-// RUN:   | FileCheck --check-prefix=CHECK-LINUX-CXX-STATIC %s
-//
-// CHECK-LINUX-CXX-STATIC: "{{(.*[^-.0-9A-Z_a-z])?}}ld{{(.exe)?}}"
-// CHECK-LINUX-CXX-STATIC-NOT: stdc++
-// CHECK-LINUX-CXX-STATIC: "-whole-archive" "{{.*}}libclang_rt.asan-i386.a" "-no-whole-archive"
-// CHECK-LINUX-CXX-STATIC: stdc++
-
-// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
-// RUN:     -target arm-linux-androideabi -fsanitize=address \
-// RUN:     --sysroot=%S/Inputs/basic_android_tree/sysroot \
-// RUN:   | FileCheck --check-prefix=CHECK-ANDROID %s
-//
-// CHECK-ANDROID: "{{(.*[^.0-9A-Z_a-z])?}}ld{{(.exe)?}}"
-// CHECK-ANDROID-NOT: "-lc"
-// CHECK-ANDROID: libclang_rt.asan-arm-android.so"
-// CHECK-ANDROID-NOT: "-lpthread"
-//
-// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
-// RUN:     -target arm-linux-androideabi -fsanitize=address \
-// RUN:     --sysroot=%S/Inputs/basic_android_tree/sysroot \
-// RUN:     -shared \
-// RUN:   | FileCheck --check-prefix=CHECK-ANDROID-SHARED %s
-//
-// CHECK-ANDROID-SHARED: "{{(.*[^.0-9A-Z_a-z])?}}ld{{(.exe)?}}"
-// CHECK-ANDROID-SHARED-NOT: "-lc"
-// CHECK-ANDROID-SHARED: libclang_rt.asan-arm-android.so"
-// CHECK-ANDROID-SHARED-NOT: "-lpthread"

Added: cfe/trunk/test/Driver/sanitizer-ld.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Driver/sanitizer-ld.c?rev=176178&view=auto
==============================================================================
--- cfe/trunk/test/Driver/sanitizer-ld.c (added)
+++ cfe/trunk/test/Driver/sanitizer-ld.c Wed Feb 27 05:14:55 2013
@@ -0,0 +1,102 @@
+// Test sanitizers ld flags.
+
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     -target i386-unknown-linux -fsanitize=address \
+// RUN:     --sysroot=%S/Inputs/basic_linux_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-ASAN-LINUX %s
+//
+// CHECK-ASAN-LINUX: "{{(.*[^-.0-9A-Z_a-z])?}}ld{{(.exe)?}}"
+// CHECK-ASAN-LINUX-NOT: "-lc"
+// CHECK-ASAN-LINUX: libclang_rt.asan-i386.a"
+// CHECK-ASAN-LINUX: "-lpthread"
+// CHECK-ASAN-LINUX: "-ldl"
+// CHECK-ASAN-LINUX: "-export-dynamic"
+
+// RUN: %clangxx -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     -target i386-unknown-linux -fsanitize=address \
+// RUN:     --sysroot=%S/Inputs/basic_linux_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-ASAN-LINUX-CXX %s
+//
+// CHECK-ASAN-LINUX-CXX: "{{(.*[^-.0-9A-Z_a-z])?}}ld{{(.exe)?}}"
+// CHECK-ASAN-LINUX-CXX-NOT: "-lc"
+// CHECK-ASAN-LINUX-CXX: "-whole-archive" "{{.*}}libclang_rt.asan-i386.a" "-no-whole-archive"
+// CHECK-ASAN-LINUX-CXX: "-lpthread"
+// CHECK-ASAN-LINUX-CXX: "-ldl"
+// CHECK-ASAN-LINUX-CXX: "-export-dynamic"
+// CHECK-ASAN-LINUX-CXX: stdc++
+
+// RUN: %clang -no-canonical-prefixes %s -### -o /dev/null -fsanitize=address \
+// RUN:     -target i386-unknown-linux --sysroot=%S/Inputs/basic_linux_tree \
+// RUN:     -lstdc++ -static 2>&1 \
+// RUN:   | FileCheck --check-prefix=CHECK-ASAN-LINUX-CXX-STATIC %s
+//
+// CHECK-ASAN-LINUX-CXX-STATIC: "{{(.*[^-.0-9A-Z_a-z])?}}ld{{(.exe)?}}"
+// CHECK-ASAN-LINUX-CXX-STATIC-NOT: stdc++
+// CHECK-ASAN-LINUX-CXX-STATIC: "-whole-archive" "{{.*}}libclang_rt.asan-i386.a" "-no-whole-archive"
+// CHECK-ASAN-LINUX-CXX-STATIC: stdc++
+
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     -target arm-linux-androideabi -fsanitize=address \
+// RUN:     --sysroot=%S/Inputs/basic_android_tree/sysroot \
+// RUN:   | FileCheck --check-prefix=CHECK-ASAN-ANDROID %s
+//
+// CHECK-ASAN-ANDROID: "{{(.*[^.0-9A-Z_a-z])?}}ld{{(.exe)?}}"
+// CHECK-ASAN-ANDROID-NOT: "-lc"
+// CHECK-ASAN-ANDROID: libclang_rt.asan-arm-android.so"
+// CHECK-ASAN-ANDROID-NOT: "-lpthread"
+//
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     -target arm-linux-androideabi -fsanitize=address \
+// RUN:     --sysroot=%S/Inputs/basic_android_tree/sysroot \
+// RUN:     -shared \
+// RUN:   | FileCheck --check-prefix=CHECK-ASAN-ANDROID-SHARED %s
+//
+// CHECK-ASAN-ANDROID-SHARED: "{{(.*[^.0-9A-Z_a-z])?}}ld{{(.exe)?}}"
+// CHECK-ASAN-ANDROID-SHARED-NOT: "-lc"
+// CHECK-ASAN-ANDROID-SHARED: libclang_rt.asan-arm-android.so"
+// CHECK-ASAN-ANDROID-SHARED-NOT: "-lpthread"
+
+// RUN: %clangxx -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     -target x86_64-unknown-linux -lstdc++ -fsanitize=thread \
+// RUN:     --sysroot=%S/Inputs/basic_linux_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-TSAN-LINUX-CXX %s
+//
+// CHECK-TSAN-LINUX-CXX: "{{(.*[^-.0-9A-Z_a-z])?}}ld{{(.exe)?}}"
+// CHECK-TSAN-LINUX-CXX-NOT: stdc++
+// CHECK-TSAN-LINUX-CXX: "-whole-archive" "{{.*}}libclang_rt.tsan-x86_64.a" "-no-whole-archive"
+// CHECK-TSAN-LINUX-CXX: "-lpthread"
+// CHECK-TSAN-LINUX-CXX: "-ldl"
+// CHECK-TSAN-LINUX-CXX: "-export-dynamic"
+// CHECK-TSAN-LINUX-CXX: stdc++
+
+// RUN: %clangxx -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     -target x86_64-unknown-linux -lstdc++ -fsanitize=memory \
+// RUN:     --sysroot=%S/Inputs/basic_linux_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-MSAN-LINUX-CXX %s
+//
+// CHECK-MSAN-LINUX-CXX: "{{(.*[^-.0-9A-Z_a-z])?}}ld{{(.exe)?}}"
+// CHECK-MSAN-LINUX-CXX-NOT: stdc++
+// CHECK-MSAN-LINUX-CXX: "-whole-archive" "{{.*}}libclang_rt.msan-x86_64.a" "-no-whole-archive"
+// CHECK-MSAN-LINUX-CXX: "-lpthread"
+// CHECK-MSAN-LINUX-CXX: "-ldl"
+// CHECK-MSAN-LINUX-CXX: "-export-dynamic"
+// CHECK-MSAN-LINUX-CXX: stdc++
+
+// RUN: %clang -fsanitize=undefined %s -### -o %t.o 2>&1 \
+// RUN:     -target i386-unknown-linux \
+// RUN:     --sysroot=%S/Inputs/basic_linux_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-UBSAN-LINUX %s
+// CHECK-UBSAN-LINUX: "{{.*}}ld{{(.exe)?}}"
+// CHECK-UBSAN-LINUX-NOT: "-lc"
+// CHECK-UBSAN-LINUX: libclang_rt.ubsan-i386.a"
+// CHECK-UBSAN-LINUX: "-lpthread"
+
+// RUN: %clang -fsanitize=undefined %s -### -o %t.o 2>&1 \
+// RUN:     -target i386-unknown-linux \
+// RUN:     --sysroot=%S/Inputs/basic_linux_tree \
+// RUN:     -shared \
+// RUN:   | FileCheck --check-prefix=CHECK-UBSAN-LINUX-SHARED %s
+// CHECK-UBSAN-LINUX-SHARED: "{{.*}}ld{{(.exe)?}}"
+// CHECK-UBSAN-LINUX-SHARED-NOT: "-lc"
+// CHECK-UBSAN-LINUX-SHARED: libclang_rt.ubsan-i386.a"
+// CHECK-UBSAN-LINUX-SHARED: "-lpthread"

Removed: cfe/trunk/test/Driver/ubsan-ld.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Driver/ubsan-ld.c?rev=176177&view=auto
==============================================================================
--- cfe/trunk/test/Driver/ubsan-ld.c (original)
+++ cfe/trunk/test/Driver/ubsan-ld.c (removed)
@@ -1,20 +0,0 @@
-// Test UndefinedBehaviorSanitizer ld flags.
-
-// RUN: %clang -fsanitize=undefined %s -### -o %t.o 2>&1 \
-// RUN:     -target i386-unknown-linux \
-// RUN:     --sysroot=%S/Inputs/basic_linux_tree \
-// RUN:   | FileCheck --check-prefix=CHECK-LINUX %s
-// CHECK-LINUX: "{{.*}}ld{{(.exe)?}}"
-// CHECK-LINUX-NOT: "-lc"
-// CHECK-LINUX: libclang_rt.ubsan-i386.a"
-// CHECK-LINUX: "-lpthread"
-
-// RUN: %clang -fsanitize=undefined %s -### -o %t.o 2>&1 \
-// RUN:     -target i386-unknown-linux \
-// RUN:     --sysroot=%S/Inputs/basic_linux_tree \
-// RUN:     -shared \
-// RUN:   | FileCheck --check-prefix=CHECK-LINUX-SHARED %s
-// CHECK-LINUX-SHARED: "{{.*}}ld{{(.exe)?}}"
-// CHECK-LINUX-SHARED-NOT: "-lc"
-// CHECK-LINUX-SHARED: libclang_rt.ubsan-i386.a"
-// CHECK-LINUX-SHARED: "-lpthread"





More information about the cfe-commits mailing list