xref: /llvm-project/compiler-rt/lib/msan/msan.cpp (revision a0bb2e21c10bebcdb6bc6b8bc18f74dcf7c4b8b2)
160c66db4SNico Weber //===-- msan.cpp ----------------------------------------------------------===//
260c66db4SNico Weber //
360c66db4SNico Weber // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
460c66db4SNico Weber // See https://llvm.org/LICENSE.txt for license information.
560c66db4SNico Weber // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
660c66db4SNico Weber //
760c66db4SNico Weber //===----------------------------------------------------------------------===//
860c66db4SNico Weber //
960c66db4SNico Weber // This file is a part of MemorySanitizer.
1060c66db4SNico Weber //
1160c66db4SNico Weber // MemorySanitizer runtime.
1260c66db4SNico Weber //===----------------------------------------------------------------------===//
1360c66db4SNico Weber 
1460c66db4SNico Weber #include "msan.h"
15595d340dSDmitry Vyukov 
1660c66db4SNico Weber #include "msan_chained_origin_depot.h"
1760c66db4SNico Weber #include "msan_origin.h"
18595d340dSDmitry Vyukov #include "msan_poisoning.h"
1960c66db4SNico Weber #include "msan_report.h"
2060c66db4SNico Weber #include "msan_thread.h"
2160c66db4SNico Weber #include "sanitizer_common/sanitizer_atomic.h"
2260c66db4SNico Weber #include "sanitizer_common/sanitizer_common.h"
2360c66db4SNico Weber #include "sanitizer_common/sanitizer_flag_parser.h"
24595d340dSDmitry Vyukov #include "sanitizer_common/sanitizer_flags.h"
25595d340dSDmitry Vyukov #include "sanitizer_common/sanitizer_interface_internal.h"
2660c66db4SNico Weber #include "sanitizer_common/sanitizer_libc.h"
2760c66db4SNico Weber #include "sanitizer_common/sanitizer_procmaps.h"
28595d340dSDmitry Vyukov #include "sanitizer_common/sanitizer_stackdepot.h"
2960c66db4SNico Weber #include "sanitizer_common/sanitizer_stacktrace.h"
3060c66db4SNico Weber #include "sanitizer_common/sanitizer_symbolizer.h"
3160c66db4SNico Weber #include "ubsan/ubsan_flags.h"
3260c66db4SNico Weber #include "ubsan/ubsan_init.h"
3360c66db4SNico Weber 
3460c66db4SNico Weber // ACHTUNG! No system header includes in this file.
3560c66db4SNico Weber 
3660c66db4SNico Weber using namespace __sanitizer;
3760c66db4SNico Weber 
3860c66db4SNico Weber // Globals.
3960c66db4SNico Weber static THREADLOCAL int msan_expect_umr = 0;
4060c66db4SNico Weber static THREADLOCAL int msan_expected_umr_found = 0;
4160c66db4SNico Weber 
4260c66db4SNico Weber // Function argument shadow. Each argument starts at the next available 8-byte
4360c66db4SNico Weber // aligned address.
4460c66db4SNico Weber SANITIZER_INTERFACE_ATTRIBUTE
4560c66db4SNico Weber THREADLOCAL u64 __msan_param_tls[kMsanParamTlsSize / sizeof(u64)];
4660c66db4SNico Weber 
4760c66db4SNico Weber // Function argument origin. Each argument starts at the same offset as the
4860c66db4SNico Weber // corresponding shadow in (__msan_param_tls). Slightly weird, but changing this
4960c66db4SNico Weber // would break compatibility with older prebuilt binaries.
5060c66db4SNico Weber SANITIZER_INTERFACE_ATTRIBUTE
5160c66db4SNico Weber THREADLOCAL u32 __msan_param_origin_tls[kMsanParamTlsSize / sizeof(u32)];
5260c66db4SNico Weber 
5360c66db4SNico Weber SANITIZER_INTERFACE_ATTRIBUTE
5460c66db4SNico Weber THREADLOCAL u64 __msan_retval_tls[kMsanRetvalTlsSize / sizeof(u64)];
5560c66db4SNico Weber 
5660c66db4SNico Weber SANITIZER_INTERFACE_ATTRIBUTE
5760c66db4SNico Weber THREADLOCAL u32 __msan_retval_origin_tls;
5860c66db4SNico Weber 
59ba66d60bSFangrui Song alignas(16) SANITIZER_INTERFACE_ATTRIBUTE THREADLOCAL u64
60ba66d60bSFangrui Song     __msan_va_arg_tls[kMsanParamTlsSize / sizeof(u64)];
6160c66db4SNico Weber 
62ba66d60bSFangrui Song alignas(16) SANITIZER_INTERFACE_ATTRIBUTE THREADLOCAL u32
63ba66d60bSFangrui Song     __msan_va_arg_origin_tls[kMsanParamTlsSize / sizeof(u32)];
6460c66db4SNico Weber 
6560c66db4SNico Weber SANITIZER_INTERFACE_ATTRIBUTE
6660c66db4SNico Weber THREADLOCAL u64 __msan_va_arg_overflow_size_tls;
6760c66db4SNico Weber 
6860c66db4SNico Weber SANITIZER_INTERFACE_ATTRIBUTE
6960c66db4SNico Weber THREADLOCAL u32 __msan_origin_tls;
7060c66db4SNico Weber 
7160c66db4SNico Weber extern "C" SANITIZER_WEAK_ATTRIBUTE const int __msan_track_origins;
7260c66db4SNico Weber 
7360c66db4SNico Weber int __msan_get_track_origins() {
7460c66db4SNico Weber   return &__msan_track_origins ? __msan_track_origins : 0;
7560c66db4SNico Weber }
7660c66db4SNico Weber 
7760c66db4SNico Weber extern "C" SANITIZER_WEAK_ATTRIBUTE const int __msan_keep_going;
7860c66db4SNico Weber 
7960c66db4SNico Weber namespace __msan {
8060c66db4SNico Weber 
8147a9528fSVitaly Buka static THREADLOCAL int is_in_symbolizer_or_unwinder;
8247a9528fSVitaly Buka static void EnterSymbolizerOrUnwider() { ++is_in_symbolizer_or_unwinder; }
8347a9528fSVitaly Buka static void ExitSymbolizerOrUnwider() { --is_in_symbolizer_or_unwinder; }
8447a9528fSVitaly Buka bool IsInSymbolizerOrUnwider() { return is_in_symbolizer_or_unwinder; }
8547a9528fSVitaly Buka 
8647a9528fSVitaly Buka struct UnwinderScope {
8747a9528fSVitaly Buka   UnwinderScope() { EnterSymbolizerOrUnwider(); }
8847a9528fSVitaly Buka   ~UnwinderScope() { ExitSymbolizerOrUnwider(); }
8947a9528fSVitaly Buka };
9060c66db4SNico Weber 
9160c66db4SNico Weber static Flags msan_flags;
9260c66db4SNico Weber 
9347a9528fSVitaly Buka Flags *flags() { return &msan_flags; }
9460c66db4SNico Weber 
9560c66db4SNico Weber int msan_inited = 0;
9660c66db4SNico Weber bool msan_init_is_running;
9760c66db4SNico Weber 
9860c66db4SNico Weber int msan_report_count = 0;
9960c66db4SNico Weber 
10060c66db4SNico Weber // Array of stack origins.
10160c66db4SNico Weber // FIXME: make it resizable.
1020e96eebcSThurston Dang // Although BSS memory doesn't cost anything until used, it is limited to 2GB
1030e96eebcSThurston Dang // in some configurations (e.g., "relocation R_X86_64_PC32 out of range:
1040e96eebcSThurston Dang // ... is not in [-2147483648, 2147483647]; references section '.bss'").
1050e96eebcSThurston Dang // We use kNumStackOriginDescrs * (sizeof(char*) + sizeof(uptr)) == 64MB.
10662c61aa2SThurston Dang #if SANITIZER_PPC
1070e96eebcSThurston Dang // soft_rss_limit test (release_origin.c) fails on PPC if kNumStackOriginDescrs
1080e96eebcSThurston Dang // is too high
1090e96eebcSThurston Dang static const uptr kNumStackOriginDescrs = 1 * 1024 * 1024;
1100e96eebcSThurston Dang #else
1110e96eebcSThurston Dang static const uptr kNumStackOriginDescrs = 4 * 1024 * 1024;
1120e96eebcSThurston Dang #endif  // SANITIZER_PPC
11360c66db4SNico Weber static const char *StackOriginDescr[kNumStackOriginDescrs];
11460c66db4SNico Weber static uptr StackOriginPC[kNumStackOriginDescrs];
11560c66db4SNico Weber static atomic_uint32_t NumStackOriginDescrs;
11660c66db4SNico Weber 
11760c66db4SNico Weber void Flags::SetDefaults() {
11860c66db4SNico Weber #define MSAN_FLAG(Type, Name, DefaultValue, Description) Name = DefaultValue;
11960c66db4SNico Weber #include "msan_flags.inc"
12060c66db4SNico Weber #undef MSAN_FLAG
12160c66db4SNico Weber }
12260c66db4SNico Weber 
12360c66db4SNico Weber // keep_going is an old name for halt_on_error,
12460c66db4SNico Weber // and it has inverse meaning.
125d48f2d7cSVitaly Buka class FlagHandlerKeepGoing final : public FlagHandlerBase {
12660c66db4SNico Weber   bool *halt_on_error_;
12760c66db4SNico Weber 
12860c66db4SNico Weber  public:
12960c66db4SNico Weber   explicit FlagHandlerKeepGoing(bool *halt_on_error)
13060c66db4SNico Weber       : halt_on_error_(halt_on_error) {}
13160c66db4SNico Weber   bool Parse(const char *value) final {
13260c66db4SNico Weber     bool tmp;
13360c66db4SNico Weber     FlagHandler<bool> h(&tmp);
13460c66db4SNico Weber     if (!h.Parse(value)) return false;
13560c66db4SNico Weber     *halt_on_error_ = !tmp;
13660c66db4SNico Weber     return true;
13760c66db4SNico Weber   }
1384c39f341SDan Liew   bool Format(char *buffer, uptr size) final {
1394c39f341SDan Liew     const char *keep_going_str = (*halt_on_error_) ? "false" : "true";
1404c39f341SDan Liew     return FormatString(buffer, size, keep_going_str);
1414c39f341SDan Liew   }
14260c66db4SNico Weber };
14360c66db4SNico Weber 
14460c66db4SNico Weber static void RegisterMsanFlags(FlagParser *parser, Flags *f) {
14560c66db4SNico Weber #define MSAN_FLAG(Type, Name, DefaultValue, Description) \
14660c66db4SNico Weber   RegisterFlag(parser, #Name, Description, &f->Name);
14760c66db4SNico Weber #include "msan_flags.inc"
14860c66db4SNico Weber #undef MSAN_FLAG
14960c66db4SNico Weber 
150afd170bdSLeonard Chan   FlagHandlerKeepGoing *fh_keep_going = new (GetGlobalLowLevelAllocator())
151afd170bdSLeonard Chan       FlagHandlerKeepGoing(&f->halt_on_error);
15260c66db4SNico Weber   parser->RegisterHandler("keep_going", fh_keep_going,
15360c66db4SNico Weber                           "deprecated, use halt_on_error");
15460c66db4SNico Weber }
15560c66db4SNico Weber 
15660c66db4SNico Weber static void InitializeFlags() {
15760c66db4SNico Weber   SetCommonFlagsDefaults();
15860c66db4SNico Weber   {
15960c66db4SNico Weber     CommonFlags cf;
16060c66db4SNico Weber     cf.CopyFrom(*common_flags());
16160c66db4SNico Weber     cf.external_symbolizer_path = GetEnv("MSAN_SYMBOLIZER_PATH");
16260c66db4SNico Weber     cf.malloc_context_size = 20;
16360c66db4SNico Weber     cf.handle_ioctl = true;
16460c66db4SNico Weber     // FIXME: test and enable.
16560c66db4SNico Weber     cf.check_printf = false;
16660c66db4SNico Weber     cf.intercept_tls_get_addr = true;
16760c66db4SNico Weber     OverrideCommonFlags(cf);
16860c66db4SNico Weber   }
16960c66db4SNico Weber 
17060c66db4SNico Weber   Flags *f = flags();
17160c66db4SNico Weber   f->SetDefaults();
17260c66db4SNico Weber 
17360c66db4SNico Weber   FlagParser parser;
17460c66db4SNico Weber   RegisterMsanFlags(&parser, f);
17560c66db4SNico Weber   RegisterCommonFlags(&parser);
17660c66db4SNico Weber 
17760c66db4SNico Weber #if MSAN_CONTAINS_UBSAN
17860c66db4SNico Weber   __ubsan::Flags *uf = __ubsan::flags();
17960c66db4SNico Weber   uf->SetDefaults();
18060c66db4SNico Weber 
18160c66db4SNico Weber   FlagParser ubsan_parser;
18260c66db4SNico Weber   __ubsan::RegisterUbsanFlags(&ubsan_parser, uf);
18360c66db4SNico Weber   RegisterCommonFlags(&ubsan_parser);
18460c66db4SNico Weber #endif
18560c66db4SNico Weber 
18660c66db4SNico Weber   // Override from user-specified string.
18760c66db4SNico Weber   parser.ParseString(__msan_default_options());
18860c66db4SNico Weber #if MSAN_CONTAINS_UBSAN
1892d7fd38cSFangrui Song   const char *ubsan_default_options = __ubsan_default_options();
19060c66db4SNico Weber   ubsan_parser.ParseString(ubsan_default_options);
19160c66db4SNico Weber #endif
19260c66db4SNico Weber 
19360c66db4SNico Weber   parser.ParseStringFromEnv("MSAN_OPTIONS");
19460c66db4SNico Weber #if MSAN_CONTAINS_UBSAN
19560c66db4SNico Weber   ubsan_parser.ParseStringFromEnv("UBSAN_OPTIONS");
19660c66db4SNico Weber #endif
19760c66db4SNico Weber 
19860c66db4SNico Weber   InitializeCommonFlags();
19960c66db4SNico Weber 
20060c66db4SNico Weber   if (Verbosity()) ReportUnrecognizedFlags();
20160c66db4SNico Weber 
20260c66db4SNico Weber   if (common_flags()->help) parser.PrintFlagDescriptions();
20360c66db4SNico Weber 
20460c66db4SNico Weber   // Check if deprecated exit_code MSan flag is set.
20560c66db4SNico Weber   if (f->exit_code != -1) {
20660c66db4SNico Weber     if (Verbosity())
20760c66db4SNico Weber       Printf("MSAN_OPTIONS=exit_code is deprecated! "
20860c66db4SNico Weber              "Please use MSAN_OPTIONS=exitcode instead.\n");
20960c66db4SNico Weber     CommonFlags cf;
21060c66db4SNico Weber     cf.CopyFrom(*common_flags());
21160c66db4SNico Weber     cf.exitcode = f->exit_code;
21260c66db4SNico Weber     OverrideCommonFlags(cf);
21360c66db4SNico Weber   }
21460c66db4SNico Weber 
21560c66db4SNico Weber   // Check flag values:
21660c66db4SNico Weber   if (f->origin_history_size < 0 ||
21760c66db4SNico Weber       f->origin_history_size > Origin::kMaxDepth) {
21860c66db4SNico Weber     Printf(
21960c66db4SNico Weber         "Origin history size invalid: %d. Must be 0 (unlimited) or in [1, %d] "
22060c66db4SNico Weber         "range.\n",
22160c66db4SNico Weber         f->origin_history_size, Origin::kMaxDepth);
22260c66db4SNico Weber     Die();
22360c66db4SNico Weber   }
22460c66db4SNico Weber   // Limiting to kStackDepotMaxUseCount / 2 to avoid overflow in
22560c66db4SNico Weber   // StackDepotHandle::inc_use_count_unsafe.
22660c66db4SNico Weber   if (f->origin_history_per_stack_limit < 0 ||
22760c66db4SNico Weber       f->origin_history_per_stack_limit > kStackDepotMaxUseCount / 2) {
22860c66db4SNico Weber     Printf(
22960c66db4SNico Weber         "Origin per-stack limit invalid: %d. Must be 0 (unlimited) or in [1, "
23060c66db4SNico Weber         "%d] range.\n",
23160c66db4SNico Weber         f->origin_history_per_stack_limit, kStackDepotMaxUseCount / 2);
23260c66db4SNico Weber     Die();
23360c66db4SNico Weber   }
23460c66db4SNico Weber   if (f->store_context_size < 1) f->store_context_size = 1;
23560c66db4SNico Weber }
23660c66db4SNico Weber 
23760c66db4SNico Weber void PrintWarningWithOrigin(uptr pc, uptr bp, u32 origin) {
23860c66db4SNico Weber   if (msan_expect_umr) {
23960c66db4SNico Weber     // Printf("Expected UMR\n");
24060c66db4SNico Weber     __msan_origin_tls = origin;
24160c66db4SNico Weber     msan_expected_umr_found = 1;
24260c66db4SNico Weber     return;
24360c66db4SNico Weber   }
24460c66db4SNico Weber 
24560c66db4SNico Weber   ++msan_report_count;
24660c66db4SNico Weber 
24760c66db4SNico Weber   GET_FATAL_STACK_TRACE_PC_BP(pc, bp);
24860c66db4SNico Weber 
24960c66db4SNico Weber   u32 report_origin =
25060c66db4SNico Weber     (__msan_get_track_origins() && Origin::isValidId(origin)) ? origin : 0;
25160c66db4SNico Weber   ReportUMR(&stack, report_origin);
25260c66db4SNico Weber 
25360c66db4SNico Weber   if (__msan_get_track_origins() && !Origin::isValidId(origin)) {
25460c66db4SNico Weber     Printf(
25560c66db4SNico Weber         "  ORIGIN: invalid (%x). Might be a bug in MemorySanitizer origin "
25660c66db4SNico Weber         "tracking.\n    This could still be a bug in your code, too!\n",
25760c66db4SNico Weber         origin);
25860c66db4SNico Weber   }
25960c66db4SNico Weber }
26060c66db4SNico Weber 
26160c66db4SNico Weber void UnpoisonParam(uptr n) {
26260c66db4SNico Weber   internal_memset(__msan_param_tls, 0, n * sizeof(*__msan_param_tls));
26360c66db4SNico Weber }
26460c66db4SNico Weber 
26560c66db4SNico Weber // Backup MSan runtime TLS state.
26660c66db4SNico Weber // Implementation must be async-signal-safe.
26760c66db4SNico Weber // Instances of this class may live on the signal handler stack, and data size
26860c66db4SNico Weber // may be an issue.
26960c66db4SNico Weber void ScopedThreadLocalStateBackup::Backup() {
27060c66db4SNico Weber   va_arg_overflow_size_tls = __msan_va_arg_overflow_size_tls;
27160c66db4SNico Weber }
27260c66db4SNico Weber 
27360c66db4SNico Weber void ScopedThreadLocalStateBackup::Restore() {
27460c66db4SNico Weber   // A lame implementation that only keeps essential state and resets the rest.
27560c66db4SNico Weber   __msan_va_arg_overflow_size_tls = va_arg_overflow_size_tls;
27660c66db4SNico Weber 
27760c66db4SNico Weber   internal_memset(__msan_param_tls, 0, sizeof(__msan_param_tls));
27860c66db4SNico Weber   internal_memset(__msan_retval_tls, 0, sizeof(__msan_retval_tls));
27960c66db4SNico Weber   internal_memset(__msan_va_arg_tls, 0, sizeof(__msan_va_arg_tls));
28060c66db4SNico Weber   internal_memset(__msan_va_arg_origin_tls, 0,
28160c66db4SNico Weber                   sizeof(__msan_va_arg_origin_tls));
28260c66db4SNico Weber 
28360c66db4SNico Weber   if (__msan_get_track_origins()) {
28460c66db4SNico Weber     internal_memset(&__msan_retval_origin_tls, 0,
28560c66db4SNico Weber                     sizeof(__msan_retval_origin_tls));
28660c66db4SNico Weber     internal_memset(__msan_param_origin_tls, 0,
28760c66db4SNico Weber                     sizeof(__msan_param_origin_tls));
28860c66db4SNico Weber   }
28960c66db4SNico Weber }
29060c66db4SNico Weber 
29160c66db4SNico Weber void UnpoisonThreadLocalState() {
29260c66db4SNico Weber }
29360c66db4SNico Weber 
29460c66db4SNico Weber const char *GetStackOriginDescr(u32 id, uptr *pc) {
29560c66db4SNico Weber   CHECK_LT(id, kNumStackOriginDescrs);
29660c66db4SNico Weber   if (pc) *pc = StackOriginPC[id];
29760c66db4SNico Weber   return StackOriginDescr[id];
29860c66db4SNico Weber }
29960c66db4SNico Weber 
30060c66db4SNico Weber u32 ChainOrigin(u32 id, StackTrace *stack) {
30160c66db4SNico Weber   MsanThread *t = GetCurrentThread();
30260c66db4SNico Weber   if (t && t->InSignalHandler())
30360c66db4SNico Weber     return id;
30460c66db4SNico Weber 
30560c66db4SNico Weber   Origin o = Origin::FromRawId(id);
30660c66db4SNico Weber   stack->tag = StackTrace::TAG_UNKNOWN;
30760c66db4SNico Weber   Origin chained = Origin::CreateChainedOrigin(o, stack);
30860c66db4SNico Weber   return chained.raw_id();
30960c66db4SNico Weber }
31060c66db4SNico Weber 
311ec277b67SKevin Athey // Current implementation separates the 'id_ptr' from the 'descr' and makes
312ec277b67SKevin Athey // 'descr' constant.
313ec277b67SKevin Athey // Previous implementation 'descr' is created at compile time and contains
314ec277b67SKevin Athey // '----' in the beginning.  When we see descr for the first time we replace
315ec277b67SKevin Athey // '----' with a uniq id and set the origin to (id | (31-th bit)).
316ec277b67SKevin Athey static inline void SetAllocaOrigin(void *a, uptr size, u32 *id_ptr, char *descr,
317ec277b67SKevin Athey                                    uptr pc) {
318af77e5e4SVitaly Buka   static const u32 dash = '-';
319af77e5e4SVitaly Buka   static const u32 first_timer =
320af77e5e4SVitaly Buka       dash + (dash << 8) + (dash << 16) + (dash << 24);
321af77e5e4SVitaly Buka   u32 id = *id_ptr;
322ec277b67SKevin Athey   if (id == 0 || id == first_timer) {
323af77e5e4SVitaly Buka     u32 idx = atomic_fetch_add(&NumStackOriginDescrs, 1, memory_order_relaxed);
324af77e5e4SVitaly Buka     CHECK_LT(idx, kNumStackOriginDescrs);
325ec277b67SKevin Athey     StackOriginDescr[idx] = descr;
326af77e5e4SVitaly Buka     StackOriginPC[idx] = pc;
327af77e5e4SVitaly Buka     id = Origin::CreateStackOrigin(idx).raw_id();
328af77e5e4SVitaly Buka     *id_ptr = id;
329af77e5e4SVitaly Buka   }
330af77e5e4SVitaly Buka   __msan_set_origin(a, size, id);
331af77e5e4SVitaly Buka }
332af77e5e4SVitaly Buka 
33360c66db4SNico Weber }  // namespace __msan
33460c66db4SNico Weber 
33560c66db4SNico Weber void __sanitizer::BufferedStackTrace::UnwindImpl(
33660c66db4SNico Weber     uptr pc, uptr bp, void *context, bool request_fast, u32 max_depth) {
33760c66db4SNico Weber   using namespace __msan;
33860c66db4SNico Weber   MsanThread *t = GetCurrentThread();
33960c66db4SNico Weber   if (!t || !StackTrace::WillUseFastUnwind(request_fast)) {
34060c66db4SNico Weber     // Block reports from our interceptors during _Unwind_Backtrace.
34147a9528fSVitaly Buka     UnwinderScope sym_scope;
342261d6e05SFangrui Song     return Unwind(max_depth, pc, bp, context, t ? t->stack_top() : 0,
343261d6e05SFangrui Song                   t ? t->stack_bottom() : 0, false);
34460c66db4SNico Weber   }
34560c66db4SNico Weber   if (StackTrace::WillUseFastUnwind(request_fast))
34660c66db4SNico Weber     Unwind(max_depth, pc, bp, nullptr, t->stack_top(), t->stack_bottom(), true);
34760c66db4SNico Weber   else
34860c66db4SNico Weber     Unwind(max_depth, pc, 0, context, 0, 0, false);
34960c66db4SNico Weber }
35060c66db4SNico Weber 
35160c66db4SNico Weber // Interface.
35260c66db4SNico Weber 
35360c66db4SNico Weber using namespace __msan;
35460c66db4SNico Weber 
35560c66db4SNico Weber #define MSAN_MAYBE_WARNING(type, size)              \
35660c66db4SNico Weber   void __msan_maybe_warning_##size(type s, u32 o) { \
35739b8a271SFangrui Song     GET_CALLER_PC_BP;                               \
35860c66db4SNico Weber     if (UNLIKELY(s)) {                              \
35960c66db4SNico Weber       PrintWarningWithOrigin(pc, bp, o);            \
36060c66db4SNico Weber       if (__msan::flags()->halt_on_error) {         \
36160c66db4SNico Weber         Printf("Exiting\n");                        \
36260c66db4SNico Weber         Die();                                      \
36360c66db4SNico Weber       }                                             \
36460c66db4SNico Weber     }                                               \
36560c66db4SNico Weber   }
36660c66db4SNico Weber 
36760c66db4SNico Weber MSAN_MAYBE_WARNING(u8, 1)
36860c66db4SNico Weber MSAN_MAYBE_WARNING(u16, 2)
36960c66db4SNico Weber MSAN_MAYBE_WARNING(u32, 4)
37060c66db4SNico Weber MSAN_MAYBE_WARNING(u64, 8)
37160c66db4SNico Weber 
37260c66db4SNico Weber #define MSAN_MAYBE_STORE_ORIGIN(type, size)                       \
37360c66db4SNico Weber   void __msan_maybe_store_origin_##size(type s, void *p, u32 o) { \
37460c66db4SNico Weber     if (UNLIKELY(s)) {                                            \
37560c66db4SNico Weber       if (__msan_get_track_origins() > 1) {                       \
37639b8a271SFangrui Song         GET_CALLER_PC_BP;                                         \
37760c66db4SNico Weber         GET_STORE_STACK_TRACE_PC_BP(pc, bp);                      \
37860c66db4SNico Weber         o = ChainOrigin(o, &stack);                               \
37960c66db4SNico Weber       }                                                           \
38060c66db4SNico Weber       *(u32 *)MEM_TO_ORIGIN((uptr)p & ~3UL) = o;                  \
38160c66db4SNico Weber     }                                                             \
38260c66db4SNico Weber   }
38360c66db4SNico Weber 
38460c66db4SNico Weber MSAN_MAYBE_STORE_ORIGIN(u8, 1)
38560c66db4SNico Weber MSAN_MAYBE_STORE_ORIGIN(u16, 2)
38660c66db4SNico Weber MSAN_MAYBE_STORE_ORIGIN(u32, 4)
38760c66db4SNico Weber MSAN_MAYBE_STORE_ORIGIN(u64, 8)
38860c66db4SNico Weber 
38960c66db4SNico Weber void __msan_warning() {
39039b8a271SFangrui Song   GET_CALLER_PC_BP;
391ad2b356fSVitaly Buka   PrintWarningWithOrigin(pc, bp, 0);
39260c66db4SNico Weber   if (__msan::flags()->halt_on_error) {
39360c66db4SNico Weber     if (__msan::flags()->print_stats)
39460c66db4SNico Weber       ReportStats();
39560c66db4SNico Weber     Printf("Exiting\n");
39660c66db4SNico Weber     Die();
39760c66db4SNico Weber   }
39860c66db4SNico Weber }
39960c66db4SNico Weber 
40060c66db4SNico Weber void __msan_warning_noreturn() {
40139b8a271SFangrui Song   GET_CALLER_PC_BP;
402ad2b356fSVitaly Buka   PrintWarningWithOrigin(pc, bp, 0);
40360c66db4SNico Weber   if (__msan::flags()->print_stats)
40460c66db4SNico Weber     ReportStats();
40560c66db4SNico Weber   Printf("Exiting\n");
40660c66db4SNico Weber   Die();
40760c66db4SNico Weber }
40860c66db4SNico Weber 
409b0ffa8beSGui Andrade void __msan_warning_with_origin(u32 origin) {
41039b8a271SFangrui Song   GET_CALLER_PC_BP;
411b0ffa8beSGui Andrade   PrintWarningWithOrigin(pc, bp, origin);
412b0ffa8beSGui Andrade   if (__msan::flags()->halt_on_error) {
413b0ffa8beSGui Andrade     if (__msan::flags()->print_stats)
414b0ffa8beSGui Andrade       ReportStats();
415b0ffa8beSGui Andrade     Printf("Exiting\n");
416b0ffa8beSGui Andrade     Die();
417b0ffa8beSGui Andrade   }
418b0ffa8beSGui Andrade }
419b0ffa8beSGui Andrade 
420b0ffa8beSGui Andrade void __msan_warning_with_origin_noreturn(u32 origin) {
42139b8a271SFangrui Song   GET_CALLER_PC_BP;
422b0ffa8beSGui Andrade   PrintWarningWithOrigin(pc, bp, origin);
423b0ffa8beSGui Andrade   if (__msan::flags()->print_stats)
424b0ffa8beSGui Andrade     ReportStats();
425b0ffa8beSGui Andrade   Printf("Exiting\n");
426b0ffa8beSGui Andrade   Die();
427b0ffa8beSGui Andrade }
428b0ffa8beSGui Andrade 
42960c66db4SNico Weber static void OnStackUnwind(const SignalContext &sig, const void *,
43060c66db4SNico Weber                           BufferedStackTrace *stack) {
431d39e7e2cSVitaly Buka   stack->Unwind(StackTrace::GetNextInstructionPc(sig.pc), sig.bp, sig.context,
43260c66db4SNico Weber                 common_flags()->fast_unwind_on_fatal);
43360c66db4SNico Weber }
43460c66db4SNico Weber 
43560c66db4SNico Weber static void MsanOnDeadlySignal(int signo, void *siginfo, void *context) {
43660c66db4SNico Weber   HandleDeadlySignal(siginfo, context, GetTid(), &OnStackUnwind, nullptr);
43760c66db4SNico Weber }
43860c66db4SNico Weber 
4392721e27cSDmitry Vyukov static void CheckUnwind() {
4402721e27cSDmitry Vyukov   GET_FATAL_STACK_TRACE_PC_BP(StackTrace::GetCurrentPc(), GET_CURRENT_FRAME());
4412721e27cSDmitry Vyukov   stack.Print();
44260c66db4SNico Weber }
44360c66db4SNico Weber 
44460c66db4SNico Weber void __msan_init() {
44560c66db4SNico Weber   CHECK(!msan_init_is_running);
44660c66db4SNico Weber   if (msan_inited) return;
44760c66db4SNico Weber   msan_init_is_running = 1;
44860c66db4SNico Weber   SanitizerToolName = "MemorySanitizer";
44960c66db4SNico Weber 
45060c66db4SNico Weber   AvoidCVE_2016_2143();
45160c66db4SNico Weber 
45260c66db4SNico Weber   CacheBinaryName();
45360c66db4SNico Weber   InitializeFlags();
45460c66db4SNico Weber 
45560c66db4SNico Weber   // Install tool-specific callbacks in sanitizer_common.
4562721e27cSDmitry Vyukov   SetCheckUnwindCallback(CheckUnwind);
45760c66db4SNico Weber 
45860c66db4SNico Weber   __sanitizer_set_report_path(common_flags()->log_path);
45960c66db4SNico Weber 
460*a0bb2e21SVitaly Buka   InitializePlatformEarly();
461*a0bb2e21SVitaly Buka 
46260c66db4SNico Weber   InitializeInterceptors();
463fcce8432SVitaly Buka   InstallAtForkHandler();
464e2ed800dSDavid Carlier   CheckASLR();
46560c66db4SNico Weber   InstallDeadlySignalHandlers(MsanOnDeadlySignal);
46660c66db4SNico Weber   InstallAtExitHandler(); // Needs __cxa_atexit interceptor.
46760c66db4SNico Weber 
46860c66db4SNico Weber   DisableCoreDumperIfNecessary();
46960c66db4SNico Weber   if (StackSizeIsUnlimited()) {
47060c66db4SNico Weber     VPrintf(1, "Unlimited stack, doing reexec\n");
47160c66db4SNico Weber     // A reasonably large stack size. It is bigger than the usual 8Mb, because,
47260c66db4SNico Weber     // well, the program could have been run with unlimited stack for a reason.
47360c66db4SNico Weber     SetStackSizeLimitInBytes(32 * 1024 * 1024);
47460c66db4SNico Weber     ReExec();
47560c66db4SNico Weber   }
47660c66db4SNico Weber 
47760c66db4SNico Weber   __msan_clear_on_return();
47860c66db4SNico Weber   if (__msan_get_track_origins())
47960c66db4SNico Weber     VPrintf(1, "msan_track_origins\n");
48058f72518SThurston Dang   if (!InitShadowWithReExec(__msan_get_track_origins())) {
48160c66db4SNico Weber     Printf("FATAL: MemorySanitizer can not mmap the shadow memory.\n");
48260c66db4SNico Weber     Printf("FATAL: Make sure to compile with -fPIE and to link with -pie.\n");
48360c66db4SNico Weber     Printf("FATAL: Disabling ASLR is known to cause this error.\n");
48460c66db4SNico Weber     Printf("FATAL: If running under GDB, try "
48560c66db4SNico Weber            "'set disable-randomization off'.\n");
48660c66db4SNico Weber     DumpProcessMap();
48760c66db4SNico Weber     Die();
48860c66db4SNico Weber   }
48960c66db4SNico Weber 
49047a9528fSVitaly Buka   Symbolizer::GetOrInit()->AddHooks(EnterSymbolizerOrUnwider,
49147a9528fSVitaly Buka                                     ExitSymbolizerOrUnwider);
49260c66db4SNico Weber 
49360c66db4SNico Weber   InitializeCoverage(common_flags()->coverage, common_flags()->coverage_dir);
49460c66db4SNico Weber 
49560c66db4SNico Weber   MsanTSDInit(MsanTSDDtor);
49660c66db4SNico Weber 
49760c66db4SNico Weber   MsanAllocatorInit();
49860c66db4SNico Weber 
49960c66db4SNico Weber   MsanThread *main_thread = MsanThread::Create(nullptr, nullptr);
50060c66db4SNico Weber   SetCurrentThread(main_thread);
501b3267bb3SVitaly Buka   main_thread->Init();
50260c66db4SNico Weber 
50360c66db4SNico Weber #if MSAN_CONTAINS_UBSAN
50460c66db4SNico Weber   __ubsan::InitAsPlugin();
50560c66db4SNico Weber #endif
50660c66db4SNico Weber 
50760c66db4SNico Weber   VPrintf(1, "MemorySanitizer init done\n");
50860c66db4SNico Weber 
50960c66db4SNico Weber   msan_init_is_running = 0;
51060c66db4SNico Weber   msan_inited = 1;
51160c66db4SNico Weber }
51260c66db4SNico Weber 
51360c66db4SNico Weber void __msan_set_keep_going(int keep_going) {
51460c66db4SNico Weber   flags()->halt_on_error = !keep_going;
51560c66db4SNico Weber }
51660c66db4SNico Weber 
51760c66db4SNico Weber void __msan_set_expect_umr(int expect_umr) {
51860c66db4SNico Weber   if (expect_umr) {
51960c66db4SNico Weber     msan_expected_umr_found = 0;
52060c66db4SNico Weber   } else if (!msan_expected_umr_found) {
52139b8a271SFangrui Song     GET_CALLER_PC_BP;
52260c66db4SNico Weber     GET_FATAL_STACK_TRACE_PC_BP(pc, bp);
52360c66db4SNico Weber     ReportExpectedUMRNotFound(&stack);
52460c66db4SNico Weber     Die();
52560c66db4SNico Weber   }
52660c66db4SNico Weber   msan_expect_umr = expect_umr;
52760c66db4SNico Weber }
52860c66db4SNico Weber 
52960c66db4SNico Weber void __msan_print_shadow(const void *x, uptr size) {
53060c66db4SNico Weber   if (!MEM_IS_APP(x)) {
53160c66db4SNico Weber     Printf("Not a valid application address: %p\n", x);
53260c66db4SNico Weber     return;
53360c66db4SNico Weber   }
53460c66db4SNico Weber 
53560c66db4SNico Weber   DescribeMemoryRange(x, size);
53660c66db4SNico Weber }
53760c66db4SNico Weber 
53860c66db4SNico Weber void __msan_dump_shadow(const void *x, uptr size) {
53960c66db4SNico Weber   if (!MEM_IS_APP(x)) {
54060c66db4SNico Weber     Printf("Not a valid application address: %p\n", x);
54160c66db4SNico Weber     return;
54260c66db4SNico Weber   }
54360c66db4SNico Weber 
54460c66db4SNico Weber   unsigned char *s = (unsigned char*)MEM_TO_SHADOW(x);
54513a442caSMartin Liska   Printf("%p[%p]  ", (void *)s, x);
54660c66db4SNico Weber   for (uptr i = 0; i < size; i++)
54760c66db4SNico Weber     Printf("%x%x ", s[i] >> 4, s[i] & 0xf);
54860c66db4SNico Weber   Printf("\n");
54960c66db4SNico Weber }
55060c66db4SNico Weber 
55160c66db4SNico Weber sptr __msan_test_shadow(const void *x, uptr size) {
55260c66db4SNico Weber   if (!MEM_IS_APP(x)) return -1;
55360c66db4SNico Weber   unsigned char *s = (unsigned char *)MEM_TO_SHADOW((uptr)x);
554c0b5000bSGui Andrade   if (__sanitizer::mem_is_zero((const char *)s, size))
555c0b5000bSGui Andrade     return -1;
556c0b5000bSGui Andrade   // Slow path: loop through again to find the location.
55760c66db4SNico Weber   for (uptr i = 0; i < size; ++i)
55860c66db4SNico Weber     if (s[i])
55960c66db4SNico Weber       return i;
56060c66db4SNico Weber   return -1;
56160c66db4SNico Weber }
56260c66db4SNico Weber 
56360c66db4SNico Weber void __msan_check_mem_is_initialized(const void *x, uptr size) {
56460c66db4SNico Weber   if (!__msan::flags()->report_umrs) return;
56560c66db4SNico Weber   sptr offset = __msan_test_shadow(x, size);
56660c66db4SNico Weber   if (offset < 0)
56760c66db4SNico Weber     return;
56860c66db4SNico Weber 
56939b8a271SFangrui Song   GET_CALLER_PC_BP;
57060c66db4SNico Weber   ReportUMRInsideAddressRange(__func__, x, size, offset);
57160c66db4SNico Weber   __msan::PrintWarningWithOrigin(pc, bp,
57260c66db4SNico Weber                                  __msan_get_origin(((const char *)x) + offset));
57360c66db4SNico Weber   if (__msan::flags()->halt_on_error) {
57460c66db4SNico Weber     Printf("Exiting\n");
57560c66db4SNico Weber     Die();
57660c66db4SNico Weber   }
57760c66db4SNico Weber }
57860c66db4SNico Weber 
57960c66db4SNico Weber int __msan_set_poison_in_malloc(int do_poison) {
58060c66db4SNico Weber   int old = flags()->poison_in_malloc;
58160c66db4SNico Weber   flags()->poison_in_malloc = do_poison;
58260c66db4SNico Weber   return old;
58360c66db4SNico Weber }
58460c66db4SNico Weber 
58560c66db4SNico Weber int __msan_has_dynamic_component() { return false; }
58660c66db4SNico Weber 
58760c66db4SNico Weber NOINLINE
58860c66db4SNico Weber void __msan_clear_on_return() {
58960c66db4SNico Weber   __msan_param_tls[0] = 0;
59060c66db4SNico Weber }
59160c66db4SNico Weber 
59260c66db4SNico Weber void __msan_partial_poison(const void* data, void* shadow, uptr size) {
59360c66db4SNico Weber   internal_memcpy((void*)MEM_TO_SHADOW((uptr)data), shadow, size);
59460c66db4SNico Weber }
59560c66db4SNico Weber 
59660c66db4SNico Weber void __msan_load_unpoisoned(const void *src, uptr size, void *dst) {
59760c66db4SNico Weber   internal_memcpy(dst, src, size);
59860c66db4SNico Weber   __msan_unpoison(dst, size);
59960c66db4SNico Weber }
60060c66db4SNico Weber 
60160c66db4SNico Weber void __msan_set_origin(const void *a, uptr size, u32 origin) {
60260c66db4SNico Weber   if (__msan_get_track_origins()) SetOrigin(a, size, origin);
60360c66db4SNico Weber }
60460c66db4SNico Weber 
60560c66db4SNico Weber void __msan_set_alloca_origin(void *a, uptr size, char *descr) {
606ec277b67SKevin Athey   SetAllocaOrigin(a, size, reinterpret_cast<u32 *>(descr), descr + 4,
607ec277b67SKevin Athey                   GET_CALLER_PC());
60860c66db4SNico Weber }
60960c66db4SNico Weber 
61060c66db4SNico Weber void __msan_set_alloca_origin4(void *a, uptr size, char *descr, uptr pc) {
611af77e5e4SVitaly Buka   // Intentionally ignore pc and use return address. This function is here for
612af77e5e4SVitaly Buka   // compatibility, in case program is linked with library instrumented by
613af77e5e4SVitaly Buka   // older clang.
614ec277b67SKevin Athey   SetAllocaOrigin(a, size, reinterpret_cast<u32 *>(descr), descr + 4,
615ec277b67SKevin Athey                   GET_CALLER_PC());
616ec277b67SKevin Athey }
617ec277b67SKevin Athey 
618ec277b67SKevin Athey void __msan_set_alloca_origin_with_descr(void *a, uptr size, u32 *id_ptr,
619ec277b67SKevin Athey                                          char *descr) {
620ec277b67SKevin Athey   SetAllocaOrigin(a, size, id_ptr, descr, GET_CALLER_PC());
62160c66db4SNico Weber }
62260c66db4SNico Weber 
623532564deSKevin Athey void __msan_set_alloca_origin_no_descr(void *a, uptr size, u32 *id_ptr) {
624532564deSKevin Athey   SetAllocaOrigin(a, size, id_ptr, nullptr, GET_CALLER_PC());
625532564deSKevin Athey }
626532564deSKevin Athey 
62760c66db4SNico Weber u32 __msan_chain_origin(u32 id) {
62839b8a271SFangrui Song   GET_CALLER_PC_BP;
62960c66db4SNico Weber   GET_STORE_STACK_TRACE_PC_BP(pc, bp);
63060c66db4SNico Weber   return ChainOrigin(id, &stack);
63160c66db4SNico Weber }
63260c66db4SNico Weber 
63360c66db4SNico Weber u32 __msan_get_origin(const void *a) {
63460c66db4SNico Weber   if (!__msan_get_track_origins()) return 0;
63560c66db4SNico Weber   uptr x = (uptr)a;
63660c66db4SNico Weber   uptr aligned = x & ~3ULL;
63760c66db4SNico Weber   uptr origin_ptr = MEM_TO_ORIGIN(aligned);
63860c66db4SNico Weber   return *(u32*)origin_ptr;
63960c66db4SNico Weber }
64060c66db4SNico Weber 
64160c66db4SNico Weber int __msan_origin_is_descendant_or_same(u32 this_id, u32 prev_id) {
64260c66db4SNico Weber   Origin o = Origin::FromRawId(this_id);
64360c66db4SNico Weber   while (o.raw_id() != prev_id && o.isChainedOrigin())
64460c66db4SNico Weber     o = o.getNextChainedOrigin(nullptr);
64560c66db4SNico Weber   return o.raw_id() == prev_id;
64660c66db4SNico Weber }
64760c66db4SNico Weber 
64860c66db4SNico Weber u32 __msan_get_umr_origin() {
64960c66db4SNico Weber   return __msan_origin_tls;
65060c66db4SNico Weber }
65160c66db4SNico Weber 
65260c66db4SNico Weber u16 __sanitizer_unaligned_load16(const uu16 *p) {
653af380748Sserge-sans-paille   internal_memcpy(&__msan_retval_tls[0], (void *)MEM_TO_SHADOW((uptr)p),
654af380748Sserge-sans-paille                   sizeof(uu16));
65560c66db4SNico Weber   if (__msan_get_track_origins())
65660c66db4SNico Weber     __msan_retval_origin_tls = GetOriginIfPoisoned((uptr)p, sizeof(*p));
65760c66db4SNico Weber   return *p;
65860c66db4SNico Weber }
65960c66db4SNico Weber u32 __sanitizer_unaligned_load32(const uu32 *p) {
660af380748Sserge-sans-paille   internal_memcpy(&__msan_retval_tls[0], (void *)MEM_TO_SHADOW((uptr)p),
661af380748Sserge-sans-paille                   sizeof(uu32));
66260c66db4SNico Weber   if (__msan_get_track_origins())
66360c66db4SNico Weber     __msan_retval_origin_tls = GetOriginIfPoisoned((uptr)p, sizeof(*p));
66460c66db4SNico Weber   return *p;
66560c66db4SNico Weber }
66660c66db4SNico Weber u64 __sanitizer_unaligned_load64(const uu64 *p) {
667af380748Sserge-sans-paille   internal_memcpy(&__msan_retval_tls[0], (void *)MEM_TO_SHADOW((uptr)p),
668af380748Sserge-sans-paille                   sizeof(uu64));
66960c66db4SNico Weber   if (__msan_get_track_origins())
67060c66db4SNico Weber     __msan_retval_origin_tls = GetOriginIfPoisoned((uptr)p, sizeof(*p));
67160c66db4SNico Weber   return *p;
67260c66db4SNico Weber }
67360c66db4SNico Weber void __sanitizer_unaligned_store16(uu16 *p, u16 x) {
674af380748Sserge-sans-paille   static_assert(sizeof(uu16) == sizeof(u16), "incompatible types");
675af380748Sserge-sans-paille   u16 s;
676af380748Sserge-sans-paille   internal_memcpy(&s, &__msan_param_tls[1], sizeof(uu16));
677af380748Sserge-sans-paille   internal_memcpy((void *)MEM_TO_SHADOW((uptr)p), &s, sizeof(uu16));
67860c66db4SNico Weber   if (s && __msan_get_track_origins())
67960c66db4SNico Weber     if (uu32 o = __msan_param_origin_tls[2])
68060c66db4SNico Weber       SetOriginIfPoisoned((uptr)p, (uptr)&s, sizeof(s), o);
68160c66db4SNico Weber   *p = x;
68260c66db4SNico Weber }
68360c66db4SNico Weber void __sanitizer_unaligned_store32(uu32 *p, u32 x) {
684af380748Sserge-sans-paille   static_assert(sizeof(uu32) == sizeof(u32), "incompatible types");
685af380748Sserge-sans-paille   u32 s;
686af380748Sserge-sans-paille   internal_memcpy(&s, &__msan_param_tls[1], sizeof(uu32));
687af380748Sserge-sans-paille   internal_memcpy((void *)MEM_TO_SHADOW((uptr)p), &s, sizeof(uu32));
68860c66db4SNico Weber   if (s && __msan_get_track_origins())
68960c66db4SNico Weber     if (uu32 o = __msan_param_origin_tls[2])
69060c66db4SNico Weber       SetOriginIfPoisoned((uptr)p, (uptr)&s, sizeof(s), o);
69160c66db4SNico Weber   *p = x;
69260c66db4SNico Weber }
69360c66db4SNico Weber void __sanitizer_unaligned_store64(uu64 *p, u64 x) {
69460c66db4SNico Weber   u64 s = __msan_param_tls[1];
69560c66db4SNico Weber   *(uu64 *)MEM_TO_SHADOW((uptr)p) = s;
69660c66db4SNico Weber   if (s && __msan_get_track_origins())
69760c66db4SNico Weber     if (uu32 o = __msan_param_origin_tls[2])
69860c66db4SNico Weber       SetOriginIfPoisoned((uptr)p, (uptr)&s, sizeof(s), o);
69960c66db4SNico Weber   *p = x;
70060c66db4SNico Weber }
70160c66db4SNico Weber 
70260c66db4SNico Weber void __msan_set_death_callback(void (*callback)(void)) {
70360c66db4SNico Weber   SetUserDieCallback(callback);
70460c66db4SNico Weber }
70560c66db4SNico Weber 
7061d3ef5f1SJustin Cady void __msan_start_switch_fiber(const void *bottom, uptr size) {
7071d3ef5f1SJustin Cady   MsanThread *t = GetCurrentThread();
7081d3ef5f1SJustin Cady   if (!t) {
7091d3ef5f1SJustin Cady     VReport(1, "__msan_start_switch_fiber called from unknown thread\n");
7101d3ef5f1SJustin Cady     return;
7111d3ef5f1SJustin Cady   }
7121d3ef5f1SJustin Cady   t->StartSwitchFiber((uptr)bottom, size);
7131d3ef5f1SJustin Cady }
7141d3ef5f1SJustin Cady 
7151d3ef5f1SJustin Cady void __msan_finish_switch_fiber(const void **bottom_old, uptr *size_old) {
7161d3ef5f1SJustin Cady   MsanThread *t = GetCurrentThread();
7171d3ef5f1SJustin Cady   if (!t) {
7181d3ef5f1SJustin Cady     VReport(1, "__msan_finish_switch_fiber called from unknown thread\n");
7191d3ef5f1SJustin Cady     return;
7201d3ef5f1SJustin Cady   }
7211d3ef5f1SJustin Cady   t->FinishSwitchFiber((uptr *)bottom_old, (uptr *)size_old);
7221d3ef5f1SJustin Cady 
7231d3ef5f1SJustin Cady   internal_memset(__msan_param_tls, 0, sizeof(__msan_param_tls));
7241d3ef5f1SJustin Cady   internal_memset(__msan_retval_tls, 0, sizeof(__msan_retval_tls));
7251d3ef5f1SJustin Cady   internal_memset(__msan_va_arg_tls, 0, sizeof(__msan_va_arg_tls));
7261d3ef5f1SJustin Cady 
7271d3ef5f1SJustin Cady   if (__msan_get_track_origins()) {
7281d3ef5f1SJustin Cady     internal_memset(__msan_param_origin_tls, 0,
7291d3ef5f1SJustin Cady                     sizeof(__msan_param_origin_tls));
7301d3ef5f1SJustin Cady     internal_memset(&__msan_retval_origin_tls, 0,
7311d3ef5f1SJustin Cady                     sizeof(__msan_retval_origin_tls));
7321d3ef5f1SJustin Cady     internal_memset(__msan_va_arg_origin_tls, 0,
7331d3ef5f1SJustin Cady                     sizeof(__msan_va_arg_origin_tls));
7341d3ef5f1SJustin Cady   }
7351d3ef5f1SJustin Cady }
7361d3ef5f1SJustin Cady 
7372d7fd38cSFangrui Song SANITIZER_INTERFACE_WEAK_DEF(const char *, __msan_default_options, void) {
7382d7fd38cSFangrui Song   return "";
7392d7fd38cSFangrui Song }
74060c66db4SNico Weber 
74160c66db4SNico Weber extern "C" {
74260c66db4SNico Weber SANITIZER_INTERFACE_ATTRIBUTE
74360c66db4SNico Weber void __sanitizer_print_stack_trace() {
74460c66db4SNico Weber   GET_FATAL_STACK_TRACE_PC_BP(StackTrace::GetCurrentPc(), GET_CURRENT_FRAME());
74560c66db4SNico Weber   stack.Print();
74660c66db4SNico Weber }
74760c66db4SNico Weber } // extern "C"
748