[cfe-commits] [PATCH] Clang support for MemorySanitizer

Evgeniy Stepanov eugenis at google.com
Thu Nov 29 03:51:36 PST 2012


Hi kcc, chandlerc, nicholas,

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

Files:
  llvm/tools/clang/include/clang/Basic/DiagnosticDriverKinds.td
  llvm/tools/clang/include/clang/Basic/Sanitizers.def
  llvm/tools/clang/lib/CodeGen/BackendUtil.cpp
  llvm/tools/clang/lib/Driver/SanitizerArgs.h
  llvm/tools/clang/lib/Driver/Tools.cpp

Index: llvm/tools/clang/include/clang/Basic/DiagnosticDriverKinds.td
===================================================================
--- llvm/tools/clang/include/clang/Basic/DiagnosticDriverKinds.td
+++ llvm/tools/clang/include/clang/Basic/DiagnosticDriverKinds.td
@@ -101,6 +101,8 @@
   "option '-MG' requires '-M' or '-MM'">;
 def err_drv_asan_android_requires_pie : Error<
   "AddressSanitizer on Android requires '-pie'">;
+def err_drv_tsan_msan_require_pie : Error<
+  "ThreadSanitizer and MemorySanitizer require '-pie'">;
 def err_drv_unknown_objc_runtime : Error<
   "unknown or ill-formed Objective-C runtime '%0'">;
 
Index: llvm/tools/clang/include/clang/Basic/Sanitizers.def
===================================================================
--- llvm/tools/clang/include/clang/Basic/Sanitizers.def
+++ llvm/tools/clang/include/clang/Basic/Sanitizers.def
@@ -41,6 +41,9 @@
 // AddressSanitizer
 SANITIZER("address", Address)
 
+// MemorySanitizer
+SANITIZER("memory", Memory)
+
 // ThreadSanitizer
 SANITIZER("thread", Thread)
 
Index: llvm/tools/clang/lib/CodeGen/BackendUtil.cpp
===================================================================
--- llvm/tools/clang/lib/CodeGen/BackendUtil.cpp
+++ llvm/tools/clang/lib/CodeGen/BackendUtil.cpp
@@ -163,6 +163,47 @@
   PM.add(createAddressSanitizerModulePass());
 }
 
+static cl::opt<bool> ClMSanMoreOpt(
+  "msan-more-opt",
+  cl::desc("add more general purpose optimizations after MemorySanitizer pass"),
+  cl::Hidden, cl::init(true));
+
+static void addMemorySanitizerPass(const PassManagerBuilder &Builder,
+                                   PassManagerBase &PM) {
+  PM.add(createMemorySanitizerPass());
+
+  // MemorySanitizer pass generates complex instrumentation which can benefit
+  // from re-running common optimizations.
+  if (ClMSanMoreOpt && Builder.OptLevel > 0) {
+    PM.add(createEarlyCSEPass());              // Catch trivial redundancies
+    PM.add(createJumpThreadingPass());         // Thread jumps.
+    PM.add(createCorrelatedValuePropagationPass()); // Propagate conditionals
+    PM.add(createCFGSimplificationPass());     // Merge & remove BBs
+    PM.add(createInstructionCombiningPass());  // Combine silly seq's
+
+    PM.add(createTailCallEliminationPass());   // Eliminate tail calls
+    PM.add(createCFGSimplificationPass());     // Merge & remove BBs
+    PM.add(createReassociatePass());           // Reassociate expressions
+    PM.add(createLoopRotatePass());            // Rotate Loop
+    PM.add(createLICMPass());                  // Hoist loop invariants
+    PM.add(createInstructionCombiningPass());
+    PM.add(createIndVarSimplifyPass());        // Canonicalize indvars
+    PM.add(createLoopIdiomPass());             // Recognize idioms like memset.
+    PM.add(createLoopDeletionPass());          // Delete dead loops
+
+    PM.add(createGVNPass());                   // Remove redundancies
+    PM.add(createMemCpyOptPass());             // Remove memcpy / form memset
+    PM.add(createSCCPPass());                  // Constant prop with SCCP
+
+    // Run instcombine after redundancy elimination to exploit opportunities
+    // opened up by them.
+    PM.add(createInstructionCombiningPass());
+    PM.add(createJumpThreadingPass());         // Thread jumps
+    PM.add(createCorrelatedValuePropagationPass());
+    PM.add(createDeadStoreEliminationPass());  // Delete dead stores
+  }
+}
+
 static void addThreadSanitizerPass(const PassManagerBuilder &Builder,
                                    PassManagerBase &PM) {
   PM.add(createThreadSanitizerPass());
@@ -211,6 +252,13 @@
                            addAddressSanitizerPass);
   }
 
+  if (LangOpts.SanitizeMemory) {
+    PMBuilder.addExtension(PassManagerBuilder::EP_OptimizerLast,
+                           addMemorySanitizerPass);
+    PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0,
+                           addMemorySanitizerPass);
+  }
+
   if (LangOpts.SanitizeThread) {
     PMBuilder.addExtension(PassManagerBuilder::EP_OptimizerLast,
                            addThreadSanitizerPass);
Index: llvm/tools/clang/lib/Driver/SanitizerArgs.h
===================================================================
--- llvm/tools/clang/lib/Driver/SanitizerArgs.h
+++ llvm/tools/clang/lib/Driver/SanitizerArgs.h
@@ -30,6 +30,7 @@
 #include "clang/Basic/Sanitizers.def"
     NeedsAsanRt = Address,
     NeedsTsanRt = Thread,
+    NeedsMsanRt = Memory,
     NeedsUbsanRt = (Undefined & ~Bounds) | Integer
   };
   unsigned Kind;
@@ -41,6 +42,7 @@
 
   bool needsAsanRt() const { return Kind & NeedsAsanRt; }
   bool needsTsanRt() const { return Kind & NeedsTsanRt; }
+  bool needsMsanRt() const { return Kind & NeedsMsanRt; }
   bool needsUbsanRt() const { return Kind & NeedsUbsanRt; }
 
   bool sanitizesVptr() const { return Kind & Vptr; }
Index: llvm/tools/clang/lib/Driver/Tools.cpp
===================================================================
--- llvm/tools/clang/lib/Driver/Tools.cpp
+++ llvm/tools/clang/lib/Driver/Tools.cpp
@@ -1512,6 +1512,8 @@
 static void addTsanRTLinux(const ToolChain &TC, const ArgList &Args,
                            ArgStringList &CmdArgs) {
   if (!Args.hasArg(options::OPT_shared)) {
+    if (!Args.hasArg(options::OPT_pie))
+      TC.getDriver().Diag(diag::err_drv_tsan_msan_require_pie);
     // LibTsan is "libclang_rt.tsan-<ArchName>.a" in the Linux library
     // resource directory.
     SmallString<128> LibTsan(TC.getDriver().ResourceDir);
@@ -1525,6 +1527,26 @@
   }
 }
 
+/// If MemorySanitizer is enabled, add appropriate linker flags (Linux).
+/// This needs to be called before we add the C run-time (malloc, etc).
+static void addMsanRTLinux(const ToolChain &TC, const ArgList &Args,
+                           ArgStringList &CmdArgs) {
+  if (!Args.hasArg(options::OPT_shared)) {
+    if (!Args.hasArg(options::OPT_pie))
+      TC.getDriver().Diag(diag::err_drv_tsan_msan_require_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");
+  }
+}
+
 /// If UndefinedBehaviorSanitizer is enabled, add appropriate linker flags
 /// (Linux).
 static void addUbsanRTLinux(const ToolChain &TC, const ArgList &Args,
@@ -4069,7 +4091,9 @@
   // -fsanitize=undefined, unresolved symbols may appear. Mark all
   // of them as dynamic_lookup. Linking executables is handled in
   // lib/Driver/ToolChains.cpp.
-  if (Sanitize.needsAsanRt() || Sanitize.needsUbsanRt()) {
+  if (Sanitize.needsAsanRt() ||
+      Sanitize.needsMsanRt() ||
+      Sanitize.needsUbsanRt()) {
     if (Args.hasArg(options::OPT_dynamiclib) ||
         Args.hasArg(options::OPT_bundle)) {
       CmdArgs.push_back("-undefined");
@@ -5445,6 +5469,8 @@
     addAsanRTLinux(getToolChain(), Args, CmdArgs);
   if (Sanitize.needsTsanRt())
     addTsanRTLinux(getToolChain(), Args, CmdArgs);
+  if (Sanitize.needsMsanRt())
+    addMsanRTLinux(getToolChain(), Args, CmdArgs);
 
   if (!Args.hasArg(options::OPT_nostdlib)) {
     if (!Args.hasArg(options::OPT_nodefaultlibs)) {
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D146.1.patch
Type: text/x-patch
Size: 7446 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20121129/697086bf/attachment.bin>


More information about the cfe-commits mailing list