[asan] change _sanitizer_cov_module_init to accept int* instead of int**

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@224999 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Kostya Serebryany 2014-12-30 19:29:28 +00:00
parent 08c26613e1
commit dd890d5c5e
2 changed files with 35 additions and 19 deletions

View File

@ -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;

View File

@ -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*{{.*}})