Skip to content

Commit 532564d

Browse files
committed
[MSAN] add flag to suppress storage of stack variable names with -sanitize-memory-track-origins
Allows for even more savings in the binary image while simultaneously removing the name of the offending stack variable. Depends on D131631 Reviewed By: vitalybuka Differential Revision: https://reviews.llvm.org/D131728
1 parent ec7e779 commit 532564d

File tree

6 files changed

+62
-15
lines changed

6 files changed

+62
-15
lines changed

compiler-rt/lib/msan/msan.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -621,6 +621,10 @@ void __msan_set_alloca_origin_with_descr(void *a, uptr size, u32 *id_ptr,
621621
SetAllocaOrigin(a, size, id_ptr, descr, GET_CALLER_PC());
622622
}
623623

624+
void __msan_set_alloca_origin_no_descr(void *a, uptr size, u32 *id_ptr) {
625+
SetAllocaOrigin(a, size, id_ptr, nullptr, GET_CALLER_PC());
626+
}
627+
624628
u32 __msan_chain_origin(u32 id) {
625629
GET_CALLER_PC_BP_SP;
626630
(void)sp;

compiler-rt/lib/msan/msan_interface_internal.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,8 @@ SANITIZER_INTERFACE_ATTRIBUTE
112112
void __msan_set_alloca_origin_with_descr(void *a, uptr size, u32 *id_ptr,
113113
char *descr);
114114
SANITIZER_INTERFACE_ATTRIBUTE
115+
void __msan_set_alloca_origin_no_descr(void *a, uptr size, u32 *id_ptr);
116+
SANITIZER_INTERFACE_ATTRIBUTE
115117
u32 __msan_chain_origin(u32 id);
116118
SANITIZER_INTERFACE_ATTRIBUTE
117119
u32 __msan_get_origin(const void *a);

compiler-rt/lib/msan/msan_report.cpp

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,15 @@ class Decorator: public __sanitizer::SanitizerCommonDecorator {
3737
static void DescribeStackOrigin(const char *so, uptr pc) {
3838
Decorator d;
3939
Printf("%s", d.Origin());
40-
Printf(
41-
" %sUninitialized value was created by an allocation of '%s%s%s'"
42-
" in the stack frame%s\n",
43-
d.Origin(), d.Name(), so, d.Origin(), d.Default());
40+
if (so == nullptr) {
41+
Printf(" %sUninitialized value was created in the stack frame%s\n",
42+
d.Origin(), d.Default());
43+
} else {
44+
Printf(
45+
" %sUninitialized value was created by an allocation of '%s%s%s'"
46+
" in the stack frame%s\n",
47+
d.Origin(), d.Name(), so, d.Origin(), d.Default());
48+
}
4449

4550
if (pc)
4651
StackTrace(&pc, 1).Print();

compiler-rt/test/msan/stack-origin.cpp

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,16 @@
88
// RUN: FileCheck %s < %t.out
99

1010
// RUN: %clangxx_msan -fsanitize-memory-track-origins -O0 %s -o %t && not %run %t >%t.out 2>&1
11-
// RUN: FileCheck %s < %t.out && FileCheck %s --check-prefix=CHECK-ORIGINS < %t.out
11+
// RUN: FileCheck %s < %t.out && FileCheck %s --check-prefixes=CHECK-ORIGINS,ORIGINS-FAT < %t.out
1212
// RUN: %clangxx_msan -fsanitize-memory-track-origins -O1 %s -o %t && not %run %t >%t.out 2>&1
13-
// RUN: FileCheck %s < %t.out && FileCheck %s --check-prefix=CHECK-ORIGINS < %t.out
13+
// RUN: FileCheck %s < %t.out && FileCheck %s --check-prefixes=CHECK-ORIGINS,ORIGINS-FAT < %t.out
1414
// RUN: %clangxx_msan -fsanitize-memory-track-origins -O2 %s -o %t && not %run %t >%t.out 2>&1
15-
// RUN: FileCheck %s < %t.out && FileCheck %s --check-prefix=CHECK-ORIGINS < %t.out
15+
// RUN: FileCheck %s < %t.out && FileCheck %s --check-prefixes=CHECK-ORIGINS,ORIGINS-FAT < %t.out
1616
// RUN: %clangxx_msan -fsanitize-memory-track-origins -O3 %s -o %t && not %run %t >%t.out 2>&1
17-
// RUN: FileCheck %s < %t.out && FileCheck %s --check-prefix=CHECK-ORIGINS < %t.out
17+
// RUN: FileCheck %s < %t.out && FileCheck %s --check-prefixes=CHECK-ORIGINS,ORIGINS-FAT < %t.out
18+
19+
// RUN: %clangxx_msan -fsanitize-memory-track-origins -mllvm -msan-print-stack-names=0 -O0 %s -o %t && not %run %t >%t.out 2>&1
20+
// RUN: FileCheck %s < %t.out && FileCheck %s --check-prefixes=CHECK-ORIGINS,ORIGINS-LEAN < %t.out
1821

1922
#include <stdlib.h>
2023
int main(int argc, char **argv) {
@@ -24,8 +27,9 @@ int main(int argc, char **argv) {
2427
// CHECK: WARNING: MemorySanitizer: use-of-uninitialized-value
2528
// CHECK: {{#0 0x.* in main .*stack-origin.cpp:}}[[@LINE-2]]
2629

27-
// CHECK-ORIGINS: Uninitialized value was created by an allocation of 'x' in the stack frame
28-
// CHECK-ORIGINS: {{#0 0x.* in main .*stack-origin.cpp:}}[[@LINE-7]]
30+
// ORIGINS-FAT: Uninitialized value was created by an allocation of 'x' in the stack frame
31+
// ORIGINS-LEAN: Uninitialized value was created in the stack frame
32+
// CHECK-ORIGINS: {{#0 0x.* in main .*stack-origin.cpp:}}[[@LINE-8]]
2933

3034
// CHECK: SUMMARY: MemorySanitizer: use-of-uninitialized-value {{.*stack-origin.cpp:.* main}}
3135
}

llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,10 @@ static cl::opt<int> ClPoisonStackPattern("msan-poison-stack-pattern",
237237
cl::desc("poison uninitialized stack variables with the given pattern"),
238238
cl::Hidden, cl::init(0xff));
239239

240+
static cl::opt<bool> ClPrintStackNames("msan-print-stack-names",
241+
cl::desc("Print name of local stack variable"),
242+
cl::Hidden, cl::init(true));
243+
240244
static cl::opt<bool> ClPoisonUndef("msan-poison-undef",
241245
cl::desc("poison undef temps"),
242246
cl::Hidden, cl::init(true));
@@ -580,6 +584,8 @@ class MemorySanitizer {
580584
/// Run-time helper that generates a new origin value for a stack
581585
/// allocation.
582586
FunctionCallee MsanSetAllocaOriginWithDescriptionFn;
587+
// No description version
588+
FunctionCallee MsanSetAllocaOriginNoDescriptionFn;
583589

584590
/// Run-time helper that poisons stack on function entry.
585591
FunctionCallee MsanPoisonStackFn;
@@ -828,6 +834,9 @@ void MemorySanitizer::createUserspaceApi(Module &M) {
828834
MsanSetAllocaOriginWithDescriptionFn = M.getOrInsertFunction(
829835
"__msan_set_alloca_origin_with_descr", IRB.getVoidTy(),
830836
IRB.getInt8PtrTy(), IntptrTy, IRB.getInt8PtrTy(), IRB.getInt8PtrTy());
837+
MsanSetAllocaOriginNoDescriptionFn = M.getOrInsertFunction(
838+
"__msan_set_alloca_origin_no_descr", IRB.getVoidTy(), IRB.getInt8PtrTy(),
839+
IntptrTy, IRB.getInt8PtrTy());
831840
MsanPoisonStackFn =
832841
M.getOrInsertFunction("__msan_poison_stack", IRB.getVoidTy(),
833842
IRB.getInt8PtrTy(), IntptrTy);
@@ -3904,11 +3913,17 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
39043913

39053914
if (PoisonStack && MS.TrackOrigins) {
39063915
Value *Idptr = getLocalVarIdptr(I);
3907-
Value *Descr = getLocalVarDescription(I);
3908-
IRB.CreateCall(MS.MsanSetAllocaOriginWithDescriptionFn,
3909-
{IRB.CreatePointerCast(&I, IRB.getInt8PtrTy()), Len,
3910-
IRB.CreatePointerCast(Idptr, IRB.getInt8PtrTy()),
3911-
IRB.CreatePointerCast(Descr, IRB.getInt8PtrTy())});
3916+
if (ClPrintStackNames) {
3917+
Value *Descr = getLocalVarDescription(I);
3918+
IRB.CreateCall(MS.MsanSetAllocaOriginWithDescriptionFn,
3919+
{IRB.CreatePointerCast(&I, IRB.getInt8PtrTy()), Len,
3920+
IRB.CreatePointerCast(Idptr, IRB.getInt8PtrTy()),
3921+
IRB.CreatePointerCast(Descr, IRB.getInt8PtrTy())});
3922+
} else {
3923+
IRB.CreateCall(MS.MsanSetAllocaOriginNoDescriptionFn,
3924+
{IRB.CreatePointerCast(&I, IRB.getInt8PtrTy()), Len,
3925+
IRB.CreatePointerCast(Idptr, IRB.getInt8PtrTy())});
3926+
}
39123927
}
39133928
}
39143929

llvm/test/Instrumentation/MemorySanitizer/alloca.ll

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
; RUN: -passes=msan 2>&1 | FileCheck %s "--check-prefixes=CHECK,ORIGIN"
77
; RUN: opt < %s -msan-check-access-address=0 -msan-track-origins=2 -S \
88
; RUN: -passes=msan 2>&1 | FileCheck %s "--check-prefixes=CHECK,ORIGIN"
9+
; RUN: opt < %s -msan-check-access-address=0 -msan-track-origins=2 -msan-print-stack-names=false -S \
10+
; RUN: -passes=msan 2>&1 | FileCheck %s "--check-prefixes=CHECK,ORIGIN-LEAN"
911
; RUN: opt < %s -S -passes="msan<kernel>" 2>&1 | FileCheck %s \
1012
; RUN: "--check-prefixes=CHECK,KMSAN"
1113
; RUN: opt < %s -msan-kernel=1 -S -passes=msan 2>&1 | FileCheck %s \
@@ -15,6 +17,7 @@ target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f3
1517
target triple = "x86_64-unknown-linux-gnu"
1618

1719
; ORIGIN: [[IDPTR:@[0-9]+]] = private global i32 0
20+
; ORIGIN-LEAN: [[IDPTR:@[0-9]+]] = private global i32 0
1821
; ORIGIN: [[DESCR:@[0-9]+]] = private constant [9 x i8] c"unique_x\00"
1922

2023
define void @static() sanitize_memory {
@@ -27,6 +30,7 @@ entry:
2730
; INLINE: call void @llvm.memset.p0i8.i64(i8* align 4 {{.*}}, i8 -1, i64 4, i1 false)
2831
; CALL: call void @__msan_poison_stack(i8* {{.*}}, i64 4)
2932
; ORIGIN: call void @__msan_set_alloca_origin_with_descr(i8* {{.*}}, i64 4, i8* {{.*}} [[IDPTR]] {{.*}}, i8* {{.*}} [[DESCR]],
33+
; ORIGIN-LEAN: call void @__msan_set_alloca_origin_no_descr(i8* {{.*}}, i64 4, i8* {{.*}} [[IDPTR]]
3034
; KMSAN: call void @__msan_poison_alloca(i8* {{.*}}, i64 4,
3135
; CHECK: ret void
3236

@@ -43,6 +47,7 @@ l:
4347
; INLINE: call void @llvm.memset.p0i8.i64(i8* align 4 {{.*}}, i8 -1, i64 4, i1 false)
4448
; CALL: call void @__msan_poison_stack(i8* {{.*}}, i64 4)
4549
; ORIGIN: call void @__msan_set_alloca_origin_with_descr(i8* {{.*}}, i64 4,
50+
; ORIGIN-LEAN: call void @__msan_set_alloca_origin_no_descr(i8* {{.*}}, i64 4,
4651
; KMSAN: call void @__msan_poison_alloca(i8* {{.*}}, i64 4,
4752
; CHECK: ret void
4853

@@ -56,6 +61,7 @@ entry:
5661
; INLINE: call void @llvm.memset.p0i8.i64(i8* align 4 {{.*}}, i8 -1, i64 20, i1 false)
5762
; CALL: call void @__msan_poison_stack(i8* {{.*}}, i64 20)
5863
; ORIGIN: call void @__msan_set_alloca_origin_with_descr(i8* {{.*}}, i64 20,
64+
; ORIGIN-LEAN: call void @__msan_set_alloca_origin_no_descr(i8* {{.*}}, i64 20,
5965
; KMSAN: call void @__msan_poison_alloca(i8* {{.*}}, i64 20,
6066
; CHECK: ret void
6167

@@ -70,6 +76,7 @@ entry:
7076
; INLINE: call void @llvm.memset.p0i8.i64(i8* align 4 {{.*}}, i8 -1, i64 %[[A]], i1 false)
7177
; CALL: call void @__msan_poison_stack(i8* {{.*}}, i64 %[[A]])
7278
; ORIGIN: call void @__msan_set_alloca_origin_with_descr(i8* {{.*}}, i64 %[[A]],
79+
; ORIGIN-LEAN: call void @__msan_set_alloca_origin_no_descr(i8* {{.*}}, i64 %[[A]],
7380
; KMSAN: call void @__msan_poison_alloca(i8* {{.*}}, i64 %[[A]],
7481
; CHECK: ret void
7582

@@ -84,6 +91,7 @@ entry:
8491
; INLINE: call void @llvm.memset.p0i8.i64(i8* align 4 {{.*}}, i8 0, i64 20, i1 false)
8592
; CALL: call void @llvm.memset.p0i8.i64(i8* align 4 {{.*}}, i8 0, i64 20, i1 false)
8693
; ORIGIN-NOT: call void @__msan_set_alloca_origin_with_descr(i8* {{.*}}, i64 20,
94+
; ORIGIN-LEAN-NOT: call void @__msan_set_alloca_origin_no_descr(i8* {{.*}}, i64 20,
8795
; KMSAN: call void @__msan_unpoison_alloca(i8* {{.*}}, i64 20)
8896
; CHECK: ret void
8997

@@ -113,12 +121,14 @@ another_bb:
113121
; INLINE: call void @llvm.memset.p0i8.i64(i8* align 4 {{.*}}, i8 -1, i64 4, i1 false)
114122
; CALL: call void @__msan_poison_stack(i8* {{.*}}, i64 4)
115123
; ORIGIN: call void @__msan_set_alloca_origin_with_descr(i8* {{.*}}, i64 4,
124+
; ORIGIN-LEAN: call void @__msan_set_alloca_origin_no_descr(i8* {{.*}}, i64 4,
116125
; KMSAN: call void @__msan_poison_alloca(i8* {{.*}}, i64 4,
117126

118127
; CHECK: call void @llvm.lifetime.start
119128
; INLINE: call void @llvm.memset.p0i8.i64(i8* align 4 {{.*}}, i8 -1, i64 4, i1 false)
120129
; CALL: call void @__msan_poison_stack(i8* {{.*}}, i64 4)
121130
; ORIGIN: call void @__msan_set_alloca_origin_with_descr(i8* {{.*}}, i64 4,
131+
; ORIGIN-LEAN: call void @__msan_set_alloca_origin_no_descr(i8* {{.*}}, i64 4,
122132
; KMSAN: call void @__msan_poison_alloca(i8* {{.*}}, i64 4,
123133
; CHECK: ret void
124134

@@ -140,6 +150,7 @@ entry:
140150
; INLINE: call void @llvm.memset.p0i8.i64(i8* align 4 {{.*}}, i8 -1, i64 %[[A]], i1 false)
141151
; CALL: call void @__msan_poison_stack(i8* {{.*}}, i64 %[[A]])
142152
; ORIGIN: call void @__msan_set_alloca_origin_with_descr(i8* {{.*}}, i64 %[[A]],
153+
; ORIGIN-LEAN: call void @__msan_set_alloca_origin_no_descr(i8* {{.*}}, i64 %[[A]],
143154
; KMSAN: call void @__msan_poison_alloca(i8* {{.*}}, i64 %[[A]],
144155
; CHECK: call void @llvm.lifetime.end
145156
; CHECK: ret void
@@ -180,35 +191,41 @@ another_bb:
180191
; INLINE: call void @llvm.memset.p0i8.i64(i8* align 4 {{.*}}, i8 -1, i64 4, i1 false)
181192
; CALL: call void @__msan_poison_stack(i8* {{.*}}, i64 4)
182193
; ORIGIN: call void @__msan_set_alloca_origin_with_descr(i8* {{.*}}, i64 4,
194+
; ORIGIN-LEAN: call void @__msan_set_alloca_origin_no_descr(i8* {{.*}}, i64 4,
183195
; KMSAN: call void @__msan_poison_alloca(i8* {{.*}}, i64 4,
184196
; CHECK: %y = alloca i32
185197
; INLINE: call void @llvm.memset.p0i8.i64(i8* align 4 {{.*}}, i8 -1, i64 4, i1 false)
186198
; CALL: call void @__msan_poison_stack(i8* {{.*}}, i64 4)
187199
; ORIGIN: call void @__msan_set_alloca_origin_with_descr(i8* {{.*}}, i64 4,
200+
; ORIGIN-LEAN: call void @__msan_set_alloca_origin_no_descr(i8* {{.*}}, i64 4,
188201
; KMSAN: call void @__msan_poison_alloca(i8* {{.*}}, i64 4,
189202
; CHECK: %z = alloca i32
190203
; INLINE: call void @llvm.memset.p0i8.i64(i8* align 4 {{.*}}, i8 -1, i64 4, i1 false)
191204
; CALL: call void @__msan_poison_stack(i8* {{.*}}, i64 4)
192205
; ORIGIN: call void @__msan_set_alloca_origin_with_descr(i8* {{.*}}, i64 4,
206+
; ORIGIN-LEAN: call void @__msan_set_alloca_origin_no_descr(i8* {{.*}}, i64 4,
193207
; KMSAN: call void @__msan_poison_alloca(i8* {{.*}}, i64 4,
194208

195209
; There're two lifetime intrinsics for %z, but we must instrument it only once.
196210
; INLINE-NOT: call void @llvm.memset.p0i8.i64(i8* align 4 {{.*}}, i8 -1, i64 4, i1 false)
197211
; CALL-NOT: call void @__msan_poison_stack(i8* {{.*}}, i64 4)
198212
; ORIGIN-NOT: call void @__msan_set_alloca_origin_with_descr(i8* {{.*}}, i64 4,
213+
; ORIGIN-LEAN-NOT: call void @__msan_set_alloca_origin_no_descr(i8* {{.*}}, i64 4,
199214
; KMSAN-NOT: call void @__msan_poison_alloca(i8* {{.*}}, i64 4,
200215
; CHECK-LABEL: another_bb:
201216

202217
; CHECK: call void @llvm.lifetime.start
203218
; INLINE-NOT: call void @llvm.memset.p0i8.i64(i8* align 4 {{.*}}, i8 -1, i64 4, i1 false)
204219
; CALL-NOT: call void @__msan_poison_stack(i8* {{.*}}, i64 4)
205220
; ORIGIN-NOT: call void @__msan_set_alloca_origin_with_descr(i8* {{.*}}, i64 4,
221+
; ORIGIN-LEAN-NOT: call void @__msan_set_alloca_origin_no_descr(i8* {{.*}}, i64 4,
206222
; KMSAN-NOT: call void @__msan_poison_alloca(i8* {{.*}}, i64 4,
207223
; CHECK: call void @llvm.lifetime.end
208224
; CHECK: call void @llvm.lifetime.start
209225
; INLINE-NOT: call void @llvm.memset.p0i8.i64(i8* align 4 {{.*}}, i8 -1, i64 4, i1 false)
210226
; CALL-NOT: call void @__msan_poison_stack(i8* {{.*}}, i64 4)
211227
; ORIGIN-NOT: call void @__msan_set_alloca_origin_with_descr(i8* {{.*}}, i64 4,
228+
; ORIGIN-LEAN-NOT: call void @__msan_set_alloca_origin_no_descr(i8* {{.*}}, i64 4,
212229
; KMSAN-NOT: call void @__msan_poison_alloca(i8* {{.*}}, i64 4,
213230
; CHECK: call void @llvm.lifetime.end
214231

0 commit comments

Comments
 (0)