[llvm] r224789 - [asan] change the coverage collection scheme so that we can easily emit coverage for the entire process as a single bit set, and if coverage_bitset=1 actually emit that bitset
Kostya Serebryany
kcc at google.com
Tue Dec 23 14:32:18 PST 2014
Author: kcc
Date: Tue Dec 23 16:32:17 2014
New Revision: 224789
URL: http://llvm.org/viewvc/llvm-project?rev=224789&view=rev
Log:
[asan] change the coverage collection scheme so that we can easily emit coverage for the entire process as a single bit set, and if coverage_bitset=1 actually emit that bitset
Modified:
llvm/trunk/lib/Transforms/Instrumentation/SanitizerCoverage.cpp
llvm/trunk/test/Instrumentation/SanitizerCoverage/coverage-dbg.ll
llvm/trunk/test/Instrumentation/SanitizerCoverage/coverage.ll
llvm/trunk/test/Instrumentation/SanitizerCoverage/coverage2-dbg.ll
Modified: llvm/trunk/lib/Transforms/Instrumentation/SanitizerCoverage.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Instrumentation/SanitizerCoverage.cpp?rev=224789&r1=224788&r2=224789&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Instrumentation/SanitizerCoverage.cpp (original)
+++ llvm/trunk/lib/Transforms/Instrumentation/SanitizerCoverage.cpp Tue Dec 23 16:32:17 2014
@@ -10,10 +10,10 @@
// Coverage instrumentation that works with AddressSanitizer
// and potentially with other Sanitizers.
//
-// We create a Guard boolean variable with the same linkage
+// We create a Guard variable with the same linkage
// as the function and inject this code into the entry block (CoverageLevel=1)
// or all blocks (CoverageLevel>=2):
-// if (Guard) {
+// if (Guard < 0) {
// __sanitizer_cov(&Guard);
// }
// The accesses to Guard are atomic. The rest of the logic is
@@ -112,6 +112,8 @@ class SanitizerCoverageModule : public M
Type *IntptrTy;
LLVMContext *C;
+ SmallVector<Constant *, 16> Guards;
+
int CoverageLevel;
};
@@ -134,6 +136,8 @@ bool SanitizerCoverageModule::runOnModul
IntptrTy = Type::getIntNTy(*C, DLP->getDataLayout().getPointerSizeInBits());
Type *VoidTy = Type::getVoidTy(*C);
IRBuilder<> IRB(*C);
+ Type *Int32PtrTy = PointerType::getUnqual(IRB.getInt32Ty());
+ Type *Int32PtrPtrTy = PointerType::getUnqual(Int32PtrTy);
Function *CtorFunc =
Function::Create(FunctionType::get(VoidTy, false),
@@ -142,11 +146,12 @@ bool SanitizerCoverageModule::runOnModul
appendToGlobalCtors(M, CtorFunc, kSanCtorAndDtorPriority);
SanCovFunction = checkInterfaceFunction(
- M.getOrInsertFunction(kSanCovName, VoidTy, IRB.getInt8PtrTy(), nullptr));
+ M.getOrInsertFunction(kSanCovName, VoidTy, Int32PtrTy, nullptr));
SanCovIndirCallFunction = checkInterfaceFunction(M.getOrInsertFunction(
kSanCovIndirCallName, VoidTy, IntptrTy, IntptrTy, nullptr));
- SanCovModuleInit = checkInterfaceFunction(M.getOrInsertFunction(
- kSanCovModuleInitName, Type::getVoidTy(*C), IntptrTy, nullptr));
+ SanCovModuleInit = checkInterfaceFunction(
+ M.getOrInsertFunction(kSanCovModuleInitName, Type::getVoidTy(*C),
+ Int32PtrPtrTy, IntptrTy, nullptr));
SanCovModuleInit->setLinkage(Function::ExternalLinkage);
// We insert an empty inline asm after cov callbacks to avoid callback merge.
EmptyAsm = InlineAsm::get(FunctionType::get(IRB.getVoidTy(), false),
@@ -163,9 +168,15 @@ bool SanitizerCoverageModule::runOnModul
for (auto &F : M)
runOnFunction(F);
+ ArrayType *ArrayOfInt32PtrTy = ArrayType::get(Int32PtrTy, Guards.size());
IRB.SetInsertPoint(CtorFunc->getEntryBlock().getTerminator());
- IRB.CreateCall(SanCovModuleInit,
- ConstantInt::get(IntptrTy, SanCovFunction->getNumUses()));
+ GlobalVariable *AllGuards = new GlobalVariable(
+ M, ArrayOfInt32PtrTy, false, GlobalVariable::InternalLinkage,
+ ConstantArray::get(ArrayOfInt32PtrTy, Guards), "");
+ assert(SanCovFunction->getNumUses() == Guards.size());
+ IRB.CreateCall2(SanCovModuleInit,
+ IRB.CreatePointerCast(AllGuards, Int32PtrPtrTy),
+ ConstantInt::get(IntptrTy, Guards.size()));
return true;
}
@@ -271,16 +282,16 @@ void SanitizerCoverageModule::InjectCove
: IP->getDebugLoc();
IRBuilder<> IRB(IP);
IRB.SetCurrentDebugLocation(EntryLoc);
- Type *Int8Ty = IRB.getInt8Ty();
+ Type *Int32Ty = IRB.getInt32Ty();
GlobalVariable *Guard = new GlobalVariable(
- *F.getParent(), Int8Ty, false, GlobalValue::PrivateLinkage,
- Constant::getNullValue(Int8Ty), "__sancov_gen_cov_" + F.getName());
+ *F.getParent(), Int32Ty, false, GlobalValue::PrivateLinkage,
+ Constant::getNullValue(Int32Ty), "__sancov_gen_cov_" + F.getName());
LoadInst *Load = IRB.CreateLoad(Guard);
Load->setAtomic(Monotonic);
- Load->setAlignment(1);
+ Load->setAlignment(4);
Load->setMetadata(F.getParent()->getMDKindID("nosanitize"),
MDNode::get(*C, None));
- Value *Cmp = IRB.CreateICmpEQ(Constant::getNullValue(Int8Ty), Load);
+ Value *Cmp = IRB.CreateICmpSGE(Constant::getNullValue(Int32Ty), Load);
Instruction *Ins = SplitBlockAndInsertIfThen(
Cmp, IP, false, MDBuilder(*C).createBranchWeights(1, 100000));
IRB.SetInsertPoint(Ins);
@@ -288,6 +299,7 @@ void SanitizerCoverageModule::InjectCove
// __sanitizer_cov gets the PC of the instruction using GET_CALLER_PC.
IRB.CreateCall(SanCovFunction, Guard);
IRB.CreateCall(EmptyAsm); // Avoids callback merge.
+ Guards.push_back(Guard); // Save the guard for later.
}
char SanitizerCoverageModule::ID = 0;
Modified: llvm/trunk/test/Instrumentation/SanitizerCoverage/coverage-dbg.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Instrumentation/SanitizerCoverage/coverage-dbg.ll?rev=224789&r1=224788&r2=224789&view=diff
==============================================================================
--- llvm/trunk/test/Instrumentation/SanitizerCoverage/coverage-dbg.ll (original)
+++ llvm/trunk/test/Instrumentation/SanitizerCoverage/coverage-dbg.ll Tue Dec 23 16:32:17 2014
@@ -15,7 +15,7 @@
; and add sanitize_address to @_ZN1A1fEv
; Test that __sanitizer_cov call has !dbg pointing to the opening { of A::f().
-; CHECK: call void @__sanitizer_cov(i8*{{.*}}), !dbg [[A:!.*]]
+; CHECK: call void @__sanitizer_cov(i32*{{.*}}), !dbg [[A:!.*]]
; CHECK: [[A]] = !{i32 6, i32 0, !{{.*}}, null}
Modified: llvm/trunk/test/Instrumentation/SanitizerCoverage/coverage.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Instrumentation/SanitizerCoverage/coverage.ll?rev=224789&r1=224788&r2=224789&view=diff
==============================================================================
--- llvm/trunk/test/Instrumentation/SanitizerCoverage/coverage.ll (original)
+++ llvm/trunk/test/Instrumentation/SanitizerCoverage/coverage.ll Tue Dec 23 16:32:17 2014
@@ -33,17 +33,17 @@ entry:
; CHECK0-NOT: call void @__sanitizer_cov_module_init(
; CHECK1-LABEL: define void @foo
-; CHECK1: %0 = load atomic i8* @__sancov_gen_cov_foo monotonic, align 1, !nosanitize
-; CHECK1: %1 = icmp eq i8 0, %0
+; CHECK1: %0 = load atomic i32* @__sancov_gen_cov_foo monotonic, align 4, !nosanitize
+; CHECK1: %1 = icmp sge i32 0, %0
; CHECK1: br i1 %1, label %2, label %3
-; CHECK1: call void @__sanitizer_cov(i8*{{.*}})
+; CHECK1: call void @__sanitizer_cov(i32*{{.*}})
; CHECK1: call void asm sideeffect "", ""()
; CHECK1-NOT: call void @__sanitizer_cov
; CHECK1: ret void
; CHECK1-LABEL: define internal void @sancov.module_ctor
; CHECK1-NOT: ret
-; CHECK1: call void @__sanitizer_cov_module_init(i64 2)
+; CHECK1: call void @__sanitizer_cov_module_init({{.*}}, i64 2)
; CHECK1: ret
@@ -59,7 +59,7 @@ entry:
; CHECK2-LABEL: define internal void @sancov.module_ctor
; CHECK2-NOT: ret
-; CHECK2: call void @__sanitizer_cov_module_init(i64 4)
+; CHECK2: call void @__sanitizer_cov_module_init({{.*}}, i64 4)
; CHECK2: ret
; CHECK3-LABEL: define void @foo
Modified: llvm/trunk/test/Instrumentation/SanitizerCoverage/coverage2-dbg.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Instrumentation/SanitizerCoverage/coverage2-dbg.ll?rev=224789&r1=224788&r2=224789&view=diff
==============================================================================
--- llvm/trunk/test/Instrumentation/SanitizerCoverage/coverage2-dbg.ll (original)
+++ llvm/trunk/test/Instrumentation/SanitizerCoverage/coverage2-dbg.ll Tue Dec 23 16:32:17 2014
@@ -17,9 +17,9 @@ target triple = "x86_64-unknown-linux-gn
; Check that __sanitizer_cov call has !dgb pointing to the beginning
; of appropriate basic blocks.
; CHECK-LABEL:_Z3fooPi
-; CHECK: call void @__sanitizer_cov(i8*{{.*}}), !dbg [[A:!.*]]
-; CHECK: call void @__sanitizer_cov(i8*{{.*}}), !dbg [[B:!.*]]
-; CHECK: call void @__sanitizer_cov(i8*{{.*}}), !dbg [[C:!.*]]
+; CHECK: call void @__sanitizer_cov(i32*{{.*}}), !dbg [[A:!.*]]
+; CHECK: call void @__sanitizer_cov(i32*{{.*}}), !dbg [[B:!.*]]
+; CHECK: call void @__sanitizer_cov(i32*{{.*}}), !dbg [[C:!.*]]
; CHECK: ret void
; CHECK: [[A]] = !{i32 1, i32 0, !{{.*}}, null}
; CHECK: [[B]] = !{i32 3, i32 5, !{{.*}}, null}
More information about the llvm-commits
mailing list