diff --git a/compiler-rt/lib/asan/asan_emscripten.cpp b/compiler-rt/lib/asan/asan_emscripten.cpp index 90b3c5bbae8ee..59457db3a8252 100644 --- a/compiler-rt/lib/asan/asan_emscripten.cpp +++ b/compiler-rt/lib/asan/asan_emscripten.cpp @@ -109,8 +109,6 @@ void GetAllocatorCacheRange(uptr *begin, uptr *end) { } #endif -u32 GetCurrentThread() { return __asan::GetCurrentThread()->tid(); } - } // namespace __lsan #endif // SANITIZER_EMSCRIPTEN diff --git a/compiler-rt/lib/asan/asan_interceptors.cpp b/compiler-rt/lib/asan/asan_interceptors.cpp index 12f5fe918d95c..bd87c64d78e96 100644 --- a/compiler-rt/lib/asan/asan_interceptors.cpp +++ b/compiler-rt/lib/asan/asan_interceptors.cpp @@ -286,9 +286,9 @@ INTERCEPTOR(int, pthread_detach, void *thread) { return result; } -INTERCEPTOR(int, pthread_exit, void *retval) { +INTERCEPTOR(void, pthread_exit, void *retval) { asanThreadArgRetval().Finish(GetThreadSelf(), retval); - return REAL(pthread_exit)(retval); + REAL(pthread_exit)(retval); } # if ASAN_INTERCEPT_TRYJOIN diff --git a/compiler-rt/lib/asan/asan_rtl.cpp b/compiler-rt/lib/asan/asan_rtl.cpp index d77b27bc336e3..fb9dab47eb6b3 100644 --- a/compiler-rt/lib/asan/asan_rtl.cpp +++ b/compiler-rt/lib/asan/asan_rtl.cpp @@ -447,7 +447,9 @@ static void AsanInitInternal() { ReplaceSystemMalloc(); +#if !SANITIZER_EMSCRIPTEN DisableCoreDumperIfNecessary(); +#endif InitializeShadowMemory(); diff --git a/compiler-rt/lib/lsan/lsan_common.cpp b/compiler-rt/lib/lsan/lsan_common.cpp index 22259e30288fc..d3dfec5ede1b5 100644 --- a/compiler-rt/lib/lsan/lsan_common.cpp +++ b/compiler-rt/lib/lsan/lsan_common.cpp @@ -595,17 +595,17 @@ void ScanRootRegions(Frontier *frontier, static void ProcessRootRegions(Frontier *frontier) { if (!flags()->use_root_regions || !HasRootRegions()) return; + InternalMmapVector mapped_regions; #if SANITIZER_EMSCRIPTEN - ScanRootRegion(frontier, root_region, 0, emscripten_get_heap_size(), true); + mapped_regions.push_back({0, emscripten_get_heap_size()}); #else MemoryMappingLayout proc_maps(/*cache_enabled*/ true); MemoryMappedSegment segment; - InternalMmapVector mapped_regions; while (proc_maps.Next(&segment)) if (segment.IsReadable()) mapped_regions.push_back({segment.start, segment.end}); - ScanRootRegions(frontier, mapped_regions); #endif // SANITIZER_EMSCRIPTEN + ScanRootRegions(frontier, mapped_regions); } static void FloodFillTag(Frontier *frontier, ChunkTag tag) { diff --git a/compiler-rt/lib/lsan/lsan_common_emscripten.cpp b/compiler-rt/lib/lsan/lsan_common_emscripten.cpp index f2b1301577238..46bfedb9b519b 100644 --- a/compiler-rt/lib/lsan/lsan_common_emscripten.cpp +++ b/compiler-rt/lib/lsan/lsan_common_emscripten.cpp @@ -105,15 +105,13 @@ void LockStuffAndStopTheWorld(StopTheWorldCallback callback, CheckForLeaksParam *argument) { // Currently, on Emscripten this does nothing and just calls the callback. // This works fine on a single-threaded environment. - LockThreadRegistry(); + LockThreads(); LockAllocator(); StopTheWorld(callback, argument); UnlockAllocator(); - UnlockThreadRegistry(); + UnlockThreads(); } -u32 GetCurrentThread(); - // This is based on ProcessThreads in lsan_common.cc. // We changed this to be a callback that gets called per thread by // ThreadRegistry::RunCallbackForEachThreadLocked. @@ -142,7 +140,7 @@ static void ProcessThreadsCallback(ThreadContextBase *tctx, void *arg) { // We can't get the SP for other threads to narrow down the range, but we // we can for the current thread. - if (tctx->tid == GetCurrentThread()) { + if (tctx->os_id == GetTid()) { uptr sp = (uptr) __builtin_frame_address(0); if (sp < stack_begin || sp >= stack_end) { // SP is outside the recorded stack range (e.g. the thread is running a diff --git a/compiler-rt/lib/lsan/lsan_interceptors.cpp b/compiler-rt/lib/lsan/lsan_interceptors.cpp index 10494cee230eb..c4c6088d3663b 100644 --- a/compiler-rt/lib/lsan/lsan_interceptors.cpp +++ b/compiler-rt/lib/lsan/lsan_interceptors.cpp @@ -40,6 +40,7 @@ int emscripten_builtin_pthread_create(void *thread, void *attr, void *(*callback)(void *), void *arg); int emscripten_builtin_pthread_join(void *th, void **ret); int emscripten_builtin_pthread_detach(void *th); +void emscripten_builtin_pthread_exit(void *th); } #endif @@ -452,13 +453,21 @@ INTERCEPTOR(int, pthread_create, void *th, void *attr, ENSURE_LSAN_INITED; EnsureMainThreadIDIsCorrect(); +#if SANITIZER_EMSCRIPTEN + // In Emscripten sanitizer, attr can be nonzero but __ATTRP_C11_THREAD in case + // of C11 threads, in which case we need to run pthread_attr_init as well, so + // we treat __ATTRP_C11_THREAD like the nullptr in this function. + if (attr == __ATTRP_C11_THREAD) + attr = nullptr; +#endif + bool detached = [attr]() { int d = 0; return attr && !pthread_attr_getdetachstate(attr, &d) && IsStateDetached(d); }(); __sanitizer_pthread_attr_t myattr; - if (!attr || attr == __ATTRP_C11_THREAD) { + if (!attr) { pthread_attr_init(&myattr); attr = &myattr; } @@ -501,9 +510,9 @@ INTERCEPTOR(int, pthread_detach, void *thread) { return result; } -INTERCEPTOR(int, pthread_exit, void *retval) { +INTERCEPTOR(void, pthread_exit, void *retval) { GetThreadArgRetval().Finish(GetThreadSelf(), retval); - return REAL(pthread_exit)(retval); + REAL(pthread_exit)(retval); } # if SANITIZER_INTERCEPT_TRYJOIN diff --git a/compiler-rt/lib/lsan/lsan_thread.cpp b/compiler-rt/lib/lsan/lsan_thread.cpp index f27e36f2e9ca4..41fc7da7c7ebe 100644 --- a/compiler-rt/lib/lsan/lsan_thread.cpp +++ b/compiler-rt/lib/lsan/lsan_thread.cpp @@ -45,7 +45,10 @@ void InitializeThreads() { thread_arg_retval = new (thread_arg_retval_placeholder) ThreadArgRetval(); } -ThreadArgRetval &GetThreadArgRetval() { return *thread_arg_retval; } +ThreadArgRetval &GetThreadArgRetval() { + ENSURE_LSAN_INITED; + return *thread_arg_retval; +} ThreadContextLsanBase::ThreadContextLsanBase(int tid) : ThreadContextBase(tid) {} diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h index 08d1a685208be..9b3d95ef592c3 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h @@ -445,8 +445,7 @@ struct __sanitizer_file_handle { }; #endif -// These fields are not actually pointers, and so wasm64 must use unsigned and not uptr for them -#if SANITIZER_APPLE || SANITIZER_EMSCRIPTEN +#if SANITIZER_APPLE struct __sanitizer_msghdr { void *msg_name; unsigned msg_namelen; diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_posix.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_posix.cpp index 8159bc0b92c10..ae8f8fe07c588 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_posix.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_posix.cpp @@ -159,7 +159,11 @@ bool MprotectReadOnly(uptr addr, uptr size) { } bool MprotectReadWrite(uptr addr, uptr size) { +#if SANITIZER_EMSCRIPTEN + return true; +#else return 0 == internal_mprotect((void *)addr, size, PROT_READ | PROT_WRITE); +#endif } #if !SANITIZER_APPLE diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_posix_libcdep.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_posix_libcdep.cpp index 2c34bcbc8bf0e..b780f57279b7d 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_posix_libcdep.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_posix_libcdep.cpp @@ -83,6 +83,7 @@ bool DontDumpShadowMemory(uptr addr, uptr length) { #endif // MADV_DONTDUMP } +#if !SANITIZER_EMSCRIPTEN static rlim_t getlim(int res) { rlimit rlim; CHECK_EQ(0, getrlimit(res, &rlim)); @@ -127,6 +128,7 @@ void SetAddressSpaceUnlimited() { setlim(RLIMIT_AS, RLIM_INFINITY); CHECK(AddressSpaceIsUnlimited()); } +#endif void Abort() { #if !SANITIZER_GO diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_redefine_builtins.h b/compiler-rt/lib/sanitizer_common/sanitizer_redefine_builtins.h index 6649ff5844f5c..9e4c2028dc430 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_redefine_builtins.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_redefine_builtins.h @@ -15,7 +15,8 @@ #define SANITIZER_REDEFINE_BUILTINS_H // The asm hack only works with GCC and Clang. -#if !defined(_WIN32) +// XXX Emscripten This does not work in Wasm. +#if !defined(_WIN32) && !defined(__wasm__) asm("memcpy = __sanitizer_internal_memcpy"); asm("memmove = __sanitizer_internal_memmove"); @@ -46,7 +47,7 @@ using unordered_set = Define_SANITIZER_COMMON_NO_REDEFINE_BUILTINS_in_cpp_file; using vector = Define_SANITIZER_COMMON_NO_REDEFINE_BUILTINS_in_cpp_file; } // namespace std -#endif // !_WIN32 +#endif // !_WIN32 && !__wasm__ #endif // SANITIZER_REDEFINE_BUILTINS_H #endif // SANITIZER_COMMON_NO_REDEFINE_BUILTINS diff --git a/libcxx/include/__locale b/libcxx/include/__locale index 5c060ab04c768..20c515287ea26 100644 --- a/libcxx/include/__locale +++ b/libcxx/include/__locale @@ -406,12 +406,12 @@ public: static const mask __regex_word = 0x4000; // 0x8000 and 0x0100 and 0x00ff are used # define _LIBCPP_CTYPE_MASK_IS_COMPOSITE_PRINT # define _LIBCPP_CTYPE_MASK_IS_COMPOSITE_ALPHA -#elif defined(__APPLE__) || defined(__FreeBSD__) || defined(__EMSCRIPTEN__) || defined(__NetBSD__) +#elif defined(__APPLE__) || defined(__FreeBSD__) || defined(__NetBSD__) # ifdef __APPLE__ typedef __uint32_t mask; # elif defined(__FreeBSD__) typedef unsigned long mask; -# elif defined(__EMSCRIPTEN__) || defined(__NetBSD__) +# elif defined(__NetBSD__) typedef unsigned short mask; # endif static const mask space = _CTYPE_S; diff --git a/libcxx/src/new.cpp b/libcxx/src/new.cpp index 7653e937f9394..9e51dae446e68 100644 --- a/libcxx/src/new.cpp +++ b/libcxx/src/new.cpp @@ -53,7 +53,7 @@ operator new(std::size_t size) _THROW_BAD_ALLOC return p; } -#if defined(__EMSCRIPTEN__) && defined(_LIBCPP_NO_EXCEPTIONS) +#if defined(__EMSCRIPTEN__) && defined(_LIBCPP_HAS_NO_EXCEPTIONS) void* _new_nothrow(size_t size) noexcept { /// We cannot call ::operator new(size) here because it would abort @@ -78,7 +78,7 @@ _LIBCPP_WEAK void* operator new(size_t size, const std::nothrow_t&) noexcept { -#if defined(__EMSCRIPTEN__) && defined(_LIBCPP_NO_EXCEPTIONS) +#if defined(__EMSCRIPTEN__) && defined(_LIBCPP_HAS_NO_EXCEPTIONS) return _new_nothrow(size); #else void* p = nullptr; @@ -94,7 +94,7 @@ operator new(size_t size, const std::nothrow_t&) noexcept } #endif // _LIBCPP_HAS_NO_EXCEPTIONS return p; -#endif // __EMSCRIPTEN__ && _LIBCPP_NO_EXCEPTIONS +#endif // __EMSCRIPTEN__ && _LIBCPP_HAS_NO_EXCEPTIONS } _LIBCPP_WEAK @@ -108,7 +108,7 @@ _LIBCPP_WEAK void* operator new[](size_t size, const std::nothrow_t&) noexcept { -#if defined(__EMSCRIPTEN__) && defined(_LIBCPP_NO_EXCEPTIONS) +#if defined(__EMSCRIPTEN__) && defined(_LIBCPP_HAS_NO_EXCEPTIONS) return _new_nothrow(size); #else void* p = nullptr; @@ -124,7 +124,7 @@ operator new[](size_t size, const std::nothrow_t&) noexcept } #endif // _LIBCPP_HAS_NO_EXCEPTIONS return p; -#endif // __EMSCRIPTEN__ && _LIBCPP_NO_EXCEPTIONS +#endif // __EMSCRIPTEN__ && _LIBCPP_HAS_NO_EXCEPTIONS } _LIBCPP_WEAK