diff options
author | Matt Morehouse <mascasa@google.com> | 2020-02-28 15:49:37 -0800 |
---|---|---|
committer | Matt Morehouse <mascasa@google.com> | 2020-02-28 15:49:44 -0800 |
commit | 30bb737a757ecbc706bcae778ceaebe1597ec268 (patch) | |
tree | 778f9ee0a91d24dde23eccaf8e8f5e1f81fece3f /llvm/lib | |
parent | 2e4f5e629de8ba77ae6facba5c595ef23d95acf4 (diff) | |
download | llvm-30bb737a757ecbc706bcae778ceaebe1597ec268.zip llvm-30bb737a757ecbc706bcae778ceaebe1597ec268.tar.gz llvm-30bb737a757ecbc706bcae778ceaebe1597ec268.tar.bz2 |
[DFSan] Add __dfsan_cmp_callback.
Summary:
When -dfsan-event-callbacks is specified, insert a call to
__dfsan_cmp_callback on every CMP instruction.
Reviewers: vitalybuka, pcc, kcc
Reviewed By: kcc
Subscribers: hiraditya, #sanitizers, eugenis, llvm-commits
Tags: #sanitizers, #llvm
Differential Revision: https://reviews.llvm.org/D75389
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp | 37 |
1 files changed, 26 insertions, 11 deletions
diff --git a/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp index 83449ac..82de8ed 100644 --- a/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp +++ b/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp @@ -163,14 +163,15 @@ static cl::opt<bool> ClDebugNonzeroLabels( cl::Hidden); // Experimental feature that inserts callbacks for certain data events. -// Currently callbacks are only inserted for loads, stores, and memory transfers -// (i.e. memcpy and memmove). +// Currently callbacks are only inserted for loads, stores, memory transfers +// (i.e. memcpy and memmove), and comparisons. // // If this flag is set to true, the user must provide definitions for the // following callback functions: // void __dfsan_load_callback(dfsan_label Label); // void __dfsan_store_callback(dfsan_label Label); // void __dfsan_mem_transfer_callback(dfsan_label *Start, size_t Len); +// void __dfsan_cmp_callback(dfsan_label CombinedLabel); static cl::opt<bool> ClEventCallbacks( "dfsan-event-callbacks", cl::desc("Insert calls to __dfsan_*_callback functions on data events."), @@ -359,7 +360,7 @@ class DataFlowSanitizer : public ModulePass { FunctionType *DFSanSetLabelFnTy; FunctionType *DFSanNonzeroLabelFnTy; FunctionType *DFSanVarargWrapperFnTy; - FunctionType *DFSanLoadStoreCallbackFnTy; + FunctionType *DFSanLoadStoreCmpCallbackFnTy; FunctionType *DFSanMemTransferCallbackFnTy; FunctionCallee DFSanUnionFn; FunctionCallee DFSanCheckedUnionFn; @@ -371,6 +372,7 @@ class DataFlowSanitizer : public ModulePass { FunctionCallee DFSanLoadCallbackFn; FunctionCallee DFSanStoreCallbackFn; FunctionCallee DFSanMemTransferCallbackFn; + FunctionCallee DFSanCmpCallbackFn; MDNode *ColdCallWeights; DFSanABIList ABIList; DenseMap<Value *, Function *> UnwrappedFnMap; @@ -457,7 +459,10 @@ public: return DFSF.F->getParent()->getDataLayout(); } - void visitOperandShadowInst(Instruction &I); + // Combines shadow values for all of I's operands. Returns the combined shadow + // value. + Value *visitOperandShadowInst(Instruction &I); + void visitUnaryOperator(UnaryOperator &UO); void visitBinaryOperator(BinaryOperator &BO); void visitCastInst(CastInst &CI); @@ -602,7 +607,7 @@ bool DataFlowSanitizer::doInitialization(Module &M) { Type::getVoidTy(*Ctx), None, /*isVarArg=*/false); DFSanVarargWrapperFnTy = FunctionType::get( Type::getVoidTy(*Ctx), Type::getInt8PtrTy(*Ctx), /*isVarArg=*/false); - DFSanLoadStoreCallbackFnTy = + DFSanLoadStoreCmpCallbackFnTy = FunctionType::get(Type::getVoidTy(*Ctx), ShadowTy, /*isVarArg=*/false); Type *DFSanMemTransferCallbackArgs[2] = {ShadowPtrTy, IntptrTy}; DFSanMemTransferCallbackFnTy = @@ -809,11 +814,13 @@ bool DataFlowSanitizer::runOnModule(Module &M) { DFSanVarargWrapperFnTy); DFSanLoadCallbackFn = Mod->getOrInsertFunction("__dfsan_load_callback", - DFSanLoadStoreCallbackFnTy); - DFSanStoreCallbackFn = Mod->getOrInsertFunction("__dfsan_store_callback", - DFSanLoadStoreCallbackFnTy); + DFSanLoadStoreCmpCallbackFnTy); + DFSanStoreCallbackFn = Mod->getOrInsertFunction( + "__dfsan_store_callback", DFSanLoadStoreCmpCallbackFnTy); DFSanMemTransferCallbackFn = Mod->getOrInsertFunction( "__dfsan_mem_transfer_callback", DFSanMemTransferCallbackFnTy); + DFSanCmpCallbackFn = Mod->getOrInsertFunction("__dfsan_cmp_callback", + DFSanLoadStoreCmpCallbackFnTy); std::vector<Function *> FnsToInstrument; SmallPtrSet<Function *, 2> FnsWithNativeABI; @@ -828,7 +835,8 @@ bool DataFlowSanitizer::runOnModule(Module &M) { &i != DFSanVarargWrapperFn.getCallee()->stripPointerCasts() && &i != DFSanLoadCallbackFn.getCallee()->stripPointerCasts() && &i != DFSanStoreCallbackFn.getCallee()->stripPointerCasts() && - &i != DFSanMemTransferCallbackFn.getCallee()->stripPointerCasts()) + &i != DFSanMemTransferCallbackFn.getCallee()->stripPointerCasts() && + &i != DFSanCmpCallbackFn.getCallee()->stripPointerCasts()) FnsToInstrument.push_back(&i); } @@ -1212,9 +1220,10 @@ Value *DFSanFunction::combineOperandShadows(Instruction *Inst) { return Shadow; } -void DFSanVisitor::visitOperandShadowInst(Instruction &I) { +Value *DFSanVisitor::visitOperandShadowInst(Instruction &I) { Value *CombinedShadow = DFSF.combineOperandShadows(&I); DFSF.setShadow(&I, CombinedShadow); + return CombinedShadow; } // Generates IR to load shadow corresponding to bytes [Addr, Addr+Size), where @@ -1451,7 +1460,13 @@ void DFSanVisitor::visitBinaryOperator(BinaryOperator &BO) { void DFSanVisitor::visitCastInst(CastInst &CI) { visitOperandShadowInst(CI); } -void DFSanVisitor::visitCmpInst(CmpInst &CI) { visitOperandShadowInst(CI); } +void DFSanVisitor::visitCmpInst(CmpInst &CI) { + Value *CombinedShadow = visitOperandShadowInst(CI); + if (ClEventCallbacks) { + IRBuilder<> IRB(&CI); + IRB.CreateCall(DFSF.DFS.DFSanCmpCallbackFn, CombinedShadow); + } +} void DFSanVisitor::visitGetElementPtrInst(GetElementPtrInst &GEPI) { visitOperandShadowInst(GEPI); |