Index: msan/msan.h =================================================================== --- msan/msan.h +++ msan/msan.h @@ -26,6 +26,10 @@ # define MSAN_REPLACE_OPERATORS_NEW_AND_DELETE 1 #endif +#if SANITIZER_ANDROID +#define MSAN_CONTAINS_UBSAN 0 +#endif // SANITIZER_ANDROID + #ifndef MSAN_CONTAINS_UBSAN # define MSAN_CONTAINS_UBSAN CAN_SANITIZE_UB #endif @@ -212,9 +216,6 @@ #define MEM_IS_SHADOW(mem) addr_is_type((uptr)(mem), MappingDesc::SHADOW) #define MEM_IS_ORIGIN(mem) addr_is_type((uptr)(mem), MappingDesc::ORIGIN) -// These constants must be kept in sync with the ones in MemorySanitizer.cc. -const int kMsanParamTlsSize = 800; -const int kMsanRetvalTlsSize = 800; namespace __msan { extern int msan_inited; Index: msan/msan.cc =================================================================== --- msan/msan.cc +++ msan/msan.cc @@ -33,38 +33,6 @@ using namespace __sanitizer; -// Globals. -static THREADLOCAL int msan_expect_umr = 0; -static THREADLOCAL int msan_expected_umr_found = 0; - -// Function argument shadow. Each argument starts at the next available 8-byte -// aligned address. -SANITIZER_INTERFACE_ATTRIBUTE -THREADLOCAL u64 __msan_param_tls[kMsanParamTlsSize / sizeof(u64)]; - -// Function argument origin. Each argument starts at the same offset as the -// corresponding shadow in (__msan_param_tls). Slightly weird, but changing this -// would break compatibility with older prebuilt binaries. -SANITIZER_INTERFACE_ATTRIBUTE -THREADLOCAL u32 __msan_param_origin_tls[kMsanParamTlsSize / sizeof(u32)]; - -SANITIZER_INTERFACE_ATTRIBUTE -THREADLOCAL u64 __msan_retval_tls[kMsanRetvalTlsSize / sizeof(u64)]; - -SANITIZER_INTERFACE_ATTRIBUTE -THREADLOCAL u32 __msan_retval_origin_tls; - -SANITIZER_INTERFACE_ATTRIBUTE -ALIGNED(16) THREADLOCAL u64 __msan_va_arg_tls[kMsanParamTlsSize / sizeof(u64)]; - -SANITIZER_INTERFACE_ATTRIBUTE -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() { @@ -75,9 +43,9 @@ namespace __msan { -void EnterSymbolizer() { ++is_in_symbolizer; } -void ExitSymbolizer() { --is_in_symbolizer; } -bool IsInSymbolizer() { return is_in_symbolizer; } +void EnterSymbolizer() { ++(*get_is_in_symbolizer()); } +void ExitSymbolizer() { --(*get_is_in_symbolizer()); } +bool IsInSymbolizer() { return *get_is_in_symbolizer(); } static Flags msan_flags; @@ -230,14 +198,14 @@ } void PrintWarning(uptr pc, uptr bp) { - PrintWarningWithOrigin(pc, bp, __msan_origin_tls); + PrintWarningWithOrigin(pc, bp, *msan_origin_tls()); } void PrintWarningWithOrigin(uptr pc, uptr bp, u32 origin) { - if (msan_expect_umr) { + if (*get_msan_expect_umr()) { // Printf("Expected UMR\n"); - __msan_origin_tls = origin; - msan_expected_umr_found = 1; + *msan_origin_tls() = origin; + *get_msan_expected_umr_found() = 1; return; } @@ -258,7 +226,7 @@ } void UnpoisonParam(uptr n) { - internal_memset(__msan_param_tls, 0, n * sizeof(*__msan_param_tls)); + internal_memset(*msan_param_tls(), 0, n * sizeof(**msan_param_tls())); } // Backup MSan runtime TLS state. @@ -266,22 +234,22 @@ // Instances of this class may live on the signal handler stack, and data size // may be an issue. void ScopedThreadLocalStateBackup::Backup() { - va_arg_overflow_size_tls = __msan_va_arg_overflow_size_tls; + va_arg_overflow_size_tls = *msan_va_arg_overflow_size_tls(); } void ScopedThreadLocalStateBackup::Restore() { // A lame implementation that only keeps essential state and resets the rest. - __msan_va_arg_overflow_size_tls = va_arg_overflow_size_tls; + *msan_va_arg_overflow_size_tls() = va_arg_overflow_size_tls; - internal_memset(__msan_param_tls, 0, sizeof(__msan_param_tls)); - internal_memset(__msan_retval_tls, 0, sizeof(__msan_retval_tls)); - internal_memset(__msan_va_arg_tls, 0, sizeof(__msan_va_arg_tls)); + internal_memset(*msan_param_tls(), 0, sizeof(*msan_param_tls())); + internal_memset(*msan_retval_tls(), 0, sizeof(*msan_retval_tls())); + internal_memset(*msan_va_arg_tls(), 0, sizeof(*msan_va_arg_tls())); if (__msan_get_track_origins()) { - internal_memset(&__msan_retval_origin_tls, 0, - sizeof(__msan_retval_origin_tls)); - internal_memset(__msan_param_origin_tls, 0, - sizeof(__msan_param_origin_tls)); + internal_memset(msan_retval_origin_tls(), 0, + sizeof(*msan_retval_origin_tls())); + internal_memset(*msan_param_origin_tls(), 0, + sizeof(*msan_param_origin_tls())); } } @@ -426,6 +394,8 @@ VPrintf(1, "MemorySanitizer init done\n"); + AndroidLogInit(); + msan_init_is_running = 0; msan_inited = 1; } @@ -436,15 +406,15 @@ void __msan_set_expect_umr(int expect_umr) { if (expect_umr) { - msan_expected_umr_found = 0; - } else if (!msan_expected_umr_found) { + *get_msan_expected_umr_found() = 0; + } else if (!*get_msan_expected_umr_found()) { GET_CALLER_PC_BP_SP; (void)sp; GET_FATAL_STACK_TRACE_PC_BP(pc, bp); ReportExpectedUMRNotFound(&stack); Die(); } - msan_expect_umr = expect_umr; + *get_msan_expect_umr() = expect_umr; } void __msan_print_shadow(const void *x, uptr size) { @@ -504,7 +474,7 @@ NOINLINE void __msan_clear_on_return() { - __msan_param_tls[0] = 0; + (*msan_param_tls())[0] = 0; } void __msan_partial_poison(const void* data, void* shadow, uptr size) { @@ -579,48 +549,48 @@ } u32 __msan_get_umr_origin() { - return __msan_origin_tls; + return *msan_origin_tls(); } u16 __sanitizer_unaligned_load16(const uu16 *p) { - *(uu16 *)&__msan_retval_tls[0] = *(uu16 *)MEM_TO_SHADOW((uptr)p); + *(uu16 *)&(*msan_retval_tls())[0] = *(uu16 *)MEM_TO_SHADOW((uptr)p); if (__msan_get_track_origins()) - __msan_retval_origin_tls = GetOriginIfPoisoned((uptr)p, sizeof(*p)); + *msan_retval_origin_tls() = GetOriginIfPoisoned((uptr)p, sizeof(*p)); return *p; } u32 __sanitizer_unaligned_load32(const uu32 *p) { - *(uu32 *)&__msan_retval_tls[0] = *(uu32 *)MEM_TO_SHADOW((uptr)p); + *(uu32 *)&(*msan_retval_tls())[0] = *(uu32 *)MEM_TO_SHADOW((uptr)p); if (__msan_get_track_origins()) - __msan_retval_origin_tls = GetOriginIfPoisoned((uptr)p, sizeof(*p)); + *msan_retval_origin_tls() = GetOriginIfPoisoned((uptr)p, sizeof(*p)); return *p; } u64 __sanitizer_unaligned_load64(const uu64 *p) { - __msan_retval_tls[0] = *(uu64 *)MEM_TO_SHADOW((uptr)p); + (*msan_retval_tls())[0] = *(uu64 *)MEM_TO_SHADOW((uptr)p); if (__msan_get_track_origins()) - __msan_retval_origin_tls = GetOriginIfPoisoned((uptr)p, sizeof(*p)); + *msan_retval_origin_tls() = GetOriginIfPoisoned((uptr)p, sizeof(*p)); return *p; } void __sanitizer_unaligned_store16(uu16 *p, u16 x) { - u16 s = *(uu16 *)&__msan_param_tls[1]; + u16 s = *(uu16 *)&(*msan_param_tls())[1]; *(uu16 *)MEM_TO_SHADOW((uptr)p) = s; if (s && __msan_get_track_origins()) - if (uu32 o = __msan_param_origin_tls[2]) + if (uu32 o = (*msan_param_origin_tls())[2]) SetOriginIfPoisoned((uptr)p, (uptr)&s, sizeof(s), o); *p = x; } void __sanitizer_unaligned_store32(uu32 *p, u32 x) { - u32 s = *(uu32 *)&__msan_param_tls[1]; + u32 s = *(uu32 *)&(*msan_param_tls())[1]; *(uu32 *)MEM_TO_SHADOW((uptr)p) = s; if (s && __msan_get_track_origins()) - if (uu32 o = __msan_param_origin_tls[2]) + if (uu32 o = (*msan_param_origin_tls())[2]) SetOriginIfPoisoned((uptr)p, (uptr)&s, sizeof(s), o); *p = x; } void __sanitizer_unaligned_store64(uu64 *p, u64 x) { - u64 s = __msan_param_tls[1]; + u64 s = (*msan_param_tls())[1]; *(uu64 *)MEM_TO_SHADOW((uptr)p) = s; if (s && __msan_get_track_origins()) - if (uu32 o = __msan_param_origin_tls[2]) + if (uu32 o = (*msan_param_origin_tls())[2]) SetOriginIfPoisoned((uptr)p, (uptr)&s, sizeof(s), o); *p = x; } Index: msan/msan_flags.inc =================================================================== --- msan/msan_flags.inc +++ msan/msan_flags.inc @@ -29,7 +29,11 @@ MSAN_FLAG(bool, report_umrs, true, "") MSAN_FLAG(bool, wrap_signals, true, "") MSAN_FLAG(bool, print_stats, false, "") +#if SANITIZER_ANDROID +MSAN_FLAG(bool, halt_on_error, false, "") +#else MSAN_FLAG(bool, halt_on_error, !&__msan_keep_going, "") +#endif // SANITIZER_ANDROID MSAN_FLAG(bool, atexit, false, "") MSAN_FLAG(int, store_context_size, 20, "Like malloc_context_size, but for uninit stores.") Index: msan/msan_interceptors.cc =================================================================== --- msan/msan_interceptors.cc +++ msan/msan_interceptors.cc @@ -16,10 +16,10 @@ //===----------------------------------------------------------------------===// #include "interception/interception.h" +#include "msan_thread.h" #include "msan.h" #include "msan_chained_origin_depot.h" #include "msan_origin.h" -#include "msan_thread.h" #include "msan_poisoning.h" #include "sanitizer_common/sanitizer_platform_limits_posix.h" #include "sanitizer_common/sanitizer_allocator.h" @@ -50,18 +50,27 @@ #define __errno_location __error #endif -// True if this is a nested interceptor. -static THREADLOCAL int in_interceptor_scope; - +#if SANITIZER_ANDROID +// From bionic/libc/include/errno.h: +// "internal function returning the address of the thread-specific errno" +extern "C" volatile int* __errno(void); +#define __errno_location (int*)__errno +#else extern "C" int *__errno_location(void); +#endif // SANITIZER_ANDROID struct InterceptorScope { - InterceptorScope() { ++in_interceptor_scope; } - ~InterceptorScope() { --in_interceptor_scope; } + InterceptorScope() { + ++(*get_in_interceptor_scope()); + } + + ~InterceptorScope() { + --(*get_in_interceptor_scope()); + } }; bool IsInInterceptorScope() { - return in_interceptor_scope; + return *get_in_interceptor_scope(); } #define ENSURE_MSAN_INITED() do { \ @@ -1188,6 +1197,7 @@ DECLARE_REAL(int, shmctl, int shmid, int cmd, void *buf) +#if !SANITIZER_ANDROID INTERCEPTOR(void *, shmat, int shmid, const void *shmaddr, int shmflg) { ENSURE_MSAN_INITED(); void *p = REAL(shmat)(shmid, shmaddr, shmflg); @@ -1200,6 +1210,10 @@ } return p; } +#define MSAN_MAYBE_INTERCEPT_SHMAT INTERCEPT_FUNCTION(shmat) +#else +#define MSAN_MAYBE_INTERCEPT_SHMAT +#endif // !SANITIZER_ANDROID static void BeforeFork() { StackDepotLockAll(); @@ -1346,13 +1360,16 @@ #define COMMON_SYSCALL_POST_WRITE_RANGE(p, s) __msan_unpoison(p, s) #include "sanitizer_common/sanitizer_common_syscalls.inc" +#if !SANITIZER_ANDROID struct dlinfo { char *dli_fname; void *dli_fbase; char *dli_sname; void *dli_saddr; }; +#endif // !SANITIZER_ANDROID +#if !SANITIZER_ANDROID INTERCEPTOR(int, dladdr, void *addr, dlinfo *info) { void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, dladdr, addr, info); @@ -1366,7 +1383,12 @@ } return res; } +#define MSAN_MAYBE_INTERCEPT_DLADDR INTERCEPT_FUNCTION(dladdr) +#else +#define MSAN_MAYBE_INTERCEPT_DLADDR +#endif // !SANITIZER_ANDROID +#if !SANITIZER_ANDROID INTERCEPTOR(char *, dlerror, int fake) { void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, dlerror, fake); @@ -1374,7 +1396,12 @@ if (res) __msan_unpoison(res, REAL(strlen)(res) + 1); return res; } +#define MSAN_MAYBE_INTERCEPT_DLERROR INTERCEPT_FUNCTION(dlerror) +#else +#define MSAN_MAYBE_INTERCEPT_DLERROR +#endif // !SANITIZER_ANDROID +#if !SANITIZER_ANDROID typedef int (*dl_iterate_phdr_cb)(__sanitizer_dl_phdr_info *info, SIZE_T size, void *data); struct dl_iterate_phdr_data { @@ -1395,7 +1422,9 @@ UnpoisonParam(3); return cbdata->callback(info, size, cbdata->data); } +#endif // !SANITIZER_ANDROID +#if !SANITIZER_ANDROID INTERCEPTOR(int, dl_iterate_phdr, dl_iterate_phdr_cb callback, void *data) { void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, dl_iterate_phdr, callback, data); @@ -1405,6 +1434,10 @@ int res = REAL(dl_iterate_phdr)(msan_dl_iterate_phdr_cb, (void *)&cbdata); return res; } +#define MSAN_MAYBE_INTERCEPT_DL_ITERATE_PHDR INTERCEPT_FUNCTION(dl_iterate_phdr) +#else +#define MSAN_MAYBE_INTERCEPT_DL_ITERATE_PHDR +#endif // !SANITIZER_ANDROID // These interface functions reside here so that they can use // REAL(memset), etc. @@ -1566,9 +1599,9 @@ INTERCEPT_FUNCTION(gethostname); MSAN_MAYBE_INTERCEPT_EPOLL_WAIT; MSAN_MAYBE_INTERCEPT_EPOLL_PWAIT; - INTERCEPT_FUNCTION(dladdr); - INTERCEPT_FUNCTION(dlerror); - INTERCEPT_FUNCTION(dl_iterate_phdr); + MSAN_MAYBE_INTERCEPT_DLADDR; + MSAN_MAYBE_INTERCEPT_DLERROR; + MSAN_MAYBE_INTERCEPT_DL_ITERATE_PHDR; INTERCEPT_FUNCTION(getrusage); INTERCEPT_FUNCTION(sigaction); INTERCEPT_FUNCTION(signal); @@ -1581,7 +1614,7 @@ INTERCEPT_FUNCTION(pthread_join); INTERCEPT_FUNCTION(tzset); INTERCEPT_FUNCTION(__cxa_atexit); - INTERCEPT_FUNCTION(shmat); + MSAN_MAYBE_INTERCEPT_SHMAT; INTERCEPT_FUNCTION(fork); INTERCEPT_FUNCTION(openpty); INTERCEPT_FUNCTION(forkpty); Index: msan/msan_linux.cc =================================================================== --- msan/msan_linux.cc +++ msan/msan_linux.cc @@ -26,7 +26,12 @@ #include #include #include +#include + +#if !SANITIZER_ANDROID #include +#endif // !SANITIZER_ANDROID + #include #include @@ -173,38 +178,55 @@ // ---------------------- TSD ---------------- {{{1 -static pthread_key_t tsd_key; static bool tsd_key_inited = false; void MsanTSDInit(void (*destructor)(void *tsd)) { CHECK(!tsd_key_inited); tsd_key_inited = true; - CHECK_EQ(0, pthread_key_create(&tsd_key, destructor)); } -static THREADLOCAL MsanThread* msan_current_thread; - MsanThread *GetCurrentThread() { - return msan_current_thread; +#if SANITIZER_ANDROID + // These assume 64-bit Linux (ILP64). + // If any of these assertions break (perhaps because k{MsanParam/RetvalTls}Size + // change), we must also update MemorySanitizer.cpp. + static_assert (offsetof(MsanTLSSlot, __msan_param_tls) == 0, + "__msan_param_tls offset"); + static_assert (offsetof(MsanTLSSlot, __msan_param_origin_tls) == 800, + "__msan_param_origin_tls offset"); + static_assert (offsetof(MsanTLSSlot, __msan_retval_tls) == 1600, + "__msan_retval_tls offset"); + static_assert (offsetof(MsanTLSSlot, __msan_retval_origin_tls) == 2424, + "u32 __msan_retval_origin_tls offset"); + static_assert (offsetof(MsanTLSSlot, __msan_origin_tls) == 2428, + "u32 __msan_origin_tls offset"); + static_assert (offsetof(MsanTLSSlot, __msan_va_arg_overflow_size_tls) == 2432, + "u64 __msan_va_arg_overflow_tls offset"); + static_assert (offsetof(MsanTLSSlot, __msan_va_arg_tls) == 2448, + "ALIGNED(16) u64 __msan_va_arg_tls offset"); + + static_assert (sizeof(MsanTLSSlot) == 3248, + "sizeof(MsanTLSSlot)"); +#endif + + return *get_msan_current_thread(); } void SetCurrentThread(MsanThread *t) { // Make sure we do not reset the current MsanThread. - CHECK_EQ(0, msan_current_thread); - msan_current_thread = t; + CHECK_EQ(0, *get_msan_current_thread()); + *get_msan_current_thread() = t; // Make sure that MsanTSDDtor gets called at the end. CHECK(tsd_key_inited); - pthread_setspecific(tsd_key, (void *)t); } void MsanTSDDtor(void *tsd) { MsanThread *t = (MsanThread*)tsd; if (t->destructor_iterations_ > 1) { t->destructor_iterations_--; - CHECK_EQ(0, pthread_setspecific(tsd_key, tsd)); return; } - msan_current_thread = nullptr; + *get_msan_current_thread() = nullptr; // Make sure that signal handler can not see a stale current thread pointer. atomic_signal_fence(memory_order_seq_cst); MsanThread::TSDDtor(tsd); Index: msan/msan_thread.h =================================================================== --- msan/msan_thread.h +++ msan/msan_thread.h @@ -17,6 +17,12 @@ #include "msan_allocator.h" #include "sanitizer_common/sanitizer_common.h" +#if SANITIZER_ANDROID +#define TLSVAR(x) GetMsanTLS()->x +#else +#define TLSVAR(x) x +#endif + namespace __msan { class MsanThread { @@ -66,6 +72,49 @@ MsanThread *GetCurrentThread(); void SetCurrentThread(MsanThread *t); +// These constants must be kept in sync with the ones in MemorySanitizer.cc. +const int kMsanParamTlsSize = 800; +const int kMsanRetvalTlsSize = 800; + +struct MsanTLSSlot { + u64 __msan_param_tls[kMsanParamTlsSize / sizeof(u64)]; + + u32 __msan_param_origin_tls[kMsanParamTlsSize / sizeof(u32)]; + + u64 __msan_retval_tls[kMsanRetvalTlsSize / sizeof(u64)]; + + __msan::MsanThread* msan_current_thread; + + int in_interceptor_scope; + int is_in_symbolizer; + + int msan_expect_umr; + int msan_expected_umr_found; + + u32 __msan_retval_origin_tls; + + u32 __msan_origin_tls; + + u64 __msan_va_arg_overflow_size_tls; + + ALIGNED(16) u64 __msan_va_arg_tls[kMsanParamTlsSize / sizeof(u64)]; +}; + +MsanTLSSlot* GetMsanTLS(void); + +u64 (*msan_param_tls())[kMsanParamTlsSize / sizeof(u64)]; +u32 (*msan_param_origin_tls())[kMsanParamTlsSize / sizeof(u32)]; +u64 (*msan_retval_tls())[kMsanRetvalTlsSize / sizeof(u64)]; +u32 *msan_retval_origin_tls(); +u32 *msan_origin_tls(); +u64 *msan_va_arg_overflow_size_tls(); +u64 (*msan_va_arg_tls())[kMsanParamTlsSize / sizeof(u64)]; + +__msan::MsanThread** get_msan_current_thread(); +int *get_in_interceptor_scope(); +int *get_is_in_symbolizer(); +int *get_msan_expect_umr(); +int *get_msan_expected_umr_found(); } // namespace __msan #endif // MSAN_THREAD_H Index: msan/msan_thread.cc =================================================================== --- msan/msan_thread.cc +++ msan/msan_thread.cc @@ -4,6 +4,39 @@ #include "msan_interface_internal.h" #include "sanitizer_common/sanitizer_tls_get_addr.h" +#include "sanitizer_common/sanitizer_linux.h" + +#if !SANITIZER_ANDROID +static THREADLOCAL int msan_expect_umr = 0; +static THREADLOCAL int msan_expected_umr_found = 0; + +SANITIZER_INTERFACE_ATTRIBUTE +THREADLOCAL u64 __msan_param_tls[__msan::kMsanParamTlsSize / sizeof(u64)]; + +SANITIZER_INTERFACE_ATTRIBUTE +THREADLOCAL u32 __msan_param_origin_tls[__msan::kMsanParamTlsSize / sizeof(u32)]; + +SANITIZER_INTERFACE_ATTRIBUTE +THREADLOCAL u64 __msan_retval_tls[__msan::kMsanRetvalTlsSize / sizeof(u64)]; + +SANITIZER_INTERFACE_ATTRIBUTE +THREADLOCAL u32 __msan_retval_origin_tls; + +SANITIZER_INTERFACE_ATTRIBUTE +ALIGNED(16) THREADLOCAL u64 __msan_va_arg_tls[__msan::kMsanParamTlsSize / sizeof(u64)]; + +SANITIZER_INTERFACE_ATTRIBUTE +THREADLOCAL u64 __msan_va_arg_overflow_size_tls; + +SANITIZER_INTERFACE_ATTRIBUTE +THREADLOCAL u32 __msan_origin_tls; + +static THREADLOCAL int is_in_symbolizer; + +static THREADLOCAL int in_interceptor_scope; + +static THREADLOCAL __msan::MsanThread* msan_current_thread; +#endif // !SANITIZER_ANDROID namespace __msan { @@ -35,10 +68,12 @@ __msan_unpoison((void *)stack_bottom_, stack_top_ - stack_bottom_); if (tls_begin_ != tls_end_) __msan_unpoison((void *)tls_begin_, tls_end_ - tls_begin_); +#if !SANITIZER_ANDROID DTLS *dtls = DTLS_Get(); CHECK_NE(dtls, 0); for (uptr i = 0; i < dtls->dtv_size; ++i) __msan_unpoison((void *)(dtls->dtv[i].beg), dtls->dtv[i].size); +#endif // !SANITIZER_ANDROID } void MsanThread::Init() { @@ -79,4 +114,39 @@ return res; } +#if SANITIZER_ANDROID +// Based on tsan_platform_linux.cc::cur_thread +MsanTLSSlot* GetMsanTLS(void) { + MsanTLSSlot* tls = (MsanTLSSlot*)(*AndroidGetTls()); + if (tls == nullptr) { + __sanitizer_sigset_t emptyset; + internal_sigfillset(&emptyset); + __sanitizer_sigset_t oldset; + CHECK_EQ(0, internal_sigprocmask(sig_setmask, &emptyset, &oldset)); + tls = reinterpret_cast(*AndroidGetTls()); + if (tls == nullptr) { + tls = reinterpret_cast(MmapOrDie(sizeof(MsanTLSSlot), + "MsanTLSSlot")); + *(AndroidGetTls()) = tls; + } + CHECK_EQ(0, internal_sigprocmask(sig_setmask, &oldset, nullptr)); + } + return tls; +} +#endif // SANITIZER_ANDROID + +u64 (*msan_param_tls())[kMsanParamTlsSize / sizeof(u64)] { return &TLSVAR(__msan_param_tls); } +u32 (*msan_param_origin_tls())[kMsanParamTlsSize / sizeof(u32)] { return &TLSVAR(__msan_param_origin_tls); } +u64 (*msan_retval_tls())[kMsanRetvalTlsSize / sizeof(u64)] { return &TLSVAR(__msan_retval_tls); } +u32 *msan_retval_origin_tls() { return &TLSVAR(__msan_retval_origin_tls); } +u32 *msan_origin_tls() { return &TLSVAR(__msan_origin_tls); } +u64 *msan_va_arg_overflow_size_tls() { return &TLSVAR(__msan_va_arg_overflow_size_tls); } +u64 (*msan_va_arg_tls())[kMsanParamTlsSize / sizeof(u64)] { return &TLSVAR(__msan_va_arg_tls); } + +__msan::MsanThread** get_msan_current_thread() { return &TLSVAR(msan_current_thread); } +int *get_in_interceptor_scope() { return &TLSVAR(in_interceptor_scope); } +int *get_is_in_symbolizer() { return &TLSVAR(is_in_symbolizer); } +int *get_msan_expect_umr() { return &TLSVAR(msan_expect_umr); } +int *get_msan_expected_umr_found() { return &TLSVAR(msan_expected_umr_found); } + } // namespace __msan Index: sanitizer_common/sanitizer_common.h =================================================================== --- sanitizer_common/sanitizer_common.h +++ sanitizer_common/sanitizer_common.h @@ -834,4 +834,22 @@ uptr allocated; }; +#if SANITIZER_ANDROID +// Voodoo from tsan +#if defined(__aarch64__) +# define __get_tls() ({ void** __val; __asm__("mrs %0, tpidr_el0" : "=r"(__val)); __val; }) +#elif defined(__x86_64__) +# define __get_tls() ({ void** __val; __asm__("mov %%fs:0, %0" : "=r"(__val)); __val; }) +#endif + +static const int TLS_SLOT_TSAN = 8; + +#if defined(__aarch64__) || defined(__x86_64__) +INLINE void **AndroidGetTls() { return &__get_tls()[TLS_SLOT_TSAN];} +#else +INLINE void **AndroidGetTls() { return nullptr;} +#endif + +#endif // SANITIZER_ANDROID + #endif // SANITIZER_COMMON_H Index: sanitizer_common/sanitizer_platform_limits_posix.h =================================================================== --- sanitizer_common/sanitizer_platform_limits_posix.h +++ sanitizer_common/sanitizer_platform_limits_posix.h @@ -53,9 +53,10 @@ #if !SANITIZER_ANDROID extern unsigned struct_statfs_sz; extern unsigned struct_sockaddr_sz; - extern unsigned ucontext_t_sz; #endif // !SANITIZER_ANDROID + extern unsigned ucontext_t_sz; + #if SANITIZER_LINUX #if defined(__x86_64__) @@ -174,13 +175,16 @@ }; #endif +#if SANITIZER_LINUX + extern unsigned struct_rlimit64_sz; +#endif + #if SANITIZER_LINUX && !SANITIZER_ANDROID struct __sanitizer_mallinfo { int v[10]; }; extern unsigned struct_ustat_sz; - extern unsigned struct_rlimit64_sz; extern unsigned struct_statvfs64_sz; struct __sanitizer_ipc_perm { Index: sanitizer_common/sanitizer_platform_limits_posix.cc =================================================================== --- sanitizer_common/sanitizer_platform_limits_posix.cc +++ sanitizer_common/sanitizer_platform_limits_posix.cc @@ -232,9 +232,10 @@ #if !SANITIZER_ANDROID unsigned struct_statfs_sz = sizeof(struct statfs); unsigned struct_sockaddr_sz = sizeof(struct sockaddr); - unsigned ucontext_t_sz = sizeof(ucontext_t); #endif // !SANITIZER_ANDROID +unsigned ucontext_t_sz = sizeof(ucontext_t); + #if SANITIZER_LINUX unsigned struct_epoll_event_sz = sizeof(struct epoll_event); unsigned struct_sysinfo_sz = sizeof(struct sysinfo); @@ -255,10 +256,13 @@ #if SANITIZER_LINUX && !SANITIZER_ANDROID unsigned struct_ustat_sz = sizeof(struct ustat); - unsigned struct_rlimit64_sz = sizeof(struct rlimit64); unsigned struct_statvfs64_sz = sizeof(struct statvfs64); #endif // SANITIZER_LINUX && !SANITIZER_ANDROID +#if SANITIZER_LINUX + unsigned struct_rlimit64_sz = sizeof(struct rlimit64); +#endif // SANITIZER_LINUX + #if (SANITIZER_LINUX || SANITIZER_FREEBSD) && !SANITIZER_ANDROID unsigned struct_timex_sz = sizeof(struct timex); unsigned struct_msqid_ds_sz = sizeof(struct msqid_ds);