Path: blob/main/contrib/llvm-project/compiler-rt/lib/msan/msan.cpp
35262 views
//===-- msan.cpp ----------------------------------------------------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// This file is a part of MemorySanitizer.9//10// MemorySanitizer runtime.11//===----------------------------------------------------------------------===//1213#include "msan.h"1415#include "msan_chained_origin_depot.h"16#include "msan_origin.h"17#include "msan_poisoning.h"18#include "msan_report.h"19#include "msan_thread.h"20#include "sanitizer_common/sanitizer_atomic.h"21#include "sanitizer_common/sanitizer_common.h"22#include "sanitizer_common/sanitizer_flag_parser.h"23#include "sanitizer_common/sanitizer_flags.h"24#include "sanitizer_common/sanitizer_interface_internal.h"25#include "sanitizer_common/sanitizer_libc.h"26#include "sanitizer_common/sanitizer_procmaps.h"27#include "sanitizer_common/sanitizer_stackdepot.h"28#include "sanitizer_common/sanitizer_stacktrace.h"29#include "sanitizer_common/sanitizer_symbolizer.h"30#include "ubsan/ubsan_flags.h"31#include "ubsan/ubsan_init.h"3233// ACHTUNG! No system header includes in this file.3435using namespace __sanitizer;3637// Globals.38static THREADLOCAL int msan_expect_umr = 0;39static THREADLOCAL int msan_expected_umr_found = 0;4041// Function argument shadow. Each argument starts at the next available 8-byte42// aligned address.43SANITIZER_INTERFACE_ATTRIBUTE44THREADLOCAL u64 __msan_param_tls[kMsanParamTlsSize / sizeof(u64)];4546// Function argument origin. Each argument starts at the same offset as the47// corresponding shadow in (__msan_param_tls). Slightly weird, but changing this48// would break compatibility with older prebuilt binaries.49SANITIZER_INTERFACE_ATTRIBUTE50THREADLOCAL u32 __msan_param_origin_tls[kMsanParamTlsSize / sizeof(u32)];5152SANITIZER_INTERFACE_ATTRIBUTE53THREADLOCAL u64 __msan_retval_tls[kMsanRetvalTlsSize / sizeof(u64)];5455SANITIZER_INTERFACE_ATTRIBUTE56THREADLOCAL u32 __msan_retval_origin_tls;5758alignas(16) SANITIZER_INTERFACE_ATTRIBUTE THREADLOCAL u6459__msan_va_arg_tls[kMsanParamTlsSize / sizeof(u64)];6061alignas(16) SANITIZER_INTERFACE_ATTRIBUTE THREADLOCAL u3262__msan_va_arg_origin_tls[kMsanParamTlsSize / sizeof(u32)];6364SANITIZER_INTERFACE_ATTRIBUTE65THREADLOCAL u64 __msan_va_arg_overflow_size_tls;6667SANITIZER_INTERFACE_ATTRIBUTE68THREADLOCAL u32 __msan_origin_tls;6970extern "C" SANITIZER_WEAK_ATTRIBUTE const int __msan_track_origins;7172int __msan_get_track_origins() {73return &__msan_track_origins ? __msan_track_origins : 0;74}7576extern "C" SANITIZER_WEAK_ATTRIBUTE const int __msan_keep_going;7778namespace __msan {7980static THREADLOCAL int is_in_symbolizer_or_unwinder;81static void EnterSymbolizerOrUnwider() { ++is_in_symbolizer_or_unwinder; }82static void ExitSymbolizerOrUnwider() { --is_in_symbolizer_or_unwinder; }83bool IsInSymbolizerOrUnwider() { return is_in_symbolizer_or_unwinder; }8485struct UnwinderScope {86UnwinderScope() { EnterSymbolizerOrUnwider(); }87~UnwinderScope() { ExitSymbolizerOrUnwider(); }88};8990static Flags msan_flags;9192Flags *flags() { return &msan_flags; }9394int msan_inited = 0;95bool msan_init_is_running;9697int msan_report_count = 0;9899// Array of stack origins.100// FIXME: make it resizable.101// Although BSS memory doesn't cost anything until used, it is limited to 2GB102// in some configurations (e.g., "relocation R_X86_64_PC32 out of range:103// ... is not in [-2147483648, 2147483647]; references section '.bss'").104// We use kNumStackOriginDescrs * (sizeof(char*) + sizeof(uptr)) == 64MB.105#if SANITIZER_PPC106// soft_rss_limit test (release_origin.c) fails on PPC if kNumStackOriginDescrs107// is too high108static const uptr kNumStackOriginDescrs = 1 * 1024 * 1024;109#else110static const uptr kNumStackOriginDescrs = 4 * 1024 * 1024;111#endif // SANITIZER_PPC112static const char *StackOriginDescr[kNumStackOriginDescrs];113static uptr StackOriginPC[kNumStackOriginDescrs];114static atomic_uint32_t NumStackOriginDescrs;115116void Flags::SetDefaults() {117#define MSAN_FLAG(Type, Name, DefaultValue, Description) Name = DefaultValue;118#include "msan_flags.inc"119#undef MSAN_FLAG120}121122// keep_going is an old name for halt_on_error,123// and it has inverse meaning.124class FlagHandlerKeepGoing final : public FlagHandlerBase {125bool *halt_on_error_;126127public:128explicit FlagHandlerKeepGoing(bool *halt_on_error)129: halt_on_error_(halt_on_error) {}130bool Parse(const char *value) final {131bool tmp;132FlagHandler<bool> h(&tmp);133if (!h.Parse(value)) return false;134*halt_on_error_ = !tmp;135return true;136}137bool Format(char *buffer, uptr size) final {138const char *keep_going_str = (*halt_on_error_) ? "false" : "true";139return FormatString(buffer, size, keep_going_str);140}141};142143static void RegisterMsanFlags(FlagParser *parser, Flags *f) {144#define MSAN_FLAG(Type, Name, DefaultValue, Description) \145RegisterFlag(parser, #Name, Description, &f->Name);146#include "msan_flags.inc"147#undef MSAN_FLAG148149FlagHandlerKeepGoing *fh_keep_going = new (GetGlobalLowLevelAllocator())150FlagHandlerKeepGoing(&f->halt_on_error);151parser->RegisterHandler("keep_going", fh_keep_going,152"deprecated, use halt_on_error");153}154155static void InitializeFlags() {156SetCommonFlagsDefaults();157{158CommonFlags cf;159cf.CopyFrom(*common_flags());160cf.external_symbolizer_path = GetEnv("MSAN_SYMBOLIZER_PATH");161cf.malloc_context_size = 20;162cf.handle_ioctl = true;163// FIXME: test and enable.164cf.check_printf = false;165cf.intercept_tls_get_addr = true;166OverrideCommonFlags(cf);167}168169Flags *f = flags();170f->SetDefaults();171172FlagParser parser;173RegisterMsanFlags(&parser, f);174RegisterCommonFlags(&parser);175176#if MSAN_CONTAINS_UBSAN177__ubsan::Flags *uf = __ubsan::flags();178uf->SetDefaults();179180FlagParser ubsan_parser;181__ubsan::RegisterUbsanFlags(&ubsan_parser, uf);182RegisterCommonFlags(&ubsan_parser);183#endif184185// Override from user-specified string.186parser.ParseString(__msan_default_options());187#if MSAN_CONTAINS_UBSAN188const char *ubsan_default_options = __ubsan_default_options();189ubsan_parser.ParseString(ubsan_default_options);190#endif191192parser.ParseStringFromEnv("MSAN_OPTIONS");193#if MSAN_CONTAINS_UBSAN194ubsan_parser.ParseStringFromEnv("UBSAN_OPTIONS");195#endif196197InitializeCommonFlags();198199if (Verbosity()) ReportUnrecognizedFlags();200201if (common_flags()->help) parser.PrintFlagDescriptions();202203// Check if deprecated exit_code MSan flag is set.204if (f->exit_code != -1) {205if (Verbosity())206Printf("MSAN_OPTIONS=exit_code is deprecated! "207"Please use MSAN_OPTIONS=exitcode instead.\n");208CommonFlags cf;209cf.CopyFrom(*common_flags());210cf.exitcode = f->exit_code;211OverrideCommonFlags(cf);212}213214// Check flag values:215if (f->origin_history_size < 0 ||216f->origin_history_size > Origin::kMaxDepth) {217Printf(218"Origin history size invalid: %d. Must be 0 (unlimited) or in [1, %d] "219"range.\n",220f->origin_history_size, Origin::kMaxDepth);221Die();222}223// Limiting to kStackDepotMaxUseCount / 2 to avoid overflow in224// StackDepotHandle::inc_use_count_unsafe.225if (f->origin_history_per_stack_limit < 0 ||226f->origin_history_per_stack_limit > kStackDepotMaxUseCount / 2) {227Printf(228"Origin per-stack limit invalid: %d. Must be 0 (unlimited) or in [1, "229"%d] range.\n",230f->origin_history_per_stack_limit, kStackDepotMaxUseCount / 2);231Die();232}233if (f->store_context_size < 1) f->store_context_size = 1;234}235236void PrintWarningWithOrigin(uptr pc, uptr bp, u32 origin) {237if (msan_expect_umr) {238// Printf("Expected UMR\n");239__msan_origin_tls = origin;240msan_expected_umr_found = 1;241return;242}243244++msan_report_count;245246GET_FATAL_STACK_TRACE_PC_BP(pc, bp);247248u32 report_origin =249(__msan_get_track_origins() && Origin::isValidId(origin)) ? origin : 0;250ReportUMR(&stack, report_origin);251252if (__msan_get_track_origins() && !Origin::isValidId(origin)) {253Printf(254" ORIGIN: invalid (%x). Might be a bug in MemorySanitizer origin "255"tracking.\n This could still be a bug in your code, too!\n",256origin);257}258}259260void UnpoisonParam(uptr n) {261internal_memset(__msan_param_tls, 0, n * sizeof(*__msan_param_tls));262}263264// Backup MSan runtime TLS state.265// Implementation must be async-signal-safe.266// Instances of this class may live on the signal handler stack, and data size267// may be an issue.268void ScopedThreadLocalStateBackup::Backup() {269va_arg_overflow_size_tls = __msan_va_arg_overflow_size_tls;270}271272void ScopedThreadLocalStateBackup::Restore() {273// A lame implementation that only keeps essential state and resets the rest.274__msan_va_arg_overflow_size_tls = va_arg_overflow_size_tls;275276internal_memset(__msan_param_tls, 0, sizeof(__msan_param_tls));277internal_memset(__msan_retval_tls, 0, sizeof(__msan_retval_tls));278internal_memset(__msan_va_arg_tls, 0, sizeof(__msan_va_arg_tls));279internal_memset(__msan_va_arg_origin_tls, 0,280sizeof(__msan_va_arg_origin_tls));281282if (__msan_get_track_origins()) {283internal_memset(&__msan_retval_origin_tls, 0,284sizeof(__msan_retval_origin_tls));285internal_memset(__msan_param_origin_tls, 0,286sizeof(__msan_param_origin_tls));287}288}289290void UnpoisonThreadLocalState() {291}292293const char *GetStackOriginDescr(u32 id, uptr *pc) {294CHECK_LT(id, kNumStackOriginDescrs);295if (pc) *pc = StackOriginPC[id];296return StackOriginDescr[id];297}298299u32 ChainOrigin(u32 id, StackTrace *stack) {300MsanThread *t = GetCurrentThread();301if (t && t->InSignalHandler())302return id;303304Origin o = Origin::FromRawId(id);305stack->tag = StackTrace::TAG_UNKNOWN;306Origin chained = Origin::CreateChainedOrigin(o, stack);307return chained.raw_id();308}309310// Current implementation separates the 'id_ptr' from the 'descr' and makes311// 'descr' constant.312// Previous implementation 'descr' is created at compile time and contains313// '----' in the beginning. When we see descr for the first time we replace314// '----' with a uniq id and set the origin to (id | (31-th bit)).315static inline void SetAllocaOrigin(void *a, uptr size, u32 *id_ptr, char *descr,316uptr pc) {317static const u32 dash = '-';318static const u32 first_timer =319dash + (dash << 8) + (dash << 16) + (dash << 24);320u32 id = *id_ptr;321if (id == 0 || id == first_timer) {322u32 idx = atomic_fetch_add(&NumStackOriginDescrs, 1, memory_order_relaxed);323CHECK_LT(idx, kNumStackOriginDescrs);324StackOriginDescr[idx] = descr;325StackOriginPC[idx] = pc;326id = Origin::CreateStackOrigin(idx).raw_id();327*id_ptr = id;328}329__msan_set_origin(a, size, id);330}331332} // namespace __msan333334void __sanitizer::BufferedStackTrace::UnwindImpl(335uptr pc, uptr bp, void *context, bool request_fast, u32 max_depth) {336using namespace __msan;337MsanThread *t = GetCurrentThread();338if (!t || !StackTrace::WillUseFastUnwind(request_fast)) {339// Block reports from our interceptors during _Unwind_Backtrace.340UnwinderScope sym_scope;341return Unwind(max_depth, pc, bp, context, t ? t->stack_top() : 0,342t ? t->stack_bottom() : 0, false);343}344if (StackTrace::WillUseFastUnwind(request_fast))345Unwind(max_depth, pc, bp, nullptr, t->stack_top(), t->stack_bottom(), true);346else347Unwind(max_depth, pc, 0, context, 0, 0, false);348}349350// Interface.351352using namespace __msan;353354#define MSAN_MAYBE_WARNING(type, size) \355void __msan_maybe_warning_##size(type s, u32 o) { \356GET_CALLER_PC_BP; \357if (UNLIKELY(s)) { \358PrintWarningWithOrigin(pc, bp, o); \359if (__msan::flags()->halt_on_error) { \360Printf("Exiting\n"); \361Die(); \362} \363} \364}365366MSAN_MAYBE_WARNING(u8, 1)367MSAN_MAYBE_WARNING(u16, 2)368MSAN_MAYBE_WARNING(u32, 4)369MSAN_MAYBE_WARNING(u64, 8)370371#define MSAN_MAYBE_STORE_ORIGIN(type, size) \372void __msan_maybe_store_origin_##size(type s, void *p, u32 o) { \373if (UNLIKELY(s)) { \374if (__msan_get_track_origins() > 1) { \375GET_CALLER_PC_BP; \376GET_STORE_STACK_TRACE_PC_BP(pc, bp); \377o = ChainOrigin(o, &stack); \378} \379*(u32 *)MEM_TO_ORIGIN((uptr)p & ~3UL) = o; \380} \381}382383MSAN_MAYBE_STORE_ORIGIN(u8, 1)384MSAN_MAYBE_STORE_ORIGIN(u16, 2)385MSAN_MAYBE_STORE_ORIGIN(u32, 4)386MSAN_MAYBE_STORE_ORIGIN(u64, 8)387388void __msan_warning() {389GET_CALLER_PC_BP;390PrintWarningWithOrigin(pc, bp, 0);391if (__msan::flags()->halt_on_error) {392if (__msan::flags()->print_stats)393ReportStats();394Printf("Exiting\n");395Die();396}397}398399void __msan_warning_noreturn() {400GET_CALLER_PC_BP;401PrintWarningWithOrigin(pc, bp, 0);402if (__msan::flags()->print_stats)403ReportStats();404Printf("Exiting\n");405Die();406}407408void __msan_warning_with_origin(u32 origin) {409GET_CALLER_PC_BP;410PrintWarningWithOrigin(pc, bp, origin);411if (__msan::flags()->halt_on_error) {412if (__msan::flags()->print_stats)413ReportStats();414Printf("Exiting\n");415Die();416}417}418419void __msan_warning_with_origin_noreturn(u32 origin) {420GET_CALLER_PC_BP;421PrintWarningWithOrigin(pc, bp, origin);422if (__msan::flags()->print_stats)423ReportStats();424Printf("Exiting\n");425Die();426}427428static void OnStackUnwind(const SignalContext &sig, const void *,429BufferedStackTrace *stack) {430stack->Unwind(StackTrace::GetNextInstructionPc(sig.pc), sig.bp, sig.context,431common_flags()->fast_unwind_on_fatal);432}433434static void MsanOnDeadlySignal(int signo, void *siginfo, void *context) {435HandleDeadlySignal(siginfo, context, GetTid(), &OnStackUnwind, nullptr);436}437438static void CheckUnwind() {439GET_FATAL_STACK_TRACE_PC_BP(StackTrace::GetCurrentPc(), GET_CURRENT_FRAME());440stack.Print();441}442443void __msan_init() {444CHECK(!msan_init_is_running);445if (msan_inited) return;446msan_init_is_running = 1;447SanitizerToolName = "MemorySanitizer";448449AvoidCVE_2016_2143();450451CacheBinaryName();452InitializeFlags();453454// Install tool-specific callbacks in sanitizer_common.455SetCheckUnwindCallback(CheckUnwind);456457__sanitizer_set_report_path(common_flags()->log_path);458459InitializeInterceptors();460InstallAtForkHandler();461CheckASLR();462InitTlsSize();463InstallDeadlySignalHandlers(MsanOnDeadlySignal);464InstallAtExitHandler(); // Needs __cxa_atexit interceptor.465466DisableCoreDumperIfNecessary();467if (StackSizeIsUnlimited()) {468VPrintf(1, "Unlimited stack, doing reexec\n");469// A reasonably large stack size. It is bigger than the usual 8Mb, because,470// well, the program could have been run with unlimited stack for a reason.471SetStackSizeLimitInBytes(32 * 1024 * 1024);472ReExec();473}474475__msan_clear_on_return();476if (__msan_get_track_origins())477VPrintf(1, "msan_track_origins\n");478if (!InitShadowWithReExec(__msan_get_track_origins())) {479Printf("FATAL: MemorySanitizer can not mmap the shadow memory.\n");480Printf("FATAL: Make sure to compile with -fPIE and to link with -pie.\n");481Printf("FATAL: Disabling ASLR is known to cause this error.\n");482Printf("FATAL: If running under GDB, try "483"'set disable-randomization off'.\n");484DumpProcessMap();485Die();486}487488Symbolizer::GetOrInit()->AddHooks(EnterSymbolizerOrUnwider,489ExitSymbolizerOrUnwider);490491InitializeCoverage(common_flags()->coverage, common_flags()->coverage_dir);492493MsanTSDInit(MsanTSDDtor);494495MsanAllocatorInit();496497MsanThread *main_thread = MsanThread::Create(nullptr, nullptr);498SetCurrentThread(main_thread);499main_thread->Init();500501#if MSAN_CONTAINS_UBSAN502__ubsan::InitAsPlugin();503#endif504505VPrintf(1, "MemorySanitizer init done\n");506507msan_init_is_running = 0;508msan_inited = 1;509}510511void __msan_set_keep_going(int keep_going) {512flags()->halt_on_error = !keep_going;513}514515void __msan_set_expect_umr(int expect_umr) {516if (expect_umr) {517msan_expected_umr_found = 0;518} else if (!msan_expected_umr_found) {519GET_CALLER_PC_BP;520GET_FATAL_STACK_TRACE_PC_BP(pc, bp);521ReportExpectedUMRNotFound(&stack);522Die();523}524msan_expect_umr = expect_umr;525}526527void __msan_print_shadow(const void *x, uptr size) {528if (!MEM_IS_APP(x)) {529Printf("Not a valid application address: %p\n", x);530return;531}532533DescribeMemoryRange(x, size);534}535536void __msan_dump_shadow(const void *x, uptr size) {537if (!MEM_IS_APP(x)) {538Printf("Not a valid application address: %p\n", x);539return;540}541542unsigned char *s = (unsigned char*)MEM_TO_SHADOW(x);543Printf("%p[%p] ", (void *)s, x);544for (uptr i = 0; i < size; i++)545Printf("%x%x ", s[i] >> 4, s[i] & 0xf);546Printf("\n");547}548549sptr __msan_test_shadow(const void *x, uptr size) {550if (!MEM_IS_APP(x)) return -1;551unsigned char *s = (unsigned char *)MEM_TO_SHADOW((uptr)x);552if (__sanitizer::mem_is_zero((const char *)s, size))553return -1;554// Slow path: loop through again to find the location.555for (uptr i = 0; i < size; ++i)556if (s[i])557return i;558return -1;559}560561void __msan_check_mem_is_initialized(const void *x, uptr size) {562if (!__msan::flags()->report_umrs) return;563sptr offset = __msan_test_shadow(x, size);564if (offset < 0)565return;566567GET_CALLER_PC_BP;568ReportUMRInsideAddressRange(__func__, x, size, offset);569__msan::PrintWarningWithOrigin(pc, bp,570__msan_get_origin(((const char *)x) + offset));571if (__msan::flags()->halt_on_error) {572Printf("Exiting\n");573Die();574}575}576577int __msan_set_poison_in_malloc(int do_poison) {578int old = flags()->poison_in_malloc;579flags()->poison_in_malloc = do_poison;580return old;581}582583int __msan_has_dynamic_component() { return false; }584585NOINLINE586void __msan_clear_on_return() {587__msan_param_tls[0] = 0;588}589590void __msan_partial_poison(const void* data, void* shadow, uptr size) {591internal_memcpy((void*)MEM_TO_SHADOW((uptr)data), shadow, size);592}593594void __msan_load_unpoisoned(const void *src, uptr size, void *dst) {595internal_memcpy(dst, src, size);596__msan_unpoison(dst, size);597}598599void __msan_set_origin(const void *a, uptr size, u32 origin) {600if (__msan_get_track_origins()) SetOrigin(a, size, origin);601}602603void __msan_set_alloca_origin(void *a, uptr size, char *descr) {604SetAllocaOrigin(a, size, reinterpret_cast<u32 *>(descr), descr + 4,605GET_CALLER_PC());606}607608void __msan_set_alloca_origin4(void *a, uptr size, char *descr, uptr pc) {609// Intentionally ignore pc and use return address. This function is here for610// compatibility, in case program is linked with library instrumented by611// older clang.612SetAllocaOrigin(a, size, reinterpret_cast<u32 *>(descr), descr + 4,613GET_CALLER_PC());614}615616void __msan_set_alloca_origin_with_descr(void *a, uptr size, u32 *id_ptr,617char *descr) {618SetAllocaOrigin(a, size, id_ptr, descr, GET_CALLER_PC());619}620621void __msan_set_alloca_origin_no_descr(void *a, uptr size, u32 *id_ptr) {622SetAllocaOrigin(a, size, id_ptr, nullptr, GET_CALLER_PC());623}624625u32 __msan_chain_origin(u32 id) {626GET_CALLER_PC_BP;627GET_STORE_STACK_TRACE_PC_BP(pc, bp);628return ChainOrigin(id, &stack);629}630631u32 __msan_get_origin(const void *a) {632if (!__msan_get_track_origins()) return 0;633uptr x = (uptr)a;634uptr aligned = x & ~3ULL;635uptr origin_ptr = MEM_TO_ORIGIN(aligned);636return *(u32*)origin_ptr;637}638639int __msan_origin_is_descendant_or_same(u32 this_id, u32 prev_id) {640Origin o = Origin::FromRawId(this_id);641while (o.raw_id() != prev_id && o.isChainedOrigin())642o = o.getNextChainedOrigin(nullptr);643return o.raw_id() == prev_id;644}645646u32 __msan_get_umr_origin() {647return __msan_origin_tls;648}649650u16 __sanitizer_unaligned_load16(const uu16 *p) {651internal_memcpy(&__msan_retval_tls[0], (void *)MEM_TO_SHADOW((uptr)p),652sizeof(uu16));653if (__msan_get_track_origins())654__msan_retval_origin_tls = GetOriginIfPoisoned((uptr)p, sizeof(*p));655return *p;656}657u32 __sanitizer_unaligned_load32(const uu32 *p) {658internal_memcpy(&__msan_retval_tls[0], (void *)MEM_TO_SHADOW((uptr)p),659sizeof(uu32));660if (__msan_get_track_origins())661__msan_retval_origin_tls = GetOriginIfPoisoned((uptr)p, sizeof(*p));662return *p;663}664u64 __sanitizer_unaligned_load64(const uu64 *p) {665internal_memcpy(&__msan_retval_tls[0], (void *)MEM_TO_SHADOW((uptr)p),666sizeof(uu64));667if (__msan_get_track_origins())668__msan_retval_origin_tls = GetOriginIfPoisoned((uptr)p, sizeof(*p));669return *p;670}671void __sanitizer_unaligned_store16(uu16 *p, u16 x) {672static_assert(sizeof(uu16) == sizeof(u16), "incompatible types");673u16 s;674internal_memcpy(&s, &__msan_param_tls[1], sizeof(uu16));675internal_memcpy((void *)MEM_TO_SHADOW((uptr)p), &s, sizeof(uu16));676if (s && __msan_get_track_origins())677if (uu32 o = __msan_param_origin_tls[2])678SetOriginIfPoisoned((uptr)p, (uptr)&s, sizeof(s), o);679*p = x;680}681void __sanitizer_unaligned_store32(uu32 *p, u32 x) {682static_assert(sizeof(uu32) == sizeof(u32), "incompatible types");683u32 s;684internal_memcpy(&s, &__msan_param_tls[1], sizeof(uu32));685internal_memcpy((void *)MEM_TO_SHADOW((uptr)p), &s, sizeof(uu32));686if (s && __msan_get_track_origins())687if (uu32 o = __msan_param_origin_tls[2])688SetOriginIfPoisoned((uptr)p, (uptr)&s, sizeof(s), o);689*p = x;690}691void __sanitizer_unaligned_store64(uu64 *p, u64 x) {692u64 s = __msan_param_tls[1];693*(uu64 *)MEM_TO_SHADOW((uptr)p) = s;694if (s && __msan_get_track_origins())695if (uu32 o = __msan_param_origin_tls[2])696SetOriginIfPoisoned((uptr)p, (uptr)&s, sizeof(s), o);697*p = x;698}699700void __msan_set_death_callback(void (*callback)(void)) {701SetUserDieCallback(callback);702}703704void __msan_start_switch_fiber(const void *bottom, uptr size) {705MsanThread *t = GetCurrentThread();706if (!t) {707VReport(1, "__msan_start_switch_fiber called from unknown thread\n");708return;709}710t->StartSwitchFiber((uptr)bottom, size);711}712713void __msan_finish_switch_fiber(const void **bottom_old, uptr *size_old) {714MsanThread *t = GetCurrentThread();715if (!t) {716VReport(1, "__msan_finish_switch_fiber called from unknown thread\n");717return;718}719t->FinishSwitchFiber((uptr *)bottom_old, (uptr *)size_old);720721internal_memset(__msan_param_tls, 0, sizeof(__msan_param_tls));722internal_memset(__msan_retval_tls, 0, sizeof(__msan_retval_tls));723internal_memset(__msan_va_arg_tls, 0, sizeof(__msan_va_arg_tls));724725if (__msan_get_track_origins()) {726internal_memset(__msan_param_origin_tls, 0,727sizeof(__msan_param_origin_tls));728internal_memset(&__msan_retval_origin_tls, 0,729sizeof(__msan_retval_origin_tls));730internal_memset(__msan_va_arg_origin_tls, 0,731sizeof(__msan_va_arg_origin_tls));732}733}734735SANITIZER_INTERFACE_WEAK_DEF(const char *, __msan_default_options, void) {736return "";737}738739extern "C" {740SANITIZER_INTERFACE_ATTRIBUTE741void __sanitizer_print_stack_trace() {742GET_FATAL_STACK_TRACE_PC_BP(StackTrace::GetCurrentPc(), GET_CURRENT_FRAME());743stack.Print();744}745} // extern "C"746747748