[PATCH] PR17633: -fsanitize=function requires -export-symbols.

Peter Collingbourne peter at pcc.me.uk
Thu Oct 24 00:00:13 PDT 2013


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

Files:
  include/clang/Driver/SanitizerArgs.h
  lib/Driver/Tools.cpp
  test/Driver/sanitizer-ld.c

Index: include/clang/Driver/SanitizerArgs.h
===================================================================
--- include/clang/Driver/SanitizerArgs.h
+++ include/clang/Driver/SanitizerArgs.h
@@ -41,7 +41,8 @@
     NeedsLeakDetection = Leak,
     NeedsUbsanRt = Undefined | Integer,
     NotAllowedWithTrap = Vptr,
-    HasZeroBaseShadow = Thread | Memory | DataFlow
+    HasZeroBaseShadow = Thread | Memory | DataFlow,
+    UsesTextRelocations = Function
   };
   unsigned Kind;
 
@@ -76,6 +77,7 @@
   bool hasZeroBaseShadow(const ToolChain &TC) const {
     return (Kind & HasZeroBaseShadow) || hasAsanZeroBaseShadow(TC);
   }
+  bool usesTextRelocations() const { return Kind & UsesTextRelocations; }
   void addArgs(const ToolChain &TC, const llvm::opt::ArgList &Args,
                llvm::opt::ArgStringList &CmdArgs) const;
 
Index: lib/Driver/Tools.cpp
===================================================================
--- lib/Driver/Tools.cpp
+++ lib/Driver/Tools.cpp
@@ -1715,10 +1715,16 @@
   CmdArgs.push_back(Args.MakeArgString(LibProfile));
 }
 
+enum ExportsKind {
+  EK_None,
+  EK_SymsFile,
+  EK_All
+};
+
 static void addSanitizerRTLinkFlagsLinux(
     const ToolChain &TC, const ArgList &Args, ArgStringList &CmdArgs,
     const StringRef Sanitizer, bool BeforeLibStdCXX,
-    bool ExportSymbols = true) {
+    ExportsKind EK = EK_SymsFile) {
   // Sanitizer runtime is located in the Linux library directory and
   // has name "libclang_rt.<Sanitizer>-<ArchName>.a".
   SmallString<128> LibSanitizer(TC.getDriver().ResourceDir);
@@ -1744,11 +1750,11 @@
   CmdArgs.push_back("-lrt");
   CmdArgs.push_back("-ldl");
 
-  // 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"))
+  // If possible (and requested), 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 (EK != EK_None) {
+    if (EK == EK_SymsFile && llvm::sys::fs::exists(LibSanitizer + ".syms"))
       CmdArgs.push_back(
           Args.MakeArgString("--dynamic-list=" + LibSanitizer + ".syms"));
     else
@@ -1800,18 +1806,20 @@
 /// (Linux).
 static void addUbsanRTLinux(const ToolChain &TC, const ArgList &Args,
                             ArgStringList &CmdArgs, bool IsCXX,
-                            bool HasOtherSanitizerRt) {
+                            bool HasOtherSanitizerRt, bool ExportAll) {
   // 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);
+    addSanitizerRTLinkFlagsLinux(TC, Args, CmdArgs, "san", true, EK_None);
+
+  ExportsKind EK = ExportAll ? EK_All : EK_SymsFile;
 
-  addSanitizerRTLinkFlagsLinux(TC, Args, CmdArgs, "ubsan", false);
+  addSanitizerRTLinkFlagsLinux(TC, Args, CmdArgs, "ubsan", false, EK);
 
   // 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);
+    addSanitizerRTLinkFlagsLinux(TC, Args, CmdArgs, "ubsan_cxx", false, EK);
 }
 
 static void addDfsanRTLinux(const ToolChain &TC, const ArgList &Args,
@@ -6313,7 +6321,10 @@
   if (Sanitize.needsUbsanRt())
     addUbsanRTLinux(getToolChain(), Args, CmdArgs, D.CCCIsCXX(),
                     Sanitize.needsAsanRt() || Sanitize.needsTsanRt() ||
-                    Sanitize.needsMsanRt() || Sanitize.needsLsanRt());
+                    Sanitize.needsMsanRt() || Sanitize.needsLsanRt(),
+                    // If the sanitizer uses .text relocations we must export
+                    // all symbols (see PR17633).
+                    Sanitize.usesTextRelocations());
   if (Sanitize.needsAsanRt())
     addAsanRTLinux(getToolChain(), Args, CmdArgs);
   if (Sanitize.needsTsanRt())
Index: test/Driver/sanitizer-ld.c
===================================================================
--- test/Driver/sanitizer-ld.c
+++ test/Driver/sanitizer-ld.c
@@ -109,6 +109,7 @@
 
 // RUN: %clangxx -fsanitize=undefined %s -### -o %t.o 2>&1 \
 // RUN:     -target i386-unknown-linux \
+// RUN:     -resource-dir=%S/Inputs/resource_dir \
 // RUN:     --sysroot=%S/Inputs/basic_linux_tree \
 // RUN:   | FileCheck --check-prefix=CHECK-UBSAN-LINUX-CXX %s
 // CHECK-UBSAN-LINUX-CXX: "{{.*}}ld{{(.exe)?}}"
@@ -118,8 +119,16 @@
 // CHECK-UBSAN-LINUX-CXX: "-whole-archive" "{{.*}}libclang_rt.ubsan-i386.a" "-no-whole-archive"
 // CHECK-UBSAN-LINUX-CXX: "-whole-archive" "{{.*}}libclang_rt.ubsan_cxx-i386.a" "-no-whole-archive"
 // CHECK-UBSAN-LINUX-CXX: "-lpthread"
+// CHECK-UBSAN-LINUX-CXX: "-export-dynamic"
 // CHECK-UBSAN-LINUX-CXX: "-lstdc++"
 
+// RUN: %clangxx -fsanitize=undefined -fno-sanitize=function %s -### -o %t.o 2>&1 \
+// RUN:     -target i386-unknown-linux \
+// RUN:     -resource-dir=%S/Inputs/resource_dir \
+// RUN:     --sysroot=%S/Inputs/basic_linux_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-UBSAN-NO-FSAN-LINUX-CXX %s
+// CHECK-UBSAN-NO-FSAN-LINUX-CXX: "--dynamic-list={{.*}}libclang_rt.ubsan-i386.a.syms"
+
 // RUN: %clang -fsanitize=address,undefined %s -### -o %t.o 2>&1 \
 // RUN:     -target i386-unknown-linux \
 // RUN:     --sysroot=%S/Inputs/basic_linux_tree \
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D2010.1.patch
Type: text/x-patch
Size: 5547 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20131024/deb87082/attachment.bin>


More information about the cfe-commits mailing list