[llvm] r222290 - [asan] add experimental basic-block tracing to asan-coverage; also fix -fsanitize-coverage=3 which was broken by r221718

Kostya Serebryany kcc at google.com
Tue Nov 18 16:22:58 PST 2014


Author: kcc
Date: Tue Nov 18 18:22:58 2014
New Revision: 222290

URL: http://llvm.org/viewvc/llvm-project?rev=222290&view=rev
Log:
[asan] add experimental basic-block tracing to asan-coverage; also fix -fsanitize-coverage=3 which was broken by r221718

Added:
    llvm/trunk/test/Instrumentation/SanitizerCoverage/tracing.ll
Modified:
    llvm/trunk/lib/Transforms/Instrumentation/AddressSanitizer.cpp
    llvm/trunk/lib/Transforms/Instrumentation/SanitizerCoverage.cpp
    llvm/trunk/test/Instrumentation/SanitizerCoverage/coverage.ll

Modified: llvm/trunk/lib/Transforms/Instrumentation/AddressSanitizer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Instrumentation/AddressSanitizer.cpp?rev=222290&r1=222289&r2=222290&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Instrumentation/AddressSanitizer.cpp (original)
+++ llvm/trunk/lib/Transforms/Instrumentation/AddressSanitizer.cpp Tue Nov 18 18:22:58 2014
@@ -89,6 +89,7 @@ static const int         kMaxAsanStackMa
 static const char *const kAsanStackMallocNameTemplate = "__asan_stack_malloc_";
 static const char *const kAsanStackFreeNameTemplate = "__asan_stack_free_";
 static const char *const kAsanGenPrefix = "__asan_gen_";
+static const char *const kSanCovGenPrefix = "__sancov_gen_";
 static const char *const kAsanPoisonStackMemoryName =
     "__asan_poison_stack_memory";
 static const char *const kAsanUnpoisonStackMemoryName =
@@ -619,7 +620,8 @@ static GlobalVariable *createPrivateGlob
 }
 
 static bool GlobalWasGeneratedByAsan(GlobalVariable *G) {
-  return G->getName().find(kAsanGenPrefix) == 0;
+  return G->getName().find(kAsanGenPrefix) == 0 ||
+         G->getName().find(kSanCovGenPrefix) == 0;
 }
 
 Value *AddressSanitizer::memToShadow(Value *Shadow, IRBuilder<> &IRB) {

Modified: llvm/trunk/lib/Transforms/Instrumentation/SanitizerCoverage.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Instrumentation/SanitizerCoverage.cpp?rev=222290&r1=222289&r2=222290&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Instrumentation/SanitizerCoverage.cpp (original)
+++ llvm/trunk/lib/Transforms/Instrumentation/SanitizerCoverage.cpp Tue Nov 18 18:22:58 2014
@@ -56,6 +56,8 @@ using namespace llvm;
 static const char *const kSanCovModuleInitName = "__sanitizer_cov_module_init";
 static const char *const kSanCovName = "__sanitizer_cov";
 static const char *const kSanCovIndirCallName = "__sanitizer_cov_indir_call16";
+static const char *const kSanCovTraceEnter = "__sanitizer_cov_trace_func_enter";
+static const char *const kSanCovTraceBB = "__sanitizer_cov_trace_basic_block";
 static const char *const kSanCovModuleCtorName = "sancov.module_ctor";
 static const uint64_t    kSanCtorAndDtorPriority = 1;
 
@@ -71,15 +73,19 @@ static cl::opt<int> ClCoverageBlockThres
              "are more than this number of blocks."),
     cl::Hidden, cl::init(1500));
 
+static cl::opt<bool>
+    ClExperimentalTracing("sanitizer-coverage-experimental-tracing",
+                          cl::desc("Experimental basic-block tracing: insert "
+                                   "callbacks at every basic block"),
+                          cl::Hidden, cl::init(false));
+
 namespace {
 
 class SanitizerCoverageModule : public ModulePass {
  public:
-  SanitizerCoverageModule(int CoverageLevel = 0)
+   SanitizerCoverageModule(int CoverageLevel = 0)
        : ModulePass(ID),
-         CoverageLevel(std::max(CoverageLevel, (int)ClCoverageLevel)) {
-    initializeBreakCriticalEdgesPass(*PassRegistry::getPassRegistry());
-  }
+         CoverageLevel(std::max(CoverageLevel, (int)ClCoverageLevel)) {}
   bool runOnModule(Module &M) override;
   bool runOnFunction(Function &F);
   static char ID;  // Pass identification, replacement for typeid
@@ -88,8 +94,6 @@ class SanitizerCoverageModule : public M
   }
 
   void getAnalysisUsage(AnalysisUsage &AU) const override {
-    if (CoverageLevel >= 3)
-      AU.addRequiredID(BreakCriticalEdgesID);
     AU.addRequired<DataLayoutPass>();
   }
 
@@ -98,10 +102,12 @@ class SanitizerCoverageModule : public M
                                       ArrayRef<Instruction *> IndirCalls);
   bool InjectCoverage(Function &F, ArrayRef<BasicBlock *> AllBlocks,
                       ArrayRef<Instruction *> IndirCalls);
+  bool InjectTracing(Function &F, ArrayRef<BasicBlock *> AllBlocks);
   void InjectCoverageAtBlock(Function &F, BasicBlock &BB);
   Function *SanCovFunction;
   Function *SanCovIndirCallFunction;
   Function *SanCovModuleInit;
+  Function *SanCovTraceEnter, *SanCovTraceBB;
   Type *IntptrTy;
   LLVMContext *C;
 
@@ -141,6 +147,13 @@ bool SanitizerCoverageModule::runOnModul
       kSanCovModuleInitName, Type::getVoidTy(*C), IntptrTy, nullptr));
   SanCovModuleInit->setLinkage(Function::ExternalLinkage);
 
+  if (ClExperimentalTracing) {
+    SanCovTraceEnter = checkInterfaceFunction(
+        M.getOrInsertFunction(kSanCovTraceEnter, VoidTy, IntptrTy, nullptr));
+    SanCovTraceBB = checkInterfaceFunction(
+        M.getOrInsertFunction(kSanCovTraceBB, VoidTy, IntptrTy, nullptr));
+  }
+
   for (auto &F : M)
     runOnFunction(F);
 
@@ -155,6 +168,8 @@ bool SanitizerCoverageModule::runOnFunct
   // For now instrument only functions that will also be asan-instrumented.
   if (!F.hasFnAttribute(Attribute::SanitizeAddress))
     return false;
+  if (CoverageLevel >= 3)
+    SplitAllCriticalEdges(F, this);
   SmallVector<Instruction*, 8> IndirCalls;
   SmallVector<BasicBlock*, 16> AllBlocks;
   for (auto &BB : F) {
@@ -167,6 +182,25 @@ bool SanitizerCoverageModule::runOnFunct
       }
   }
   InjectCoverage(F, AllBlocks, IndirCalls);
+  InjectTracing(F, AllBlocks);
+  return true;
+}
+
+// Experimental support for tracing.
+// Basicaly, insert a callback at the beginning of every basic block.
+// Every callback gets a pointer to a uniqie global for internal storage.
+bool SanitizerCoverageModule::InjectTracing(Function &F,
+                                            ArrayRef<BasicBlock *> AllBlocks) {
+  if (!ClExperimentalTracing) return false;
+  Type *Ty = ArrayType::get(IntptrTy, 1);  // May need to use more words later.
+  for (auto BB : AllBlocks) {
+    IRBuilder<> IRB(BB->getFirstInsertionPt());
+    GlobalVariable *TraceCache = new GlobalVariable(
+        *F.getParent(), Ty, false, GlobalValue::PrivateLinkage,
+        Constant::getNullValue(Ty), "__sancov_gen_trace_cache");
+    IRB.CreateCall(&F.getEntryBlock() == BB ? SanCovTraceEnter : SanCovTraceBB,
+                   IRB.CreatePointerCast(TraceCache, IntptrTy));
+  }
   return true;
 }
 

Modified: llvm/trunk/test/Instrumentation/SanitizerCoverage/coverage.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Instrumentation/SanitizerCoverage/coverage.ll?rev=222290&r1=222289&r2=222290&view=diff
==============================================================================
--- llvm/trunk/test/Instrumentation/SanitizerCoverage/coverage.ll (original)
+++ llvm/trunk/test/Instrumentation/SanitizerCoverage/coverage.ll Tue Nov 18 18:22:58 2014
@@ -62,6 +62,7 @@ entry:
 ; CHECK3: call void @__sanitizer_cov
 ; CHECK3: call void @__sanitizer_cov
 ; CHECK3: call void @__sanitizer_cov
+; CHECK3-NOT: ret void
 ; CHECK3: call void @__sanitizer_cov
 ; CHECK3-NOT: call void @__sanitizer_cov
 ; CHECK3: ret void

Added: llvm/trunk/test/Instrumentation/SanitizerCoverage/tracing.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Instrumentation/SanitizerCoverage/tracing.ll?rev=222290&view=auto
==============================================================================
--- llvm/trunk/test/Instrumentation/SanitizerCoverage/tracing.ll (added)
+++ llvm/trunk/test/Instrumentation/SanitizerCoverage/tracing.ll Tue Nov 18 18:22:58 2014
@@ -0,0 +1,33 @@
+; Test -sanitizer-coverage-experimental-tracing
+; RUN: opt < %s -sancov -sanitizer-coverage-level=1 -sanitizer-coverage-experimental-tracing  -S | FileCheck %s --check-prefix=CHECK1
+; RUN: opt < %s -sancov -sanitizer-coverage-level=3 -sanitizer-coverage-experimental-tracing  -S | FileCheck %s --check-prefix=CHECK3
+
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
+target triple = "x86_64-unknown-linux-gnu"
+define void @foo(i32* %a) sanitize_address {
+entry:
+  %tobool = icmp eq i32* %a, null
+  br i1 %tobool, label %if.end, label %if.then
+
+  if.then:                                          ; preds = %entry
+  store i32 0, i32* %a, align 4
+  br label %if.end
+
+  if.end:                                           ; preds = %entry, %if.then
+  ret void
+}
+
+; CHECK1-LABEL: define void @foo
+; CHECK1: call void @__sanitizer_cov_trace_func_enter
+; CHECK1: call void @__sanitizer_cov_trace_basic_block
+; CHECK1: call void @__sanitizer_cov_trace_basic_block
+; CHECK1-NOT: call void @__sanitizer_cov_trace_basic_block
+; CHECK1: ret void
+
+; CHECK3-LABEL: define void @foo
+; CHECK3: call void @__sanitizer_cov_trace_func_enter
+; CHECK3: call void @__sanitizer_cov_trace_basic_block
+; CHECK3: call void @__sanitizer_cov_trace_basic_block
+; CHECK3: call void @__sanitizer_cov_trace_basic_block
+; CHECK3-NOT: call void @__sanitizer_cov_trace_basic_block
+; CHECK3: ret void





More information about the llvm-commits mailing list