From f02c6069acbf63d8d5234f647e405e11e822a9ad Mon Sep 17 00:00:00 2001 From: Kostya Serebryany Date: Fri, 20 Jul 2012 09:54:50 +0000 Subject: [asan] make sure that the crash callbacks do not get merged (Chandler's idea: insert an empty InlineAsm). Change the order in which the new BBs are inserted: the slow path BB is insert between old BBs, the crash BB is inserted at the end. Don't create an empty BB (introduced by recent commits). Update the test. The experimental code that does manual crash callback merge will most likely be deleted later. llvm-svn: 160544 --- .../Transforms/Instrumentation/AddressSanitizer.cpp | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) (limited to 'llvm/lib') diff --git a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp index 14348b9bac6..336802668ca 100644 --- a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp +++ b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp @@ -18,6 +18,7 @@ #include "FunctionBlackList.h" #include "llvm/Function.h" #include "llvm/IRBuilder.h" +#include "llvm/InlineAsm.h" #include "llvm/IntrinsicInst.h" #include "llvm/LLVMContext.h" #include "llvm/Module.h" @@ -224,6 +225,7 @@ struct AddressSanitizer : public ModulePass { OwningPtr BL; // This array is indexed by AccessIsWrite and log2(AccessSize). Function *AsanErrorCallback[2][kNumberOfAccessSizes]; + InlineAsm *EmptyAsm; }; } // namespace @@ -276,7 +278,7 @@ static BranchInst *splitBlockAndInsertIfThen(Value *Cmp, BranchInst *CheckTerm = 0; if (!ThenBlock) { LLVMContext &C = Head->getParent()->getParent()->getContext(); - ThenBlock = BasicBlock::Create(C, "", Head->getParent()); + ThenBlock = BasicBlock::Create(C, "", Head->getParent(), Tail); CheckTerm = BranchInst::Create(Tail, ThenBlock); } BranchInst *HeadNewTerm = @@ -414,7 +416,10 @@ Instruction *AddressSanitizer::generateCrashCode( Addr, PC); else Call = IRB.CreateCall(AsanErrorCallback[IsWrite][AccessSizeIndex], Addr); - Call->setDoesNotReturn(); + // We don't do Call->setDoesNotReturn() because the BB already has + // UnreachableInst at the end. + // This EmptyAsm is required to avoid callback merge. + IRB.CreateCall(EmptyAsm); return Call; } @@ -483,10 +488,13 @@ void AddressSanitizer::instrumentAddress(AsanFunctionContext &AFC, size_t Granularity = 1 << MappingScale; if (TypeSize < 8 * Granularity) { - Instruction *CheckTerm = splitBlockAndInsertIfThen(Cmp); + BranchInst *CheckTerm = splitBlockAndInsertIfThen(Cmp); + assert(CheckTerm->isUnconditional()); + BasicBlock *NextBB = CheckTerm->getSuccessor(0); IRB.SetInsertPoint(CheckTerm); Value *Cmp2 = createSlowPathCmp(IRB, AddrLong, ShadowValue, TypeSize); - splitBlockAndInsertIfThen(Cmp2, CrashBlock); + BranchInst *NewTerm = BranchInst::Create(CrashBlock, NextBB, Cmp2); + ReplaceInstWithInst(CheckTerm, NewTerm); } else { splitBlockAndInsertIfThen(Cmp, CrashBlock); } @@ -695,6 +703,10 @@ bool AddressSanitizer::runOnModule(Module &M) { M.getOrInsertFunction(FunctionName, IRB.getVoidTy(), IntptrTy, NULL)); } } + // We insert an empty inline asm after __asan_report* to avoid callback merge. + EmptyAsm = InlineAsm::get(FunctionType::get(IRB.getVoidTy(), false), + StringRef(""), StringRef(""), + /*hasSideEffects=*/true); llvm::Triple targetTriple(M.getTargetTriple()); bool isAndroid = targetTriple.getEnvironment() == llvm::Triple::ANDROIDEABI; -- cgit v1.2.3