diff --git a/compiler-rt/lib/msan/msan.cpp b/compiler-rt/lib/msan/msan.cpp --- a/compiler-rt/lib/msan/msan.cpp +++ b/compiler-rt/lib/msan/msan.cpp @@ -101,7 +101,6 @@ // Array of stack origins. // FIXME: make it resizable. static const uptr kNumStackOriginDescrs = 1024 * 1024; -static const char *StackOriginDescr[kNumStackOriginDescrs]; static uptr StackOriginPC[kNumStackOriginDescrs]; static atomic_uint32_t NumStackOriginDescrs; @@ -289,7 +288,7 @@ const char *GetStackOriginDescr(u32 id, uptr *pc) { CHECK_LT(id, kNumStackOriginDescrs); if (pc) *pc = StackOriginPC[id]; - return StackOriginDescr[id]; + return nullptr; } u32 ChainOrigin(u32 id, StackTrace *stack) { @@ -585,7 +584,10 @@ // When we see descr for the first time we replace '----' with a uniq id // and set the origin to (id | (31-th bit)). void __msan_set_alloca_origin(void *a, uptr size, char *descr) { - __msan_set_alloca_origin4(a, size, descr, 0); + __msan_set_alloca_origin4( + a, size, descr, + StackTrace::GetPreviousInstructionPc( + reinterpret_cast(__builtin_return_address(0)))); } void __msan_set_alloca_origin4(void *a, uptr size, char *descr, uptr pc) { @@ -598,7 +600,6 @@ if (id == first_timer) { u32 idx = atomic_fetch_add(&NumStackOriginDescrs, 1, memory_order_relaxed); CHECK_LT(idx, kNumStackOriginDescrs); - StackOriginDescr[idx] = descr + 4; #if SANITIZER_PPC64V1 // On PowerPC64 ELFv1, the address of a function actually points to a // three-doubleword data structure with the first field containing diff --git a/compiler-rt/lib/msan/msan_report.cpp b/compiler-rt/lib/msan/msan_report.cpp --- a/compiler-rt/lib/msan/msan_report.cpp +++ b/compiler-rt/lib/msan/msan_report.cpp @@ -35,23 +35,24 @@ }; static void DescribeStackOrigin(const char *so, uptr pc) { + const char* function_name = "kUNKNOWN_FUNCTIONk"; + if (pc) { + // For some reason function address in LLVM IR is 1 less then the address + // of the first instruction. + pc = StackTrace::GetNextInstructionPc(pc); + SymbolizedStack *frame = Symbolizer::GetOrInit()->SymbolizePC(pc); + // TODO: Does not work for SANITIZER_NETBSD + function_name = frame->info.function; + } Decorator d; - char *s = internal_strdup(so); - char *sep = internal_strchr(s, '@'); - CHECK(sep); - *sep = '\0'; Printf("%s", d.Origin()); Printf( " %sUninitialized value was created by an allocation of '%s%s%s'" " in the stack frame of function '%s%s%s'%s\n", - d.Origin(), d.Name(), s, d.Origin(), d.Name(), sep + 1, d.Origin(), - d.Default()); - InternalFree(s); + d.Origin(), d.Name(), "kUNKNOWN_VARIABLEk", d.Origin(), d.Name(), + function_name, d.Origin(), d.Default()); if (pc) { - // For some reason function address in LLVM IR is 1 less then the address - // of the first instruction. - pc = StackTrace::GetNextInstructionPc(pc); StackTrace(&pc, 1).Print(); } } diff --git a/compiler-rt/test/msan/chained_origin.cpp b/compiler-rt/test/msan/chained_origin.cpp --- a/compiler-rt/test/msan/chained_origin.cpp +++ b/compiler-rt/test/msan/chained_origin.cpp @@ -61,7 +61,7 @@ // CHECK-SHORT-STACK: {{#0 .* in fn_g.*chained_origin.cpp:}}[[@LINE-37]] // CHECK-STACK: Uninitialized value was created by an allocation of 'z' in the stack frame of function 'main' -// CHECK-STACK: {{#0 .* in main.*chained_origin.cpp:}}[[@LINE-27]] +// CHECK-STACK: {{#0 .* in main.*chained_origin.cpp:}}[[@LINE-22]] // CHECK-HEAP: Uninitialized value was created by a heap allocation // CHECK-HEAP: {{#1 .* in main.*chained_origin.cpp:}}[[@LINE-28]] diff --git a/compiler-rt/test/msan/chained_origin_memcpy.cpp b/compiler-rt/test/msan/chained_origin_memcpy.cpp --- a/compiler-rt/test/msan/chained_origin_memcpy.cpp +++ b/compiler-rt/test/msan/chained_origin_memcpy.cpp @@ -59,4 +59,5 @@ // CHECK-Z1: Uninitialized value was created by an allocation of 'z1' in the stack frame of function 'main' // CHECK-Z2: Uninitialized value was created by an allocation of 'z2' in the stack frame of function 'main' -// CHECK: {{#0 .* in main.*chained_origin_memcpy.cpp:}}[[@LINE-22]] +// CHECK-Z1: {{#0 .* in main.*chained_origin_memcpy.cpp:}}[[@LINE-21]] +// CHECK-Z2: {{#0 .* in main.*chained_origin_memcpy.cpp:}}[[@LINE-21]] diff --git a/compiler-rt/test/msan/chained_origin_memmove.cpp b/compiler-rt/test/msan/chained_origin_memmove.cpp --- a/compiler-rt/test/msan/chained_origin_memmove.cpp +++ b/compiler-rt/test/msan/chained_origin_memmove.cpp @@ -54,4 +54,5 @@ // CHECK-Z1: Uninitialized value was created by an allocation of 'z1' in the stack frame of function 'main' // CHECK-Z2: Uninitialized value was created by an allocation of 'z2' in the stack frame of function 'main' -// CHECK: {{#0 .* in main.*chained_origin_memmove.cpp:}}[[@LINE-22]] +// CHECK-Z1: {{#0 .* in main.*chained_origin_memmove.cpp:}}[[@LINE-21]] +// CHECK-Z2: {{#0 .* in main.*chained_origin_memmove.cpp:}}[[@LINE-21]] diff --git a/compiler-rt/test/msan/msan_print_shadow.cpp b/compiler-rt/test/msan/msan_print_shadow.cpp --- a/compiler-rt/test/msan/msan_print_shadow.cpp +++ b/compiler-rt/test/msan/msan_print_shadow.cpp @@ -107,7 +107,7 @@ // CHECK-ORIGINS-2: Uninitialized value was stored to memory at // CHECK-ORIGINS-2: #0 {{.*}} in main{{.*}}msan_print_shadow.cpp:48 // CHECK-ORIGINS: Uninitialized value was created by an allocation of 'x' in the stack frame of function 'main' -// CHECK-ORIGINS: #0 {{.*}} in main{{.*}}msan_print_shadow.cpp:12 +// CHECK-ORIGINS: #0 {{.*}} in main{{.*}}msan_print_shadow.cpp:13 // CHECK-ORIGINS: Origin D (origin_id {{.*}}): // CHECK-ORIGINS: Memory was marked as uninitialized diff --git a/compiler-rt/test/msan/report-demangling.cpp b/compiler-rt/test/msan/report-demangling.cpp --- a/compiler-rt/test/msan/report-demangling.cpp +++ b/compiler-rt/test/msan/report-demangling.cpp @@ -15,5 +15,5 @@ return f(); // CHECK: WARNING: MemorySanitizer: use-of-uninitialized-value // CHECK: Uninitialized value was created by an allocation of 'x' in the stack frame of function '_Z1fv' - // CHECK: #0 {{.*}} in f{{.*}} {{.*}}report-demangling.cpp:[[@LINE-10]] + // CHECK: #0 {{.*}} in f{{.*}} {{.*}}report-demangling.cpp:[[@LINE-9]] } diff --git a/compiler-rt/test/msan/stack-origin.cpp b/compiler-rt/test/msan/stack-origin.cpp --- a/compiler-rt/test/msan/stack-origin.cpp +++ b/compiler-rt/test/msan/stack-origin.cpp @@ -25,7 +25,7 @@ // CHECK: {{#0 0x.* in main .*stack-origin.cpp:}}[[@LINE-2]] // CHECK-ORIGINS: Uninitialized value was created by an allocation of 'x' in the stack frame of function 'main' - // CHECK-ORIGINS: {{#0 0x.* in main .*stack-origin.cpp:}}[[@LINE-8]] + // CHECK-ORIGINS: {{#0 0x.* in main .*stack-origin.cpp:}}[[@LINE-7]] // CHECK: SUMMARY: MemorySanitizer: use-of-uninitialized-value {{.*stack-origin.cpp:.* main}} } diff --git a/compiler-rt/test/msan/stack-origin2.cpp b/compiler-rt/test/msan/stack-origin2.cpp --- a/compiler-rt/test/msan/stack-origin2.cpp +++ b/compiler-rt/test/msan/stack-origin2.cpp @@ -35,7 +35,7 @@ // CHECK: {{#0 0x.* in main .*stack-origin2.cpp:}}[[@LINE-2]] // CHECK-ORIGINS: Uninitialized value was created by an allocation of 'x' in the stack frame of function 'f' - // CHECK-ORIGINS: {{#0 0x.* in f .*stack-origin2.cpp:}}[[@LINE-14]] + // CHECK-ORIGINS: {{#0 0x.* in f .*stack-origin2.cpp:}}[[@LINE-11]] // CHECK: SUMMARY: MemorySanitizer: use-of-uninitialized-value {{.*stack-origin2.cpp:.* main}} } diff --git a/compiler-rt/test/msan/unaligned_read_origin.cpp b/compiler-rt/test/msan/unaligned_read_origin.cpp --- a/compiler-rt/test/msan/unaligned_read_origin.cpp +++ b/compiler-rt/test/msan/unaligned_read_origin.cpp @@ -12,5 +12,5 @@ // CHECK: WARNING: MemorySanitizer: use-of-uninitialized-value // CHECK: {{#0 0x.* in main .*unaligned_read_origin.cpp:}}[[@LINE-2]] // CHECK: Uninitialized value was created by an allocation of 'x' in the stack frame of function 'main' - // CHECK: {{#0 0x.* in main .*unaligned_read_origin.cpp:}}[[@LINE-7]] + // CHECK: {{#0 0x.* in main .*unaligned_read_origin.cpp:}}[[@LINE-6]] } diff --git a/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp b/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp --- a/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp +++ b/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp @@ -579,7 +579,7 @@ /// Run-time helper that generates a new origin value for a stack /// allocation. - FunctionCallee MsanSetAllocaOrigin4Fn; + FunctionCallee MsanSetAllocaOriginFn; /// Run-time helper that poisons stack on function entry. FunctionCallee MsanPoisonStackFn; @@ -825,9 +825,9 @@ IRB.getInt32Ty()); } - MsanSetAllocaOrigin4Fn = M.getOrInsertFunction( - "__msan_set_alloca_origin4", IRB.getVoidTy(), IRB.getInt8PtrTy(), IntptrTy, - IRB.getInt8PtrTy(), IntptrTy); + MsanSetAllocaOriginFn = M.getOrInsertFunction( + "__msan_set_alloca_origin", IRB.getVoidTy(), IRB.getInt8PtrTy(), IntptrTy, + IRB.getInt8PtrTy()); MsanPoisonStackFn = M.getOrInsertFunction("__msan_poison_stack", IRB.getVoidTy(), IRB.getInt8PtrTy(), IntptrTy); @@ -3875,7 +3875,7 @@ // It will be printed by the run-time if stack-originated UMR is found. // The first 4 bytes of the string are set to '----' and will be replaced // by __msan_va_arg_overflow_size_tls at the first call. - StackDescription << "----" << I.getName() << "@" << F.getName(); + StackDescription << "----"; return createPrivateNonConstGlobalForString(*F.getParent(), StackDescription.str()); } @@ -3895,10 +3895,9 @@ if (PoisonStack && MS.TrackOrigins) { Value *Descr = getLocalVarDescription(I); - IRB.CreateCall(MS.MsanSetAllocaOrigin4Fn, + IRB.CreateCall(MS.MsanSetAllocaOriginFn, {IRB.CreatePointerCast(&I, IRB.getInt8PtrTy()), Len, - IRB.CreatePointerCast(Descr, IRB.getInt8PtrTy()), - IRB.CreatePointerCast(&F, MS.IntptrTy)}); + IRB.CreatePointerCast(Descr, IRB.getInt8PtrTy())}); } } @@ -3918,6 +3917,7 @@ if (!InsPoint) InsPoint = &I; IRBuilder<> IRB(InsPoint->getNextNode()); + IRB.SetCurrentDebugLocation(InsPoint->getDebugLoc()); const DataLayout &DL = F.getParent()->getDataLayout(); uint64_t TypeSize = DL.getTypeAllocSize(I.getAllocatedType()); Value *Len = ConstantInt::get(MS.IntptrTy, TypeSize); diff --git a/llvm/test/Instrumentation/MemorySanitizer/alloca.ll b/llvm/test/Instrumentation/MemorySanitizer/alloca.ll --- a/llvm/test/Instrumentation/MemorySanitizer/alloca.ll +++ b/llvm/test/Instrumentation/MemorySanitizer/alloca.ll @@ -23,7 +23,7 @@ ; CHECK-LABEL: define void @static( ; INLINE: call void @llvm.memset.p0i8.i64(i8* align 4 {{.*}}, i8 -1, i64 4, i1 false) ; CALL: call void @__msan_poison_stack(i8* {{.*}}, i64 4) -; ORIGIN: call void @__msan_set_alloca_origin4(i8* {{.*}}, i64 4, +; ORIGIN: call void @__msan_set_alloca_origin(i8* {{.*}}, i64 4, ; KMSAN: call void @__msan_poison_alloca(i8* {{.*}}, i64 4, ; CHECK: ret void @@ -39,7 +39,7 @@ ; CHECK-LABEL: define void @dynamic( ; INLINE: call void @llvm.memset.p0i8.i64(i8* align 4 {{.*}}, i8 -1, i64 4, i1 false) ; CALL: call void @__msan_poison_stack(i8* {{.*}}, i64 4) -; ORIGIN: call void @__msan_set_alloca_origin4(i8* {{.*}}, i64 4, +; ORIGIN: call void @__msan_set_alloca_origin(i8* {{.*}}, i64 4, ; KMSAN: call void @__msan_poison_alloca(i8* {{.*}}, i64 4, ; CHECK: ret void @@ -52,7 +52,7 @@ ; CHECK-LABEL: define void @array( ; INLINE: call void @llvm.memset.p0i8.i64(i8* align 4 {{.*}}, i8 -1, i64 20, i1 false) ; CALL: call void @__msan_poison_stack(i8* {{.*}}, i64 20) -; ORIGIN: call void @__msan_set_alloca_origin4(i8* {{.*}}, i64 20, +; ORIGIN: call void @__msan_set_alloca_origin(i8* {{.*}}, i64 20, ; KMSAN: call void @__msan_poison_alloca(i8* {{.*}}, i64 20, ; CHECK: ret void @@ -66,7 +66,7 @@ ; CHECK: %[[A:.*]] = mul i64 4, %cnt ; INLINE: call void @llvm.memset.p0i8.i64(i8* align 4 {{.*}}, i8 -1, i64 %[[A]], i1 false) ; CALL: call void @__msan_poison_stack(i8* {{.*}}, i64 %[[A]]) -; ORIGIN: call void @__msan_set_alloca_origin4(i8* {{.*}}, i64 %[[A]], +; ORIGIN: call void @__msan_set_alloca_origin(i8* {{.*}}, i64 %[[A]], ; KMSAN: call void @__msan_poison_alloca(i8* {{.*}}, i64 %[[A]], ; CHECK: ret void @@ -80,7 +80,7 @@ ; CHECK-LABEL: define void @unpoison_local( ; INLINE: call void @llvm.memset.p0i8.i64(i8* align 4 {{.*}}, i8 0, i64 20, i1 false) ; CALL: call void @llvm.memset.p0i8.i64(i8* align 4 {{.*}}, i8 0, i64 20, i1 false) -; ORIGIN-NOT: call void @__msan_set_alloca_origin4(i8* {{.*}}, i64 20, +; ORIGIN-NOT: call void @__msan_set_alloca_origin(i8* {{.*}}, i64 20, ; KMSAN: call void @__msan_unpoison_alloca(i8* {{.*}}, i64 20) ; CHECK: ret void @@ -109,13 +109,13 @@ ; CHECK: call void @llvm.lifetime.start ; INLINE: call void @llvm.memset.p0i8.i64(i8* align 4 {{.*}}, i8 -1, i64 4, i1 false) ; CALL: call void @__msan_poison_stack(i8* {{.*}}, i64 4) -; ORIGIN: call void @__msan_set_alloca_origin4(i8* {{.*}}, i64 4, +; ORIGIN: call void @__msan_set_alloca_origin(i8* {{.*}}, i64 4, ; KMSAN: call void @__msan_poison_alloca(i8* {{.*}}, i64 4, ; CHECK: call void @llvm.lifetime.start ; INLINE: call void @llvm.memset.p0i8.i64(i8* align 4 {{.*}}, i8 -1, i64 4, i1 false) ; CALL: call void @__msan_poison_stack(i8* {{.*}}, i64 4) -; ORIGIN: call void @__msan_set_alloca_origin4(i8* {{.*}}, i64 4, +; ORIGIN: call void @__msan_set_alloca_origin(i8* {{.*}}, i64 4, ; KMSAN: call void @__msan_poison_alloca(i8* {{.*}}, i64 4, ; CHECK: ret void @@ -136,7 +136,7 @@ ; CHECK: %[[A:.*]] = mul i64 4, %cnt ; INLINE: call void @llvm.memset.p0i8.i64(i8* align 4 {{.*}}, i8 -1, i64 %[[A]], i1 false) ; CALL: call void @__msan_poison_stack(i8* {{.*}}, i64 %[[A]]) -; ORIGIN: call void @__msan_set_alloca_origin4(i8* {{.*}}, i64 %[[A]], +; ORIGIN: call void @__msan_set_alloca_origin(i8* {{.*}}, i64 %[[A]], ; KMSAN: call void @__msan_poison_alloca(i8* {{.*}}, i64 %[[A]], ; CHECK: call void @llvm.lifetime.end ; CHECK: ret void @@ -176,36 +176,36 @@ ; CHECK: %x = alloca i32 ; INLINE: call void @llvm.memset.p0i8.i64(i8* align 4 {{.*}}, i8 -1, i64 4, i1 false) ; CALL: call void @__msan_poison_stack(i8* {{.*}}, i64 4) -; ORIGIN: call void @__msan_set_alloca_origin4(i8* {{.*}}, i64 4, +; ORIGIN: call void @__msan_set_alloca_origin(i8* {{.*}}, i64 4, ; KMSAN: call void @__msan_poison_alloca(i8* {{.*}}, i64 4, ; CHECK: %y = alloca i32 ; INLINE: call void @llvm.memset.p0i8.i64(i8* align 4 {{.*}}, i8 -1, i64 4, i1 false) ; CALL: call void @__msan_poison_stack(i8* {{.*}}, i64 4) -; ORIGIN: call void @__msan_set_alloca_origin4(i8* {{.*}}, i64 4, +; ORIGIN: call void @__msan_set_alloca_origin(i8* {{.*}}, i64 4, ; KMSAN: call void @__msan_poison_alloca(i8* {{.*}}, i64 4, ; CHECK: %z = alloca i32 ; INLINE: call void @llvm.memset.p0i8.i64(i8* align 4 {{.*}}, i8 -1, i64 4, i1 false) ; CALL: call void @__msan_poison_stack(i8* {{.*}}, i64 4) -; ORIGIN: call void @__msan_set_alloca_origin4(i8* {{.*}}, i64 4, +; ORIGIN: call void @__msan_set_alloca_origin(i8* {{.*}}, i64 4, ; KMSAN: call void @__msan_poison_alloca(i8* {{.*}}, i64 4, ; There're two lifetime intrinsics for %z, but we must instrument it only once. ; INLINE-NOT: call void @llvm.memset.p0i8.i64(i8* align 4 {{.*}}, i8 -1, i64 4, i1 false) ; CALL-NOT: call void @__msan_poison_stack(i8* {{.*}}, i64 4) -; ORIGIN-NOT: call void @__msan_set_alloca_origin4(i8* {{.*}}, i64 4, +; ORIGIN-NOT: call void @__msan_set_alloca_origin(i8* {{.*}}, i64 4, ; KMSAN-NOT: call void @__msan_poison_alloca(i8* {{.*}}, i64 4, ; CHECK-LABEL: another_bb: ; CHECK: call void @llvm.lifetime.start ; INLINE-NOT: call void @llvm.memset.p0i8.i64(i8* align 4 {{.*}}, i8 -1, i64 4, i1 false) ; CALL-NOT: call void @__msan_poison_stack(i8* {{.*}}, i64 4) -; ORIGIN-NOT: call void @__msan_set_alloca_origin4(i8* {{.*}}, i64 4, +; ORIGIN-NOT: call void @__msan_set_alloca_origin(i8* {{.*}}, i64 4, ; KMSAN-NOT: call void @__msan_poison_alloca(i8* {{.*}}, i64 4, ; CHECK: call void @llvm.lifetime.end ; CHECK: call void @llvm.lifetime.start ; INLINE-NOT: call void @llvm.memset.p0i8.i64(i8* align 4 {{.*}}, i8 -1, i64 4, i1 false) ; CALL-NOT: call void @__msan_poison_stack(i8* {{.*}}, i64 4) -; ORIGIN-NOT: call void @__msan_set_alloca_origin4(i8* {{.*}}, i64 4, +; ORIGIN-NOT: call void @__msan_set_alloca_origin(i8* {{.*}}, i64 4, ; KMSAN-NOT: call void @__msan_poison_alloca(i8* {{.*}}, i64 4, ; CHECK: call void @llvm.lifetime.end