Skip to content

Commit c9075a1

Browse files
committed
[dfsan] Record dfsan metadata in globals
This will allow identifying exactly how many shadow bytes were used during compilation, for when fast8 mode is introduced. Also, it will provide a consistent matching point for instrumentation tests so that the exact llvm type used (i8 or i16) for the shadow can be replaced by a pattern substitution. This is handy for tests with multiple prefixes. Reviewed by: stephan.yichao.zhao, morehouse Differential Revision: https://reviews.llvm.org/D97409
1 parent 812a906 commit c9075a1

File tree

2 files changed

+35
-10
lines changed

2 files changed

+35
-10
lines changed

llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -450,6 +450,7 @@ class DataFlowSanitizer {
450450
Constant *getOrBuildTrampolineFunction(FunctionType *FT, StringRef FName);
451451
void initializeCallbackFunctions(Module &M);
452452
void initializeRuntimeFunctions(Module &M);
453+
void injectMetadataGlobals(Module &M);
453454

454455
bool init(Module &M);
455456

@@ -1267,6 +1268,26 @@ void DataFlowSanitizer::initializeCallbackFunctions(Module &M) {
12671268
Mod->getOrInsertFunction("__dfsan_cmp_callback", DFSanCmpCallbackFnTy);
12681269
}
12691270

1271+
void DataFlowSanitizer::injectMetadataGlobals(Module &M) {
1272+
// These variables can be used:
1273+
// - by the runtime (to discover what the shadow width was, during
1274+
// compilation)
1275+
// - in testing (to avoid hardcoding the shadow width and type but instead
1276+
// extract them by pattern matching)
1277+
Type *IntTy = Type::getInt32Ty(*Ctx);
1278+
(void)Mod->getOrInsertGlobal("__dfsan_shadow_width_bits", IntTy, [&] {
1279+
return new GlobalVariable(
1280+
M, IntTy, /*isConstant=*/true, GlobalValue::WeakODRLinkage,
1281+
ConstantInt::get(IntTy, ShadowWidthBits), "__dfsan_shadow_width_bits");
1282+
});
1283+
(void)Mod->getOrInsertGlobal("__dfsan_shadow_width_bytes", IntTy, [&] {
1284+
return new GlobalVariable(M, IntTy, /*isConstant=*/true,
1285+
GlobalValue::WeakODRLinkage,
1286+
ConstantInt::get(IntTy, ShadowWidthBytes),
1287+
"__dfsan_shadow_width_bytes");
1288+
});
1289+
}
1290+
12701291
bool DataFlowSanitizer::runImpl(Module &M) {
12711292
init(M);
12721293

@@ -1307,6 +1328,8 @@ bool DataFlowSanitizer::runImpl(Module &M) {
13071328
"__dfsan_track_origins");
13081329
});
13091330

1331+
injectMetadataGlobals(M);
1332+
13101333
ExternalShadowMask =
13111334
Mod->getOrInsertGlobal(kDFSanExternShadowPtrMask, IntptrTy);
13121335

llvm/test/Instrumentation/DataFlowSanitizer/basic.ll

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,34 +9,36 @@ target triple = "x86_64-unknown-linux-gnu"
99
; CHECK: @__dfsan_retval_origin_tls = external thread_local(initialexec) global i32
1010
; CHECK_NO_ORIGIN: @__dfsan_track_origins = weak_odr constant i32 0
1111
; CHECK_ORIGIN: @__dfsan_track_origins = weak_odr constant i32 1
12+
; CHECK: @__dfsan_shadow_width_bits = weak_odr constant i32 [[#SBITS:]]
13+
; CHECK: @__dfsan_shadow_width_bytes = weak_odr constant i32 [[#SBYTES:]]
1214
; CHECK: @__dfsan_shadow_ptr_mask = external global i64
13-
; CHECK: declare void @__dfsan_load_callback(i16, i8*)
14-
; CHECK: declare void @__dfsan_store_callback(i16, i8*)
15-
; CHECK: declare void @__dfsan_mem_transfer_callback(i16*, i64)
16-
; CHECK: declare void @__dfsan_cmp_callback(i16)
15+
; CHECK: declare void @__dfsan_load_callback(i[[#SBITS]], i8*)
16+
; CHECK: declare void @__dfsan_store_callback(i[[#SBITS]], i8*)
17+
; CHECK: declare void @__dfsan_mem_transfer_callback(i[[#SBITS]]*, i64)
18+
; CHECK: declare void @__dfsan_cmp_callback(i[[#SBITS]])
1719

1820
; CHECK: ; Function Attrs: nounwind readnone
19-
; CHECK-NEXT: declare zeroext i16 @__dfsan_union(i16 zeroext, i16 zeroext) #0
21+
; CHECK-NEXT: declare zeroext i[[#SBITS]] @__dfsan_union(i[[#SBITS]] zeroext, i[[#SBITS]] zeroext) #0
2022

2123
; CHECK: ; Function Attrs: nounwind readnone
22-
; CHECK-NEXT: declare zeroext i16 @dfsan_union(i16 zeroext, i16 zeroext) #0
24+
; CHECK-NEXT: declare zeroext i[[#SBITS]] @dfsan_union(i[[#SBITS]] zeroext, i[[#SBITS]] zeroext) #0
2325

2426
; CHECK: ; Function Attrs: nounwind readonly
25-
; CHECK-NEXT: declare zeroext i16 @__dfsan_union_load(i16*, i64) #1
27+
; CHECK-NEXT: declare zeroext i[[#SBITS]] @__dfsan_union_load(i[[#SBITS]]*, i64) #1
2628

2729
; CHECK: ; Function Attrs: nounwind readonly
28-
; CHECK-NEXT: declare zeroext i16 @__dfsan_union_load_fast16labels(i16*, i64) #1
30+
; CHECK-NEXT: declare zeroext i[[#SBITS]] @__dfsan_union_load_fast16labels(i[[#SBITS]]*, i64) #1
2931

3032
; CHECK: ; Function Attrs: nounwind readonly
3133
; CHECK-NEXT: declare zeroext i64 @__dfsan_load_label_and_origin(i8*, i64) #1
3234

3335
; CHECK: declare void @__dfsan_unimplemented(i8*)
34-
; CHECK: declare void @__dfsan_set_label(i16 zeroext, i32 zeroext, i8*, i64)
36+
; CHECK: declare void @__dfsan_set_label(i[[#SBITS]] zeroext, i32 zeroext, i8*, i64)
3537
; CHECK: declare void @__dfsan_nonzero_label()
3638
; CHECK: declare void @__dfsan_vararg_wrapper(i8*)
3739
; CHECK: declare zeroext i32 @__dfsan_chain_origin(i32 zeroext)
3840
; CHECK: declare void @__dfsan_mem_origin_transfer(i8*, i8*, i64)
39-
; CHECK: declare void @__dfsan_maybe_store_origin(i16 zeroext, i8*, i64, i32 zeroext)
41+
; CHECK: declare void @__dfsan_maybe_store_origin(i[[#SBITS]] zeroext, i8*, i64, i32 zeroext)
4042

4143
define void @foo() {
4244
ret void

0 commit comments

Comments
 (0)