[asan] instead of inserting inline instrumentation around memset/memcpy/memmove, replace the intrinsic with __asan_memset/etc. This makes the memset/etc handling more complete and consistent with what we do in msan. It may slowdown some cases (when the intrinsic was actually inlined) and speedup other cases (when it was not inlined)

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@206746 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Kostya Serebryany 2014-04-21 11:50:42 +00:00
parent 57418d8f54
commit 470565b5e4

View File

@ -141,8 +141,6 @@ static cl::opt<int> ClCoverageBlockThreshold("asan-coverage-block-threshold",
cl::Hidden, cl::init(1500)); cl::Hidden, cl::init(1500));
static cl::opt<bool> ClInitializers("asan-initialization-order", static cl::opt<bool> ClInitializers("asan-initialization-order",
cl::desc("Handle C++ initializer order"), cl::Hidden, cl::init(false)); cl::desc("Handle C++ initializer order"), cl::Hidden, cl::init(false));
static cl::opt<bool> ClMemIntrin("asan-memintrin",
cl::desc("Handle memset/memcpy/memmove"), cl::Hidden, cl::init(true));
static cl::opt<bool> ClInvalidPointerPairs("asan-detect-invalid-pointer-pair", static cl::opt<bool> ClInvalidPointerPairs("asan-detect-invalid-pointer-pair",
cl::desc("Instrument <, <=, >, >=, - with pointer operands"), cl::desc("Instrument <, <=, >, >=, - with pointer operands"),
cl::Hidden, cl::init(false)); cl::Hidden, cl::init(false));
@ -327,7 +325,7 @@ struct AddressSanitizer : public FunctionPass {
Instruction *generateCrashCode(Instruction *InsertBefore, Value *Addr, Instruction *generateCrashCode(Instruction *InsertBefore, Value *Addr,
bool IsWrite, size_t AccessSizeIndex, bool IsWrite, size_t AccessSizeIndex,
Value *SizeArgument); Value *SizeArgument);
bool instrumentMemIntrinsic(MemIntrinsic *MI, bool UseCalls); void instrumentMemIntrinsic(MemIntrinsic *MI);
void instrumentMemIntrinsicParam(Instruction *OrigIns, Value *Addr, void instrumentMemIntrinsicParam(Instruction *OrigIns, Value *Addr,
Value *Size, Instruction *InsertBefore, Value *Size, Instruction *InsertBefore,
bool IsWrite, bool UseCalls); bool IsWrite, bool UseCalls);
@ -367,6 +365,7 @@ struct AddressSanitizer : public FunctionPass {
// This array is indexed by AccessIsWrite. // This array is indexed by AccessIsWrite.
Function *AsanErrorCallbackSized[2], Function *AsanErrorCallbackSized[2],
*AsanMemoryAccessCallbackSized[2]; *AsanMemoryAccessCallbackSized[2];
Function *AsanMemmove, *AsanMemcpy, *AsanMemset;
InlineAsm *EmptyAsm; InlineAsm *EmptyAsm;
SetOfDynamicallyInitializedGlobals DynamicallyInitializedGlobals; SetOfDynamicallyInitializedGlobals DynamicallyInitializedGlobals;
@ -623,29 +622,24 @@ void AddressSanitizer::instrumentMemIntrinsicParam(Instruction *OrigIns,
} }
// Instrument memset/memmove/memcpy // Instrument memset/memmove/memcpy
bool AddressSanitizer::instrumentMemIntrinsic(MemIntrinsic *MI, bool UseCalls) { void AddressSanitizer::instrumentMemIntrinsic(MemIntrinsic *MI) {
Value *Dst = MI->getDest(); IRBuilder<> IRB(MI);
MemTransferInst *MemTran = dyn_cast<MemTransferInst>(MI); Instruction *Call = 0;
Value *Src = MemTran ? MemTran->getSource() : 0; if (isa<MemTransferInst>(MI)) {
Value *Length = MI->getLength(); Call = IRB.CreateCall3(
isa<MemMoveInst>(MI) ? AsanMemmove : AsanMemcpy,
Constant *ConstLength = dyn_cast<Constant>(Length); IRB.CreatePointerCast(MI->getOperand(0), IRB.getInt8PtrTy()),
Instruction *InsertBefore = MI; IRB.CreatePointerCast(MI->getOperand(1), IRB.getInt8PtrTy()),
if (ConstLength) { IRB.CreateIntCast(MI->getOperand(2), IntptrTy, false));
if (ConstLength->isNullValue()) return false; } else if (isa<MemSetInst>(MI)) {
} else { Call = IRB.CreateCall3(
// The size is not a constant so it could be zero -- check at run-time. AsanMemset,
IRBuilder<> IRB(InsertBefore); IRB.CreatePointerCast(MI->getOperand(0), IRB.getInt8PtrTy()),
IRB.CreateIntCast(MI->getOperand(1), IRB.getInt32Ty(), false),
Value *Cmp = IRB.CreateICmpNE(Length, IRB.CreateIntCast(MI->getOperand(2), IntptrTy, false));
Constant::getNullValue(Length->getType()));
InsertBefore = SplitBlockAndInsertIfThen(Cmp, InsertBefore, false);
} }
Call->setDebugLoc(MI->getDebugLoc());
instrumentMemIntrinsicParam(MI, Dst, Length, InsertBefore, true, UseCalls); MI->eraseFromParent();
if (Src)
instrumentMemIntrinsicParam(MI, Src, Length, InsertBefore, false, UseCalls);
return true;
} }
// If I is an interesting memory access, return the PointerOperand // If I is an interesting memory access, return the PointerOperand
@ -1156,8 +1150,18 @@ void AddressSanitizer::initializeCallbacks(Module &M) {
M.getOrInsertFunction(ClMemoryAccessCallbackPrefix + "storeN", M.getOrInsertFunction(ClMemoryAccessCallbackPrefix + "storeN",
IRB.getVoidTy(), IntptrTy, IntptrTy, NULL)); IRB.getVoidTy(), IntptrTy, IntptrTy, NULL));
AsanHandleNoReturnFunc = checkInterfaceFunction(M.getOrInsertFunction( AsanMemmove = checkInterfaceFunction(M.getOrInsertFunction(
kAsanHandleNoReturnName, IRB.getVoidTy(), NULL)); ClMemoryAccessCallbackPrefix + "memmove", IRB.getInt8PtrTy(),
IRB.getInt8PtrTy(), IRB.getInt8PtrTy(), IntptrTy, NULL));
AsanMemcpy = checkInterfaceFunction(M.getOrInsertFunction(
ClMemoryAccessCallbackPrefix + "memcpy", IRB.getInt8PtrTy(),
IRB.getInt8PtrTy(), IRB.getInt8PtrTy(), IntptrTy, NULL));
AsanMemset = checkInterfaceFunction(M.getOrInsertFunction(
ClMemoryAccessCallbackPrefix + "memset", IRB.getInt8PtrTy(),
IRB.getInt8PtrTy(), IRB.getInt32Ty(), IntptrTy, NULL));
AsanHandleNoReturnFunc = checkInterfaceFunction(
M.getOrInsertFunction(kAsanHandleNoReturnName, IRB.getVoidTy(), NULL));
AsanCovFunction = checkInterfaceFunction(M.getOrInsertFunction( AsanCovFunction = checkInterfaceFunction(M.getOrInsertFunction(
kAsanCovName, IRB.getVoidTy(), NULL)); kAsanCovName, IRB.getVoidTy(), NULL));
AsanPtrCmpFunction = checkInterfaceFunction(M.getOrInsertFunction( AsanPtrCmpFunction = checkInterfaceFunction(M.getOrInsertFunction(
@ -1328,7 +1332,7 @@ bool AddressSanitizer::runOnFunction(Function &F) {
isInterestingPointerComparisonOrSubtraction(BI)) { isInterestingPointerComparisonOrSubtraction(BI)) {
PointerComparisonsOrSubtracts.push_back(BI); PointerComparisonsOrSubtracts.push_back(BI);
continue; continue;
} else if (isa<MemIntrinsic>(BI) && ClMemIntrin) { } else if (isa<MemIntrinsic>(BI)) {
// ok, take it. // ok, take it.
} else { } else {
if (isa<AllocaInst>(BI)) if (isa<AllocaInst>(BI))
@ -1374,7 +1378,7 @@ bool AddressSanitizer::runOnFunction(Function &F) {
if (isInterestingMemoryAccess(Inst, &IsWrite)) if (isInterestingMemoryAccess(Inst, &IsWrite))
instrumentMop(Inst, UseCalls); instrumentMop(Inst, UseCalls);
else else
instrumentMemIntrinsic(cast<MemIntrinsic>(Inst), UseCalls); instrumentMemIntrinsic(cast<MemIntrinsic>(Inst));
} }
NumInstrumented++; NumInstrumented++;
} }