Skip to content

Commit

Permalink
Extend the dfsan store/load callback with write/read address
Browse files Browse the repository at this point in the history
This helped debugging.

Reviewed-by: morehouse

Differential Revision: https://reviews.llvm.org/D91236
  • Loading branch information
stephan-yichao-zhao committed Nov 13, 2020
1 parent 5a4b2e1 commit 06c9b4a
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 12 deletions.
33 changes: 21 additions & 12 deletions llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp
Expand Up @@ -169,8 +169,8 @@ static cl::opt<bool> ClDebugNonzeroLabels(
//
// 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_load_callback(dfsan_label Label, void* addr);
// void __dfsan_store_callback(dfsan_label Label, void* addr);
// void __dfsan_mem_transfer_callback(dfsan_label *Start, size_t Len);
// void __dfsan_cmp_callback(dfsan_label CombinedLabel);
static cl::opt<bool> ClEventCallbacks(
Expand Down Expand Up @@ -353,6 +353,7 @@ class DataFlowSanitizer {

Module *Mod;
LLVMContext *Ctx;
Type *Int8Ptr;
IntegerType *ShadowTy;
PointerType *ShadowPtrTy;
IntegerType *IntptrTy;
Expand All @@ -372,7 +373,8 @@ class DataFlowSanitizer {
FunctionType *DFSanSetLabelFnTy;
FunctionType *DFSanNonzeroLabelFnTy;
FunctionType *DFSanVarargWrapperFnTy;
FunctionType *DFSanLoadStoreCmpCallbackFnTy;
FunctionType *DFSanCmpCallbackFnTy;
FunctionType *DFSanLoadStoreCallbackFnTy;
FunctionType *DFSanMemTransferCallbackFnTy;
FunctionCallee DFSanUnionFn;
FunctionCallee DFSanCheckedUnionFn;
Expand Down Expand Up @@ -575,6 +577,7 @@ bool DataFlowSanitizer::init(Module &M) {

Mod = &M;
Ctx = &M.getContext();
Int8Ptr = Type::getInt8PtrTy(*Ctx);
ShadowTy = IntegerType::get(*Ctx, ShadowWidthBits);
ShadowPtrTy = PointerType::getUnqual(ShadowTy);
IntptrTy = DL.getIntPtrType(*Ctx);
Expand Down Expand Up @@ -605,8 +608,12 @@ bool DataFlowSanitizer::init(Module &M) {
Type::getVoidTy(*Ctx), None, /*isVarArg=*/false);
DFSanVarargWrapperFnTy = FunctionType::get(
Type::getVoidTy(*Ctx), Type::getInt8PtrTy(*Ctx), /*isVarArg=*/false);
DFSanLoadStoreCmpCallbackFnTy =
FunctionType::get(Type::getVoidTy(*Ctx), ShadowTy, /*isVarArg=*/false);
DFSanCmpCallbackFnTy = FunctionType::get(Type::getVoidTy(*Ctx), ShadowTy,
/*isVarArg=*/false);
Type *DFSanLoadStoreCallbackArgs[2] = {ShadowTy, Int8Ptr};
DFSanLoadStoreCallbackFnTy =
FunctionType::get(Type::getVoidTy(*Ctx), DFSanLoadStoreCallbackArgs,
/*isVarArg=*/false);
Type *DFSanMemTransferCallbackArgs[2] = {ShadowPtrTy, IntptrTy};
DFSanMemTransferCallbackFnTy =
FunctionType::get(Type::getVoidTy(*Ctx), DFSanMemTransferCallbackArgs,
Expand Down Expand Up @@ -792,13 +799,13 @@ void DataFlowSanitizer::initializeRuntimeFunctions(Module &M) {
// Initializes event callback functions and declare them in the module
void DataFlowSanitizer::initializeCallbackFunctions(Module &M) {
DFSanLoadCallbackFn = Mod->getOrInsertFunction("__dfsan_load_callback",
DFSanLoadStoreCmpCallbackFnTy);
DFSanStoreCallbackFn = Mod->getOrInsertFunction(
"__dfsan_store_callback", DFSanLoadStoreCmpCallbackFnTy);
DFSanLoadStoreCallbackFnTy);
DFSanStoreCallbackFn = Mod->getOrInsertFunction("__dfsan_store_callback",
DFSanLoadStoreCallbackFnTy);
DFSanMemTransferCallbackFn = Mod->getOrInsertFunction(
"__dfsan_mem_transfer_callback", DFSanMemTransferCallbackFnTy);
DFSanCmpCallbackFn = Mod->getOrInsertFunction("__dfsan_cmp_callback",
DFSanLoadStoreCmpCallbackFnTy);
DFSanCmpCallbackFn =
Mod->getOrInsertFunction("__dfsan_cmp_callback", DFSanCmpCallbackFnTy);
}

bool DataFlowSanitizer::runImpl(Module &M) {
Expand Down Expand Up @@ -1404,7 +1411,8 @@ void DFSanVisitor::visitLoadInst(LoadInst &LI) {
DFSF.setShadow(&LI, Shadow);
if (ClEventCallbacks) {
IRBuilder<> IRB(&LI);
IRB.CreateCall(DFSF.DFS.DFSanLoadCallbackFn, Shadow);
Value *Addr8 = IRB.CreateBitCast(LI.getPointerOperand(), DFSF.DFS.Int8Ptr);
IRB.CreateCall(DFSF.DFS.DFSanLoadCallbackFn, {Shadow, Addr8});
}
}

Expand Down Expand Up @@ -1477,7 +1485,8 @@ void DFSanVisitor::visitStoreInst(StoreInst &SI) {
DFSF.storeShadow(SI.getPointerOperand(), Size, Alignment, Shadow, &SI);
if (ClEventCallbacks) {
IRBuilder<> IRB(&SI);
IRB.CreateCall(DFSF.DFS.DFSanStoreCallbackFn, Shadow);
Value *Addr8 = IRB.CreateBitCast(SI.getPointerOperand(), DFSF.DFS.Int8Ptr);
IRB.CreateCall(DFSF.DFS.DFSanStoreCallbackFn, {Shadow, Addr8});
}
}

Expand Down
29 changes: 29 additions & 0 deletions llvm/test/Instrumentation/DataFlowSanitizer/callback.ll
@@ -0,0 +1,29 @@
; RUN: opt < %s -dfsan -dfsan-event-callbacks=1 -S | FileCheck %s
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"

define i8 @load8(i8* %p) {
; CHECK: call void @__dfsan_load_callback(i16 %{{.*}}, i8* %p)
; CHECK: %a = load i8, i8* %p

%a = load i8, i8* %p
ret i8 %a
}

define void @store8(i8* %p, i8 %a) {
; CHECK: store i16 %[[l:.*]], i16* %{{.*}}
; CHECK: call void @__dfsan_store_callback(i16 %[[l]], i8* %p)
; CHECK: store i8 %a, i8* %p

store i8 %a, i8* %p
ret void
}

define i1 @cmp(i8 %a, i8 %b) {
; CHECK: call void @__dfsan_cmp_callback(i16 %[[l:.*]])
; CHECK: %c = icmp ne i8 %a, %b
; CHECK: store i16 %[[l]], i16* @__dfsan_retval_tls

%c = icmp ne i8 %a, %b
ret i1 %c
}

0 comments on commit 06c9b4a

Please sign in to comment.