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 @@ -380,6 +380,28 @@ Die(); } +void __msan_warning_with_origin(u32 origin) { + GET_CALLER_PC_BP_SP; + (void)sp; + PrintWarningWithOrigin(pc, bp, origin); + if (__msan::flags()->halt_on_error) { + if (__msan::flags()->print_stats) + ReportStats(); + Printf("Exiting\n"); + Die(); + } +} + +void __msan_warning_with_origin_noreturn(u32 origin) { + GET_CALLER_PC_BP_SP; + (void)sp; + PrintWarningWithOrigin(pc, bp, origin); + if (__msan::flags()->print_stats) + ReportStats(); + Printf("Exiting\n"); + Die(); +} + static void OnStackUnwind(const SignalContext &sig, const void *, BufferedStackTrace *stack) { stack->Unwind(StackTrace::GetNextInstructionPc(sig.pc), sig.bp, sig.context, diff --git a/compiler-rt/lib/msan/msan_interface_internal.h b/compiler-rt/lib/msan/msan_interface_internal.h --- a/compiler-rt/lib/msan/msan_interface_internal.h +++ b/compiler-rt/lib/msan/msan_interface_internal.h @@ -46,6 +46,12 @@ using __sanitizer::u16; using __sanitizer::u8; +// Versions of the above which take Origin as a parameter +SANITIZER_INTERFACE_ATTRIBUTE +void __msan_warning_with_origin(u32 origin); +SANITIZER_INTERFACE_ATTRIBUTE __attribute__((noreturn)) +void __msan_warning_with_origin_noreturn(u32 origin); + SANITIZER_INTERFACE_ATTRIBUTE void __msan_maybe_warning_1(u8 s, u32 o); SANITIZER_INTERFACE_ATTRIBUTE 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 @@ -557,6 +557,9 @@ /// The run-time callback to print a warning. FunctionCallee WarningFn; + /// True if Origin is passed as a parameter, false if over TLS. + bool WarningFnTakesOrigin; + // These arrays are indexed by log2(AccessSize). FunctionCallee MaybeWarningFn[kNumberOfAccessSizes]; FunctionCallee MaybeStoreOriginFn[kNumberOfAccessSizes]; @@ -723,6 +726,7 @@ OriginTLS = nullptr; // __msan_warning() in the kernel takes an origin. + WarningFnTakesOrigin = true; WarningFn = M.getOrInsertFunction("__msan_warning", IRB.getVoidTy(), IRB.getInt32Ty()); // Requests the per-task context state (kmsan_context_state*) from the @@ -777,12 +781,22 @@ /// Insert declarations for userspace-specific functions and globals. void MemorySanitizer::createUserspaceApi(Module &M) { IRBuilder<> IRB(*C); + + // Enable origin as param with eager checks, as a space saving measure. + WarningFnTakesOrigin = ClEagerChecks; + // Create the callback. // FIXME: this function should have "Cold" calling conv, // which is not yet implemented. - StringRef WarningFnName = Recover ? "__msan_warning" - : "__msan_warning_noreturn"; - WarningFn = M.getOrInsertFunction(WarningFnName, IRB.getVoidTy()); + std::string WarningFnName = "__msan_warning"; + if (WarningFnTakesOrigin) + WarningFnName += "_with_origin"; + if (!Recover) + WarningFnName += "_noreturn"; + if (WarningFnTakesOrigin) + WarningFn = M.getOrInsertFunction(WarningFnName, IRB.getVoidTy(), IRB.getInt32Ty()); + else + WarningFn = M.getOrInsertFunction(WarningFnName, IRB.getVoidTy()); // Create the global TLS variables. RetvalTLS = @@ -1248,7 +1262,8 @@ void insertWarningFn(IRBuilder<> &IRB, Value *Origin) { if (!Origin) Origin = (Value *)IRB.getInt32(0); - if (MS.CompileKernel) { + if (MS.WarningFnTakesOrigin) { + assert(Origin->getType()->isIntegerTy()); IRB.CreateCall(MS.WarningFn, Origin); } else { if (MS.TrackOrigins) {