Skip to content

Commit 1ad9ba1

Browse files
committed
[SWDEV-409372] [Sanitizer] Make sanitizer passes idempotent.
Change-Id: I17993b13f5c3c28b00c336d97b6ab503d9640fc5
1 parent 6f001d3 commit 1ad9ba1

File tree

17 files changed

+525
-250
lines changed

17 files changed

+525
-250
lines changed

clang/test/CodeGenObjC/no-sanitize.m

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
@interface I0 @end
44
@implementation I0
5-
// CHECK-NOT: sanitize_address
5+
// CHECK-NOT: Function Attrs: sanitize_address
66
- (void) im0: (int) a0 __attribute__((no_sanitize("address"))) {
77
int (^blockName)(void) = ^int(void) { return 0; };
88
}

llvm/include/llvm/Transforms/Instrumentation.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,10 @@ class Triple;
3030
class OptimizationRemarkEmitter;
3131
class Comdat;
3232
class CallBase;
33+
class Module;
34+
35+
/// Check if module has flag attached, if not add the flag.
36+
bool checkIfAlreadyInstrumented(Module &M, StringRef Flag);
3337

3438
/// Instrumentation passes often insert conditional checks into entry blocks.
3539
/// Call this function before splitting the entry block to move instructions

llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1175,6 +1175,11 @@ AddressSanitizerPass::AddressSanitizerPass(
11751175

11761176
PreservedAnalyses AddressSanitizerPass::run(Module &M,
11771177
ModuleAnalysisManager &MAM) {
1178+
// Return early if nosanitize_address module flag is present for the module.
1179+
// This implies that asan pass has already run before.
1180+
if (checkIfAlreadyInstrumented(M, "nosanitize_address"))
1181+
return PreservedAnalyses::all();
1182+
11781183
ModuleAddressSanitizer ModuleSanitizer(
11791184
M, Options.InsertVersionCheck, Options.CompileKernel, Options.Recover,
11801185
UseGlobalGC, UseOdrIndicator, DestructorKind, ConstructorKind);

llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp

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

34593459
PreservedAnalyses DataFlowSanitizerPass::run(Module &M,
34603460
ModuleAnalysisManager &AM) {
3461+
// Return early if nosanitize_dataflow module flag is present for the module.
3462+
if (checkIfAlreadyInstrumented(M, "nosanitize_dataflow"))
3463+
return PreservedAnalyses::all();
3464+
34613465
auto GetTLI = [&](Function &F) -> TargetLibraryInfo & {
34623466
auto &FAM =
34633467
AM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();

llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
#include "llvm/Support/Debug.h"
5252
#include "llvm/Support/raw_ostream.h"
5353
#include "llvm/TargetParser/Triple.h"
54+
#include "llvm/Transforms/Instrumentation.h"
5455
#include "llvm/Transforms/Instrumentation/AddressSanitizerCommon.h"
5556
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
5657
#include "llvm/Transforms/Utils/Local.h"
@@ -430,6 +431,9 @@ class HWAddressSanitizer {
430431

431432
PreservedAnalyses HWAddressSanitizerPass::run(Module &M,
432433
ModuleAnalysisManager &MAM) {
434+
// Return early if nosanitize_hwaddress module flag is present for the module.
435+
if (checkIfAlreadyInstrumented(M, "nosanitize_hwaddress"))
436+
return PreservedAnalyses::all();
433437
const StackSafetyGlobalInfo *SSI = nullptr;
434438
auto TargetTriple = llvm::Triple(M.getTargetTriple());
435439
if (shouldUseStackSafetyAnalysis(TargetTriple, Options.DisableOptimization))

llvm/lib/Transforms/Instrumentation/Instrumentation.cpp

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,47 @@
1212
//===----------------------------------------------------------------------===//
1313

1414
#include "llvm/Transforms/Instrumentation.h"
15+
#include "llvm/IR/DiagnosticInfo.h"
16+
#include "llvm/IR/DiagnosticPrinter.h"
1517
#include "llvm/IR/IntrinsicInst.h"
1618
#include "llvm/IR/Module.h"
1719
#include "llvm/TargetParser/Triple.h"
1820

1921
using namespace llvm;
2022

23+
static cl::opt<bool> ClIgnoreRedundantInstrumentation(
24+
"ignore-redundant-instrumentation",
25+
cl::desc("Ignore redundant instrumentation"), cl::Hidden, cl::init(false));
26+
27+
namespace {
28+
/// Diagnostic information for IR instrumentation reporting.
29+
class DiagnosticInfoInstrumentation : public DiagnosticInfo {
30+
const Twine &Msg;
31+
32+
public:
33+
DiagnosticInfoInstrumentation(const Twine &DiagMsg,
34+
DiagnosticSeverity Severity = DS_Warning)
35+
: DiagnosticInfo(DK_Linker, Severity), Msg(DiagMsg) {}
36+
void print(DiagnosticPrinter &DP) const override { DP << Msg; }
37+
};
38+
} // namespace
39+
40+
/// Check if module has flag attached, if not add the flag.
41+
bool llvm::checkIfAlreadyInstrumented(Module &M, StringRef Flag) {
42+
if (!M.getModuleFlag(Flag)) {
43+
M.addModuleFlag(Module::ModFlagBehavior::Override, Flag, 1);
44+
return false;
45+
}
46+
if (ClIgnoreRedundantInstrumentation)
47+
return true;
48+
std::string diagInfo =
49+
"Redundant instrumentation detected, with module flag: " +
50+
std::string(Flag);
51+
M.getContext().diagnose(
52+
DiagnosticInfoInstrumentation(diagInfo, DiagnosticSeverity::DS_Warning));
53+
return true;
54+
}
55+
2156
/// Moves I before IP. Returns new insert point.
2257
static BasicBlock::iterator moveBeforeInsertPoint(BasicBlock::iterator I, BasicBlock::iterator IP) {
2358
// If I is IP, move the insert point down.

llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,7 @@
194194
#include "llvm/Support/MathExtras.h"
195195
#include "llvm/Support/raw_ostream.h"
196196
#include "llvm/TargetParser/Triple.h"
197+
#include "llvm/Transforms/Instrumentation.h"
197198
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
198199
#include "llvm/Transforms/Utils/Local.h"
199200
#include "llvm/Transforms/Utils/ModuleUtils.h"
@@ -702,6 +703,9 @@ MemorySanitizerOptions::MemorySanitizerOptions(int TO, bool R, bool K,
702703

703704
PreservedAnalyses MemorySanitizerPass::run(Module &M,
704705
ModuleAnalysisManager &AM) {
706+
// Return early if nosanitize_memory module flag is present for the module.
707+
if (checkIfAlreadyInstrumented(M, "nosanitize_memory"))
708+
return PreservedAnalyses::all();
705709
bool Modified = false;
706710
if (!Options.Kernel) {
707711
insertModuleCtor(M);

llvm/lib/Transforms/Instrumentation/ThreadSanitizer.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,9 @@ PreservedAnalyses ThreadSanitizerPass::run(Function &F,
192192

193193
PreservedAnalyses ModuleThreadSanitizerPass::run(Module &M,
194194
ModuleAnalysisManager &MAM) {
195+
// Return early if nosanitize_thread module flag is present for the module.
196+
if (checkIfAlreadyInstrumented(M, "nosanitize_thread"))
197+
return PreservedAnalyses::all();
195198
insertModuleCtor(M);
196199
return PreservedAnalyses::none();
197200
}
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
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 -passes=asan,asan -S | FileCheck %s
4+
5+
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
6+
target triple = "x86_64-unknown-linux-gnu"
7+
8+
; Function with sanitize_address is instrumented.
9+
; Function Attrs: nounwind uwtable
10+
;.
11+
; CHECK: @llvm.used = appending global [1 x ptr] [ptr @asan.module_ctor], section "llvm.metadata"
12+
; CHECK: @___asan_globals_registered = common hidden global i64 0
13+
; CHECK: @__start_asan_globals = extern_weak hidden global i64
14+
; CHECK: @__stop_asan_globals = extern_weak hidden global i64
15+
; CHECK: @llvm.global_ctors = appending global [1 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 1, ptr @asan.module_ctor, ptr @asan.module_ctor }]
16+
;.
17+
define void @instr_sa(ptr %a) sanitize_address {
18+
; CHECK: Function Attrs: sanitize_address
19+
; CHECK-LABEL: define void @instr_sa(
20+
; CHECK-SAME: ptr [[A:%.*]]) #[[ATTR0:[0-9]+]] {
21+
; CHECK-NEXT: entry:
22+
; CHECK-NEXT: [[TMP0:%.*]] = ptrtoint ptr [[A]] to i64
23+
; CHECK-NEXT: [[TMP1:%.*]] = lshr i64 [[TMP0]], 3
24+
; CHECK-NEXT: [[TMP2:%.*]] = add i64 [[TMP1]], 2147450880
25+
; CHECK-NEXT: [[TMP3:%.*]] = inttoptr i64 [[TMP2]] to ptr
26+
; CHECK-NEXT: [[TMP4:%.*]] = load i8, ptr [[TMP3]], align 1
27+
; CHECK-NEXT: [[TMP5:%.*]] = icmp ne i8 [[TMP4]], 0
28+
; CHECK-NEXT: br i1 [[TMP5]], label [[TMP6:%.*]], label [[TMP12:%.*]], !prof [[PROF1:![0-9]+]]
29+
; CHECK: 6:
30+
; CHECK-NEXT: [[TMP7:%.*]] = and i64 [[TMP0]], 7
31+
; CHECK-NEXT: [[TMP8:%.*]] = add i64 [[TMP7]], 3
32+
; CHECK-NEXT: [[TMP9:%.*]] = trunc i64 [[TMP8]] to i8
33+
; CHECK-NEXT: [[TMP10:%.*]] = icmp sge i8 [[TMP9]], [[TMP4]]
34+
; CHECK-NEXT: br i1 [[TMP10]], label [[TMP11:%.*]], label [[TMP12]]
35+
; CHECK: 11:
36+
; CHECK-NEXT: call void @__asan_report_load4(i64 [[TMP0]]) #[[ATTR3:[0-9]+]]
37+
; CHECK-NEXT: unreachable
38+
; CHECK: 12:
39+
; CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[A]], align 4
40+
; CHECK-NEXT: [[TMP2:%.*]] = add i32 [[TMP1]], 1
41+
; CHECK-NEXT: store i32 [[TMP2]], ptr [[A]], align 4
42+
; CHECK-NEXT: ret void
43+
;
44+
entry:
45+
%tmp1 = load i32, ptr %a, align 4
46+
%tmp2 = add i32 %tmp1, 1
47+
store i32 %tmp2, ptr %a, align 4
48+
ret void
49+
}
50+
;.
51+
; CHECK: attributes #[[ATTR0]] = { sanitize_address }
52+
; CHECK: attributes #[[ATTR1:[0-9]+]] = { nocallback nofree nosync nounwind speculatable willreturn memory(none) }
53+
; CHECK: attributes #[[ATTR2:[0-9]+]] = { nounwind }
54+
; CHECK: attributes #[[ATTR3]] = { nomerge }
55+
;.
56+
; CHECK: [[META0:![0-9]+]] = !{i32 4, !"nosanitize_address", i32 1}
57+
; CHECK: [[PROF1]] = !{!"branch_weights", i32 1, i32 100000}
58+
;.

llvm/test/Instrumentation/AddressSanitizer/missing_dbg.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,4 +34,4 @@ entry:
3434
!4 = !DISubroutineType(types: !5)
3535
!5 = !{}
3636

37-
; CHECK: [[DBG]] = !DILocation(line: 0, scope: !3)
37+
; CHECK: [[DBG]] = !DILocation(line: 0, scope: !4)
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_dataflow", i32 1}

0 commit comments

Comments
 (0)