From 8ad415574543c5ee4de98678fbe7452f60a086e3 Mon Sep 17 00:00:00 2001 From: Kostya Serebryany Date: Sat, 17 Sep 2016 05:03:05 +0000 Subject: [PATCH] [sanitizer-coverage] change trace-pc to use 8-byte guards llvm-svn: 281809 --- clang/docs/SanitizerCoverage.rst | 19 ++++---- .../Instrumentation/SanitizerCoverage.cpp | 51 ++++++++++++---------- .../Instrumentation/SanitizerCoverage/tracing.ll | 2 +- 3 files changed, 37 insertions(+), 35 deletions(-) diff --git a/clang/docs/SanitizerCoverage.rst b/clang/docs/SanitizerCoverage.rst index 9061500..a4693fe 100644 --- a/clang/docs/SanitizerCoverage.rst +++ b/clang/docs/SanitizerCoverage.rst @@ -331,24 +331,23 @@ on every edge: .. code-block:: none - if (guard_variable != 0xff) + if (guard_variable >= 0) __sanitizer_cov_trace_pc_guard(&guard_variable) -Every edge will have its own 1-byte `guard_variable`. -All such guard variables will reside in a dedicated section -(i.e. they essentially form an array). - -Similarly to `trace-pc,indirect-calls`, with `trace-pc-guards,indirect-calls` -``__sanitizer_cov_trace_pc_indirect(void *callee)`` will be inserted on every indirect call. +Every edge will have its own 8-byte `guard_variable`. The compler will also insert a module constructor that will call .. code-block:: c++ - // The guard section is the address range [start, stop). - __sanitizer_cov_trace_pc_guard_init(void *start, void *stop); + // The guards are [start, stop). + // This function may be called multiple times with the same values of start/stop. + __sanitizer_cov_trace_pc_guard_init(uint64_t *start, uint64_t *stop); + +Similarly to `trace-pc,indirect-calls`, with `trace-pc-guards,indirect-calls` +``__sanitizer_cov_trace_pc_indirect(void *callee)`` will be inserted on every indirect call. -The functions `__sanitizer_cov_trace_pc_guard[_init]` should be defined by the user. +The functions `__sanitizer_cov_trace_pc_*` should be defined by the user. Tracing data flow ================= diff --git a/llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp b/llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp index f8844bd..3c137c9 100644 --- a/llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp +++ b/llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp @@ -293,7 +293,7 @@ bool SanitizerCoverageModule::runOnModule(Module &M) { SanCovTracePC = checkSanitizerInterfaceFunction( M.getOrInsertFunction(SanCovTracePCName, VoidTy, nullptr)); SanCovTracePCGuard = checkSanitizerInterfaceFunction(M.getOrInsertFunction( - SanCovTracePCGuardName, VoidTy, IRB.getInt8PtrTy(), nullptr)); + SanCovTracePCGuardName, VoidTy, Int64PtrTy, nullptr)); SanCovTraceEnter = checkSanitizerInterfaceFunction( M.getOrInsertFunction(SanCovTraceEnterName, VoidTy, Int32PtrTy, nullptr)); SanCovTraceBB = checkSanitizerInterfaceFunction( @@ -352,16 +352,18 @@ bool SanitizerCoverageModule::runOnModule(Module &M) { 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); + GlobalVariable *Bounds[2]; + const char *Prefix[2] = {"__start_", "__stop_"}; + for (int i = 0; i < 2; i++) { + Bounds[i] = new GlobalVariable(M, Int64PtrTy, false, + GlobalVariable::ExternalLinkage, nullptr, + Prefix[i] + SectionName); + Bounds[i]->setVisibility(GlobalValue::HiddenVisibility); + } std::tie(CtorFunc, std::ignore) = createSanitizerCtorAndInitFunctions( M, SanCovModuleCtorName, SanCovTracePCGuardInitName, - {Int8PtrTy, Int8PtrTy}, {IRB.CreatePointerCast(Start, Int8PtrTy), - IRB.CreatePointerCast(Stop, Int8PtrTy)}); + {Int64PtrTy, Int64PtrTy}, {IRB.CreatePointerCast(Bounds[0], Int64PtrTy), + IRB.CreatePointerCast(Bounds[1], Int64PtrTy)}); appendToGlobalCtors(M, CtorFunc, SanCtorAndDtorPriority); @@ -662,23 +664,24 @@ void SanitizerCoverageModule::InjectCoverageAtBlock(Function &F, BasicBlock &BB, 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()); + auto GuardVar = new GlobalVariable( + *F.getParent(), Int64Ty, false, GlobalVariable::LinkOnceODRLinkage, + Constant::getNullValue(Int64Ty), "__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); + auto GuardPtr = IRB.CreatePointerCast(GuardVar, Int64PtrTy); + if (!UseCalls) { + auto GuardLoad = IRB.CreateLoad(GuardPtr); + GuardLoad->setAtomic(AtomicOrdering::Monotonic); + GuardLoad->setAlignment(8); + SetNoSanitizeMetadata(GuardLoad); // Don't instrument with e.g. asan. + auto Cmp = IRB.CreateICmpSGE( + GuardLoad, Constant::getNullValue(GuardLoad->getType())); + 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) { diff --git a/llvm/test/Instrumentation/SanitizerCoverage/tracing.ll b/llvm/test/Instrumentation/SanitizerCoverage/tracing.ll index 5b6a17b..df804f6 100644 --- a/llvm/test/Instrumentation/SanitizerCoverage/tracing.ll +++ b/llvm/test/Instrumentation/SanitizerCoverage/tracing.ll @@ -46,4 +46,4 @@ entry: ; 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*)) +; CHECK_PC_GUARD: call void @__sanitizer_cov_trace_pc_guard_init(i64* bitcast (i64** @__start___sancov_guards to i64*), i64* bitcast (i64** @__stop___sancov_guards to i64*)) -- 2.7.4