Skip to content

Commit 1b0b12f

Browse files
committed
[Sanitizer] Make hwsan, msan, dfsan passes idempotent.
1 parent 6552d84 commit 1b0b12f

File tree

6 files changed

+114
-0
lines changed

6 files changed

+114
-0
lines changed

llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3473,6 +3473,9 @@ void DFSanVisitor::visitPHINode(PHINode &PN) {
34733473

34743474
PreservedAnalyses DataFlowSanitizerPass::run(Module &M,
34753475
ModuleAnalysisManager &AM) {
3476+
// Return early if nosanitize module flag is present for the module.
3477+
if (M.getModuleFlag("nosanitize"))
3478+
return PreservedAnalyses::all();
34763479
auto GetTLI = [&](Function &F) -> TargetLibraryInfo & {
34773480
auto &FAM =
34783481
AM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
@@ -3486,5 +3489,6 @@ PreservedAnalyses DataFlowSanitizerPass::run(Module &M,
34863489
// explicitly invalidated; PreservedAnalyses::none() is not enough. Sanitizers
34873490
// make changes that require GlobalsAA to be invalidated.
34883491
PA.abandon<GlobalsAA>();
3492+
M.addModuleFlag(Module::ModFlagBehavior::Override, "nosanitize", 1);
34893493
return PA;
34903494
}

llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -455,6 +455,9 @@ class HWAddressSanitizer {
455455

456456
PreservedAnalyses HWAddressSanitizerPass::run(Module &M,
457457
ModuleAnalysisManager &MAM) {
458+
// Return early if nosanitize module flag is present for the module.
459+
if (M.getModuleFlag("nosanitize"))
460+
return PreservedAnalyses::all();
458461
const StackSafetyGlobalInfo *SSI = nullptr;
459462
auto TargetTriple = llvm::Triple(M.getTargetTriple());
460463
if (shouldUseStackSafetyAnalysis(TargetTriple, Options.DisableOptimization))
@@ -476,6 +479,7 @@ PreservedAnalyses HWAddressSanitizerPass::run(Module &M,
476479
// explicitly invalidated; PreservedAnalyses::none() is not enough. Sanitizers
477480
// make changes that require GlobalsAA to be invalidated.
478481
PA.abandon<GlobalsAA>();
482+
M.addModuleFlag(Module::ModFlagBehavior::Override, "nosanitize", 1);
479483
return PA;
480484
}
481485
void HWAddressSanitizerPass::printPipeline(

llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -706,6 +706,9 @@ MemorySanitizerOptions::MemorySanitizerOptions(int TO, bool R, bool K,
706706

707707
PreservedAnalyses MemorySanitizerPass::run(Module &M,
708708
ModuleAnalysisManager &AM) {
709+
// Return early if nosanitize module flag is present for the module.
710+
if (M.getModuleFlag("nosanitize"))
711+
return PreservedAnalyses::all();
709712
bool Modified = false;
710713
if (!Options.Kernel) {
711714
insertModuleCtor(M);
@@ -721,6 +724,8 @@ PreservedAnalyses MemorySanitizerPass::run(Module &M,
721724
Msan.sanitizeFunction(F, FAM.getResult<TargetLibraryAnalysis>(F));
722725
}
723726

727+
if (Modified)
728+
M.addModuleFlag(Module::ModFlagBehavior::Override, "nosanitize", 1);
724729
if (!Modified)
725730
return PreservedAnalyses::all();
726731

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
; RUN: opt < %s -passes=dfsan,dfsan -S | FileCheck %s
2+
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"
3+
target triple = "x86_64-unknown-linux-gnu"
4+
5+
define i8 @add(i8 %a, i8 %b) {
6+
; CHECK: @add.dfsan
7+
; CHECK-DAG: %[[#ALABEL:]] = load i8, ptr @__dfsan_arg_tls, align [[ALIGN:2]]
8+
; CHECK-DAG: %[[#BLABEL:]] = load i8, ptr inttoptr (i64 add (i64 ptrtoint (ptr @__dfsan_arg_tls to i64), i64 2) to ptr), align [[ALIGN]]
9+
; CHECK: %[[#UNION:]] = or i8 %[[#ALABEL]], %[[#BLABEL]]
10+
; CHECK: %c = add i8 %a, %b
11+
; CHECK: store i8 %[[#UNION]], ptr @__dfsan_retval_tls, align [[ALIGN]]
12+
; CHECK: ret i8 %c
13+
%c = add i8 %a, %b
14+
ret i8 %c
15+
}
16+
17+
; CHECK: [[META0:![0-9]+]] = !{i32 4, !"nosanitize", i32 1}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-attributes --check-globals --version 2
2+
; Test basic address sanitizer instrumentation.
3+
;
4+
; RUN: opt < %s -passes=hwasan,hwasan -S | FileCheck %s
5+
6+
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"
7+
target triple = "x86_64-unknown-linux-gnu"
8+
9+
;.
10+
; CHECK: @llvm.used = appending global [1 x ptr] [ptr @hwasan.module_ctor], section "llvm.metadata"
11+
; CHECK: @llvm.global_ctors = appending global [1 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 0, ptr @hwasan.module_ctor, ptr @hwasan.module_ctor }]
12+
; CHECK: @__start_hwasan_globals = external hidden constant [0 x i8]
13+
; CHECK: @__stop_hwasan_globals = external hidden constant [0 x i8]
14+
; CHECK: @hwasan.note = private constant { i32, i32, i32, [8 x i8], i32, i32 } { i32 8, i32 8, i32 3, [8 x i8] c"LLVM\00\00\00\00", i32 trunc (i64 sub (i64 ptrtoint (ptr @__start_hwasan_globals to i64), i64 ptrtoint (ptr @hwasan.note to i64)) to i32), i32 trunc (i64 sub (i64 ptrtoint (ptr @__stop_hwasan_globals to i64), i64 ptrtoint (ptr @hwasan.note to i64)) to i32) }, section ".note.hwasan.globals", comdat($hwasan.module_ctor), align 4
15+
; CHECK: @hwasan.dummy.global = private constant [0 x i8] zeroinitializer, section "hwasan_globals", comdat($hwasan.module_ctor), !associated [[META0:![0-9]+]]
16+
; CHECK: @__hwasan_tls = external thread_local(initialexec) global i64
17+
; CHECK: @llvm.compiler.used = appending global [3 x ptr] [ptr @hwasan.note, ptr @hwasan.dummy.global, ptr @__hwasan_tls], section "llvm.metadata"
18+
; CHECK: @__hwasan_shadow = external global [0 x i8]
19+
;.
20+
define i8 @test_load8(ptr %a) sanitize_hwaddress {
21+
; CHECK: Function Attrs: sanitize_hwaddress
22+
; CHECK-LABEL: define i8 @test_load8
23+
; CHECK-SAME: (ptr [[A:%.*]]) #[[ATTR0:[0-9]+]] {
24+
; CHECK-NEXT: entry:
25+
; CHECK-NEXT: [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr null)
26+
; CHECK-NEXT: [[TMP0:%.*]] = ptrtoint ptr [[A]] to i64
27+
; CHECK-NEXT: call void @__hwasan_load1(i64 [[TMP0]])
28+
; CHECK-NEXT: [[B:%.*]] = load i8, ptr [[A]], align 4
29+
; CHECK-NEXT: ret i8 [[B]]
30+
;
31+
entry:
32+
%b = load i8, ptr %a, align 4
33+
ret i8 %b
34+
}
35+
;.
36+
; CHECK: attributes #[[ATTR0]] = { sanitize_hwaddress }
37+
; CHECK: attributes #[[ATTR1:[0-9]+]] = { nounwind }
38+
;.
39+
; CHECK: [[META0]] = !{ptr @hwasan.note}
40+
; CHECK: [[META1:![0-9]+]] = !{i32 4, !"nosanitize", i32 1}
41+
;.
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-attributes --check-globals all --version 5
2+
; This test checks in the second run, function is not instrumented again.
3+
; RUN: opt < %s -msan-check-access-address=0 -S -passes=msan,msan | FileCheck %s
4+
5+
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"
6+
target triple = "x86_64-unknown-linux-gnu"
7+
8+
;.
9+
; CHECK: @llvm.used = appending global [1 x ptr] [ptr @msan.module_ctor], section "llvm.metadata"
10+
; CHECK: @llvm.global_ctors = appending global [1 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 0, ptr @msan.module_ctor, ptr null }]
11+
; CHECK: @__msan_retval_tls = external thread_local(initialexec) global [100 x i64]
12+
; CHECK: @__msan_retval_origin_tls = external thread_local(initialexec) global i32
13+
; CHECK: @__msan_param_tls = external thread_local(initialexec) global [100 x i64]
14+
; CHECK: @__msan_param_origin_tls = external thread_local(initialexec) global [200 x i32]
15+
; CHECK: @__msan_va_arg_tls = external thread_local(initialexec) global [100 x i64]
16+
; CHECK: @__msan_va_arg_origin_tls = external thread_local(initialexec) global [200 x i32]
17+
; CHECK: @__msan_va_arg_overflow_size_tls = external thread_local(initialexec) global i64
18+
;.
19+
define void @array() sanitize_memory {
20+
; CHECK: Function Attrs: sanitize_memory
21+
; CHECK-LABEL: define void @array(
22+
; CHECK-SAME: ) #[[ATTR0:[0-9]+]] {
23+
; CHECK-NEXT: [[ENTRY:.*:]]
24+
; CHECK-NEXT: call void @llvm.donothing()
25+
; CHECK-NEXT: [[X:%.*]] = alloca i32, i64 5, align 4
26+
; CHECK-NEXT: [[TMP0:%.*]] = ptrtoint ptr [[X]] to i64
27+
; CHECK-NEXT: [[TMP1:%.*]] = xor i64 [[TMP0]], 87960930222080
28+
; CHECK-NEXT: [[TMP2:%.*]] = inttoptr i64 [[TMP1]] to ptr
29+
; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 4 [[TMP2]], i8 -1, i64 20, i1 false)
30+
; CHECK-NEXT: ret void
31+
;
32+
entry:
33+
%x = alloca i32, i64 5, align 4
34+
ret void
35+
}
36+
;.
37+
; CHECK: attributes #[[ATTR0]] = { sanitize_memory }
38+
; CHECK: attributes #[[ATTR1:[0-9]+]] = { nounwind }
39+
; CHECK: attributes #[[ATTR2:[0-9]+]] = { nocallback nofree nosync nounwind willreturn memory(none) }
40+
; CHECK: attributes #[[ATTR3:[0-9]+]] = { nocallback nofree nounwind willreturn memory(argmem: write) }
41+
;.
42+
; CHECK: [[META0:![0-9]+]] = !{i32 4, !"nosanitize", i32 1}
43+
;.

0 commit comments

Comments
 (0)