//
// 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(
Module *Mod;
LLVMContext *Ctx;
+ Type *Int8Ptr;
IntegerType *ShadowTy;
PointerType *ShadowPtrTy;
IntegerType *IntptrTy;
FunctionType *DFSanSetLabelFnTy;
FunctionType *DFSanNonzeroLabelFnTy;
FunctionType *DFSanVarargWrapperFnTy;
- FunctionType *DFSanLoadStoreCmpCallbackFnTy;
+ FunctionType *DFSanCmpCallbackFnTy;
+ FunctionType *DFSanLoadStoreCallbackFnTy;
FunctionType *DFSanMemTransferCallbackFnTy;
FunctionCallee DFSanUnionFn;
FunctionCallee DFSanCheckedUnionFn;
Mod = &M;
Ctx = &M.getContext();
+ Int8Ptr = Type::getInt8PtrTy(*Ctx);
ShadowTy = IntegerType::get(*Ctx, ShadowWidthBits);
ShadowPtrTy = PointerType::getUnqual(ShadowTy);
IntptrTy = DL.getIntPtrType(*Ctx);
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,
// 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) {
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});
}
}
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});
}
}
--- /dev/null
+; 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
+}
\ No newline at end of file