aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib
diff options
context:
space:
mode:
authorMatt Morehouse <mascasa@google.com>2020-02-28 15:49:37 -0800
committerMatt Morehouse <mascasa@google.com>2020-02-28 15:49:44 -0800
commit30bb737a757ecbc706bcae778ceaebe1597ec268 (patch)
tree778f9ee0a91d24dde23eccaf8e8f5e1f81fece3f /llvm/lib
parent2e4f5e629de8ba77ae6facba5c595ef23d95acf4 (diff)
downloadllvm-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.cpp37
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);