summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKostya Serebryany <kcc@google.com>2014-12-30 19:29:28 +0000
committerKostya Serebryany <kcc@google.com>2014-12-30 19:29:28 +0000
commitaa185bfc4b70e7329f2e98b5e685d18b9668ace4 (patch)
tree82be4cc8914b8144c74d289cf6ccd03c9ef3048d
parentc43b063358a8b307b17faecae850e6d3d8b5ff49 (diff)
downloadbcm5719-llvm-aa185bfc4b70e7329f2e98b5e685d18b9668ace4.tar.gz
bcm5719-llvm-aa185bfc4b70e7329f2e98b5e685d18b9668ace4.zip
[asan] change _sanitizer_cov_module_init to accept int* instead of int**
llvm-svn: 224999
-rw-r--r--compiler-rt/lib/sanitizer_common/sanitizer_coverage_libcdep.cc19
-rw-r--r--llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp52
-rw-r--r--llvm/test/Instrumentation/SanitizerCoverage/coverage.ll2
3 files changed, 46 insertions, 27 deletions
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_coverage_libcdep.cc b/compiler-rt/lib/sanitizer_common/sanitizer_coverage_libcdep.cc
index a00109a4299..e28a6aee375 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_coverage_libcdep.cc
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_coverage_libcdep.cc
@@ -79,7 +79,7 @@ class CoverageData {
ALWAYS_INLINE
void TraceBasicBlock(uptr *cache);
- void InitializeGuards(s32 **guards, uptr n);
+ void InitializeGuards(s32 *guards, uptr n);
uptr *data();
uptr size();
@@ -246,16 +246,19 @@ void CoverageData::Extend(uptr npcs) {
atomic_store(&pc_array_size, size, memory_order_release);
}
-void CoverageData::InitializeGuards(s32 **guards, uptr n) {
- for (uptr i = 0; i < n; i++) {
+void CoverageData::InitializeGuards(s32 *guards, uptr n) {
+ // The array 'guards' has n+1 elements, we use the element zero
+ // to store 'n'.
+ CHECK_LT(n, 1 << 30);
+ guards[0] = static_cast<s32>(n);
+ for (uptr i = 1; i <= n; i++) {
uptr idx = atomic_fetch_add(&pc_array_index, 1, memory_order_relaxed);
- *guards[i] = -static_cast<s32>(idx + 1);
+ guards[i] = -static_cast<s32>(idx + 1);
}
}
-// Atomically add the pc to the vector. The atomically set the guard to 1.
-// If the function is called more than once for a given PC it will
-// be inserted multiple times, which is fine.
+// If guard is negative, atomically set it to -guard and store the PC in
+// pc_array.
void CoverageData::Add(uptr pc, u32 *guard) {
atomic_uint32_t *atomic_guard = reinterpret_cast<atomic_uint32_t*>(guard);
s32 guard_value = atomic_load(atomic_guard, memory_order_relaxed);
@@ -624,7 +627,7 @@ SANITIZER_INTERFACE_ATTRIBUTE void __sanitizer_cov_init() {
coverage_data.Init();
}
SANITIZER_INTERFACE_ATTRIBUTE void __sanitizer_cov_dump() { CovDump(); }
-SANITIZER_INTERFACE_ATTRIBUTE void __sanitizer_cov_module_init(s32 **guards,
+SANITIZER_INTERFACE_ATTRIBUTE void __sanitizer_cov_module_init(s32 *guards,
uptr npcs) {
coverage_data.InitializeGuards(guards, npcs);
if (!common_flags()->coverage_direct) return;
diff --git a/llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp b/llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp
index 8600f9183e0..bf04bb17fc4 100644
--- a/llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp
+++ b/llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp
@@ -112,7 +112,7 @@ class SanitizerCoverageModule : public ModulePass {
Type *IntptrTy;
LLVMContext *C;
- SmallVector<Constant *, 16> Guards;
+ GlobalVariable *GuardArray;
int CoverageLevel;
};
@@ -137,7 +137,6 @@ bool SanitizerCoverageModule::runOnModule(Module &M) {
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),
@@ -151,7 +150,7 @@ bool SanitizerCoverageModule::runOnModule(Module &M) {
kSanCovIndirCallName, VoidTy, IntptrTy, IntptrTy, nullptr));
SanCovModuleInit = checkInterfaceFunction(
M.getOrInsertFunction(kSanCovModuleInitName, Type::getVoidTy(*C),
- Int32PtrPtrTy, IntptrTy, nullptr));
+ Int32PtrTy, 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),
@@ -165,18 +164,34 @@ bool SanitizerCoverageModule::runOnModule(Module &M) {
M.getOrInsertFunction(kSanCovTraceBB, VoidTy, IntptrTy, nullptr));
}
+ // At this point we create a dummy array of guards because we don't
+ // know how many elements we will need.
+ Type *Int32Ty = IRB.getInt32Ty();
+ GuardArray =
+ new GlobalVariable(M, Int32Ty, false, GlobalValue::ExternalLinkage,
+ nullptr, "__sancov_gen_cov_tmp");
+
for (auto &F : M)
runOnFunction(F);
- ArrayType *ArrayOfInt32PtrTy = ArrayType::get(Int32PtrTy, Guards.size());
+ // 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);
+ GlobalVariable *RealGuardArray = new GlobalVariable(
+ M, Int32ArrayNTy, false, GlobalValue::PrivateLinkage,
+ Constant::getNullValue(Int32ArrayNTy), "__sancov_gen_cov");
+
+ // Replace the dummy array with the real one.
+ GuardArray->replaceAllUsesWith(
+ IRB.CreatePointerCast(RealGuardArray, Int32PtrTy));
+ GuardArray->eraseFromParent();
+
+ // Call __sanitizer_cov_module_init
IRB.SetInsertPoint(CtorFunc->getEntryBlock().getTerminator());
- 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()));
+ IRB.CreatePointerCast(RealGuardArray, Int32PtrTy),
+ ConstantInt::get(IntptrTy, SanCovFunction->getNumUses()));
return true;
}
@@ -282,24 +297,25 @@ void SanitizerCoverageModule::InjectCoverageAtBlock(Function &F,
: IP->getDebugLoc();
IRBuilder<> IRB(IP);
IRB.SetCurrentDebugLocation(EntryLoc);
- Type *Int32Ty = IRB.getInt32Ty();
- GlobalVariable *Guard = new GlobalVariable(
- *F.getParent(), Int32Ty, false, GlobalValue::PrivateLinkage,
- Constant::getNullValue(Int32Ty), "__sancov_gen_cov_" + F.getName());
- LoadInst *Load = IRB.CreateLoad(Guard);
+ SmallVector<Value *, 1> Indices;
+ Value *GuardP = IRB.CreateAdd(
+ IRB.CreatePointerCast(GuardArray, IntptrTy),
+ ConstantInt::get(IntptrTy, (1 + SanCovFunction->getNumUses()) * 4));
+ Type *Int32PtrTy = PointerType::getUnqual(IRB.getInt32Ty());
+ GuardP = IRB.CreateIntToPtr(GuardP, Int32PtrTy);
+ LoadInst *Load = IRB.CreateLoad(GuardP);
Load->setAtomic(Monotonic);
Load->setAlignment(4);
Load->setMetadata(F.getParent()->getMDKindID("nosanitize"),
MDNode::get(*C, None));
- Value *Cmp = IRB.CreateICmpSGE(Constant::getNullValue(Int32Ty), Load);
+ Value *Cmp = IRB.CreateICmpSGE(Constant::getNullValue(Load->getType()), Load);
Instruction *Ins = SplitBlockAndInsertIfThen(
Cmp, IP, false, MDBuilder(*C).createBranchWeights(1, 100000));
IRB.SetInsertPoint(Ins);
IRB.SetCurrentDebugLocation(EntryLoc);
// __sanitizer_cov gets the PC of the instruction using GET_CALLER_PC.
- IRB.CreateCall(SanCovFunction, Guard);
+ IRB.CreateCall(SanCovFunction, GuardP);
IRB.CreateCall(EmptyAsm); // Avoids callback merge.
- Guards.push_back(Guard); // Save the guard for later.
}
char SanitizerCoverageModule::ID = 0;
diff --git a/llvm/test/Instrumentation/SanitizerCoverage/coverage.ll b/llvm/test/Instrumentation/SanitizerCoverage/coverage.ll
index 9a05fa8c083..77e781e5474 100644
--- a/llvm/test/Instrumentation/SanitizerCoverage/coverage.ll
+++ b/llvm/test/Instrumentation/SanitizerCoverage/coverage.ll
@@ -33,7 +33,7 @@ entry:
; CHECK0-NOT: call void @__sanitizer_cov_module_init(
; CHECK1-LABEL: define void @foo
-; CHECK1: %0 = load atomic i32* @__sancov_gen_cov_foo monotonic, align 4, !nosanitize
+; CHECK1: %0 = load atomic i32* {{.*}} monotonic, align 4, !nosanitize
; CHECK1: %1 = icmp sge i32 0, %0
; CHECK1: br i1 %1, label %2, label %3
; CHECK1: call void @__sanitizer_cov(i32*{{.*}})
OpenPOWER on IntegriCloud