From 935a3aa5bc1441ec05e8b2656080b73f3a5fef1a Mon Sep 17 00:00:00 2001 From: Kostya Serebryany Date: Tue, 10 Mar 2015 01:58:27 +0000 Subject: [PATCH] [sanitizer] fix instrumentation with -mllvm -sanitizer-coverage-block-threshold=0 to actually do something useful. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@231736 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../Instrumentation/SanitizerCoverage.cpp | 17 ++++++++++------- .../SanitizerCoverage/coverage.ll | 5 +++++ 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/lib/Transforms/Instrumentation/SanitizerCoverage.cpp b/lib/Transforms/Instrumentation/SanitizerCoverage.cpp index fcb6ab04f5e..9c74b5ea5c2 100644 --- a/lib/Transforms/Instrumentation/SanitizerCoverage.cpp +++ b/lib/Transforms/Instrumentation/SanitizerCoverage.cpp @@ -111,6 +111,9 @@ class SanitizerCoverageModule : public ModulePass { ArrayRef IndirCalls); void SetNoSanitizeMetada(Instruction *I); void InjectCoverageAtBlock(Function &F, BasicBlock &BB, bool UseCalls); + unsigned NumberOfInstrumentedBlocks() { + return SanCovFunction->getNumUses() + SanCovWithCheckFunction->getNumUses(); + } Function *SanCovFunction; Function *SanCovWithCheckFunction; Function *SanCovIndirCallFunction; @@ -192,10 +195,11 @@ bool SanitizerCoverageModule::runOnModule(Module &M) { for (auto &F : M) runOnFunction(F); + auto N = NumberOfInstrumentedBlocks(); + // Now we know how many elements we need. Create an array of guards // with one extra element at the beginning for the size. - Type *Int32ArrayNTy = - ArrayType::get(Int32Ty, SanCovFunction->getNumUses() + 1); + Type *Int32ArrayNTy = ArrayType::get(Int32Ty, N + 1); GlobalVariable *RealGuardArray = new GlobalVariable( M, Int32ArrayNTy, false, GlobalValue::PrivateLinkage, Constant::getNullValue(Int32ArrayNTy), "__sancov_gen_cov"); @@ -211,8 +215,7 @@ bool SanitizerCoverageModule::runOnModule(Module &M) { // Make sure the array is 16-aligned. static const int kCounterAlignment = 16; Type *Int8ArrayNTy = - ArrayType::get(Int8Ty, RoundUpToAlignment(SanCovFunction->getNumUses(), - kCounterAlignment)); + ArrayType::get(Int8Ty, RoundUpToAlignment(N, kCounterAlignment)); RealEightBitCounterArray = new GlobalVariable( M, Int8ArrayNTy, false, GlobalValue::PrivateLinkage, Constant::getNullValue(Int8ArrayNTy), "__sancov_gen_cov_counter"); @@ -233,7 +236,7 @@ bool SanitizerCoverageModule::runOnModule(Module &M) { IRB.SetInsertPoint(CtorFunc->getEntryBlock().getTerminator()); IRB.CreateCall4( SanCovModuleInit, IRB.CreatePointerCast(RealGuardArray, Int32PtrTy), - ConstantInt::get(IntptrTy, SanCovFunction->getNumUses()), + ConstantInt::get(IntptrTy, N), ClUse8bitCounters ? IRB.CreatePointerCast(RealEightBitCounterArray, Int8PtrTy) : Constant::getNullValue(Int8PtrTy), @@ -333,7 +336,7 @@ void SanitizerCoverageModule::InjectCoverageAtBlock(Function &F, BasicBlock &BB, SmallVector Indices; Value *GuardP = IRB.CreateAdd( IRB.CreatePointerCast(GuardArray, IntptrTy), - ConstantInt::get(IntptrTy, (1 + SanCovFunction->getNumUses()) * 4)); + ConstantInt::get(IntptrTy, (1 + NumberOfInstrumentedBlocks()) * 4)); Type *Int32PtrTy = PointerType::getUnqual(IRB.getInt32Ty()); GuardP = IRB.CreateIntToPtr(GuardP, Int32PtrTy); if (UseCalls) { @@ -357,7 +360,7 @@ void SanitizerCoverageModule::InjectCoverageAtBlock(Function &F, BasicBlock &BB, IRB.SetInsertPoint(IP); Value *P = IRB.CreateAdd( IRB.CreatePointerCast(EightBitCounterArray, IntptrTy), - ConstantInt::get(IntptrTy, SanCovFunction->getNumUses() - 1)); + ConstantInt::get(IntptrTy, NumberOfInstrumentedBlocks() - 1)); P = IRB.CreateIntToPtr(P, IRB.getInt8PtrTy()); LoadInst *LI = IRB.CreateLoad(P); Value *Inc = IRB.CreateAdd(LI, ConstantInt::get(IRB.getInt8Ty(), 1)); diff --git a/test/Instrumentation/SanitizerCoverage/coverage.ll b/test/Instrumentation/SanitizerCoverage/coverage.ll index 024a9dceff3..b2f0ab0680b 100644 --- a/test/Instrumentation/SanitizerCoverage/coverage.ll +++ b/test/Instrumentation/SanitizerCoverage/coverage.ll @@ -2,6 +2,7 @@ ; RUN: opt < %s -sancov -sanitizer-coverage-level=1 -S | FileCheck %s --check-prefix=CHECK1 ; RUN: opt < %s -sancov -sanitizer-coverage-level=2 -S | FileCheck %s --check-prefix=CHECK2 ; RUN: opt < %s -sancov -sanitizer-coverage-level=2 -sanitizer-coverage-block-threshold=10 -S | FileCheck %s --check-prefix=CHECK2 +; RUN: opt < %s -sancov -sanitizer-coverage-level=2 -sanitizer-coverage-block-threshold=0 -S | FileCheck %s --check-prefix=CHECK_WITH_CHECK ; RUN: opt < %s -sancov -sanitizer-coverage-level=2 -sanitizer-coverage-block-threshold=1 -S | FileCheck %s --check-prefix=CHECK_WITH_CHECK ; RUN: opt < %s -sancov -sanitizer-coverage-level=3 -sanitizer-coverage-block-threshold=10 -S | FileCheck %s --check-prefix=CHECK3 ; RUN: opt < %s -sancov -sanitizer-coverage-level=4 -S | FileCheck %s --check-prefix=CHECK4 @@ -51,6 +52,10 @@ entry: ; CHECK_WITH_CHECK-LABEL: define void @foo ; CHECK_WITH_CHECK: __sanitizer_cov_with_check ; CHECK_WITH_CHECK: ret void +; CHECK_WITH_CHECK-LABEL: define internal void @sancov.module_ctor +; CHECK_WITH_CHECK-NOT: ret +; CHECK_WITH_CHECK: call void @__sanitizer_cov_module_init({{.*}}, i64 4, +; CHECK_WITH_CHECK: ret ; CHECK2-LABEL: define void @foo ; CHECK2: call void @__sanitizer_cov -- 2.34.1