aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/compiler-rt/lib/msan/msan.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm-project/compiler-rt/lib/msan/msan.cpp')
-rw-r--r--contrib/llvm-project/compiler-rt/lib/msan/msan.cpp146
1 files changed, 74 insertions, 72 deletions
diff --git a/contrib/llvm-project/compiler-rt/lib/msan/msan.cpp b/contrib/llvm-project/compiler-rt/lib/msan/msan.cpp
index 4fa772fdcb6e..a2fc27de1901 100644
--- a/contrib/llvm-project/compiler-rt/lib/msan/msan.cpp
+++ b/contrib/llvm-project/compiler-rt/lib/msan/msan.cpp
@@ -12,20 +12,22 @@
//===----------------------------------------------------------------------===//
#include "msan.h"
+
#include "msan_chained_origin_depot.h"
#include "msan_origin.h"
+#include "msan_poisoning.h"
#include "msan_report.h"
#include "msan_thread.h"
-#include "msan_poisoning.h"
#include "sanitizer_common/sanitizer_atomic.h"
#include "sanitizer_common/sanitizer_common.h"
-#include "sanitizer_common/sanitizer_flags.h"
#include "sanitizer_common/sanitizer_flag_parser.h"
+#include "sanitizer_common/sanitizer_flags.h"
+#include "sanitizer_common/sanitizer_interface_internal.h"
#include "sanitizer_common/sanitizer_libc.h"
#include "sanitizer_common/sanitizer_procmaps.h"
+#include "sanitizer_common/sanitizer_stackdepot.h"
#include "sanitizer_common/sanitizer_stacktrace.h"
#include "sanitizer_common/sanitizer_symbolizer.h"
-#include "sanitizer_common/sanitizer_stackdepot.h"
#include "ubsan/ubsan_flags.h"
#include "ubsan/ubsan_init.h"
@@ -67,8 +69,6 @@ THREADLOCAL u64 __msan_va_arg_overflow_size_tls;
SANITIZER_INTERFACE_ATTRIBUTE
THREADLOCAL u32 __msan_origin_tls;
-static THREADLOCAL int is_in_symbolizer;
-
extern "C" SANITIZER_WEAK_ATTRIBUTE const int __msan_track_origins;
int __msan_get_track_origins() {
@@ -79,15 +79,19 @@ extern "C" SANITIZER_WEAK_ATTRIBUTE const int __msan_keep_going;
namespace __msan {
-void EnterSymbolizer() { ++is_in_symbolizer; }
-void ExitSymbolizer() { --is_in_symbolizer; }
-bool IsInSymbolizer() { return is_in_symbolizer; }
+static THREADLOCAL int is_in_symbolizer_or_unwinder;
+static void EnterSymbolizerOrUnwider() { ++is_in_symbolizer_or_unwinder; }
+static void ExitSymbolizerOrUnwider() { --is_in_symbolizer_or_unwinder; }
+bool IsInSymbolizerOrUnwider() { return is_in_symbolizer_or_unwinder; }
+
+struct UnwinderScope {
+ UnwinderScope() { EnterSymbolizerOrUnwider(); }
+ ~UnwinderScope() { ExitSymbolizerOrUnwider(); }
+};
static Flags msan_flags;
-Flags *flags() {
- return &msan_flags;
-}
+Flags *flags() { return &msan_flags; }
int msan_inited = 0;
bool msan_init_is_running;
@@ -134,8 +138,8 @@ static void RegisterMsanFlags(FlagParser *parser, Flags *f) {
#include "msan_flags.inc"
#undef MSAN_FLAG
- FlagHandlerKeepGoing *fh_keep_going =
- new (FlagParser::Alloc) FlagHandlerKeepGoing(&f->halt_on_error);
+ FlagHandlerKeepGoing *fh_keep_going = new (GetGlobalLowLevelAllocator())
+ FlagHandlerKeepGoing(&f->halt_on_error);
parser->RegisterHandler("keep_going", fh_keep_going,
"deprecated, use halt_on_error");
}
@@ -221,10 +225,6 @@ static void InitializeFlags() {
if (f->store_context_size < 1) f->store_context_size = 1;
}
-void PrintWarning(uptr pc, uptr bp) {
- PrintWarningWithOrigin(pc, bp, __msan_origin_tls);
-}
-
void PrintWarningWithOrigin(uptr pc, uptr bp, u32 origin) {
if (msan_expect_umr) {
// Printf("Expected UMR\n");
@@ -299,7 +299,29 @@ u32 ChainOrigin(u32 id, StackTrace *stack) {
return chained.raw_id();
}
-} // namespace __msan
+// Current implementation separates the 'id_ptr' from the 'descr' and makes
+// 'descr' constant.
+// Previous implementation 'descr' is created at compile time and contains
+// '----' in the beginning. When we see descr for the first time we replace
+// '----' with a uniq id and set the origin to (id | (31-th bit)).
+static inline void SetAllocaOrigin(void *a, uptr size, u32 *id_ptr, char *descr,
+ uptr pc) {
+ static const u32 dash = '-';
+ static const u32 first_timer =
+ dash + (dash << 8) + (dash << 16) + (dash << 24);
+ u32 id = *id_ptr;
+ if (id == 0 || id == first_timer) {
+ u32 idx = atomic_fetch_add(&NumStackOriginDescrs, 1, memory_order_relaxed);
+ CHECK_LT(idx, kNumStackOriginDescrs);
+ StackOriginDescr[idx] = descr;
+ StackOriginPC[idx] = pc;
+ id = Origin::CreateStackOrigin(idx).raw_id();
+ *id_ptr = id;
+ }
+ __msan_set_origin(a, size, id);
+}
+
+} // namespace __msan
void __sanitizer::BufferedStackTrace::UnwindImpl(
uptr pc, uptr bp, void *context, bool request_fast, u32 max_depth) {
@@ -307,7 +329,7 @@ void __sanitizer::BufferedStackTrace::UnwindImpl(
MsanThread *t = GetCurrentThread();
if (!t || !StackTrace::WillUseFastUnwind(request_fast)) {
// Block reports from our interceptors during _Unwind_Backtrace.
- SymbolizerScope sym_scope;
+ UnwinderScope sym_scope;
return Unwind(max_depth, pc, bp, context, t ? t->stack_top() : 0,
t ? t->stack_bottom() : 0, false);
}
@@ -323,8 +345,7 @@ using namespace __msan;
#define MSAN_MAYBE_WARNING(type, size) \
void __msan_maybe_warning_##size(type s, u32 o) { \
- GET_CALLER_PC_BP_SP; \
- (void) sp; \
+ GET_CALLER_PC_BP; \
if (UNLIKELY(s)) { \
PrintWarningWithOrigin(pc, bp, o); \
if (__msan::flags()->halt_on_error) { \
@@ -343,8 +364,7 @@ MSAN_MAYBE_WARNING(u64, 8)
void __msan_maybe_store_origin_##size(type s, void *p, u32 o) { \
if (UNLIKELY(s)) { \
if (__msan_get_track_origins() > 1) { \
- GET_CALLER_PC_BP_SP; \
- (void) sp; \
+ GET_CALLER_PC_BP; \
GET_STORE_STACK_TRACE_PC_BP(pc, bp); \
o = ChainOrigin(o, &stack); \
} \
@@ -358,9 +378,8 @@ MSAN_MAYBE_STORE_ORIGIN(u32, 4)
MSAN_MAYBE_STORE_ORIGIN(u64, 8)
void __msan_warning() {
- GET_CALLER_PC_BP_SP;
- (void)sp;
- PrintWarning(pc, bp);
+ GET_CALLER_PC_BP;
+ PrintWarningWithOrigin(pc, bp, 0);
if (__msan::flags()->halt_on_error) {
if (__msan::flags()->print_stats)
ReportStats();
@@ -370,9 +389,8 @@ void __msan_warning() {
}
void __msan_warning_noreturn() {
- GET_CALLER_PC_BP_SP;
- (void)sp;
- PrintWarning(pc, bp);
+ GET_CALLER_PC_BP;
+ PrintWarningWithOrigin(pc, bp, 0);
if (__msan::flags()->print_stats)
ReportStats();
Printf("Exiting\n");
@@ -380,8 +398,7 @@ void __msan_warning_noreturn() {
}
void __msan_warning_with_origin(u32 origin) {
- GET_CALLER_PC_BP_SP;
- (void)sp;
+ GET_CALLER_PC_BP;
PrintWarningWithOrigin(pc, bp, origin);
if (__msan::flags()->halt_on_error) {
if (__msan::flags()->print_stats)
@@ -392,8 +409,7 @@ void __msan_warning_with_origin(u32 origin) {
}
void __msan_warning_with_origin_noreturn(u32 origin) {
- GET_CALLER_PC_BP_SP;
- (void)sp;
+ GET_CALLER_PC_BP;
PrintWarningWithOrigin(pc, bp, origin);
if (__msan::flags()->print_stats)
ReportStats();
@@ -433,6 +449,7 @@ void __msan_init() {
__sanitizer_set_report_path(common_flags()->log_path);
InitializeInterceptors();
+ InstallAtForkHandler();
CheckASLR();
InitTlsSize();
InstallDeadlySignalHandlers(MsanOnDeadlySignal);
@@ -450,7 +467,7 @@ void __msan_init() {
__msan_clear_on_return();
if (__msan_get_track_origins())
VPrintf(1, "msan_track_origins\n");
- if (!InitShadow(__msan_get_track_origins())) {
+ if (!InitShadowWithReExec(__msan_get_track_origins())) {
Printf("FATAL: MemorySanitizer can not mmap the shadow memory.\n");
Printf("FATAL: Make sure to compile with -fPIE and to link with -pie.\n");
Printf("FATAL: Disabling ASLR is known to cause this error.\n");
@@ -460,7 +477,8 @@ void __msan_init() {
Die();
}
- Symbolizer::GetOrInit()->AddHooks(EnterSymbolizer, ExitSymbolizer);
+ Symbolizer::GetOrInit()->AddHooks(EnterSymbolizerOrUnwider,
+ ExitSymbolizerOrUnwider);
InitializeCoverage(common_flags()->coverage, common_flags()->coverage_dir);
@@ -470,7 +488,7 @@ void __msan_init() {
MsanThread *main_thread = MsanThread::Create(nullptr, nullptr);
SetCurrentThread(main_thread);
- main_thread->ThreadStart();
+ main_thread->Init();
#if MSAN_CONTAINS_UBSAN
__ubsan::InitAsPlugin();
@@ -490,8 +508,7 @@ void __msan_set_expect_umr(int expect_umr) {
if (expect_umr) {
msan_expected_umr_found = 0;
} else if (!msan_expected_umr_found) {
- GET_CALLER_PC_BP_SP;
- (void)sp;
+ GET_CALLER_PC_BP;
GET_FATAL_STACK_TRACE_PC_BP(pc, bp);
ReportExpectedUMRNotFound(&stack);
Die();
@@ -515,6 +532,7 @@ void __msan_dump_shadow(const void *x, uptr size) {
}
unsigned char *s = (unsigned char*)MEM_TO_SHADOW(x);
+ Printf("%p[%p] ", (void *)s, x);
for (uptr i = 0; i < size; i++)
Printf("%x%x ", s[i] >> 4, s[i] & 0xf);
Printf("\n");
@@ -538,8 +556,7 @@ void __msan_check_mem_is_initialized(const void *x, uptr size) {
if (offset < 0)
return;
- GET_CALLER_PC_BP_SP;
- (void)sp;
+ GET_CALLER_PC_BP;
ReportUMRInsideAddressRange(__func__, x, size, offset);
__msan::PrintWarningWithOrigin(pc, bp,
__msan_get_origin(((const char *)x) + offset));
@@ -575,45 +592,30 @@ void __msan_set_origin(const void *a, uptr size, u32 origin) {
if (__msan_get_track_origins()) SetOrigin(a, size, origin);
}
-// 'descr' is created at compile time and contains '----' in the beginning.
-// 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);
+ SetAllocaOrigin(a, size, reinterpret_cast<u32 *>(descr), descr + 4,
+ GET_CALLER_PC());
}
void __msan_set_alloca_origin4(void *a, uptr size, char *descr, uptr pc) {
- static const u32 dash = '-';
- static const u32 first_timer =
- dash + (dash << 8) + (dash << 16) + (dash << 24);
- u32 *id_ptr = (u32*)descr;
- bool print = false; // internal_strstr(descr + 4, "AllocaTOTest") != 0;
- u32 id = *id_ptr;
- 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
- // the address of the function's code.
- if (pc)
- pc = *reinterpret_cast<uptr*>(pc);
-#endif
- StackOriginPC[idx] = pc;
- id = Origin::CreateStackOrigin(idx).raw_id();
- *id_ptr = id;
- if (print)
- Printf("First time: idx=%d id=%d %s %p \n", idx, id, descr + 4, pc);
- }
- if (print)
- Printf("__msan_set_alloca_origin: descr=%s id=%x\n", descr + 4, id);
- __msan_set_origin(a, size, id);
+ // Intentionally ignore pc and use return address. This function is here for
+ // compatibility, in case program is linked with library instrumented by
+ // older clang.
+ SetAllocaOrigin(a, size, reinterpret_cast<u32 *>(descr), descr + 4,
+ GET_CALLER_PC());
+}
+
+void __msan_set_alloca_origin_with_descr(void *a, uptr size, u32 *id_ptr,
+ char *descr) {
+ SetAllocaOrigin(a, size, id_ptr, descr, GET_CALLER_PC());
+}
+
+void __msan_set_alloca_origin_no_descr(void *a, uptr size, u32 *id_ptr) {
+ SetAllocaOrigin(a, size, id_ptr, nullptr, GET_CALLER_PC());
}
u32 __msan_chain_origin(u32 id) {
- GET_CALLER_PC_BP_SP;
- (void)sp;
+ GET_CALLER_PC_BP;
GET_STORE_STACK_TRACE_PC_BP(pc, bp);
return ChainOrigin(id, &stack);
}