[llvm] r281431 - [sanitizer-coverage] add yet another flavour of coverage instrumentation: trace-pc-guard. The intent is to eventually replace all of {bool coverage, 8bit-counters, trace-pc} with just this one. LLVM part

Kostya Serebryany via llvm-commits llvm-commits at lists.llvm.org
Tue Sep 13 18:39:36 PDT 2016


Author: kcc
Date: Tue Sep 13 20:39:35 2016
New Revision: 281431

URL: http://llvm.org/viewvc/llvm-project?rev=281431&view=rev
Log:
[sanitizer-coverage] add yet another flavour of coverage instrumentation: trace-pc-guard. The intent is to eventually replace all of {bool coverage, 8bit-counters, trace-pc} with just this one. LLVM part

Modified:
    llvm/trunk/include/llvm/Transforms/Instrumentation.h
    llvm/trunk/lib/Transforms/Instrumentation/SanitizerCoverage.cpp
    llvm/trunk/test/Instrumentation/SanitizerCoverage/tracing.ll

Modified: llvm/trunk/include/llvm/Transforms/Instrumentation.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/Instrumentation.h?rev=281431&r1=281430&r2=281431&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Transforms/Instrumentation.h (original)
+++ llvm/trunk/include/llvm/Transforms/Instrumentation.h Tue Sep 13 20:39:35 2016
@@ -137,7 +137,7 @@ struct SanitizerCoverageOptions {
   SanitizerCoverageOptions()
       : CoverageType(SCK_None), IndirectCalls(false), TraceBB(false),
         TraceCmp(false), TraceDiv(false), TraceGep(false),
-        Use8bitCounters(false), TracePC(false) {}
+        Use8bitCounters(false), TracePC(false), TracePCGuard(false) {}
 
   enum Type {
     SCK_None = 0,
@@ -152,6 +152,7 @@ struct SanitizerCoverageOptions {
   bool TraceGep;
   bool Use8bitCounters;
   bool TracePC;
+  bool TracePCGuard;
 };
 
 // Insert SanitizerCoverage instrumentation.

Modified: llvm/trunk/lib/Transforms/Instrumentation/SanitizerCoverage.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Instrumentation/SanitizerCoverage.cpp?rev=281431&r1=281430&r2=281431&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Instrumentation/SanitizerCoverage.cpp (original)
+++ llvm/trunk/lib/Transforms/Instrumentation/SanitizerCoverage.cpp Tue Sep 13 20:39:35 2016
@@ -78,6 +78,12 @@ static const char *const SanCovTraceSwit
 static const char *const SanCovModuleCtorName = "sancov.module_ctor";
 static const uint64_t SanCtorAndDtorPriority = 2;
 
+static const char *const SanCovTracePCGuardSection = "__sancov_guards";
+static const char *const SanCovTracePCGuardName =
+    "__sanitizer_cov_trace_pc_guard";
+static const char *const SanCovTracePCGuardInitName =
+    "__sanitizer_cov_trace_pc_guard_init";
+
 static cl::opt<int> ClCoverageLevel(
     "sanitizer-coverage-level",
     cl::desc("Sanitizer Coverage. 0: none, 1: entry block, 2: all blocks, "
@@ -101,6 +107,10 @@ static cl::opt<bool> ClExperimentalTrace
                                            cl::desc("Experimental pc tracing"),
                                            cl::Hidden, cl::init(false));
 
+static cl::opt<bool> ClTracePCGuard("sanitizer-coverage-trace-pc-guard",
+                                    cl::desc("pc tracing with a guard"),
+                                    cl::Hidden, cl::init(false));
+
 static cl::opt<bool>
     ClCMPTracing("sanitizer-coverage-trace-compares",
                  cl::desc("Tracing of CMP and similar instructions"),
@@ -165,6 +175,7 @@ SanitizerCoverageOptions OverrideFromCL(
   Options.TraceGep |= ClGEPTracing;
   Options.Use8bitCounters |= ClUse8bitCounters;
   Options.TracePC |= ClExperimentalTracePC;
+  Options.TracePCGuard |= ClTracePCGuard;
   return Options;
 }
 
@@ -206,7 +217,7 @@ private:
   Function *SanCovFunction;
   Function *SanCovWithCheckFunction;
   Function *SanCovIndirCallFunction, *SanCovTracePCIndir;
-  Function *SanCovTraceEnter, *SanCovTraceBB, *SanCovTracePC;
+  Function *SanCovTraceEnter, *SanCovTraceBB, *SanCovTracePC, *SanCovTracePCGuard;
   Function *SanCovTraceCmpFunction[4];
   Function *SanCovTraceDivFunction[2];
   Function *SanCovTraceGepFunction;
@@ -281,6 +292,8 @@ bool SanitizerCoverageModule::runOnModul
 
   SanCovTracePC = checkSanitizerInterfaceFunction(
       M.getOrInsertFunction(SanCovTracePCName, VoidTy, nullptr));
+  SanCovTracePCGuard = checkSanitizerInterfaceFunction(M.getOrInsertFunction(
+      SanCovTracePCGuardName, VoidTy, IRB.getInt8PtrTy(), nullptr));
   SanCovTraceEnter = checkSanitizerInterfaceFunction(
       M.getOrInsertFunction(SanCovTraceEnterName, VoidTy, Int32PtrTy, nullptr));
   SanCovTraceBB = checkSanitizerInterfaceFunction(
@@ -336,8 +349,23 @@ bool SanitizerCoverageModule::runOnModul
   GlobalVariable *ModuleName =
       new GlobalVariable(M, ModNameStrConst->getType(), true,
                          GlobalValue::PrivateLinkage, ModNameStrConst);
+  if (Options.TracePCGuard) {
+    Function *CtorFunc;
+    std::string SectionName(SanCovTracePCGuardSection);
+    auto Start =
+        new GlobalVariable(M, Int8PtrTy, false, GlobalVariable::ExternalLinkage,
+                           nullptr, "__start_" + SectionName);
+    auto Stop =
+        new GlobalVariable(M, Int8PtrTy, false, GlobalVariable::ExternalLinkage,
+                           nullptr, "__stop_" + SectionName);
+    std::tie(CtorFunc, std::ignore) = createSanitizerCtorAndInitFunctions(
+        M, SanCovModuleCtorName, SanCovTracePCGuardInitName,
+        {Int8PtrTy, Int8PtrTy}, {IRB.CreatePointerCast(Start, Int8PtrTy),
+                                 IRB.CreatePointerCast(Stop, Int8PtrTy)});
 
-  if (!Options.TracePC) {
+    appendToGlobalCtors(M, CtorFunc, SanCtorAndDtorPriority);
+
+  } else if (!Options.TracePC) {
     Function *CtorFunc;
     std::tie(CtorFunc, std::ignore) = createSanitizerCtorAndInitFunctions(
         M, SanCovModuleCtorName, SanCovModuleInitName,
@@ -395,6 +423,8 @@ bool SanitizerCoverageModule::runOnFunct
     return false;
   if (F.getName().find(".module_ctor") != std::string::npos)
     return false; // Should not instrument sanitizer init functions.
+  if (F.getName().startswith("__sanitizer_"))
+    return false;  // Don't instrument __sanitizer_* callbacks.
   // Don't instrument functions using SEH for now. Splitting basic blocks like
   // we do for coverage breaks WinEHPrepare.
   // FIXME: Remove this when SEH no longer uses landingpad pattern matching.
@@ -631,6 +661,26 @@ void SanitizerCoverageModule::InjectCove
   if (Options.TracePC) {
     IRB.CreateCall(SanCovTracePC); // gets the PC using GET_CALLER_PC.
     IRB.CreateCall(EmptyAsm, {}); // Avoids callback merge.
+  } else if (Options.TracePCGuard) {
+    auto GuardVar = new GlobalVariable(*F.getParent(), IRB.getInt8Ty(), false,
+                                       GlobalVariable::LinkOnceODRLinkage,
+                                       Constant::getNullValue(IRB.getInt8Ty()),
+                                       "__sancov_guard." + F.getName());
+    // TODO: add debug into to GuardVar.
+    GuardVar->setSection(SanCovTracePCGuardSection);
+    auto GuardPtr = IRB.CreatePointerCast(GuardVar, IRB.getInt8PtrTy());
+    auto GuardLoad = IRB.CreateLoad(GuardPtr);
+    GuardLoad->setAtomic(AtomicOrdering::Monotonic);
+    GuardLoad->setAlignment(1);
+    SetNoSanitizeMetadata(GuardLoad);  // Don't instrument with e.g. asan.
+    auto Cmp = IRB.CreateICmpNE(
+        Constant::getAllOnesValue(GuardLoad->getType()), GuardLoad);
+    auto Ins = SplitBlockAndInsertIfThen(
+        Cmp, &*IP, false, MDBuilder(*C).createBranchWeights(1, 100000));
+    IRB.SetCurrentDebugLocation(EntryLoc);
+    IRB.SetInsertPoint(Ins);
+    IRB.CreateCall(SanCovTracePCGuard, GuardPtr);
+    IRB.CreateCall(EmptyAsm, {}); // Avoids callback merge.
   } else if (Options.TraceBB) {
     IRB.CreateCall(IsEntryBB ? SanCovTraceEnter : SanCovTraceBB, GuardP);
   } else if (UseCalls) {

Modified: llvm/trunk/test/Instrumentation/SanitizerCoverage/tracing.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Instrumentation/SanitizerCoverage/tracing.ll?rev=281431&r1=281430&r2=281431&view=diff
==============================================================================
--- llvm/trunk/test/Instrumentation/SanitizerCoverage/tracing.ll (original)
+++ llvm/trunk/test/Instrumentation/SanitizerCoverage/tracing.ll Tue Sep 13 20:39:35 2016
@@ -2,6 +2,7 @@
 ; RUN: opt < %s -sancov -sanitizer-coverage-level=2 -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
 ; RUN: opt < %s -sancov -sanitizer-coverage-level=3 -sanitizer-coverage-trace-pc  -S | FileCheck %s --check-prefix=CHECK_PC
+; RUN: opt < %s -sancov -sanitizer-coverage-level=3 -sanitizer-coverage-trace-pc-guard  -S | FileCheck %s --check-prefix=CHECK_PC_GUARD
 
 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"
@@ -38,3 +39,11 @@ entry:
 ; CHECK_PC-NOT: call void @__sanitizer_cov_trace_pc
 ; CHECK_PC: ret void
 ; CHECK_PC-NOT: call void @__sanitizer_cov_module_init
+
+; CHECK_PC_GUARD-LABEL: define void @foo
+; CHECK_PC_GUARD: call void @__sanitizer_cov_trace_pc_guard
+; CHECK_PC_GUARD: call void @__sanitizer_cov_trace_pc_guard
+; CHECK_PC_GUARD: call void @__sanitizer_cov_trace_pc_guard
+; CHECK_PC_GUARD-NOT: call void @__sanitizer_cov_trace_pc
+; CHECK_PC_GUARD: ret void
+; CHECK_PC_GUARD: call void @__sanitizer_cov_trace_pc_guard_init(i8* bitcast (i8** @__start___sancov_guards to i8*), i8* bitcast (i8** @__stop___sancov_guards to i8*))




More information about the llvm-commits mailing list