diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2022-07-04 19:20:19 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2023-02-08 19:02:26 +0000 |
commit | 81ad626541db97eb356e2c1d4a20eb2a26a766ab (patch) | |
tree | 311b6a8987c32b1e1dcbab65c54cfac3fdb56175 /contrib/llvm-project/compiler-rt/lib | |
parent | 5fff09660e06a66bed6482da9c70df328e16bbb6 (diff) | |
parent | 145449b1e420787bb99721a429341fa6be3adfb6 (diff) | |
download | src-81ad626541db97eb356e2c1d4a20eb2a26a766ab.tar.gz src-81ad626541db97eb356e2c1d4a20eb2a26a766ab.zip |
Merge llvm-project main llvmorg-15-init-15358-g53dc0f10787
This updates llvm, clang, compiler-rt, libc++, libunwind, lld, lldb and
openmp to llvmorg-15-init-15358-g53dc0f10787.
PR: 265425
MFC after: 2 weeks
Diffstat (limited to 'contrib/llvm-project/compiler-rt/lib')
232 files changed, 3172 insertions, 1894 deletions
diff --git a/contrib/llvm-project/compiler-rt/lib/asan/asan_allocator.cpp b/contrib/llvm-project/compiler-rt/lib/asan/asan_allocator.cpp index f9f1cfcd9f87..7b7a289c2d25 100644 --- a/contrib/llvm-project/compiler-rt/lib/asan/asan_allocator.cpp +++ b/contrib/llvm-project/compiler-rt/lib/asan/asan_allocator.cpp @@ -597,7 +597,7 @@ struct Allocator { CHECK_LE(alloc_beg + sizeof(LargeChunkHeader), chunk_beg); reinterpret_cast<LargeChunkHeader *>(alloc_beg)->Set(m); } - ASAN_MALLOC_HOOK(res, size); + RunMallocHooks(res, size); return res; } @@ -678,7 +678,7 @@ struct Allocator { return; } - ASAN_FREE_HOOK(ptr); + RunFreeHooks(ptr); // Must mark the chunk as quarantined before any changes to its metadata. // Do not quarantine given chunk if we failed to set CHUNK_QUARANTINE flag. @@ -1217,16 +1217,3 @@ int __asan_update_allocation_context(void* addr) { GET_STACK_TRACE_MALLOC; return instance.UpdateAllocationStack((uptr)addr, &stack); } - -#if !SANITIZER_SUPPORTS_WEAK_HOOKS -// Provide default (no-op) implementation of malloc hooks. -SANITIZER_INTERFACE_WEAK_DEF(void, __sanitizer_malloc_hook, - void *ptr, uptr size) { - (void)ptr; - (void)size; -} - -SANITIZER_INTERFACE_WEAK_DEF(void, __sanitizer_free_hook, void *ptr) { - (void)ptr; -} -#endif diff --git a/contrib/llvm-project/compiler-rt/lib/asan/asan_errors.cpp b/contrib/llvm-project/compiler-rt/lib/asan/asan_errors.cpp index a22bf130d823..10f7c17991d7 100644 --- a/contrib/llvm-project/compiler-rt/lib/asan/asan_errors.cpp +++ b/contrib/llvm-project/compiler-rt/lib/asan/asan_errors.cpp @@ -279,9 +279,7 @@ void ErrorRssLimitExceeded::Print() { void ErrorOutOfMemory::Print() { Decorator d; Printf("%s", d.Error()); - Report( - "ERROR: AddressSanitizer: allocator is out of memory trying to allocate " - "0x%zx bytes\n", requested_size); + ERROR_OOM("allocator is trying to allocate 0x%zx bytes\n", requested_size); Printf("%s", d.Default()); stack->Print(); PrintHintAllocatorCannotReturnNull(); diff --git a/contrib/llvm-project/compiler-rt/lib/asan/asan_errors.h b/contrib/llvm-project/compiler-rt/lib/asan/asan_errors.h index af6d1f295eb2..c6ac88f6dc2a 100644 --- a/contrib/llvm-project/compiler-rt/lib/asan/asan_errors.h +++ b/contrib/llvm-project/compiler-rt/lib/asan/asan_errors.h @@ -372,7 +372,7 @@ struct ErrorGeneric : ErrorBase { u8 shadow_val; ErrorGeneric() = default; // (*) - ErrorGeneric(u32 tid, uptr addr, uptr pc_, uptr bp_, uptr sp_, bool is_write_, + ErrorGeneric(u32 tid, uptr pc_, uptr bp_, uptr sp_, uptr addr, bool is_write_, uptr access_size_); void Print(); }; diff --git a/contrib/llvm-project/compiler-rt/lib/asan/asan_fake_stack.cpp b/contrib/llvm-project/compiler-rt/lib/asan/asan_fake_stack.cpp index 08d81c72597c..74a039b65798 100644 --- a/contrib/llvm-project/compiler-rt/lib/asan/asan_fake_stack.cpp +++ b/contrib/llvm-project/compiler-rt/lib/asan/asan_fake_stack.cpp @@ -140,7 +140,6 @@ void FakeStack::HandleNoReturn() { // We do it based on their 'real_stack' values -- everything that is lower // than the current real_stack is garbage. NOINLINE void FakeStack::GC(uptr real_stack) { - uptr collected = 0; for (uptr class_id = 0; class_id < kNumberOfSizeClasses; class_id++) { u8 *flags = GetFlags(stack_size_log(), class_id); for (uptr i = 0, n = NumberOfFrames(stack_size_log(), class_id); i < n; @@ -150,7 +149,6 @@ NOINLINE void FakeStack::GC(uptr real_stack) { GetFrame(stack_size_log(), class_id, i)); if (ff->real_stack < real_stack) { flags[i] = 0; - collected++; } } } diff --git a/contrib/llvm-project/compiler-rt/lib/asan/asan_flags.cpp b/contrib/llvm-project/compiler-rt/lib/asan/asan_flags.cpp index 9ea899f84b4b..239898433232 100644 --- a/contrib/llvm-project/compiler-rt/lib/asan/asan_flags.cpp +++ b/contrib/llvm-project/compiler-rt/lib/asan/asan_flags.cpp @@ -87,7 +87,7 @@ void InitializeFlags() { RegisterCommonFlags(&ubsan_parser); #endif - if (SANITIZER_MAC) { + if (SANITIZER_APPLE) { // Support macOS MallocScribble and MallocPreScribble: // <https://developer.apple.com/library/content/documentation/Performance/ // Conceptual/ManagingMemory/Articles/MallocDebug.html> diff --git a/contrib/llvm-project/compiler-rt/lib/asan/asan_flags.inc b/contrib/llvm-project/compiler-rt/lib/asan/asan_flags.inc index 514b225c4073..fad1577d912a 100644 --- a/contrib/llvm-project/compiler-rt/lib/asan/asan_flags.inc +++ b/contrib/llvm-project/compiler-rt/lib/asan/asan_flags.inc @@ -49,9 +49,10 @@ ASAN_FLAG( "to find more errors.") ASAN_FLAG(bool, replace_intrin, true, "If set, uses custom wrappers for memset/memcpy/memmove intrinsics.") -ASAN_FLAG(bool, detect_stack_use_after_return, false, +ASAN_FLAG(bool, detect_stack_use_after_return, + SANITIZER_LINUX && !SANITIZER_ANDROID, "Enables stack-use-after-return checking at run-time.") -ASAN_FLAG(int, min_uar_stack_size_log, 16, // We can't do smaller anyway. +ASAN_FLAG(int, min_uar_stack_size_log, 16, // We can't do smaller anyway. "Minimum fake stack size log.") ASAN_FLAG(int, max_uar_stack_size_log, 20, // 1Mb per size class, i.e. ~11Mb per thread @@ -82,6 +83,10 @@ ASAN_FLAG( int, sleep_after_init, 0, "Number of seconds to sleep after AddressSanitizer is initialized. " "Useful for debugging purposes (e.g. when one needs to attach gdb).") +ASAN_FLAG( + int, sleep_before_init, 0, + "Number of seconds to sleep before AddressSanitizer starts initializing. " + "Useful for debugging purposes (e.g. when one needs to attach gdb).") ASAN_FLAG(bool, check_malloc_usable_size, true, "Allows the users to work around the bug in Nvidia drivers prior to " "295.*.") @@ -117,7 +122,7 @@ ASAN_FLAG(bool, poison_array_cookie, true, // https://github.com/google/sanitizers/issues/309 // TODO(glider,timurrrr): Fix known issues and enable this back. ASAN_FLAG(bool, alloc_dealloc_mismatch, - !SANITIZER_MAC && !SANITIZER_WINDOWS && !SANITIZER_ANDROID, + !SANITIZER_APPLE && !SANITIZER_WINDOWS && !SANITIZER_ANDROID, "Report errors on malloc/delete, new/free, new/delete[], etc.") ASAN_FLAG(bool, new_delete_type_mismatch, true, diff --git a/contrib/llvm-project/compiler-rt/lib/asan/asan_fuchsia.cpp b/contrib/llvm-project/compiler-rt/lib/asan/asan_fuchsia.cpp index 15381d5bd0e5..2b15504123be 100644 --- a/contrib/llvm-project/compiler-rt/lib/asan/asan_fuchsia.cpp +++ b/contrib/llvm-project/compiler-rt/lib/asan/asan_fuchsia.cpp @@ -14,16 +14,17 @@ #include "sanitizer_common/sanitizer_fuchsia.h" #if SANITIZER_FUCHSIA -#include "asan_interceptors.h" -#include "asan_internal.h" -#include "asan_stack.h" -#include "asan_thread.h" - #include <limits.h> #include <zircon/sanitizer.h> #include <zircon/syscalls.h> #include <zircon/threads.h> +# include "asan_interceptors.h" +# include "asan_internal.h" +# include "asan_stack.h" +# include "asan_thread.h" +# include "lsan/lsan_common.h" + namespace __asan { // The system already set up the shadow memory for us. @@ -235,8 +236,18 @@ void FlushUnneededASanShadowMemory(uptr p, uptr size) { __sanitizer_fill_shadow(p, size, 0, 0); } +// On Fuchsia, leak detection is done by a special hook after atexit hooks. +// So this doesn't install any atexit hook like on other platforms. +void InstallAtExitCheckLeaks() {} + } // namespace __asan +namespace __lsan { + +bool UseExitcodeOnLeak() { return __asan::flags()->halt_on_error; } + +} // namespace __lsan + // These are declared (in extern "C") by <zircon/sanitizer.h>. // The system runtime will call our definitions directly. diff --git a/contrib/llvm-project/compiler-rt/lib/asan/asan_globals.cpp b/contrib/llvm-project/compiler-rt/lib/asan/asan_globals.cpp index ecc2600f039a..5206d685e6e8 100644 --- a/contrib/llvm-project/compiler-rt/lib/asan/asan_globals.cpp +++ b/contrib/llvm-project/compiler-rt/lib/asan/asan_globals.cpp @@ -86,10 +86,11 @@ static void ReportGlobal(const Global &g, const char *prefix) { "odr_indicator=%p\n", prefix, (void *)&g, (void *)g.beg, g.size, g.size_with_redzone, g.name, g.module_name, g.has_dynamic_init, (void *)g.odr_indicator); - if (g.location) { - Report(" location (%p): name=%s[%p], %d %d\n", (void *)g.location, - g.location->filename, (void *)g.location->filename, - g.location->line_no, g.location->column_no); + + DataInfo info; + Symbolizer::GetOrInit()->SymbolizeData(g.beg, &info); + if (info.line != 0) { + Report(" location: name=%s, %lu\n", info.file, info.line); } } @@ -295,19 +296,15 @@ void PrintGlobalNameIfASCII(InternalScopedString *str, const __asan_global &g) { (char *)g.beg); } -static const char *GlobalFilename(const __asan_global &g) { - const char *res = g.module_name; - // Prefer the filename from source location, if is available. - if (g.location) res = g.location->filename; - CHECK(res); - return res; -} - void PrintGlobalLocation(InternalScopedString *str, const __asan_global &g) { - str->append("%s", GlobalFilename(g)); - if (!g.location) return; - if (g.location->line_no) str->append(":%d", g.location->line_no); - if (g.location->column_no) str->append(":%d", g.location->column_no); + DataInfo info; + Symbolizer::GetOrInit()->SymbolizeData(g.beg, &info); + + if (info.line != 0) { + str->append("%s:%lu", info.file, info.line); + } else { + str->append("%s", g.module_name); + } } } // namespace __asan diff --git a/contrib/llvm-project/compiler-rt/lib/asan/asan_interceptors.cpp b/contrib/llvm-project/compiler-rt/lib/asan/asan_interceptors.cpp index 2ff314a5a9cb..37d0fc67cf75 100644 --- a/contrib/llvm-project/compiler-rt/lib/asan/asan_interceptors.cpp +++ b/contrib/llvm-project/compiler-rt/lib/asan/asan_interceptors.cpp @@ -103,7 +103,7 @@ DECLARE_REAL_AND_INTERCEPTOR(void, free, void *) do { \ if (asan_init_is_running) \ return REAL(func)(__VA_ARGS__); \ - if (SANITIZER_MAC && UNLIKELY(!asan_inited)) \ + if (SANITIZER_APPLE && UNLIKELY(!asan_inited)) \ return REAL(func)(__VA_ARGS__); \ ENSURE_ASAN_INITED(); \ } while (false) @@ -355,7 +355,7 @@ INTERCEPTOR(_Unwind_Reason_Code, _Unwind_SjLj_RaiseException, INTERCEPTOR(char*, index, const char *string, int c) ALIAS(WRAPPER_NAME(strchr)); # else -# if SANITIZER_MAC +# if SANITIZER_APPLE DECLARE_REAL(char*, index, const char *string, int c) OVERRIDE_FUNCTION(index, strchr); # else @@ -409,7 +409,7 @@ INTERCEPTOR(char*, strncat, char *to, const char *from, uptr size) { INTERCEPTOR(char *, strcpy, char *to, const char *from) { void *ctx; ASAN_INTERCEPTOR_ENTER(ctx, strcpy); -#if SANITIZER_MAC +#if SANITIZER_APPLE if (UNLIKELY(!asan_inited)) return REAL(strcpy)(to, from); #endif @@ -489,7 +489,7 @@ INTERCEPTOR(long, strtol, const char *nptr, char **endptr, int base) { INTERCEPTOR(int, atoi, const char *nptr) { void *ctx; ASAN_INTERCEPTOR_ENTER(ctx, atoi); -#if SANITIZER_MAC +#if SANITIZER_APPLE if (UNLIKELY(!asan_inited)) return REAL(atoi)(nptr); #endif ENSURE_ASAN_INITED(); @@ -510,7 +510,7 @@ INTERCEPTOR(int, atoi, const char *nptr) { INTERCEPTOR(long, atol, const char *nptr) { void *ctx; ASAN_INTERCEPTOR_ENTER(ctx, atol); -#if SANITIZER_MAC +#if SANITIZER_APPLE if (UNLIKELY(!asan_inited)) return REAL(atol)(nptr); #endif ENSURE_ASAN_INITED(); @@ -563,7 +563,7 @@ static void AtCxaAtexit(void *unused) { #if ASAN_INTERCEPT___CXA_ATEXIT INTERCEPTOR(int, __cxa_atexit, void (*func)(void *), void *arg, void *dso_handle) { -#if SANITIZER_MAC +#if SANITIZER_APPLE if (UNLIKELY(!asan_inited)) return REAL(__cxa_atexit)(func, arg, dso_handle); #endif ENSURE_ASAN_INITED(); diff --git a/contrib/llvm-project/compiler-rt/lib/asan/asan_interceptors.h b/contrib/llvm-project/compiler-rt/lib/asan/asan_interceptors.h index 047b044c8bf4..35727a96497d 100644 --- a/contrib/llvm-project/compiler-rt/lib/asan/asan_interceptors.h +++ b/contrib/llvm-project/compiler-rt/lib/asan/asan_interceptors.h @@ -133,7 +133,7 @@ DECLARE_REAL(char*, strncpy, char *to, const char *from, uptr size) DECLARE_REAL(uptr, strnlen, const char *s, uptr maxlen) DECLARE_REAL(char*, strstr, const char *s1, const char *s2) -# if !SANITIZER_MAC +# if !SANITIZER_APPLE # define ASAN_INTERCEPT_FUNC(name) \ do { \ if (!INTERCEPT_FUNCTION(name)) \ @@ -156,7 +156,7 @@ DECLARE_REAL(char*, strstr, const char *s1, const char *s2) # else // OS X interceptors don't need to be initialized with INTERCEPT_FUNCTION. # define ASAN_INTERCEPT_FUNC(name) -# endif // SANITIZER_MAC +# endif // SANITIZER_APPLE #endif // !SANITIZER_FUCHSIA diff --git a/contrib/llvm-project/compiler-rt/lib/asan/asan_interface_internal.h b/contrib/llvm-project/compiler-rt/lib/asan/asan_interface_internal.h index 3e6e66028874..b0802a89ddbd 100644 --- a/contrib/llvm-project/compiler-rt/lib/asan/asan_interface_internal.h +++ b/contrib/llvm-project/compiler-rt/lib/asan/asan_interface_internal.h @@ -53,8 +53,9 @@ extern "C" { const char *module_name; // Module name as a C string. This pointer is a // unique identifier of a module. uptr has_dynamic_init; // Non-zero if the global has dynamic initializer. - __asan_global_source_location *location; // Source location of a global, - // or NULL if it is unknown. + uptr windows_padding; // TODO: Figure out how to remove this padding + // that's simply here to make the MSVC incremental + // linker happy... uptr odr_indicator; // The address of the ODR indicator symbol. }; diff --git a/contrib/llvm-project/compiler-rt/lib/asan/asan_internal.h b/contrib/llvm-project/compiler-rt/lib/asan/asan_internal.h index ad3320304d0d..7468f126d37b 100644 --- a/contrib/llvm-project/compiler-rt/lib/asan/asan_internal.h +++ b/contrib/llvm-project/compiler-rt/lib/asan/asan_internal.h @@ -17,19 +17,19 @@ #include "asan_interface_internal.h" #include "sanitizer_common/sanitizer_common.h" #include "sanitizer_common/sanitizer_internal_defs.h" -#include "sanitizer_common/sanitizer_stacktrace.h" #include "sanitizer_common/sanitizer_libc.h" +#include "sanitizer_common/sanitizer_stacktrace.h" #if __has_feature(address_sanitizer) || defined(__SANITIZE_ADDRESS__) -# error "The AddressSanitizer run-time should not be" - " instrumented by AddressSanitizer" +# error \ + "The AddressSanitizer run-time should not be instrumented by AddressSanitizer" #endif // Build-time configuration options. // If set, asan will intercept C++ exception api call(s). #ifndef ASAN_HAS_EXCEPTIONS -# define ASAN_HAS_EXCEPTIONS 1 +# define ASAN_HAS_EXCEPTIONS 1 #endif // If set, values like allocator chunk size, as well as defaults for some flags @@ -43,11 +43,11 @@ #endif #ifndef ASAN_DYNAMIC -# ifdef PIC -# define ASAN_DYNAMIC 1 -# else -# define ASAN_DYNAMIC 0 -# endif +# ifdef PIC +# define ASAN_DYNAMIC 1 +# else +# define ASAN_DYNAMIC 0 +# endif #endif // All internal functions in asan reside inside the __asan namespace @@ -123,26 +123,18 @@ void *AsanDlSymNext(const char *sym); // `dlopen()` specific initialization inside this function. bool HandleDlopenInit(); -// Add convenient macro for interface functions that may be represented as -// weak hooks. -#define ASAN_MALLOC_HOOK(ptr, size) \ - do { \ - if (&__sanitizer_malloc_hook) __sanitizer_malloc_hook(ptr, size); \ - RunMallocHooks(ptr, size); \ - } while (false) -#define ASAN_FREE_HOOK(ptr) \ - do { \ - if (&__sanitizer_free_hook) __sanitizer_free_hook(ptr); \ - RunFreeHooks(ptr); \ - } while (false) +void InstallAtExitCheckLeaks(); + #define ASAN_ON_ERROR() \ - if (&__asan_on_error) __asan_on_error() + if (&__asan_on_error) \ + __asan_on_error() extern int asan_inited; // Used to avoid infinite recursion in __asan_init(). extern bool asan_init_is_running; extern void (*death_callback)(void); -// These magic values are written to shadow for better error reporting. +// These magic values are written to shadow for better error +// reporting. const int kAsanHeapLeftRedzoneMagic = 0xfa; const int kAsanHeapFreeMagic = 0xfd; const int kAsanStackLeftRedzoneMagic = 0xf1; diff --git a/contrib/llvm-project/compiler-rt/lib/asan/asan_mac.cpp b/contrib/llvm-project/compiler-rt/lib/asan/asan_mac.cpp index 9161f728d44c..4f4ce92cc6a1 100644 --- a/contrib/llvm-project/compiler-rt/lib/asan/asan_mac.cpp +++ b/contrib/llvm-project/compiler-rt/lib/asan/asan_mac.cpp @@ -12,7 +12,7 @@ //===----------------------------------------------------------------------===// #include "sanitizer_common/sanitizer_platform.h" -#if SANITIZER_MAC +#if SANITIZER_APPLE #include "asan_interceptors.h" #include "asan_internal.h" @@ -296,4 +296,4 @@ INTERCEPTOR(void, dispatch_source_set_event_handler, } #endif -#endif // SANITIZER_MAC +#endif // SANITIZER_APPLE diff --git a/contrib/llvm-project/compiler-rt/lib/asan/asan_malloc_mac.cpp b/contrib/llvm-project/compiler-rt/lib/asan/asan_malloc_mac.cpp index e8484685daed..924d1f12640a 100644 --- a/contrib/llvm-project/compiler-rt/lib/asan/asan_malloc_mac.cpp +++ b/contrib/llvm-project/compiler-rt/lib/asan/asan_malloc_mac.cpp @@ -12,7 +12,7 @@ //===----------------------------------------------------------------------===// #include "sanitizer_common/sanitizer_platform.h" -#if SANITIZER_MAC +#if SANITIZER_APPLE #include "asan_interceptors.h" #include "asan_report.h" diff --git a/contrib/llvm-project/compiler-rt/lib/asan/asan_mapping.h b/contrib/llvm-project/compiler-rt/lib/asan/asan_mapping.h index 4ff09b103d5f..cc5f5836e742 100644 --- a/contrib/llvm-project/compiler-rt/lib/asan/asan_mapping.h +++ b/contrib/llvm-project/compiler-rt/lib/asan/asan_mapping.h @@ -174,8 +174,10 @@ #else # if SANITIZER_IOS # define ASAN_SHADOW_OFFSET_DYNAMIC -# elif SANITIZER_MAC && defined(__aarch64__) +# elif SANITIZER_APPLE && defined(__aarch64__) # define ASAN_SHADOW_OFFSET_DYNAMIC +# elif SANITIZER_FREEBSD && defined(__aarch64__) +# define ASAN_SHADOW_OFFSET_CONST 0x0000800000000000 # elif SANITIZER_RISCV64 # define ASAN_SHADOW_OFFSET_CONST 0x0000000d55550000 # elif defined(__aarch64__) @@ -188,7 +190,7 @@ # define ASAN_SHADOW_OFFSET_CONST 0x0000400000000000 # elif SANITIZER_NETBSD # define ASAN_SHADOW_OFFSET_CONST 0x0000400000000000 -# elif SANITIZER_MAC +# elif SANITIZER_APPLE # define ASAN_SHADOW_OFFSET_CONST 0x0000100000000000 # elif defined(__mips64) # define ASAN_SHADOW_OFFSET_CONST 0x0000002000000000 diff --git a/contrib/llvm-project/compiler-rt/lib/asan/asan_new_delete.cpp b/contrib/llvm-project/compiler-rt/lib/asan/asan_new_delete.cpp index da446072de18..17280129c758 100644 --- a/contrib/llvm-project/compiler-rt/lib/asan/asan_new_delete.cpp +++ b/contrib/llvm-project/compiler-rt/lib/asan/asan_new_delete.cpp @@ -89,7 +89,7 @@ enum class align_val_t: size_t {}; // delete. // To make sure that C++ allocation/deallocation operators are overridden on // OS X we need to intercept them using their mangled names. -#if !SANITIZER_MAC +#if !SANITIZER_APPLE CXX_OPERATOR_ATTRIBUTE void *operator new(size_t size) { OPERATOR_NEW_BODY(FROM_NEW, false /*nothrow*/); } @@ -115,7 +115,7 @@ CXX_OPERATOR_ATTRIBUTE void *operator new[](size_t size, std::align_val_t align, std::nothrow_t const&) { OPERATOR_NEW_BODY_ALIGN(FROM_NEW_BR, true /*nothrow*/); } -#else // SANITIZER_MAC +#else // SANITIZER_APPLE INTERCEPTOR(void *, _Znwm, size_t size) { OPERATOR_NEW_BODY(FROM_NEW, false /*nothrow*/); } @@ -128,7 +128,7 @@ INTERCEPTOR(void *, _ZnwmRKSt9nothrow_t, size_t size, std::nothrow_t const&) { INTERCEPTOR(void *, _ZnamRKSt9nothrow_t, size_t size, std::nothrow_t const&) { OPERATOR_NEW_BODY(FROM_NEW_BR, true /*nothrow*/); } -#endif // !SANITIZER_MAC +#endif // !SANITIZER_APPLE #define OPERATOR_DELETE_BODY(type) \ GET_STACK_TRACE_FREE; \ @@ -146,7 +146,7 @@ INTERCEPTOR(void *, _ZnamRKSt9nothrow_t, size_t size, std::nothrow_t const&) { GET_STACK_TRACE_FREE; \ asan_delete(ptr, size, static_cast<uptr>(align), &stack, type); -#if !SANITIZER_MAC +#if !SANITIZER_APPLE CXX_OPERATOR_ATTRIBUTE void operator delete(void *ptr) NOEXCEPT { OPERATOR_DELETE_BODY(FROM_NEW); } @@ -184,7 +184,7 @@ CXX_OPERATOR_ATTRIBUTE void operator delete[](void *ptr, size_t size, std::align_val_t align) NOEXCEPT { OPERATOR_DELETE_BODY_SIZE_ALIGN(FROM_NEW_BR); } -#else // SANITIZER_MAC +#else // SANITIZER_APPLE INTERCEPTOR(void, _ZdlPv, void *ptr) { OPERATOR_DELETE_BODY(FROM_NEW); } INTERCEPTOR(void, _ZdaPv, void *ptr) @@ -193,4 +193,4 @@ INTERCEPTOR(void, _ZdlPvRKSt9nothrow_t, void *ptr, std::nothrow_t const&) { OPERATOR_DELETE_BODY(FROM_NEW); } INTERCEPTOR(void, _ZdaPvRKSt9nothrow_t, void *ptr, std::nothrow_t const&) { OPERATOR_DELETE_BODY(FROM_NEW_BR); } -#endif // !SANITIZER_MAC +#endif // !SANITIZER_APPLE diff --git a/contrib/llvm-project/compiler-rt/lib/asan/asan_poisoning.cpp b/contrib/llvm-project/compiler-rt/lib/asan/asan_poisoning.cpp index bbc7db4709e1..3b7c9d1312d6 100644 --- a/contrib/llvm-project/compiler-rt/lib/asan/asan_poisoning.cpp +++ b/contrib/llvm-project/compiler-rt/lib/asan/asan_poisoning.cpp @@ -12,11 +12,13 @@ //===----------------------------------------------------------------------===// #include "asan_poisoning.h" + #include "asan_report.h" #include "asan_stack.h" #include "sanitizer_common/sanitizer_atomic.h" -#include "sanitizer_common/sanitizer_libc.h" #include "sanitizer_common/sanitizer_flags.h" +#include "sanitizer_common/sanitizer_interface_internal.h" +#include "sanitizer_common/sanitizer_libc.h" namespace __asan { diff --git a/contrib/llvm-project/compiler-rt/lib/asan/asan_posix.cpp b/contrib/llvm-project/compiler-rt/lib/asan/asan_posix.cpp index 63ad735f8bba..765f4a26cd7a 100644 --- a/contrib/llvm-project/compiler-rt/lib/asan/asan_posix.cpp +++ b/contrib/llvm-project/compiler-rt/lib/asan/asan_posix.cpp @@ -14,22 +14,23 @@ #include "sanitizer_common/sanitizer_platform.h" #if SANITIZER_POSIX -#include "asan_internal.h" -#include "asan_interceptors.h" -#include "asan_mapping.h" -#include "asan_poisoning.h" -#include "asan_report.h" -#include "asan_stack.h" -#include "sanitizer_common/sanitizer_libc.h" -#include "sanitizer_common/sanitizer_posix.h" -#include "sanitizer_common/sanitizer_procmaps.h" - -#include <pthread.h> -#include <signal.h> -#include <stdlib.h> -#include <sys/time.h> -#include <sys/resource.h> -#include <unistd.h> +# include <pthread.h> +# include <signal.h> +# include <stdlib.h> +# include <sys/resource.h> +# include <sys/time.h> +# include <unistd.h> + +# include "asan_interceptors.h" +# include "asan_internal.h" +# include "asan_mapping.h" +# include "asan_poisoning.h" +# include "asan_report.h" +# include "asan_stack.h" +# include "lsan/lsan_common.h" +# include "sanitizer_common/sanitizer_libc.h" +# include "sanitizer_common/sanitizer_posix.h" +# include "sanitizer_common/sanitizer_procmaps.h" namespace __asan { @@ -131,7 +132,7 @@ void AsanTSDSet(void *tsd) { } void PlatformTSDDtor(void *tsd) { - AsanThreadContext *context = (AsanThreadContext*)tsd; + AsanThreadContext *context = (AsanThreadContext *)tsd; if (context->destructor_iterations > 1) { context->destructor_iterations--; CHECK_EQ(0, pthread_setspecific(tsd_key, tsd)); @@ -140,6 +141,18 @@ void PlatformTSDDtor(void *tsd) { AsanThread::TSDDtor(tsd); } #endif + +void InstallAtExitCheckLeaks() { + if (CAN_SANITIZE_LEAKS) { + if (common_flags()->detect_leaks && common_flags()->leak_check_at_exit) { + if (flags()->halt_on_error) + Atexit(__lsan::DoLeakCheck); + else + Atexit(__lsan::DoRecoverableLeakCheckVoid); + } + } +} + } // namespace __asan #endif // SANITIZER_POSIX diff --git a/contrib/llvm-project/compiler-rt/lib/asan/asan_report.cpp b/contrib/llvm-project/compiler-rt/lib/asan/asan_report.cpp index 2a38fabaf220..2a55d6c0978d 100644 --- a/contrib/llvm-project/compiler-rt/lib/asan/asan_report.cpp +++ b/contrib/llvm-project/compiler-rt/lib/asan/asan_report.cpp @@ -11,17 +11,19 @@ // This file contains error reporting code. //===----------------------------------------------------------------------===// +#include "asan_report.h" + +#include "asan_descriptions.h" #include "asan_errors.h" #include "asan_flags.h" -#include "asan_descriptions.h" #include "asan_internal.h" #include "asan_mapping.h" -#include "asan_report.h" #include "asan_scariness_score.h" #include "asan_stack.h" #include "asan_thread.h" #include "sanitizer_common/sanitizer_common.h" #include "sanitizer_common/sanitizer_flags.h" +#include "sanitizer_common/sanitizer_interface_internal.h" #include "sanitizer_common/sanitizer_report_decorator.h" #include "sanitizer_common/sanitizer_stackdepot.h" #include "sanitizer_common/sanitizer_symbolizer.h" diff --git a/contrib/llvm-project/compiler-rt/lib/asan/asan_rtl.cpp b/contrib/llvm-project/compiler-rt/lib/asan/asan_rtl.cpp index f0bbbf32e6a6..29cf526d9eb0 100644 --- a/contrib/llvm-project/compiler-rt/lib/asan/asan_rtl.cpp +++ b/contrib/llvm-project/compiler-rt/lib/asan/asan_rtl.cpp @@ -27,6 +27,7 @@ #include "lsan/lsan_common.h" #include "sanitizer_common/sanitizer_atomic.h" #include "sanitizer_common/sanitizer_flags.h" +#include "sanitizer_common/sanitizer_interface_internal.h" #include "sanitizer_common/sanitizer_libc.h" #include "sanitizer_common/sanitizer_symbolizer.h" #include "ubsan/ubsan_init.h" @@ -44,14 +45,15 @@ static void AsanDie() { static atomic_uint32_t num_calls; if (atomic_fetch_add(&num_calls, 1, memory_order_relaxed) != 0) { // Don't die twice - run a busy loop. - while (1) { } + while (1) { + internal_sched_yield(); + } } if (common_flags()->print_module_map >= 1) DumpProcessMap(); - if (flags()->sleep_before_dying) { - Report("Sleeping for %d second(s)\n", flags()->sleep_before_dying); - SleepForSeconds(flags()->sleep_before_dying); - } + + WaitForDebugger(flags()->sleep_before_dying, "before dying"); + if (flags()->unmap_shadow_on_exit) { if (kMidMemBeg) { UnmapOrDie((void*)kLowShadowBeg, kMidMemBeg - kLowShadowBeg); @@ -184,7 +186,7 @@ ASAN_MEMORY_ACCESS_CALLBACK(store, true, 16) extern "C" NOINLINE INTERFACE_ATTRIBUTE void __asan_loadN(uptr addr, uptr size) { - if (__asan_region_is_poisoned(addr, size)) { + if ((addr = __asan_region_is_poisoned(addr, size))) { GET_CALLER_PC_BP_SP; ReportGenericError(pc, bp, sp, addr, false, size, 0, true); } @@ -193,7 +195,7 @@ void __asan_loadN(uptr addr, uptr size) { extern "C" NOINLINE INTERFACE_ATTRIBUTE void __asan_exp_loadN(uptr addr, uptr size, u32 exp) { - if (__asan_region_is_poisoned(addr, size)) { + if ((addr = __asan_region_is_poisoned(addr, size))) { GET_CALLER_PC_BP_SP; ReportGenericError(pc, bp, sp, addr, false, size, exp, true); } @@ -202,7 +204,7 @@ void __asan_exp_loadN(uptr addr, uptr size, u32 exp) { extern "C" NOINLINE INTERFACE_ATTRIBUTE void __asan_loadN_noabort(uptr addr, uptr size) { - if (__asan_region_is_poisoned(addr, size)) { + if ((addr = __asan_region_is_poisoned(addr, size))) { GET_CALLER_PC_BP_SP; ReportGenericError(pc, bp, sp, addr, false, size, 0, false); } @@ -211,7 +213,7 @@ void __asan_loadN_noabort(uptr addr, uptr size) { extern "C" NOINLINE INTERFACE_ATTRIBUTE void __asan_storeN(uptr addr, uptr size) { - if (__asan_region_is_poisoned(addr, size)) { + if ((addr = __asan_region_is_poisoned(addr, size))) { GET_CALLER_PC_BP_SP; ReportGenericError(pc, bp, sp, addr, true, size, 0, true); } @@ -220,7 +222,7 @@ void __asan_storeN(uptr addr, uptr size) { extern "C" NOINLINE INTERFACE_ATTRIBUTE void __asan_exp_storeN(uptr addr, uptr size, u32 exp) { - if (__asan_region_is_poisoned(addr, size)) { + if ((addr = __asan_region_is_poisoned(addr, size))) { GET_CALLER_PC_BP_SP; ReportGenericError(pc, bp, sp, addr, true, size, exp, true); } @@ -229,7 +231,7 @@ void __asan_exp_storeN(uptr addr, uptr size, u32 exp) { extern "C" NOINLINE INTERFACE_ATTRIBUTE void __asan_storeN_noabort(uptr addr, uptr size) { - if (__asan_region_is_poisoned(addr, size)) { + if ((addr = __asan_region_is_poisoned(addr, size))) { GET_CALLER_PC_BP_SP; ReportGenericError(pc, bp, sp, addr, true, size, 0, false); } @@ -383,6 +385,8 @@ static void AsanInitInternal() { // initialization steps look at flags(). InitializeFlags(); + WaitForDebugger(flags()->sleep_before_init, "before init"); + // Stop performing init at this point if we are being loaded via // dlopen() and the platform supports it. if (SANITIZER_SUPPORTS_INIT_FOR_DLOPEN && UNLIKELY(HandleDlopenInit())) { @@ -474,12 +478,7 @@ static void AsanInitInternal() { if (CAN_SANITIZE_LEAKS) { __lsan::InitCommonLsan(); - if (common_flags()->detect_leaks && common_flags()->leak_check_at_exit) { - if (flags()->halt_on_error) - Atexit(__lsan::DoLeakCheck); - else - Atexit(__lsan::DoRecoverableLeakCheckVoid); - } + InstallAtExitCheckLeaks(); } #if CAN_SANITIZE_UB @@ -499,10 +498,7 @@ static void AsanInitInternal() { VReport(1, "AddressSanitizer Init done\n"); - if (flags()->sleep_after_init) { - Report("Sleeping for %d second(s)\n", flags()->sleep_after_init); - SleepForSeconds(flags()->sleep_after_init); - } + WaitForDebugger(flags()->sleep_after_init, "after init"); } // Initialize as requested from some part of ASan runtime library (interceptors, diff --git a/contrib/llvm-project/compiler-rt/lib/asan/asan_rtl_static.cpp b/contrib/llvm-project/compiler-rt/lib/asan/asan_rtl_static.cpp index 74e6eb0ddf1c..a6f812bb8915 100644 --- a/contrib/llvm-project/compiler-rt/lib/asan/asan_rtl_static.cpp +++ b/contrib/llvm-project/compiler-rt/lib/asan/asan_rtl_static.cpp @@ -13,3 +13,24 @@ // This file is empty for now. Main reason to have it is workaround for Windows // build, which complains because no files are part of the asan_static lib. + +#include "sanitizer_common/sanitizer_common.h" + +#define REPORT_FUNCTION(Name) \ + extern "C" SANITIZER_WEAK_ATTRIBUTE void Name(__asan::uptr addr); \ + extern "C" void Name##_asm(uptr addr) { Name(addr); } + +namespace __asan { + +REPORT_FUNCTION(__asan_report_load1) +REPORT_FUNCTION(__asan_report_load2) +REPORT_FUNCTION(__asan_report_load4) +REPORT_FUNCTION(__asan_report_load8) +REPORT_FUNCTION(__asan_report_load16) +REPORT_FUNCTION(__asan_report_store1) +REPORT_FUNCTION(__asan_report_store2) +REPORT_FUNCTION(__asan_report_store4) +REPORT_FUNCTION(__asan_report_store8) +REPORT_FUNCTION(__asan_report_store16) + +} // namespace __asan diff --git a/contrib/llvm-project/compiler-rt/lib/asan/asan_rtl_x86_64.S b/contrib/llvm-project/compiler-rt/lib/asan/asan_rtl_x86_64.S index d27db745ed67..d93b5ed2a7fe 100644 --- a/contrib/llvm-project/compiler-rt/lib/asan/asan_rtl_x86_64.S +++ b/contrib/llvm-project/compiler-rt/lib/asan/asan_rtl_x86_64.S @@ -4,7 +4,6 @@ #if defined(__x86_64__) #include "sanitizer_common/sanitizer_platform.h" -.section .text .file "asan_rtl_x86_64.S" #define NAME(n, reg, op, s, i) n##_##op##_##i##_##s##_##reg @@ -15,6 +14,7 @@ #define FLABEL(reg, op, s, i) NAME(.fail, reg, op, s, i) #define BEGINF(reg, op, s, i) \ +.section .text.FNAME(reg, op, s, i),"ax",@progbits ;\ .globl FNAME(reg, op, s, i) ;\ .hidden FNAME(reg, op, s, i) ;\ ASM_TYPE_FUNCTION(FNAME(reg, op, s, i)) ;\ @@ -42,7 +42,7 @@ CLABEL(reg, op, 1, i): ;\ pop %rcx ;\ jl RLABEL(reg, op, 1, i);\ mov %##reg,%rdi ;\ - jmp __asan_report_##op##1@PLT ;\ + jmp __asan_report_##op##1_asm ;\ #define ASAN_MEMORY_ACCESS_EXTRA_CHECK_2(reg, op, i) \ CLABEL(reg, op, 2, i): ;\ @@ -54,7 +54,7 @@ CLABEL(reg, op, 2, i): ;\ pop %rcx ;\ jl RLABEL(reg, op, 2, i);\ mov %##reg,%rdi ;\ - jmp __asan_report_##op##2@PLT ;\ + jmp __asan_report_##op##2_asm ;\ #define ASAN_MEMORY_ACCESS_EXTRA_CHECK_4(reg, op, i) \ CLABEL(reg, op, 4, i): ;\ @@ -66,7 +66,7 @@ CLABEL(reg, op, 4, i): ;\ pop %rcx ;\ jl RLABEL(reg, op, 4, i);\ mov %##reg,%rdi ;\ - jmp __asan_report_##op##4@PLT ;\ + jmp __asan_report_##op##4_asm ;\ #define ASAN_MEMORY_ACCESS_CALLBACK_ADD_1(reg, op) \ BEGINF(reg, op, 1, add) ;\ @@ -97,7 +97,7 @@ ENDF #define ASAN_MEMORY_ACCESS_FAIL(reg, op, s, i) \ FLABEL(reg, op, s, i): ;\ mov %##reg,%rdi ;\ - jmp __asan_report_##op##s@PLT;\ + jmp __asan_report_##op##s##_asm;\ #define ASAN_MEMORY_ACCESS_CALLBACK_ADD_8(reg, op) \ BEGINF(reg, op, 8, add) ;\ diff --git a/contrib/llvm-project/compiler-rt/lib/asan/asan_thread.cpp b/contrib/llvm-project/compiler-rt/lib/asan/asan_thread.cpp index 2b06c3c4e7c0..c15963e14183 100644 --- a/contrib/llvm-project/compiler-rt/lib/asan/asan_thread.cpp +++ b/contrib/llvm-project/compiler-rt/lib/asan/asan_thread.cpp @@ -323,9 +323,7 @@ void AsanThread::ClearShadowForThreadStackAndTLS() { if (tls_begin_ != tls_end_) { uptr tls_begin_aligned = RoundDownTo(tls_begin_, ASAN_SHADOW_GRANULARITY); uptr tls_end_aligned = RoundUpTo(tls_end_, ASAN_SHADOW_GRANULARITY); - FastPoisonShadowPartialRightRedzone(tls_begin_aligned, - tls_end_ - tls_begin_aligned, - tls_end_aligned - tls_end_, 0); + FastPoisonShadow(tls_begin_aligned, tls_end_aligned - tls_begin_aligned, 0); } } diff --git a/contrib/llvm-project/compiler-rt/lib/asan/asan_win.cpp b/contrib/llvm-project/compiler-rt/lib/asan/asan_win.cpp index 53a0e3bfd385..81958038fb1c 100644 --- a/contrib/llvm-project/compiler-rt/lib/asan/asan_win.cpp +++ b/contrib/llvm-project/compiler-rt/lib/asan/asan_win.cpp @@ -1,4 +1,5 @@ -//===-- asan_win.cpp ------------------------------------------------------===// +//===-- asan_win.cpp +//------------------------------------------------------===//> // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -13,21 +14,20 @@ #include "sanitizer_common/sanitizer_platform.h" #if SANITIZER_WINDOWS -#define WIN32_LEAN_AND_MEAN -#include <windows.h> - -#include <stdlib.h> - -#include "asan_interceptors.h" -#include "asan_internal.h" -#include "asan_mapping.h" -#include "asan_report.h" -#include "asan_stack.h" -#include "asan_thread.h" -#include "sanitizer_common/sanitizer_libc.h" -#include "sanitizer_common/sanitizer_mutex.h" -#include "sanitizer_common/sanitizer_win.h" -#include "sanitizer_common/sanitizer_win_defs.h" +# define WIN32_LEAN_AND_MEAN +# include <stdlib.h> +# include <windows.h> + +# include "asan_interceptors.h" +# include "asan_internal.h" +# include "asan_mapping.h" +# include "asan_report.h" +# include "asan_stack.h" +# include "asan_thread.h" +# include "sanitizer_common/sanitizer_libc.h" +# include "sanitizer_common/sanitizer_mutex.h" +# include "sanitizer_common/sanitizer_win.h" +# include "sanitizer_common/sanitizer_win_defs.h" using namespace __asan; @@ -49,8 +49,8 @@ uptr __asan_get_shadow_memory_dynamic_address() { static LPTOP_LEVEL_EXCEPTION_FILTER default_seh_handler; static LPTOP_LEVEL_EXCEPTION_FILTER user_seh_handler; -extern "C" SANITIZER_INTERFACE_ATTRIBUTE -long __asan_unhandled_exception_filter(EXCEPTION_POINTERS *info) { +extern "C" SANITIZER_INTERFACE_ATTRIBUTE long __asan_unhandled_exception_filter( + EXCEPTION_POINTERS *info) { EXCEPTION_RECORD *exception_record = info->ExceptionRecord; CONTEXT *context = info->ContextRecord; @@ -187,6 +187,8 @@ void InitializePlatformInterceptors() { } } +void InstallAtExitCheckLeaks() {} + void AsanApplyToGlobals(globals_op_fptr op, const void *needle) { UNIMPLEMENTED(); } diff --git a/contrib/llvm-project/compiler-rt/lib/builtins/aarch64/fp_mode.c b/contrib/llvm-project/compiler-rt/lib/builtins/aarch64/fp_mode.c index 94c2ff3bb26d..03d75cd8be66 100644 --- a/contrib/llvm-project/compiler-rt/lib/builtins/aarch64/fp_mode.c +++ b/contrib/llvm-project/compiler-rt/lib/builtins/aarch64/fp_mode.c @@ -27,7 +27,7 @@ CRT_FE_ROUND_MODE __attribute__((weak)) __aarch64_fe_default_rmode = CRT_FE_TONEAREST; #endif -CRT_FE_ROUND_MODE __fe_getround() { +CRT_FE_ROUND_MODE __fe_getround(void) { #ifdef __ARM_FP uint64_t fpcr; __asm__ __volatile__("mrs %0, fpcr" : "=r" (fpcr)); @@ -48,7 +48,7 @@ CRT_FE_ROUND_MODE __fe_getround() { #endif } -int __fe_raise_inexact() { +int __fe_raise_inexact(void) { #ifdef __ARM_FP uint64_t fpsr; __asm__ __volatile__("mrs %0, fpsr" : "=r" (fpsr)); diff --git a/contrib/llvm-project/compiler-rt/lib/builtins/arm/fp_mode.c b/contrib/llvm-project/compiler-rt/lib/builtins/arm/fp_mode.c index f356e0b1316b..064f4e94fb84 100644 --- a/contrib/llvm-project/compiler-rt/lib/builtins/arm/fp_mode.c +++ b/contrib/llvm-project/compiler-rt/lib/builtins/arm/fp_mode.c @@ -27,7 +27,7 @@ CRT_FE_ROUND_MODE __attribute__((weak)) __arm_fe_default_rmode = CRT_FE_TONEAREST; #endif -CRT_FE_ROUND_MODE __fe_getround() { +CRT_FE_ROUND_MODE __fe_getround(void) { #ifdef __ARM_FP uint32_t fpscr; __asm__ __volatile__("vmrs %0, fpscr" : "=r" (fpscr)); @@ -48,7 +48,7 @@ CRT_FE_ROUND_MODE __fe_getround() { #endif } -int __fe_raise_inexact() { +int __fe_raise_inexact(void) { #ifdef __ARM_FP uint32_t fpscr; __asm__ __volatile__("vmrs %0, fpscr" : "=r" (fpscr)); diff --git a/contrib/llvm-project/compiler-rt/lib/builtins/arm/sync-ops.h b/contrib/llvm-project/compiler-rt/lib/builtins/arm/sync-ops.h index c9623249e5d2..dca201d8aef7 100644 --- a/contrib/llvm-project/compiler-rt/lib/builtins/arm/sync-ops.h +++ b/contrib/llvm-project/compiler-rt/lib/builtins/arm/sync-ops.h @@ -14,35 +14,41 @@ #include "../assembly.h" +#if __ARM_ARCH >= 7 +#define DMB dmb +#elif __ARM_ARCH >= 6 +#define DMB mcr p15, #0, r0, c7, c10, #5 +#else +#error DMB is only supported on ARMv6+ +#endif + #define SYNC_OP_4(op) \ .p2align 2; \ - .thumb; \ .syntax unified; \ - DEFINE_COMPILERRT_THUMB_FUNCTION(__sync_fetch_and_##op) \ - dmb; \ + DEFINE_COMPILERRT_FUNCTION(__sync_fetch_and_##op) \ + DMB; \ mov r12, r0; \ LOCAL_LABEL(tryatomic_##op) : ldrex r0, [r12]; \ op(r2, r0, r1); \ strex r3, r2, [r12]; \ cmp r3, #0; \ bne LOCAL_LABEL(tryatomic_##op); \ - dmb; \ + DMB; \ bx lr #define SYNC_OP_8(op) \ .p2align 2; \ - .thumb; \ .syntax unified; \ - DEFINE_COMPILERRT_THUMB_FUNCTION(__sync_fetch_and_##op) \ + DEFINE_COMPILERRT_FUNCTION(__sync_fetch_and_##op) \ push {r4, r5, r6, lr}; \ - dmb; \ + DMB; \ mov r12, r0; \ LOCAL_LABEL(tryatomic_##op) : ldrexd r0, r1, [r12]; \ op(r4, r5, r0, r1, r2, r3); \ strexd r6, r4, r5, [r12]; \ cmp r6, #0; \ bne LOCAL_LABEL(tryatomic_##op); \ - dmb; \ + DMB; \ pop { r4, r5, r6, pc } #define MINMAX_4(rD, rN, rM, cmp_kind) \ diff --git a/contrib/llvm-project/compiler-rt/lib/builtins/atomic.c b/contrib/llvm-project/compiler-rt/lib/builtins/atomic.c index 8dc2f4fc013a..852bb20f0867 100644 --- a/contrib/llvm-project/compiler-rt/lib/builtins/atomic.c +++ b/contrib/llvm-project/compiler-rt/lib/builtins/atomic.c @@ -92,6 +92,8 @@ __inline static void lock(Lock *l) { OSSpinLockLock(l); } static Lock locks[SPINLOCK_COUNT]; // initialized to OS_SPINLOCK_INIT which is 0 #else +_Static_assert(__atomic_always_lock_free(sizeof(uintptr_t), 0), + "Implementation assumes lock-free pointer-size cmpxchg"); typedef _Atomic(uintptr_t) Lock; /// Unlock a lock. This is a release operation. __inline static void unlock(Lock *l) { diff --git a/contrib/llvm-project/compiler-rt/lib/builtins/avr/divmodhi4.S b/contrib/llvm-project/compiler-rt/lib/builtins/avr/divmodhi4.S new file mode 100644 index 000000000000..37171331f4b3 --- /dev/null +++ b/contrib/llvm-project/compiler-rt/lib/builtins/avr/divmodhi4.S @@ -0,0 +1,57 @@ +//===------------- divmodhi4.S - sint16 div & mod -------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// As described at +// https://gcc.gnu.org/wiki/avr-gcc#Exceptions_to_the_Calling_Convention, the +// prototype is `struct {sint16, sint16} __divmodhi4(sint16, sint16)`. +// The sint16 quotient is returned via R23:R22, and the sint16 remainder is +// returned via R25:R24, while registers R21/R26/27/Rtmp and bit T in SREG +// are clobbered. +// +//===----------------------------------------------------------------------===// + + .text + .align 2 + +#ifdef __AVR_TINY__ + .set __tmp_reg__, 16 +#else + .set __tmp_reg__, 0 +#endif + + .globl __divmodhi4 + .type __divmodhi4, @function + +__divmodhi4: + bst r25, 7 + mov __tmp_reg__, r23 + brtc __divmodhi4_a + com __tmp_reg__ + rcall __divmodhi4_b + +__divmodhi4_a: + sbrc r23, 7 + rcall __divmodhi4_c + rcall __udivmodhi4 ; Call __udivmodhi4 to do real calculation. + sbrc __tmp_reg__, 7 + rcall __divmodhi4_c + brtc __divmodhi4_exit + +__divmodhi4_b: + com r25 + neg r24 + sbci r25, 255 + ret ; Return quotient via R23:R22 and remainder via R25:R24. + +__divmodhi4_c: + com r23 + neg r22 + sbci r23, 255 + +__divmodhi4_exit: + ret ; Return quotient via R23:R22 and remainder via R25:r24. diff --git a/contrib/llvm-project/compiler-rt/lib/builtins/avr/divmodqi4.S b/contrib/llvm-project/compiler-rt/lib/builtins/avr/divmodqi4.S new file mode 100644 index 000000000000..66cfc0c69bba --- /dev/null +++ b/contrib/llvm-project/compiler-rt/lib/builtins/avr/divmodqi4.S @@ -0,0 +1,44 @@ +//===------------- divmodqi4.S - sint8 div & mod --------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// As described at +// https://gcc.gnu.org/wiki/avr-gcc#Exceptions_to_the_Calling_Convention, the +// prototype is `struct {sint8, sint8} __divmodqi4(sint8, sint8)`. +// The sint8 quotient is returned via R24, and the sint8 remainder is returned +// via R25, while registers R23/Rtmp and bit T in SREG are clobbered. +// +//===----------------------------------------------------------------------===// + + .text + .align 2 + +#ifdef __AVR_TINY__ + .set __tmp_reg__, 16 +#else + .set __tmp_reg__, 0 +#endif + + .globl __divmodqi4 + .type __divmodqi4, @function + +__divmodqi4: + bst r24, 7 + mov __tmp_reg__, r24 + eor __tmp_reg__, r22 + sbrc r24, 7 + neg r24 + sbrc r22, 7 + neg r22 + rcall __udivmodqi4 ; Call __udivmodqi4 to do real calculation. + brtc __divmodqi4_1 + neg r25 + +__divmodqi4_1: + sbrc __tmp_reg__, 7 + neg r24 + ret ; Return quotient via R24 and remainder via R25. diff --git a/contrib/llvm-project/compiler-rt/lib/builtins/avr/exit.S b/contrib/llvm-project/compiler-rt/lib/builtins/avr/exit.S new file mode 100644 index 000000000000..3cd9c5dafdec --- /dev/null +++ b/contrib/llvm-project/compiler-rt/lib/builtins/avr/exit.S @@ -0,0 +1,18 @@ +//===------------ exit.S - global terminator for AVR ----------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + + .text + .align 2 + + .globl _exit + .type _exit, @function + +_exit: + cli ; Disable all interrupts. +__stop_program: + rjmp __stop_program ; Fall into an infinite loop. diff --git a/contrib/llvm-project/compiler-rt/lib/builtins/avr/mulhi3.S b/contrib/llvm-project/compiler-rt/lib/builtins/avr/mulhi3.S new file mode 100644 index 000000000000..d65f52ff27b5 --- /dev/null +++ b/contrib/llvm-project/compiler-rt/lib/builtins/avr/mulhi3.S @@ -0,0 +1,71 @@ +//===------------ mulhi3.S - int16 multiplication -------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// The corresponding C code is something like: +// +// int __mulhi3(int A, int B) { +// int S = 0; +// while (A != 0) { +// if (A & 1) +// S += B; +// A = ((unsigned int) A) >> 1; +// B <<= 1; +// } +// return S; +// } +// +// __mulhi3 has special ABI, as the implementation of libgcc, R25:R24 is used +// to return result, while Rtmp/R21/R22/R23 are clobbered. +// +//===----------------------------------------------------------------------===// + + .text + .align 2 + +#ifdef __AVR_TINY__ + .set __tmp_reg__, 16 + .set __zero_reg__, 17 +#else + .set __tmp_reg__, 0 + .set __zero_reg__, 1 +#endif + + .globl __mulhi3 + .type __mulhi3, @function + +__mulhi3: + ; Use Rzero:Rtmp to store the result. + clr __tmp_reg__ + clr __zero_reg__ ; S = 0; + +__mulhi3_loop: + clr r21 + cp r24, r21 + cpc r25, r21 + breq __mulhi3_end ; while (A != 0) { + + mov r21, r24 + andi r21, 1 + breq __mulhi3_loop_a ; if (A & 1) + add __tmp_reg__, r22 + adc __zero_reg__, r23 ; S += B; + +__mulhi3_loop_a: + lsr r25 + ror r24 ; A = ((unsigned int) A) >> 1; + lsl r22 + rol r23 ; B <<= 1; + rjmp __mulhi3_loop ; } + +__mulhi3_end: + ; Return the result via R25:R24. + mov r24, __tmp_reg__ + mov r25, __zero_reg__ + ; Restore __zero_reg__ to 0. + clr __zero_reg__ + ret ; return S; diff --git a/contrib/llvm-project/compiler-rt/lib/builtins/avr/mulqi3.S b/contrib/llvm-project/compiler-rt/lib/builtins/avr/mulqi3.S new file mode 100644 index 000000000000..914735cc6458 --- /dev/null +++ b/contrib/llvm-project/compiler-rt/lib/builtins/avr/mulqi3.S @@ -0,0 +1,53 @@ +//===------------ mulhi3.S - int8 multiplication --------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// The corresponding C code is something like: +// +// char __mulqi3(char A, char B) { +// int S = 0; +// while (A != 0) { +// if (A & 1) +// S += B; +// B <<= 1; +// A = ((unsigned char) A) >> 1; +// } +// return S; +// } +// +// __mulqi3 has special ABI, as the implementation of libgcc, the result is +// returned via R24, while Rtmp and R22 are clobbered. +// +//===----------------------------------------------------------------------===// + + .text + .align 2 + +#ifdef __AVR_TINY__ + .set __tmp_reg__, 16 +#else + .set __tmp_reg__, 0 +#endif + + .globl __mulqi3 + .type __mulqi3, @function + +__mulqi3: + clr __tmp_reg__ ; S = 0; + +__mulqi3_loop: + cpi r24, 0 + breq __mulqi3_end ; while (A != 0) { + sbrc r24, 0 ; if (A & 1) + add __tmp_reg__, r22 ; S += B; + add r22, r22 ; B <<= 1; + lsr r24 ; A = ((unsigned char) A) >> 1; + rjmp __mulqi3_loop ; } + +__mulqi3_end: + mov r24, __tmp_reg__ + ret ; return S; diff --git a/contrib/llvm-project/compiler-rt/lib/builtins/avr/udivmodhi4.S b/contrib/llvm-project/compiler-rt/lib/builtins/avr/udivmodhi4.S new file mode 100644 index 000000000000..0e52b86ec797 --- /dev/null +++ b/contrib/llvm-project/compiler-rt/lib/builtins/avr/udivmodhi4.S @@ -0,0 +1,49 @@ +//===------------ udivmodhi4.S - uint16 div & mod -------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// As described at +// https://gcc.gnu.org/wiki/avr-gcc#Exceptions_to_the_Calling_Convention, the +// prototype is `struct {uint16, uint16} __udivmodhi4(uint16, uint16)`. +// The uint16 quotient is returned via R23:R22, and the uint16 remainder is +// returned via R25:R24, while R21/R26/R27 are clobbered. +// +//===----------------------------------------------------------------------===// + + .text + .align 2 + + .globl __udivmodhi4 + .type __udivmodhi4, @function + +__udivmodhi4: + sub r26, r26 + sub r27, r27 ; Initialize the remainder to zero. + ldi r21, 17 ; Only loop 16 rounds for uint16. + +__udivmodhi4_loop: + adc r24, r24 + adc r25, r25 + dec r21 + breq __udivmodhi4_end + adc r26, r26 + adc r27, r27 + cp r26, r22 + cpc r27, r23 ; Compare with the divisor. + brcs __udivmodhi4_loop + sub r26, r22 + sbc r27, r23 ; Subtract the divisor. + rjmp __udivmodhi4_loop + +__udivmodhi4_end: + com r24 + com r25 + mov r22, r24 + mov r23, r25 ; The quotient is returned in R23:R22. + mov r24, r26 + mov r25, r27 ; The remainder is returned in in R25:R24. + ret diff --git a/contrib/llvm-project/compiler-rt/lib/builtins/avr/udivmodqi4.S b/contrib/llvm-project/compiler-rt/lib/builtins/avr/udivmodqi4.S new file mode 100644 index 000000000000..99aec3442936 --- /dev/null +++ b/contrib/llvm-project/compiler-rt/lib/builtins/avr/udivmodqi4.S @@ -0,0 +1,39 @@ +//===------------ udivmodqi4.S - uint8 div & mod --------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// As described at +// https://gcc.gnu.org/wiki/avr-gcc#Exceptions_to_the_Calling_Convention, the +// prototype is `struct {uint8, uint8} __udivmodqi4(uint8, uint8)`. +// The uint8 quotient is returned via R24, and the uint8 remainder is returned +// via R25, while R23 is clobbered. +// +//===----------------------------------------------------------------------===// + + .text + .align 2 + + .globl __udivmodqi4 + .type __udivmodqi4, @function + +__udivmodqi4: + sub r25, r25 ; Initialize the remainder to zero. + ldi r23, 9 ; Only loop 8 rounds for uint8. + +__udivmodqi4_loop: + adc r24, r24 + dec r23 + breq __udivmodqi4_end + adc r25, r25 + cp r25, r22 ; Compare with the divisor. + brcs __udivmodqi4_loop + sub r25, r22 ; Subtract the divisor. + rjmp __udivmodqi4_loop + +__udivmodqi4_end: + com r24 ; The uint8 quotient is returned via R24. + ret ; The uint8 remainder is returned via R25. diff --git a/contrib/llvm-project/compiler-rt/lib/builtins/clear_cache.c b/contrib/llvm-project/compiler-rt/lib/builtins/clear_cache.c index 1f1efbff3ab2..9816940b504a 100644 --- a/contrib/llvm-project/compiler-rt/lib/builtins/clear_cache.c +++ b/contrib/llvm-project/compiler-rt/lib/builtins/clear_cache.c @@ -176,12 +176,12 @@ void __clear_cache(void *start, void *end) { arg.len = (uintptr_t)end - (uintptr_t)start; sysarch(RISCV_SYNC_ICACHE, &arg); +#elif defined(__ve__) + __asm__ volatile("fencec 2"); #else #if __APPLE__ // On Darwin, sys_icache_invalidate() provides this functionality sys_icache_invalidate(start, end - start); -#elif defined(__ve__) - __asm__ volatile("fencec 2"); #else compilerrt_abort(); #endif diff --git a/contrib/llvm-project/compiler-rt/lib/builtins/cpu_model.c b/contrib/llvm-project/compiler-rt/lib/builtins/cpu_model.c index aa0fd7d85b57..228be67acb89 100644 --- a/contrib/llvm-project/compiler-rt/lib/builtins/cpu_model.c +++ b/contrib/llvm-project/compiler-rt/lib/builtins/cpu_model.c @@ -17,10 +17,17 @@ #define __has_attribute(attr) 0 #endif -#if defined(HAVE_INIT_PRIORITY) -#define CONSTRUCTOR_ATTRIBUTE __attribute__((__constructor__ 101)) -#elif __has_attribute(__constructor__) -#define CONSTRUCTOR_ATTRIBUTE __attribute__((__constructor__)) +#if __has_attribute(constructor) +#if __GNUC__ >= 9 +// Ordinarily init priorities below 101 are disallowed as they are reserved for the +// implementation. However, we are the implementation, so silence the diagnostic, +// since it doesn't apply to us. +#pragma GCC diagnostic ignored "-Wprio-ctor-dtor" +#endif +// We're choosing init priority 90 to force our constructors to run before any +// constructors in the end user application (starting at priority 101). This value +// matches the libgcc choice for the same functions. +#define CONSTRUCTOR_ATTRIBUTE __attribute__((constructor(90))) #else // FIXME: For MSVC, we should make a function pointer global in .CRT$X?? so that // this runs during initialization. @@ -149,7 +156,7 @@ enum ProcessorFeatures { // Check motivated by bug reports for OpenSSL crashing on CPUs without CPUID // support. Consequently, for i386, the presence of CPUID is checked first // via the corresponding eflags bit. -static bool isCpuIdSupported() { +static bool isCpuIdSupported(void) { #if defined(__GNUC__) || defined(__clang__) #if defined(__i386__) int __cpuid_supported; @@ -579,9 +586,9 @@ getAMDProcessorTypeAndSubtype(unsigned Family, unsigned Model, case 25: CPU = "znver3"; *Type = AMDFAM19H; - if (Model <= 0x0f) { + if (Model <= 0x0f || Model == 0x21) { *Subtype = AMDFAM19H_ZNVER3; - break; // 00h-0Fh: Zen3 + break; // 00h-0Fh, 21h: Zen3 } break; default: @@ -801,12 +808,23 @@ _Bool __aarch64_have_lse_atomics #if defined(__ANDROID__) #include <string.h> #include <sys/system_properties.h> +#elif defined(__Fuchsia__) +#include <zircon/features.h> +#include <zircon/syscalls.h> #endif static void CONSTRUCTOR_ATTRIBUTE init_have_lse_atomics(void) { #if defined(__FreeBSD__) unsigned long hwcap; int result = elf_aux_info(AT_HWCAP, &hwcap, sizeof hwcap); __aarch64_have_lse_atomics = result == 0 && (hwcap & HWCAP_ATOMICS) != 0; +#elif defined(__Fuchsia__) + // This ensures the vDSO is a direct link-time dependency of anything that + // needs this initializer code. +#pragma comment(lib, "zircon") + uint32_t features; + zx_status_t status = _zx_system_get_features(ZX_FEATURE_KIND_CPU, &features); + __aarch64_have_lse_atomics = + status == ZX_OK && (features & ZX_ARM64_FEATURE_ISA_ATOMICS) != 0; #else unsigned long hwcap = getauxval(AT_HWCAP); _Bool result = (hwcap & HWCAP_ATOMICS) != 0; @@ -815,8 +833,15 @@ static void CONSTRUCTOR_ATTRIBUTE init_have_lse_atomics(void) { char arch[PROP_VALUE_MAX]; if (__system_property_get("ro.arch", arch) > 0 && strncmp(arch, "exynos9810", sizeof("exynos9810") - 1) == 0) { - // Some cores of Exynos 9810 are ARMv8.2 and others are ARMv8.0, - // so disable the lse atomics completely. + // Some cores in the Exynos 9810 CPU are ARMv8.2 and others are ARMv8.0; + // only the former support LSE atomics. However, the kernel in the + // initial Android 8.0 release of Galaxy S9/S9+ devices incorrectly + // reported the feature as being supported. + // + // The kernel appears to have been corrected to mark it unsupported as of + // the Android 9.0 release on those devices, and this issue has not been + // observed anywhere else. Thus, this workaround may be removed if + // compiler-rt ever drops support for Android 8.0. result = false; } } diff --git a/contrib/llvm-project/compiler-rt/lib/builtins/emutls.c b/contrib/llvm-project/compiler-rt/lib/builtins/emutls.c index 3a2908a42484..390ffb25f6cf 100644 --- a/contrib/llvm-project/compiler-rt/lib/builtins/emutls.c +++ b/contrib/llvm-project/compiler-rt/lib/builtins/emutls.c @@ -93,7 +93,7 @@ static __inline void emutls_setspecific(emutls_address_array *value) { pthread_setspecific(emutls_pthread_key, (void *)value); } -static __inline emutls_address_array *emutls_getspecific() { +static __inline emutls_address_array *emutls_getspecific(void) { return (emutls_address_array *)pthread_getspecific(emutls_pthread_key); } @@ -125,9 +125,9 @@ static __inline void emutls_init_once(void) { pthread_once(&once, emutls_init); } -static __inline void emutls_lock() { pthread_mutex_lock(&emutls_mutex); } +static __inline void emutls_lock(void) { pthread_mutex_lock(&emutls_mutex); } -static __inline void emutls_unlock() { pthread_mutex_unlock(&emutls_mutex); } +static __inline void emutls_unlock(void) { pthread_mutex_unlock(&emutls_mutex); } #else // _WIN32 @@ -209,16 +209,16 @@ static __inline void emutls_init_once(void) { InitOnceExecuteOnce(&once, emutls_init, NULL, NULL); } -static __inline void emutls_lock() { EnterCriticalSection(emutls_mutex); } +static __inline void emutls_lock(void) { EnterCriticalSection(emutls_mutex); } -static __inline void emutls_unlock() { LeaveCriticalSection(emutls_mutex); } +static __inline void emutls_unlock(void) { LeaveCriticalSection(emutls_mutex); } static __inline void emutls_setspecific(emutls_address_array *value) { if (TlsSetValue(emutls_tls_index, (LPVOID)value) == 0) win_abort(GetLastError(), "TlsSetValue"); } -static __inline emutls_address_array *emutls_getspecific() { +static __inline emutls_address_array *emutls_getspecific(void) { LPVOID value = TlsGetValue(emutls_tls_index); if (value == NULL) { const DWORD err = GetLastError(); diff --git a/contrib/llvm-project/compiler-rt/lib/builtins/fp_compare_impl.inc b/contrib/llvm-project/compiler-rt/lib/builtins/fp_compare_impl.inc index 40fc7df4c679..a9a4f6fbf5df 100644 --- a/contrib/llvm-project/compiler-rt/lib/builtins/fp_compare_impl.inc +++ b/contrib/llvm-project/compiler-rt/lib/builtins/fp_compare_impl.inc @@ -18,6 +18,9 @@ typedef int CMP_RESULT; #elif __SIZEOF_POINTER__ == 8 && __SIZEOF_LONG__ == 4 // LLP64 ABIs use long long instead of long. typedef long long CMP_RESULT; +#elif __AVR__ +// AVR uses a single byte for the return value. +typedef char CMP_RESULT; #else // Otherwise the comparison functions return long. typedef long CMP_RESULT; diff --git a/contrib/llvm-project/compiler-rt/lib/builtins/fp_mode.c b/contrib/llvm-project/compiler-rt/lib/builtins/fp_mode.c index b84df8abb27d..51865473cda7 100644 --- a/contrib/llvm-project/compiler-rt/lib/builtins/fp_mode.c +++ b/contrib/llvm-project/compiler-rt/lib/builtins/fp_mode.c @@ -15,8 +15,8 @@ #include "fp_mode.h" // IEEE-754 default rounding (to nearest, ties to even). -CRT_FE_ROUND_MODE __fe_getround() { return CRT_FE_TONEAREST; } +CRT_FE_ROUND_MODE __fe_getround(void) { return CRT_FE_TONEAREST; } -int __fe_raise_inexact() { +int __fe_raise_inexact(void) { return 0; } diff --git a/contrib/llvm-project/compiler-rt/lib/builtins/fp_trunc.h b/contrib/llvm-project/compiler-rt/lib/builtins/fp_trunc.h index 00595edd5e01..7a54564a3520 100644 --- a/contrib/llvm-project/compiler-rt/lib/builtins/fp_trunc.h +++ b/contrib/llvm-project/compiler-rt/lib/builtins/fp_trunc.h @@ -59,6 +59,12 @@ typedef uint16_t dst_rep_t; #define DST_REP_C UINT16_C static const int dstSigBits = 10; +#elif defined DST_BFLOAT +typedef uint16_t dst_t; +typedef uint16_t dst_rep_t; +#define DST_REP_C UINT16_C +static const int dstSigBits = 7; + #else #error Destination should be single precision or double precision! #endif // end destination precision diff --git a/contrib/llvm-project/compiler-rt/lib/builtins/gcc_personality_v0.c b/contrib/llvm-project/compiler-rt/lib/builtins/gcc_personality_v0.c index 792fe9022724..a327a83eb9f6 100644 --- a/contrib/llvm-project/compiler-rt/lib/builtins/gcc_personality_v0.c +++ b/contrib/llvm-project/compiler-rt/lib/builtins/gcc_personality_v0.c @@ -158,7 +158,7 @@ static uintptr_t readEncodedPointer(const uint8_t **data, uint8_t encoding) { } #if defined(__arm__) && !defined(__USING_SJLJ_EXCEPTIONS__) && \ - !defined(__ARM_DWARF_EH__) + !defined(__ARM_DWARF_EH__) && !defined(__SEH__) #define USING_ARM_EHABI 1 _Unwind_Reason_Code __gnu_unwind_frame(struct _Unwind_Exception *, struct _Unwind_Context *); diff --git a/contrib/llvm-project/compiler-rt/lib/builtins/i386/fp_mode.c b/contrib/llvm-project/compiler-rt/lib/builtins/i386/fp_mode.c index 80e272e4c9a3..887ca9c34c15 100644 --- a/contrib/llvm-project/compiler-rt/lib/builtins/i386/fp_mode.c +++ b/contrib/llvm-project/compiler-rt/lib/builtins/i386/fp_mode.c @@ -14,7 +14,7 @@ #define X87_TOWARDZERO 0x0c00 #define X87_RMODE_MASK (X87_TONEAREST | X87_UPWARD | X87_DOWNWARD | X87_TOWARDZERO) -CRT_FE_ROUND_MODE __fe_getround() { +CRT_FE_ROUND_MODE __fe_getround(void) { // Assume that the rounding mode state for the fpu agrees with the SSE unit. unsigned short cw; __asm__ __volatile__ ("fnstcw %0" : "=m" (cw)); @@ -32,7 +32,7 @@ CRT_FE_ROUND_MODE __fe_getround() { return CRT_FE_TONEAREST; } -int __fe_raise_inexact() { +int __fe_raise_inexact(void) { float f = 1.0f, g = 3.0f; __asm__ __volatile__ ("fdivs %1" : "+t" (f) : "m" (g)); return 0; diff --git a/contrib/llvm-project/compiler-rt/lib/builtins/int_endianness.h b/contrib/llvm-project/compiler-rt/lib/builtins/int_endianness.h index def046c34a62..291c6b58c8ed 100644 --- a/contrib/llvm-project/compiler-rt/lib/builtins/int_endianness.h +++ b/contrib/llvm-project/compiler-rt/lib/builtins/int_endianness.h @@ -41,7 +41,7 @@ #error "unknown endianness" #endif // !_LITTLE_ENDIAN -#endif // Solaris and AuroraUX. +#endif // Solaris // .. diff --git a/contrib/llvm-project/compiler-rt/lib/builtins/os_version_check.c b/contrib/llvm-project/compiler-rt/lib/builtins/os_version_check.c index d7194b99ae54..ebfb2dfc72dd 100644 --- a/contrib/llvm-project/compiler-rt/lib/builtins/os_version_check.c +++ b/contrib/llvm-project/compiler-rt/lib/builtins/os_version_check.c @@ -307,8 +307,8 @@ static void readSystemProperties(void) { } int32_t __isOSVersionAtLeast(int32_t Major, int32_t Minor, int32_t Subminor) { - (int32_t) Minor; - (int32_t) Subminor; + (void) Minor; + (void) Subminor; static pthread_once_t once = PTHREAD_ONCE_INIT; pthread_once(&once, readSystemProperties); diff --git a/contrib/llvm-project/compiler-rt/lib/builtins/truncdfbf2.c b/contrib/llvm-project/compiler-rt/lib/builtins/truncdfbf2.c new file mode 100644 index 000000000000..dbd54dcd50ca --- /dev/null +++ b/contrib/llvm-project/compiler-rt/lib/builtins/truncdfbf2.c @@ -0,0 +1,13 @@ +//===-- lib/truncdfbf2.c - double -> bfloat conversion ------------*- C -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#define SRC_DOUBLE +#define DST_BFLOAT +#include "fp_trunc_impl.inc" + +COMPILER_RT_ABI dst_t __truncdfbf2(double a) { return __truncXfYf2__(a); } diff --git a/contrib/llvm-project/compiler-rt/lib/builtins/truncsfbf2.c b/contrib/llvm-project/compiler-rt/lib/builtins/truncsfbf2.c new file mode 100644 index 000000000000..6bed116af986 --- /dev/null +++ b/contrib/llvm-project/compiler-rt/lib/builtins/truncsfbf2.c @@ -0,0 +1,13 @@ +//===-- lib/truncsfbf2.c - single -> bfloat conversion ------------*- C -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#define SRC_SINGLE +#define DST_BFLOAT +#include "fp_trunc_impl.inc" + +COMPILER_RT_ABI dst_t __truncsfbf2(float a) { return __truncXfYf2__(a); } diff --git a/contrib/llvm-project/compiler-rt/lib/crt/crtbegin.c b/contrib/llvm-project/compiler-rt/lib/crt/crtbegin.c index 481c158ac777..7b041ff00b6b 100644 --- a/contrib/llvm-project/compiler-rt/lib/crt/crtbegin.c +++ b/contrib/llvm-project/compiler-rt/lib/crt/crtbegin.c @@ -28,7 +28,7 @@ extern fp __CTOR_LIST_END__[]; extern void __cxa_finalize(void *) __attribute__((weak)); -static void __attribute__((used)) __do_init() { +static void __attribute__((used)) __do_init(void) { static _Bool __initialized; if (__builtin_expect(__initialized, 0)) return; @@ -79,7 +79,7 @@ static fp __DTOR_LIST__[] extern fp __DTOR_LIST_END__[]; #endif -static void __attribute__((used)) __do_fini() { +static void __attribute__((used)) __do_fini(void) { static _Bool __finalized; if (__builtin_expect(__finalized, 0)) return; diff --git a/contrib/llvm-project/compiler-rt/lib/dfsan/dfsan.cpp b/contrib/llvm-project/compiler-rt/lib/dfsan/dfsan.cpp index afb01c7d889e..89364c5b3073 100644 --- a/contrib/llvm-project/compiler-rt/lib/dfsan/dfsan.cpp +++ b/contrib/llvm-project/compiler-rt/lib/dfsan/dfsan.cpp @@ -128,6 +128,17 @@ void __dfsan_unimplemented(char *fname) { fname); } +extern "C" SANITIZER_INTERFACE_ATTRIBUTE void __dfsan_wrapper_extern_weak_null( + const void *addr, char *fname) { + if (!addr) + Report( + "ERROR: DataFlowSanitizer: dfsan generated wrapper calling null " + "extern_weak function %s\nIf this only happens with dfsan, the " + "dfsan instrumentation pass may be accidentally optimizing out a " + "null check\n", + fname); +} + // Use '-mllvm -dfsan-debug-nonzero-labels' and break on this function // to try to figure out where labels are being introduced in a nominally // label-free program. @@ -937,6 +948,20 @@ void dfsan_clear_thread_local_state() { } } +SANITIZER_INTERFACE_ATTRIBUTE +void dfsan_set_arg_tls(uptr offset, dfsan_label label) { + // 2x to match ShadowTLSAlignment. + // ShadowTLSAlignment should probably be changed. + // TODO: Consider reducing ShadowTLSAlignment to 1. + // Aligning to 2 bytes is probably a remnant of fast16 mode. + ((dfsan_label *)__dfsan_arg_tls)[offset * 2] = label; +} + +SANITIZER_INTERFACE_ATTRIBUTE +void dfsan_set_arg_origin_tls(uptr offset, dfsan_origin o) { + __dfsan_arg_origin_tls[offset] = o; +} + extern "C" void dfsan_flush() { const uptr maxVirtualAddress = GetMaxUserVirtualAddress(); for (unsigned i = 0; i < kMemoryLayoutSize; ++i) { @@ -1106,7 +1131,7 @@ static void DFsanInit(int argc, char **argv, char **envp) { dfsan_allocator_init(); - DFsanThread *main_thread = DFsanThread::Create(nullptr, nullptr, nullptr); + DFsanThread *main_thread = DFsanThread::Create(nullptr, nullptr); SetCurrentThread(main_thread); main_thread->Init(); diff --git a/contrib/llvm-project/compiler-rt/lib/dfsan/dfsan.h b/contrib/llvm-project/compiler-rt/lib/dfsan/dfsan.h index f3403dd44fa8..29938a08de54 100644 --- a/contrib/llvm-project/compiler-rt/lib/dfsan/dfsan.h +++ b/contrib/llvm-project/compiler-rt/lib/dfsan/dfsan.h @@ -36,6 +36,12 @@ void dfsan_clear_arg_tls(uptr offset, uptr size); // Zero out the TLS storage. void dfsan_clear_thread_local_state(); +// Set DFSan label and origin TLS of argument for a call. +// Note that offset may not correspond with argument number. +// Some arguments (aggregate/array) will use several offsets. +void dfsan_set_arg_tls(uptr offset, dfsan_label label); +void dfsan_set_arg_origin_tls(uptr offset, dfsan_origin o); + // Return the origin associated with the first taint byte in the size bytes // from the address addr. dfsan_origin dfsan_read_origin_of_first_taint(const void *addr, uptr size); diff --git a/contrib/llvm-project/compiler-rt/lib/dfsan/dfsan_custom.cpp b/contrib/llvm-project/compiler-rt/lib/dfsan/dfsan_custom.cpp index 1965d0ddff59..6f41e225d9e8 100644 --- a/contrib/llvm-project/compiler-rt/lib/dfsan/dfsan_custom.cpp +++ b/contrib/llvm-project/compiler-rt/lib/dfsan/dfsan_custom.cpp @@ -753,7 +753,6 @@ static void *DFsanThreadStartFunc(void *arg) { } static int dfsan_pthread_create(pthread_t *thread, const pthread_attr_t *attr, - void *start_routine_trampoline, void *start_routine, void *arg, dfsan_label *ret_label, bool track_origins = false) { @@ -767,8 +766,7 @@ static int dfsan_pthread_create(pthread_t *thread, const pthread_attr_t *attr, AdjustStackSize((void *)(const_cast<pthread_attr_t *>(attr))); DFsanThread *t = - DFsanThread::Create(start_routine_trampoline, - (thread_callback_t)start_routine, arg, track_origins); + DFsanThread::Create((thread_callback_t)start_routine, arg, track_origins); ScopedBlockSignals block(&t->starting_sigset_); int res = pthread_create(thread, attr, DFsanThreadStartFunc, t); @@ -779,28 +777,22 @@ static int dfsan_pthread_create(pthread_t *thread, const pthread_attr_t *attr, } SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_pthread_create( - pthread_t *thread, const pthread_attr_t *attr, - void *(*start_routine_trampoline)(void *, void *, dfsan_label, - dfsan_label *), - void *start_routine, void *arg, dfsan_label thread_label, - dfsan_label attr_label, dfsan_label start_routine_label, - dfsan_label arg_label, dfsan_label *ret_label) { - return dfsan_pthread_create(thread, attr, (void *)start_routine_trampoline, - start_routine, arg, ret_label); + pthread_t *thread, const pthread_attr_t *attr, void *start_routine, + void *arg, dfsan_label thread_label, dfsan_label attr_label, + dfsan_label start_routine_label, dfsan_label arg_label, + dfsan_label *ret_label) { + return dfsan_pthread_create(thread, attr, start_routine, arg, ret_label); } SANITIZER_INTERFACE_ATTRIBUTE int __dfso_pthread_create( - pthread_t *thread, const pthread_attr_t *attr, - void *(*start_routine_trampoline)(void *, void *, dfsan_label, - dfsan_label *, dfsan_origin, - dfsan_origin *), - void *start_routine, void *arg, dfsan_label thread_label, - dfsan_label attr_label, dfsan_label start_routine_label, - dfsan_label arg_label, dfsan_label *ret_label, dfsan_origin thread_origin, + pthread_t *thread, const pthread_attr_t *attr, void *start_routine, + void *arg, dfsan_label thread_label, dfsan_label attr_label, + dfsan_label start_routine_label, dfsan_label arg_label, + dfsan_label *ret_label, dfsan_origin thread_origin, dfsan_origin attr_origin, dfsan_origin start_routine_origin, dfsan_origin arg_origin, dfsan_origin *ret_origin) { - return dfsan_pthread_create(thread, attr, (void *)start_routine_trampoline, - start_routine, arg, ret_label, true); + return dfsan_pthread_create(thread, attr, start_routine, arg, ret_label, + true); } SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_pthread_join(pthread_t thread, @@ -825,22 +817,7 @@ SANITIZER_INTERFACE_ATTRIBUTE int __dfso_pthread_join( } struct dl_iterate_phdr_info { - int (*callback_trampoline)(void *callback, struct dl_phdr_info *info, - size_t size, void *data, dfsan_label info_label, - dfsan_label size_label, dfsan_label data_label, - dfsan_label *ret_label); - void *callback; - void *data; -}; - -struct dl_iterate_phdr_origin_info { - int (*callback_trampoline)(void *callback, struct dl_phdr_info *info, - size_t size, void *data, dfsan_label info_label, - dfsan_label size_label, dfsan_label data_label, - dfsan_label *ret_label, dfsan_origin info_origin, - dfsan_origin size_origin, dfsan_origin data_origin, - dfsan_origin *ret_origin); - void *callback; + int (*callback)(struct dl_phdr_info *info, size_t size, void *data); void *data; }; @@ -852,53 +829,28 @@ int dl_iterate_phdr_cb(struct dl_phdr_info *info, size_t size, void *data) { dfsan_set_label( 0, const_cast<char *>(reinterpret_cast<const char *>(info->dlpi_phdr)), sizeof(*info->dlpi_phdr) * info->dlpi_phnum); - dfsan_label ret_label; - return dipi->callback_trampoline(dipi->callback, info, size, dipi->data, 0, 0, - 0, &ret_label); -} -int dl_iterate_phdr_origin_cb(struct dl_phdr_info *info, size_t size, - void *data) { - dl_iterate_phdr_origin_info *dipi = (dl_iterate_phdr_origin_info *)data; - dfsan_set_label(0, *info); - dfsan_set_label(0, const_cast<char *>(info->dlpi_name), - strlen(info->dlpi_name) + 1); - dfsan_set_label( - 0, const_cast<char *>(reinterpret_cast<const char *>(info->dlpi_phdr)), - sizeof(*info->dlpi_phdr) * info->dlpi_phnum); - dfsan_label ret_label; - dfsan_origin ret_origin; - return dipi->callback_trampoline(dipi->callback, info, size, dipi->data, 0, 0, - 0, &ret_label, 0, 0, 0, &ret_origin); + dfsan_clear_thread_local_state(); + return dipi->callback(info, size, dipi->data); } SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_dl_iterate_phdr( - int (*callback_trampoline)(void *callback, struct dl_phdr_info *info, - size_t size, void *data, dfsan_label info_label, - dfsan_label size_label, dfsan_label data_label, - dfsan_label *ret_label), - void *callback, void *data, dfsan_label callback_label, - dfsan_label data_label, dfsan_label *ret_label) { - dl_iterate_phdr_info dipi = { callback_trampoline, callback, data }; + int (*callback)(struct dl_phdr_info *info, size_t size, void *data), + void *data, dfsan_label callback_label, dfsan_label data_label, + dfsan_label *ret_label) { + dl_iterate_phdr_info dipi = {callback, data}; *ret_label = 0; return dl_iterate_phdr(dl_iterate_phdr_cb, &dipi); } SANITIZER_INTERFACE_ATTRIBUTE int __dfso_dl_iterate_phdr( - int (*callback_trampoline)(void *callback, struct dl_phdr_info *info, - size_t size, void *data, dfsan_label info_label, - dfsan_label size_label, dfsan_label data_label, - dfsan_label *ret_label, dfsan_origin info_origin, - dfsan_origin size_origin, - dfsan_origin data_origin, - dfsan_origin *ret_origin), - void *callback, void *data, dfsan_label callback_label, - dfsan_label data_label, dfsan_label *ret_label, - dfsan_origin callback_origin, dfsan_origin data_origin, - dfsan_origin *ret_origin) { - dl_iterate_phdr_origin_info dipi = {callback_trampoline, callback, data}; + int (*callback)(struct dl_phdr_info *info, size_t size, void *data), + void *data, dfsan_label callback_label, dfsan_label data_label, + dfsan_label *ret_label, dfsan_origin callback_origin, + dfsan_origin data_origin, dfsan_origin *ret_origin) { + dl_iterate_phdr_info dipi = {callback, data}; *ret_label = 0; - return dl_iterate_phdr(dl_iterate_phdr_origin_cb, &dipi); + return dl_iterate_phdr(dl_iterate_phdr_cb, &dipi); } // This function is only available for glibc 2.27 or newer. Mark it weak so @@ -1629,10 +1581,7 @@ static void SignalHandler(int signo) { SignalHandlerScope signal_handler_scope; ScopedClearThreadLocalState scoped_clear_tls; - // Clear shadows for all inputs provided by system. This is why DFSan - // instrumentation generates a trampoline function to each function pointer, - // and uses the trampoline to clear shadows. However sigaction does not use - // a function pointer directly, so we have to do this manually. + // Clear shadows for all inputs provided by system. dfsan_clear_arg_tls(0, sizeof(dfsan_label)); typedef void (*signal_cb)(int x); @@ -1733,22 +1682,18 @@ static sighandler_t dfsan_signal(int signum, sighandler_t handler, } SANITIZER_INTERFACE_ATTRIBUTE -sighandler_t __dfsw_signal(int signum, - void *(*handler_trampoline)(void *, int, dfsan_label, - dfsan_label *), - sighandler_t handler, dfsan_label signum_label, - dfsan_label handler_label, dfsan_label *ret_label) { +sighandler_t __dfsw_signal(int signum, sighandler_t handler, + dfsan_label signum_label, dfsan_label handler_label, + dfsan_label *ret_label) { return dfsan_signal(signum, handler, ret_label); } SANITIZER_INTERFACE_ATTRIBUTE -sighandler_t __dfso_signal( - int signum, - void *(*handler_trampoline)(void *, int, dfsan_label, dfsan_label *, - dfsan_origin, dfsan_origin *), - sighandler_t handler, dfsan_label signum_label, dfsan_label handler_label, - dfsan_label *ret_label, dfsan_origin signum_origin, - dfsan_origin handler_origin, dfsan_origin *ret_origin) { +sighandler_t __dfso_signal(int signum, sighandler_t handler, + dfsan_label signum_label, dfsan_label handler_label, + dfsan_label *ret_label, dfsan_origin signum_origin, + dfsan_origin handler_origin, + dfsan_origin *ret_origin) { return dfsan_signal(signum, handler, ret_label); } @@ -2088,47 +2033,62 @@ SANITIZER_INTERFACE_ATTRIBUTE int __dfso_getpeername( addrlen_label, ret_label); } -// Type of the trampoline function passed to the custom version of -// dfsan_set_write_callback. -typedef void (*write_trampoline_t)( - void *callback, - int fd, const void *buf, ssize_t count, - dfsan_label fd_label, dfsan_label buf_label, dfsan_label count_label); - -typedef void (*write_origin_trampoline_t)( - void *callback, int fd, const void *buf, ssize_t count, - dfsan_label fd_label, dfsan_label buf_label, dfsan_label count_label, - dfsan_origin fd_origin, dfsan_origin buf_origin, dfsan_origin count_origin); +// Type of the function passed to dfsan_set_write_callback. +typedef void (*write_dfsan_callback_t)(int fd, const void *buf, ssize_t count); // Calls to dfsan_set_write_callback() set the values in this struct. // Calls to the custom version of write() read (and invoke) them. static struct { - write_trampoline_t write_callback_trampoline = nullptr; - void *write_callback = nullptr; + write_dfsan_callback_t write_callback = nullptr; } write_callback_info; -static struct { - write_origin_trampoline_t write_callback_trampoline = nullptr; - void *write_callback = nullptr; -} write_origin_callback_info; - -SANITIZER_INTERFACE_ATTRIBUTE void -__dfsw_dfsan_set_write_callback( - write_trampoline_t write_callback_trampoline, - void *write_callback, - dfsan_label write_callback_label, +SANITIZER_INTERFACE_ATTRIBUTE void __dfsw_dfsan_set_write_callback( + write_dfsan_callback_t write_callback, dfsan_label write_callback_label, dfsan_label *ret_label) { - write_callback_info.write_callback_trampoline = write_callback_trampoline; write_callback_info.write_callback = write_callback; } SANITIZER_INTERFACE_ATTRIBUTE void __dfso_dfsan_set_write_callback( - write_origin_trampoline_t write_callback_trampoline, void *write_callback, - dfsan_label write_callback_label, dfsan_label *ret_label, - dfsan_origin write_callback_origin, dfsan_origin *ret_origin) { - write_origin_callback_info.write_callback_trampoline = - write_callback_trampoline; - write_origin_callback_info.write_callback = write_callback; + write_dfsan_callback_t write_callback, dfsan_label write_callback_label, + dfsan_label *ret_label, dfsan_origin write_callback_origin, + dfsan_origin *ret_origin) { + write_callback_info.write_callback = write_callback; +} + +static inline void setup_tls_args_for_write_callback( + dfsan_label fd_label, dfsan_label buf_label, dfsan_label count_label, + bool origins, dfsan_origin fd_origin, dfsan_origin buf_origin, + dfsan_origin count_origin) { + // The callback code will expect argument shadow labels in the args TLS, + // and origin labels in the origin args TLS. + // Previously this was done by a trampoline, but we want to remove this: + // https://github.com/llvm/llvm-project/issues/54172 + // + // Instead, this code is manually setting up the args TLS data. + // + // The offsets used need to correspond with the instrumentation code, + // see llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp + // DFSanFunction::getShadowForTLSArgument. + // https://github.com/llvm/llvm-project/blob/0acc9e4b5edd8b39ff3d4c6d0e17f02007671c4e/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp#L1684 + // https://github.com/llvm/llvm-project/blob/0acc9e4b5edd8b39ff3d4c6d0e17f02007671c4e/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp#L125 + // + // Here the arguments are all primitives, but it can be more complex + // to compute offsets for array/aggregate type arguments. + // + // TODO(browneee): Consider a builtin to improve maintainabliity. + // With a builtin, we would provide the argument labels via builtin, + // and the builtin would reuse parts of the instrumentation code to ensure + // that this code and the instrumentation can never be out of sync. + // Note: Currently DFSan instrumentation does not run on this code, so + // the builtin may need to be handled outside DFSan instrumentation. + dfsan_set_arg_tls(0, fd_label); + dfsan_set_arg_tls(1, buf_label); + dfsan_set_arg_tls(2, count_label); + if (origins) { + dfsan_set_arg_origin_tls(0, fd_origin); + dfsan_set_arg_origin_tls(1, buf_origin); + dfsan_set_arg_origin_tls(2, count_origin); + } } SANITIZER_INTERFACE_ATTRIBUTE int @@ -2136,10 +2096,9 @@ __dfsw_write(int fd, const void *buf, size_t count, dfsan_label fd_label, dfsan_label buf_label, dfsan_label count_label, dfsan_label *ret_label) { if (write_callback_info.write_callback) { - write_callback_info.write_callback_trampoline( - write_callback_info.write_callback, - fd, buf, count, - fd_label, buf_label, count_label); + setup_tls_args_for_write_callback(fd_label, buf_label, count_label, false, + 0, 0, 0); + write_callback_info.write_callback(fd, buf, count); } *ret_label = 0; @@ -2151,10 +2110,10 @@ SANITIZER_INTERFACE_ATTRIBUTE int __dfso_write( dfsan_label buf_label, dfsan_label count_label, dfsan_label *ret_label, dfsan_origin fd_origin, dfsan_origin buf_origin, dfsan_origin count_origin, dfsan_origin *ret_origin) { - if (write_origin_callback_info.write_callback) { - write_origin_callback_info.write_callback_trampoline( - write_origin_callback_info.write_callback, fd, buf, count, fd_label, - buf_label, count_label, fd_origin, buf_origin, count_origin); + if (write_callback_info.write_callback) { + setup_tls_args_for_write_callback(fd_label, buf_label, count_label, true, + fd_origin, buf_origin, count_origin); + write_callback_info.write_callback(fd, buf, count); } *ret_label = 0; diff --git a/contrib/llvm-project/compiler-rt/lib/dfsan/dfsan_thread.cpp b/contrib/llvm-project/compiler-rt/lib/dfsan/dfsan_thread.cpp index df7e4d9b7421..e64f0f818fb8 100644 --- a/contrib/llvm-project/compiler-rt/lib/dfsan/dfsan_thread.cpp +++ b/contrib/llvm-project/compiler-rt/lib/dfsan/dfsan_thread.cpp @@ -7,13 +7,11 @@ namespace __dfsan { -DFsanThread *DFsanThread::Create(void *start_routine_trampoline, - thread_callback_t start_routine, void *arg, +DFsanThread *DFsanThread::Create(thread_callback_t start_routine, void *arg, bool track_origins) { uptr PageSize = GetPageSizeCached(); uptr size = RoundUpTo(sizeof(DFsanThread), PageSize); DFsanThread *thread = (DFsanThread *)MmapOrDie(size, __func__); - thread->start_routine_trampoline_ = start_routine_trampoline; thread->start_routine_ = start_routine; thread->arg_ = arg; thread->track_origins_ = track_origins; @@ -74,23 +72,15 @@ thread_return_t DFsanThread::ThreadStart() { return 0; } - CHECK(start_routine_trampoline_); + // The only argument is void* arg. + // + // We have never supported propagating the pointer arg as tainted, + // __dfsw_pthread_create/__dfso_pthread_create ignore the taint label. + // Note that the bytes pointed-to (probably the much more common case) + // can still have taint labels attached to them. + dfsan_clear_thread_local_state(); - typedef void *(*thread_callback_trampoline_t)(void *, void *, dfsan_label, - dfsan_label *); - typedef void *(*thread_callback_origin_trampoline_t)( - void *, void *, dfsan_label, dfsan_label *, dfsan_origin, dfsan_origin *); - - dfsan_label ret_label; - if (!track_origins_) - return ((thread_callback_trampoline_t) - start_routine_trampoline_)((void *)start_routine_, arg_, 0, - &ret_label); - - dfsan_origin ret_origin; - return ((thread_callback_origin_trampoline_t) - start_routine_trampoline_)((void *)start_routine_, arg_, 0, - &ret_label, 0, &ret_origin); + return start_routine_(arg_); } DFsanThread::StackBounds DFsanThread::GetStackBounds() const { diff --git a/contrib/llvm-project/compiler-rt/lib/dfsan/dfsan_thread.h b/contrib/llvm-project/compiler-rt/lib/dfsan/dfsan_thread.h index 1c33a1854997..ebc25499e269 100644 --- a/contrib/llvm-project/compiler-rt/lib/dfsan/dfsan_thread.h +++ b/contrib/llvm-project/compiler-rt/lib/dfsan/dfsan_thread.h @@ -24,8 +24,7 @@ class DFsanThread { // NOTE: There is no DFsanThread constructor. It is allocated // via mmap() and *must* be valid in zero-initialized state. - static DFsanThread *Create(void *start_routine_trampoline, - thread_callback_t start_routine, void *arg, + static DFsanThread *Create(thread_callback_t start_routine, void *arg, bool track_origins = false); static void TSDDtor(void *tsd); void Destroy(); @@ -59,7 +58,6 @@ class DFsanThread { bool AddrIsInStack(uptr addr); - void *start_routine_trampoline_; thread_callback_t start_routine_; void *arg_; bool track_origins_; diff --git a/contrib/llvm-project/compiler-rt/lib/fuzzer/FuzzerInternal.h b/contrib/llvm-project/compiler-rt/lib/fuzzer/FuzzerInternal.h index 6637b0034e55..31f54eaa478a 100644 --- a/contrib/llvm-project/compiler-rt/lib/fuzzer/FuzzerInternal.h +++ b/contrib/llvm-project/compiler-rt/lib/fuzzer/FuzzerInternal.h @@ -65,7 +65,10 @@ public: static void StaticFileSizeExceedCallback(); static void StaticGracefulExitCallback(); - void ExecuteCallback(const uint8_t *Data, size_t Size); + // Executes the target callback on {Data, Size} once. + // Returns false if the input was rejected by the target (target returned -1), + // and true otherwise. + bool ExecuteCallback(const uint8_t *Data, size_t Size); bool RunOne(const uint8_t *Data, size_t Size, bool MayDeleteFile = false, InputInfo *II = nullptr, bool ForceAddToCorpus = false, bool *FoundUniqFeatures = nullptr); diff --git a/contrib/llvm-project/compiler-rt/lib/fuzzer/FuzzerLoop.cpp b/contrib/llvm-project/compiler-rt/lib/fuzzer/FuzzerLoop.cpp index 3205942f6d84..f095757229e9 100644 --- a/contrib/llvm-project/compiler-rt/lib/fuzzer/FuzzerLoop.cpp +++ b/contrib/llvm-project/compiler-rt/lib/fuzzer/FuzzerLoop.cpp @@ -511,7 +511,7 @@ bool Fuzzer::RunOne(const uint8_t *Data, size_t Size, bool MayDeleteFile, // Largest input length should be INT_MAX. assert(Size < std::numeric_limits<uint32_t>::max()); - ExecuteCallback(Data, Size); + if(!ExecuteCallback(Data, Size)) return false; auto TimeOfUnit = duration_cast<microseconds>(UnitStopTime - UnitStartTime); UniqFeatureSetTmp.clear(); @@ -586,7 +586,7 @@ static bool LooseMemeq(const uint8_t *A, const uint8_t *B, size_t Size) { // This method is not inlined because it would cause a test to fail where it // is part of the stack unwinding. See D97975 for details. -ATTRIBUTE_NOINLINE void Fuzzer::ExecuteCallback(const uint8_t *Data, +ATTRIBUTE_NOINLINE bool Fuzzer::ExecuteCallback(const uint8_t *Data, size_t Size) { TPC.RecordInitialStack(); TotalNumberOfRuns++; @@ -602,23 +602,24 @@ ATTRIBUTE_NOINLINE void Fuzzer::ExecuteCallback(const uint8_t *Data, if (CurrentUnitData && CurrentUnitData != Data) memcpy(CurrentUnitData, Data, Size); CurrentUnitSize = Size; + int CBRes = 0; { ScopedEnableMsanInterceptorChecks S; AllocTracer.Start(Options.TraceMalloc); UnitStartTime = system_clock::now(); TPC.ResetMaps(); RunningUserCallback = true; - int Res = CB(DataCopy, Size); + CBRes = CB(DataCopy, Size); RunningUserCallback = false; UnitStopTime = system_clock::now(); - (void)Res; - assert(Res == 0); + assert(CBRes == 0 || CBRes == -1); HasMoreMallocsThanFrees = AllocTracer.Stop(); } if (!LooseMemeq(DataCopy, Data, Size)) CrashOnOverwrittenData(); CurrentUnitSize = 0; delete[] DataCopy; + return CBRes == 0; } std::string Fuzzer::WriteToOutputCorpus(const Unit &U) { @@ -843,9 +844,16 @@ void Fuzzer::ReadAndExecuteSeedCorpora(std::vector<SizedFile> &CorporaFiles) { } if (Corpus.empty() && Options.MaxNumberOfRuns) { - Printf("ERROR: no interesting inputs were found. " - "Is the code instrumented for coverage? Exiting.\n"); - exit(1); + Printf("WARNING: no interesting inputs were found so far. " + "Is the code instrumented for coverage?\n" + "This may also happen if the target rejected all inputs we tried so " + "far\n"); + // The remaining logic requires that the corpus is not empty, + // so we add one fake input to the in-memory corpus. + Corpus.AddToCorpus({'\n'}, /*NumFeatures=*/1, /*MayDeleteFile=*/true, + /*HasFocusFunction=*/false, /*NeverReduce=*/false, + /*TimeOfUnit=*/duration_cast<microseconds>(0s), {0}, DFT, + /*BaseII*/ nullptr); } } diff --git a/contrib/llvm-project/compiler-rt/lib/fuzzer/FuzzerTracePC.cpp b/contrib/llvm-project/compiler-rt/lib/fuzzer/FuzzerTracePC.cpp index af8d1ce50f3f..f12f7aa61bc4 100644 --- a/contrib/llvm-project/compiler-rt/lib/fuzzer/FuzzerTracePC.cpp +++ b/contrib/llvm-project/compiler-rt/lib/fuzzer/FuzzerTracePC.cpp @@ -133,13 +133,14 @@ inline ALWAYS_INLINE uintptr_t GetPreviousInstructionPc(uintptr_t PC) { // so we return (pc-2) in that case in order to be safe. // For A32 mode we return (pc-4) because all instructions are 32 bit long. return (PC - 3) & (~1); -#elif defined(__powerpc__) || defined(__powerpc64__) || defined(__aarch64__) - // PCs are always 4 byte aligned. - return PC - 4; #elif defined(__sparc__) || defined(__mips__) return PC - 8; -#else +#elif defined(__riscv__) + return PC - 2; +#elif defined(__i386__) || defined(__x86_64__) || defined(_M_IX86) || defined(_M_X64) return PC - 1; +#else + return PC - 4; #endif } diff --git a/contrib/llvm-project/compiler-rt/lib/hwasan/hwasan.cpp b/contrib/llvm-project/compiler-rt/lib/hwasan/hwasan.cpp index 6f0ea64472c6..f8725a173432 100644 --- a/contrib/llvm-project/compiler-rt/lib/hwasan/hwasan.cpp +++ b/contrib/llvm-project/compiler-rt/lib/hwasan/hwasan.cpp @@ -25,6 +25,7 @@ #include "sanitizer_common/sanitizer_common.h" #include "sanitizer_common/sanitizer_flag_parser.h" #include "sanitizer_common/sanitizer_flags.h" +#include "sanitizer_common/sanitizer_interface_internal.h" #include "sanitizer_common/sanitizer_libc.h" #include "sanitizer_common/sanitizer_procmaps.h" #include "sanitizer_common/sanitizer_stackdepot.h" diff --git a/contrib/llvm-project/compiler-rt/lib/hwasan/hwasan.h b/contrib/llvm-project/compiler-rt/lib/hwasan/hwasan.h index 371c43f3cbde..3cc2fc40b5f6 100644 --- a/contrib/llvm-project/compiler-rt/lib/hwasan/hwasan.h +++ b/contrib/llvm-project/compiler-rt/lib/hwasan/hwasan.h @@ -172,21 +172,6 @@ void HwasanTagMismatch(uptr addr, uptr access_info, uptr *registers_frame, } // namespace __hwasan -#define HWASAN_MALLOC_HOOK(ptr, size) \ - do { \ - if (&__sanitizer_malloc_hook) { \ - __sanitizer_malloc_hook(ptr, size); \ - } \ - RunMallocHooks(ptr, size); \ - } while (false) -#define HWASAN_FREE_HOOK(ptr) \ - do { \ - if (&__sanitizer_free_hook) { \ - __sanitizer_free_hook(ptr); \ - } \ - RunFreeHooks(ptr); \ - } while (false) - #if HWASAN_WITH_INTERCEPTORS // For both bionic and glibc __sigset_t is an unsigned long. typedef unsigned long __hw_sigset_t; diff --git a/contrib/llvm-project/compiler-rt/lib/hwasan/hwasan_allocator.cpp b/contrib/llvm-project/compiler-rt/lib/hwasan/hwasan_allocator.cpp index 84e183f2384f..842455150c7b 100644 --- a/contrib/llvm-project/compiler-rt/lib/hwasan/hwasan_allocator.cpp +++ b/contrib/llvm-project/compiler-rt/lib/hwasan/hwasan_allocator.cpp @@ -199,7 +199,7 @@ static void *HwasanAllocate(StackTrace *stack, uptr orig_size, uptr alignment, } } - HWASAN_MALLOC_HOOK(user_ptr, size); + RunMallocHooks(user_ptr, size); return user_ptr; } @@ -226,7 +226,7 @@ static bool CheckInvalidFree(StackTrace *stack, void *untagged_ptr, static void HwasanDeallocate(StackTrace *stack, void *tagged_ptr) { CHECK(tagged_ptr); - HWASAN_FREE_HOOK(tagged_ptr); + RunFreeHooks(tagged_ptr); bool in_taggable_region = InTaggableRegion(reinterpret_cast<uptr>(tagged_ptr)); diff --git a/contrib/llvm-project/compiler-rt/lib/hwasan/hwasan_fuchsia.cpp b/contrib/llvm-project/compiler-rt/lib/hwasan/hwasan_fuchsia.cpp index 94e5c5fb69c7..b066d4fdd114 100644 --- a/contrib/llvm-project/compiler-rt/lib/hwasan/hwasan_fuchsia.cpp +++ b/contrib/llvm-project/compiler-rt/lib/hwasan/hwasan_fuchsia.cpp @@ -15,6 +15,9 @@ #include "sanitizer_common/sanitizer_fuchsia.h" #if SANITIZER_FUCHSIA +#include <zircon/features.h> +#include <zircon/syscalls.h> + #include "hwasan.h" #include "hwasan_interface_internal.h" #include "hwasan_report.h" @@ -182,9 +185,20 @@ void InstallAtExitHandler() {} void HwasanInstallAtForkHandler() {} -// TODO(fxbug.dev/81499): Once we finalize the tagged pointer ABI in zircon, we should come back -// here and implement the appropriate check that TBI is enabled. -void InitializeOsSupport() {} +void InitializeOsSupport() { +#ifdef __aarch64__ + uint32_t features = 0; + CHECK_EQ(zx_system_get_features(ZX_FEATURE_KIND_ADDRESS_TAGGING, &features), + ZX_OK); + if (features != ZX_ARM64_FEATURE_ADDRESS_TAGGING_TBI && + flags()->fail_without_syscall_abi) { + Printf( + "FATAL: HWAddressSanitizer requires a kernel with tagged address " + "ABI.\n"); + Die(); + } +#endif +} } // namespace __hwasan diff --git a/contrib/llvm-project/compiler-rt/lib/hwasan/hwasan_new_delete.cpp b/contrib/llvm-project/compiler-rt/lib/hwasan/hwasan_new_delete.cpp index 4e057a651e1d..495046a754f1 100644 --- a/contrib/llvm-project/compiler-rt/lib/hwasan/hwasan_new_delete.cpp +++ b/contrib/llvm-project/compiler-rt/lib/hwasan/hwasan_new_delete.cpp @@ -22,21 +22,23 @@ #if HWASAN_REPLACE_OPERATORS_NEW_AND_DELETE // TODO(alekseys): throw std::bad_alloc instead of dying on OOM. -#define OPERATOR_NEW_BODY(nothrow) \ - GET_MALLOC_STACK_TRACE; \ - void *res = hwasan_malloc(size, &stack);\ - if (!nothrow && UNLIKELY(!res)) ReportOutOfMemory(size, &stack);\ - return res -#define OPERATOR_NEW_ALIGN_BODY(nothrow) \ - GET_MALLOC_STACK_TRACE; \ - void *res = hwasan_aligned_alloc(static_cast<uptr>(align), size, &stack); \ - if (!nothrow && UNLIKELY(!res)) \ - ReportOutOfMemory(size, &stack); \ - return res - -#define OPERATOR_DELETE_BODY \ - GET_MALLOC_STACK_TRACE; \ - if (ptr) hwasan_free(ptr, &stack) +# define OPERATOR_NEW_BODY(nothrow) \ + GET_MALLOC_STACK_TRACE; \ + void *res = hwasan_malloc(size, &stack); \ + if (!nothrow && UNLIKELY(!res)) \ + ReportOutOfMemory(size, &stack); \ + return res +# define OPERATOR_NEW_ALIGN_BODY(nothrow) \ + GET_MALLOC_STACK_TRACE; \ + void *res = hwasan_memalign(static_cast<uptr>(align), size, &stack); \ + if (!nothrow && UNLIKELY(!res)) \ + ReportOutOfMemory(size, &stack); \ + return res + +# define OPERATOR_DELETE_BODY \ + GET_MALLOC_STACK_TRACE; \ + if (ptr) \ + hwasan_free(ptr, &stack) #elif defined(__ANDROID__) @@ -44,8 +46,8 @@ // since we previously released a runtime that intercepted these functions, // removing the interceptors would break ABI. Therefore we simply forward to // malloc and free. -#define OPERATOR_NEW_BODY(nothrow) return malloc(size) -#define OPERATOR_DELETE_BODY free(ptr) +# define OPERATOR_NEW_BODY(nothrow) return malloc(size) +# define OPERATOR_DELETE_BODY free(ptr) #endif @@ -55,26 +57,27 @@ using namespace __hwasan; // Fake std::nothrow_t to avoid including <new>. namespace std { - struct nothrow_t {}; +struct nothrow_t {}; } // namespace std - - -INTERCEPTOR_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE -void *operator new(size_t size) { OPERATOR_NEW_BODY(false /*nothrow*/); } -INTERCEPTOR_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE -void *operator new[](size_t size) { OPERATOR_NEW_BODY(false /*nothrow*/); } -INTERCEPTOR_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE -void *operator new(size_t size, std::nothrow_t const&) { +INTERCEPTOR_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE void *operator new(size_t size) { + OPERATOR_NEW_BODY(false /*nothrow*/); +} +INTERCEPTOR_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE void *operator new[]( + size_t size) { + OPERATOR_NEW_BODY(false /*nothrow*/); +} +INTERCEPTOR_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE void *operator new( + size_t size, std::nothrow_t const &) { OPERATOR_NEW_BODY(true /*nothrow*/); } -INTERCEPTOR_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE -void *operator new[](size_t size, std::nothrow_t const&) { +INTERCEPTOR_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE void *operator new[]( + size_t size, std::nothrow_t const &) { OPERATOR_NEW_BODY(true /*nothrow*/); } -INTERCEPTOR_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE void operator delete(void *ptr) - NOEXCEPT { +INTERCEPTOR_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE void operator delete( + void *ptr) NOEXCEPT { OPERATOR_DELETE_BODY; } INTERCEPTOR_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE void operator delete[]( diff --git a/contrib/llvm-project/compiler-rt/lib/hwasan/hwasan_preinit.cpp b/contrib/llvm-project/compiler-rt/lib/hwasan/hwasan_preinit.cpp new file mode 100644 index 000000000000..8c9c95f413be --- /dev/null +++ b/contrib/llvm-project/compiler-rt/lib/hwasan/hwasan_preinit.cpp @@ -0,0 +1,23 @@ +//===-- hwasan_preinit.cpp ------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file is a part of HWAddressSanitizer, an address sanity checker. +// +// Call __hwasan_init at the very early stage of process startup. +//===----------------------------------------------------------------------===// +#include "hwasan_interface_internal.h" +#include "sanitizer_common/sanitizer_internal_defs.h" + +#if SANITIZER_CAN_USE_PREINIT_ARRAY +// The symbol is called __local_hwasan_preinit, because it's not intended to +// be exported. +// This code linked into the main executable when -fsanitize=hwaddress is in +// the link flags. It can only use exported interface functions. +__attribute__((section(".preinit_array"), used)) static void ( + *__local_hwasan_preinit)(void) = __hwasan_init; +#endif diff --git a/contrib/llvm-project/compiler-rt/lib/interception/interception.h b/contrib/llvm-project/compiler-rt/lib/interception/interception.h index d8dc092c45f5..d97974ee9074 100644 --- a/contrib/llvm-project/compiler-rt/lib/interception/interception.h +++ b/contrib/llvm-project/compiler-rt/lib/interception/interception.h @@ -16,7 +16,7 @@ #include "sanitizer_common/sanitizer_internal_defs.h" -#if !SANITIZER_LINUX && !SANITIZER_FREEBSD && !SANITIZER_MAC && \ +#if !SANITIZER_LINUX && !SANITIZER_FREEBSD && !SANITIZER_APPLE && \ !SANITIZER_NETBSD && !SANITIZER_WINDOWS && !SANITIZER_FUCHSIA && \ !SANITIZER_SOLARIS # error "Interception doesn't work on this operating system." @@ -88,7 +88,7 @@ typedef __sanitizer::OFF64_T OFF64_T; // As it's decided at compile time which functions are to be intercepted on Mac, // INTERCEPT_FUNCTION() is effectively a no-op on this system. -#if SANITIZER_MAC +#if SANITIZER_APPLE #include <sys/cdefs.h> // For __DARWIN_ALIAS_C(). // Just a pair of pointers. @@ -157,7 +157,7 @@ const interpose_substitution substitution_##func_name[] \ # define INTERCEPTOR_ATTRIBUTE __attribute__((visibility("default"))) # define REAL(x) __unsanitized_##x # define DECLARE_REAL(ret_type, func, ...) -#elif !SANITIZER_MAC +#elif !SANITIZER_APPLE # define PTR_TO_REAL(x) real_##x # define REAL(x) __interception::PTR_TO_REAL(x) # define FUNC_TYPE(x) x##_type @@ -168,12 +168,12 @@ const interpose_substitution substitution_##func_name[] \ extern FUNC_TYPE(func) PTR_TO_REAL(func); \ } # define ASSIGN_REAL(dst, src) REAL(dst) = REAL(src) -#else // SANITIZER_MAC +#else // SANITIZER_APPLE # define REAL(x) x # define DECLARE_REAL(ret_type, func, ...) \ extern "C" ret_type func(__VA_ARGS__); # define ASSIGN_REAL(x, y) -#endif // SANITIZER_MAC +#endif // SANITIZER_APPLE #if !SANITIZER_FUCHSIA # define DECLARE_REAL_AND_INTERCEPTOR(ret_type, func, ...) \ @@ -193,7 +193,7 @@ const interpose_substitution substitution_##func_name[] \ // macros does its job. In exceptional cases you may need to call REAL(foo) // without defining INTERCEPTOR(..., foo, ...). For example, if you override // foo with an interceptor for other function. -#if !SANITIZER_MAC && !SANITIZER_FUCHSIA +#if !SANITIZER_APPLE && !SANITIZER_FUCHSIA # define DEFINE_REAL(ret_type, func, ...) \ typedef ret_type (*FUNC_TYPE(func))(__VA_ARGS__); \ namespace __interception { \ @@ -213,7 +213,7 @@ const interpose_substitution substitution_##func_name[] \ __interceptor_##func(__VA_ARGS__); \ extern "C" INTERCEPTOR_ATTRIBUTE ret_type func(__VA_ARGS__) -#elif !SANITIZER_MAC +#elif !SANITIZER_APPLE #define INTERCEPTOR(ret_type, func, ...) \ DEFINE_REAL(ret_type, func, __VA_ARGS__) \ @@ -226,7 +226,7 @@ const interpose_substitution substitution_##func_name[] \ #define INTERCEPTOR_WITH_SUFFIX(ret_type, func, ...) \ INTERCEPTOR(ret_type, func, __VA_ARGS__) -#else // SANITIZER_MAC +#else // SANITIZER_APPLE #define INTERCEPTOR_ZZZ(suffix, ret_type, func, ...) \ extern "C" ret_type func(__VA_ARGS__) suffix; \ @@ -278,7 +278,7 @@ typedef unsigned long uptr; # define INTERCEPT_FUNCTION(func) INTERCEPT_FUNCTION_LINUX_OR_FREEBSD(func) # define INTERCEPT_FUNCTION_VER(func, symver) \ INTERCEPT_FUNCTION_VER_LINUX_OR_FREEBSD(func, symver) -#elif SANITIZER_MAC +#elif SANITIZER_APPLE # include "interception_mac.h" # define INTERCEPT_FUNCTION(func) INTERCEPT_FUNCTION_MAC(func) # define INTERCEPT_FUNCTION_VER(func, symver) \ diff --git a/contrib/llvm-project/compiler-rt/lib/interception/interception_mac.cpp b/contrib/llvm-project/compiler-rt/lib/interception/interception_mac.cpp index fb6eadcff597..03eae0fdca0d 100644 --- a/contrib/llvm-project/compiler-rt/lib/interception/interception_mac.cpp +++ b/contrib/llvm-project/compiler-rt/lib/interception/interception_mac.cpp @@ -13,6 +13,6 @@ #include "interception.h" -#if SANITIZER_MAC +#if SANITIZER_APPLE -#endif // SANITIZER_MAC +#endif // SANITIZER_APPLE diff --git a/contrib/llvm-project/compiler-rt/lib/interception/interception_mac.h b/contrib/llvm-project/compiler-rt/lib/interception/interception_mac.h index eddedb8959c4..26079518c649 100644 --- a/contrib/llvm-project/compiler-rt/lib/interception/interception_mac.h +++ b/contrib/llvm-project/compiler-rt/lib/interception/interception_mac.h @@ -11,7 +11,7 @@ // Mac-specific interception methods. //===----------------------------------------------------------------------===// -#if SANITIZER_MAC +#if SANITIZER_APPLE #if !defined(INCLUDED_FROM_INTERCEPTION_LIB) # error "interception_mac.h should be included from interception.h only" @@ -24,4 +24,4 @@ #define INTERCEPT_FUNCTION_VER_MAC(func, symver) #endif // INTERCEPTION_MAC_H -#endif // SANITIZER_MAC +#endif // SANITIZER_APPLE diff --git a/contrib/llvm-project/compiler-rt/lib/interception/interception_type_test.cpp b/contrib/llvm-project/compiler-rt/lib/interception/interception_type_test.cpp index a611604a700c..2a118fb214ff 100644 --- a/contrib/llvm-project/compiler-rt/lib/interception/interception_type_test.cpp +++ b/contrib/llvm-project/compiler-rt/lib/interception/interception_type_test.cpp @@ -13,7 +13,7 @@ #include "interception.h" -#if SANITIZER_LINUX || SANITIZER_MAC +#if SANITIZER_LINUX || SANITIZER_APPLE #include <sys/types.h> #include <stddef.h> @@ -24,7 +24,7 @@ COMPILER_CHECK(sizeof(::SSIZE_T) == sizeof(ssize_t)); COMPILER_CHECK(sizeof(::PTRDIFF_T) == sizeof(ptrdiff_t)); COMPILER_CHECK(sizeof(::INTMAX_T) == sizeof(intmax_t)); -#if !SANITIZER_MAC +#if !SANITIZER_APPLE COMPILER_CHECK(sizeof(::OFF64_T) == sizeof(off64_t)); #endif diff --git a/contrib/llvm-project/compiler-rt/lib/interception/interception_win.cpp b/contrib/llvm-project/compiler-rt/lib/interception/interception_win.cpp index 10b893391f47..d0db981d519c 100644 --- a/contrib/llvm-project/compiler-rt/lib/interception/interception_win.cpp +++ b/contrib/llvm-project/compiler-rt/lib/interception/interception_win.cpp @@ -1068,4 +1068,4 @@ bool OverrideImportedFunction(const char *module_to_patch, } // namespace __interception -#endif // SANITIZER_MAC +#endif // SANITIZER_APPLE diff --git a/contrib/llvm-project/compiler-rt/lib/lsan/lsan.cpp b/contrib/llvm-project/compiler-rt/lib/lsan/lsan.cpp index b6adc248157b..489c5ca01fed 100644 --- a/contrib/llvm-project/compiler-rt/lib/lsan/lsan.cpp +++ b/contrib/llvm-project/compiler-rt/lib/lsan/lsan.cpp @@ -13,11 +13,12 @@ #include "lsan.h" -#include "sanitizer_common/sanitizer_flags.h" -#include "sanitizer_common/sanitizer_flag_parser.h" #include "lsan_allocator.h" #include "lsan_common.h" #include "lsan_thread.h" +#include "sanitizer_common/sanitizer_flag_parser.h" +#include "sanitizer_common/sanitizer_flags.h" +#include "sanitizer_common/sanitizer_interface_internal.h" bool lsan_inited; bool lsan_init_is_running; @@ -99,9 +100,7 @@ extern "C" void __lsan_init() { InitializeThreadRegistry(); InstallDeadlySignalHandlers(LsanOnDeadlySignal); InitializeMainThread(); - - if (common_flags()->detect_leaks && common_flags()->leak_check_at_exit) - Atexit(DoLeakCheck); + InstallAtExitCheckLeaks(); InitializeCoverage(common_flags()->coverage, common_flags()->coverage_dir); diff --git a/contrib/llvm-project/compiler-rt/lib/lsan/lsan.h b/contrib/llvm-project/compiler-rt/lib/lsan/lsan.h index af8efa6153a5..757edec8e104 100644 --- a/contrib/llvm-project/compiler-rt/lib/lsan/lsan.h +++ b/contrib/llvm-project/compiler-rt/lib/lsan/lsan.h @@ -39,6 +39,7 @@ namespace __lsan { void InitializeInterceptors(); void ReplaceSystemMalloc(); void LsanOnDeadlySignal(int signo, void *siginfo, void *context); +void InstallAtExitCheckLeaks(); #define ENSURE_LSAN_INITED \ do { \ diff --git a/contrib/llvm-project/compiler-rt/lib/lsan/lsan_allocator.cpp b/contrib/llvm-project/compiler-rt/lib/lsan/lsan_allocator.cpp index ea4c6c9cf647..43928ad294e2 100644 --- a/contrib/llvm-project/compiler-rt/lib/lsan/lsan_allocator.cpp +++ b/contrib/llvm-project/compiler-rt/lib/lsan/lsan_allocator.cpp @@ -104,7 +104,6 @@ void *Allocate(const StackTrace &stack, uptr size, uptr alignment, if (cleared && allocator.FromPrimary(p)) memset(p, 0, size); RegisterAllocation(stack, p, size); - if (&__sanitizer_malloc_hook) __sanitizer_malloc_hook(p, size); RunMallocHooks(p, size); return p; } @@ -120,7 +119,6 @@ static void *Calloc(uptr nmemb, uptr size, const StackTrace &stack) { } void Deallocate(void *p) { - if (&__sanitizer_free_hook) __sanitizer_free_hook(p); RunFreeHooks(p); RegisterDeallocation(p); allocator.Deallocate(GetAllocatorCache(), p); @@ -148,6 +146,8 @@ void GetAllocatorCacheRange(uptr *begin, uptr *end) { } uptr GetMallocUsableSize(const void *p) { + if (!p) + return 0; ChunkMetadata *m = Metadata(p); if (!m) return 0; return m->requested_size; @@ -364,16 +364,4 @@ uptr __sanitizer_get_allocated_size(const void *p) { return GetMallocUsableSize(p); } -#if !SANITIZER_SUPPORTS_WEAK_HOOKS -// Provide default (no-op) implementation of malloc hooks. -SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE -void __sanitizer_malloc_hook(void *ptr, uptr size) { - (void)ptr; - (void)size; -} -SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE -void __sanitizer_free_hook(void *ptr) { - (void)ptr; -} -#endif } // extern "C" diff --git a/contrib/llvm-project/compiler-rt/lib/lsan/lsan_allocator.h b/contrib/llvm-project/compiler-rt/lib/lsan/lsan_allocator.h index 45c6ac406f8a..b67d9d7750ef 100644 --- a/contrib/llvm-project/compiler-rt/lib/lsan/lsan_allocator.h +++ b/contrib/llvm-project/compiler-rt/lib/lsan/lsan_allocator.h @@ -49,8 +49,7 @@ struct ChunkMetadata { u32 stack_trace_id; }; -#if defined(__mips64) || defined(__aarch64__) || defined(__i386__) || \ - defined(__arm__) || SANITIZER_RISCV64 || defined(__hexagon__) +#if !SANITIZER_CAN_USE_ALLOCATOR64 template <typename AddressSpaceViewTy> struct AP32 { static const uptr kSpaceBeg = 0; @@ -65,13 +64,10 @@ struct AP32 { template <typename AddressSpaceView> using PrimaryAllocatorASVT = SizeClassAllocator32<AP32<AddressSpaceView>>; using PrimaryAllocator = PrimaryAllocatorASVT<LocalAddressSpaceView>; -#elif defined(__x86_64__) || defined(__powerpc64__) || defined(__s390x__) -# if SANITIZER_FUCHSIA +#else +# if SANITIZER_FUCHSIA || defined(__powerpc64__) const uptr kAllocatorSpace = ~(uptr)0; const uptr kAllocatorSize = 0x40000000000ULL; // 4T. -# elif defined(__powerpc64__) -const uptr kAllocatorSpace = 0xa0000000000ULL; -const uptr kAllocatorSize = 0x20000000000ULL; // 2T. #elif defined(__s390x__) const uptr kAllocatorSpace = 0x40000000000ULL; const uptr kAllocatorSize = 0x40000000000ULL; // 4T. diff --git a/contrib/llvm-project/compiler-rt/lib/lsan/lsan_common.cpp b/contrib/llvm-project/compiler-rt/lib/lsan/lsan_common.cpp index fd7aa38d99db..d6510d34fd68 100644 --- a/contrib/llvm-project/compiler-rt/lib/lsan/lsan_common.cpp +++ b/contrib/llvm-project/compiler-rt/lib/lsan/lsan_common.cpp @@ -105,7 +105,7 @@ static const char kStdSuppressions[] = // definition. "leak:*pthread_exit*\n" # endif // SANITIZER_SUPPRESS_LEAK_ON_PTHREAD_EXIT -# if SANITIZER_MAC +# if SANITIZER_APPLE // For Darwin and os_log/os_trace: https://reviews.llvm.org/D35173 "leak:*_os_trace*\n" # endif @@ -135,10 +135,11 @@ Suppression *LeakSuppressionContext::GetSuppressionForAddr(uptr addr) { Suppression *s = nullptr; // Suppress by module name. - if (const char *module_name = - Symbolizer::GetOrInit()->GetModuleNameForPc(addr)) - if (context.Match(module_name, kSuppressionLeak, &s)) - return s; + const char *module_name = Symbolizer::GetOrInit()->GetModuleNameForPc(addr); + if (!module_name) + module_name = "<unknown module>"; + if (context.Match(module_name, kSuppressionLeak, &s)) + return s; // Suppress by file or function name. SymbolizedStack *frames = Symbolizer::GetOrInit()->SymbolizePC(addr); @@ -239,7 +240,7 @@ class Decorator : public __sanitizer::SanitizerCommonDecorator { const char *Leak() { return Blue(); } }; -static inline bool CanBeAHeapPointer(uptr p) { +static inline bool MaybeUserPointer(uptr p) { // Since our heap is located in mmap-ed memory, we can assume a sensible lower // bound on heap addresses. const uptr kMinAddress = 4 * 4096; @@ -251,8 +252,8 @@ static inline bool CanBeAHeapPointer(uptr p) { # elif defined(__mips64) return ((p >> 40) == 0); # elif defined(__aarch64__) - unsigned runtimeVMA = (MostSignificantSetBitIndex(GET_CURRENT_FRAME()) + 1); - return ((p >> runtimeVMA) == 0); + // Accept up to 48 bit VMA. + return ((p >> 48) == 0); # else return true; # endif @@ -275,7 +276,7 @@ void ScanRangeForPointers(uptr begin, uptr end, Frontier *frontier, pp = pp + alignment - pp % alignment; for (; pp + sizeof(void *) <= end; pp += alignment) { void *p = *reinterpret_cast<void **>(pp); - if (!CanBeAHeapPointer(reinterpret_cast<uptr>(p))) + if (!MaybeUserPointer(reinterpret_cast<uptr>(p))) continue; uptr chunk = PointsIntoChunk(p); if (!chunk) @@ -1031,13 +1032,11 @@ SANITIZER_INTERFACE_WEAK_DEF(const char *, __lsan_default_options, void) { } #if !SANITIZER_SUPPORTS_WEAK_HOOKS -SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE int -__lsan_is_turned_off() { +SANITIZER_INTERFACE_WEAK_DEF(int, __lsan_is_turned_off, void) { return 0; } -SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE const char * -__lsan_default_suppressions() { +SANITIZER_INTERFACE_WEAK_DEF(const char *, __lsan_default_suppressions, void) { return ""; } #endif diff --git a/contrib/llvm-project/compiler-rt/lib/lsan/lsan_common.h b/contrib/llvm-project/compiler-rt/lib/lsan/lsan_common.h index 6b06c4517cd5..d7153751faee 100644 --- a/contrib/llvm-project/compiler-rt/lib/lsan/lsan_common.h +++ b/contrib/llvm-project/compiler-rt/lib/lsan/lsan_common.h @@ -34,11 +34,11 @@ // is missing. This caused a link error. #if SANITIZER_ANDROID && (__ANDROID_API__ < 28 || defined(__arm__)) # define CAN_SANITIZE_LEAKS 0 -#elif (SANITIZER_LINUX || SANITIZER_MAC) && (SANITIZER_WORDSIZE == 64) && \ +#elif (SANITIZER_LINUX || SANITIZER_APPLE) && (SANITIZER_WORDSIZE == 64) && \ (defined(__x86_64__) || defined(__mips64) || defined(__aarch64__) || \ defined(__powerpc64__) || defined(__s390x__)) # define CAN_SANITIZE_LEAKS 1 -#elif defined(__i386__) && (SANITIZER_LINUX || SANITIZER_MAC) +#elif defined(__i386__) && (SANITIZER_LINUX || SANITIZER_APPLE) # define CAN_SANITIZE_LEAKS 1 #elif defined(__arm__) && SANITIZER_LINUX # define CAN_SANITIZE_LEAKS 1 diff --git a/contrib/llvm-project/compiler-rt/lib/lsan/lsan_common_fuchsia.cpp b/contrib/llvm-project/compiler-rt/lib/lsan/lsan_common_fuchsia.cpp index e5e8cd2b4c23..edb4ca6c8578 100644 --- a/contrib/llvm-project/compiler-rt/lib/lsan/lsan_common_fuchsia.cpp +++ b/contrib/llvm-project/compiler-rt/lib/lsan/lsan_common_fuchsia.cpp @@ -52,7 +52,16 @@ void ProcessPlatformSpecificAllocations(Frontier *frontier) {} // behavior and causes rare race conditions. void HandleLeaks() {} +// This is defined differently in asan_fuchsia.cpp and lsan_fuchsia.cpp. +bool UseExitcodeOnLeak(); + int ExitHook(int status) { + if (common_flags()->detect_leaks && common_flags()->leak_check_at_exit) { + if (UseExitcodeOnLeak()) + DoLeakCheck(); + else + DoRecoverableLeakCheckVoid(); + } return status == 0 && HasReportedLeaks() ? common_flags()->exitcode : status; } diff --git a/contrib/llvm-project/compiler-rt/lib/lsan/lsan_common_mac.cpp b/contrib/llvm-project/compiler-rt/lib/lsan/lsan_common_mac.cpp index a4204740c7fa..26b623fb1d49 100644 --- a/contrib/llvm-project/compiler-rt/lib/lsan/lsan_common_mac.cpp +++ b/contrib/llvm-project/compiler-rt/lib/lsan/lsan_common_mac.cpp @@ -15,7 +15,7 @@ #include "sanitizer_common/sanitizer_libc.h" #include "lsan_common.h" -#if CAN_SANITIZE_LEAKS && SANITIZER_MAC +#if CAN_SANITIZE_LEAKS && SANITIZER_APPLE #include "sanitizer_common/sanitizer_allocator_internal.h" #include "lsan_allocator.h" @@ -201,4 +201,4 @@ void LockStuffAndStopTheWorld(StopTheWorldCallback callback, } // namespace __lsan -#endif // CAN_SANITIZE_LEAKS && SANITIZER_MAC +#endif // CAN_SANITIZE_LEAKS && SANITIZER_APPLE diff --git a/contrib/llvm-project/compiler-rt/lib/lsan/lsan_fuchsia.cpp b/contrib/llvm-project/compiler-rt/lib/lsan/lsan_fuchsia.cpp index cb9f62a0341c..2d96206754a9 100644 --- a/contrib/llvm-project/compiler-rt/lib/lsan/lsan_fuchsia.cpp +++ b/contrib/llvm-project/compiler-rt/lib/lsan/lsan_fuchsia.cpp @@ -76,6 +76,13 @@ void GetAllThreadAllocatorCachesLocked(InternalMmapVector<uptr> *caches) { caches); } +// On Fuchsia, leak detection is done by a special hook after atexit hooks. +// So this doesn't install any atexit hook like on other platforms. +void InstallAtExitCheckLeaks() {} + +// ASan defines this to check its `halt_on_error` flag. +bool UseExitcodeOnLeak() { return true; } + } // namespace __lsan // These are declared (in extern "C") by <zircon/sanitizer.h>. diff --git a/contrib/llvm-project/compiler-rt/lib/lsan/lsan_interceptors.cpp b/contrib/llvm-project/compiler-rt/lib/lsan/lsan_interceptors.cpp index 205e85685a7f..3a1b2afdbb74 100644 --- a/contrib/llvm-project/compiler-rt/lib/lsan/lsan_interceptors.cpp +++ b/contrib/llvm-project/compiler-rt/lib/lsan/lsan_interceptors.cpp @@ -67,7 +67,7 @@ namespace std { enum class align_val_t: size_t; } -#if !SANITIZER_MAC +#if !SANITIZER_APPLE INTERCEPTOR(void*, malloc, uptr size) { if (DlsymAlloc::Use()) return DlsymAlloc::Allocate(size); @@ -116,7 +116,7 @@ INTERCEPTOR(void*, valloc, uptr size) { GET_STACK_TRACE_MALLOC; return lsan_valloc(size, stack); } -#endif // !SANITIZER_MAC +#endif // !SANITIZER_APPLE #if SANITIZER_INTERCEPT_MEMALIGN INTERCEPTOR(void*, memalign, uptr alignment, uptr size) { @@ -242,7 +242,7 @@ INTERCEPTOR(int, mprobe, void *ptr) { // libstdc++, each of has its implementation of new and delete. // To make sure that C++ allocation/deallocation operators are overridden on // OS X we need to intercept them using their mangled names. -#if !SANITIZER_MAC +#if !SANITIZER_APPLE INTERCEPTOR_ATTRIBUTE void *operator new(size_t size) { OPERATOR_NEW_BODY(false /*nothrow*/); } @@ -301,7 +301,7 @@ INTERCEPTOR_ATTRIBUTE void operator delete[](void *ptr, size_t size, std::align_val_t) NOEXCEPT { OPERATOR_DELETE_BODY; } -#else // SANITIZER_MAC +#else // SANITIZER_APPLE INTERCEPTOR(void *, _Znwm, size_t size) { OPERATOR_NEW_BODY(false /*nothrow*/); } @@ -321,7 +321,7 @@ INTERCEPTOR(void, _ZdlPvRKSt9nothrow_t, void *ptr, std::nothrow_t const&) INTERCEPTOR(void, _ZdaPvRKSt9nothrow_t, void *ptr, std::nothrow_t const&) { OPERATOR_DELETE_BODY; } -#endif // !SANITIZER_MAC +#endif // !SANITIZER_APPLE ///// Thread initialization and finalization. ///// diff --git a/contrib/llvm-project/compiler-rt/lib/lsan/lsan_mac.cpp b/contrib/llvm-project/compiler-rt/lib/lsan/lsan_mac.cpp index 10a73f8fa93d..6964a9ba28df 100644 --- a/contrib/llvm-project/compiler-rt/lib/lsan/lsan_mac.cpp +++ b/contrib/llvm-project/compiler-rt/lib/lsan/lsan_mac.cpp @@ -12,7 +12,7 @@ //===----------------------------------------------------------------------===// #include "sanitizer_common/sanitizer_platform.h" -#if SANITIZER_MAC +#if SANITIZER_APPLE #include "interception/interception.h" #include "lsan.h" @@ -188,4 +188,4 @@ INTERCEPTOR(void, dispatch_source_set_event_handler, dispatch_source_t ds, } #endif -#endif // SANITIZER_MAC +#endif // SANITIZER_APPLE diff --git a/contrib/llvm-project/compiler-rt/lib/lsan/lsan_malloc_mac.cpp b/contrib/llvm-project/compiler-rt/lib/lsan/lsan_malloc_mac.cpp index d03eb2e915c0..525c30272ccc 100644 --- a/contrib/llvm-project/compiler-rt/lib/lsan/lsan_malloc_mac.cpp +++ b/contrib/llvm-project/compiler-rt/lib/lsan/lsan_malloc_mac.cpp @@ -12,7 +12,7 @@ //===----------------------------------------------------------------------===// #include "sanitizer_common/sanitizer_platform.h" -#if SANITIZER_MAC +#if SANITIZER_APPLE #include "lsan.h" #include "lsan_allocator.h" @@ -56,4 +56,4 @@ using namespace __lsan; #include "sanitizer_common/sanitizer_malloc_mac.inc" -#endif // SANITIZER_MAC +#endif // SANITIZER_APPLE diff --git a/contrib/llvm-project/compiler-rt/lib/lsan/lsan_posix.cpp b/contrib/llvm-project/compiler-rt/lib/lsan/lsan_posix.cpp index 77118a29f2ea..8f277db22375 100644 --- a/contrib/llvm-project/compiler-rt/lib/lsan/lsan_posix.cpp +++ b/contrib/llvm-project/compiler-rt/lib/lsan/lsan_posix.cpp @@ -91,6 +91,11 @@ void LsanOnDeadlySignal(int signo, void *siginfo, void *context) { nullptr); } +void InstallAtExitCheckLeaks() { + if (common_flags()->detect_leaks && common_flags()->leak_check_at_exit) + Atexit(DoLeakCheck); +} + } // namespace __lsan #endif // SANITIZER_POSIX diff --git a/contrib/llvm-project/compiler-rt/lib/memprof/memprof_allocator.cpp b/contrib/llvm-project/compiler-rt/lib/memprof/memprof_allocator.cpp index 14e7bfe53534..2733051b2e49 100644 --- a/contrib/llvm-project/compiler-rt/lib/memprof/memprof_allocator.cpp +++ b/contrib/llvm-project/compiler-rt/lib/memprof/memprof_allocator.cpp @@ -43,32 +43,32 @@ void Print(const MemInfoBlock &M, const u64 id, bool print_terse) { u64 p; if (print_terse) { - p = M.total_size * 100 / M.alloc_count; - Printf("MIB:%llu/%u/%llu.%02llu/%u/%u/", id, M.alloc_count, p / 100, - p % 100, M.min_size, M.max_size); - p = M.total_access_count * 100 / M.alloc_count; - Printf("%llu.%02llu/%llu/%llu/", p / 100, p % 100, M.min_access_count, - M.max_access_count); - p = M.total_lifetime * 100 / M.alloc_count; - Printf("%llu.%02llu/%u/%u/", p / 100, p % 100, M.min_lifetime, - M.max_lifetime); - Printf("%u/%u/%u/%u\n", M.num_migrated_cpu, M.num_lifetime_overlaps, - M.num_same_alloc_cpu, M.num_same_dealloc_cpu); + p = M.TotalSize * 100 / M.AllocCount; + Printf("MIB:%llu/%u/%llu.%02llu/%u/%u/", id, M.AllocCount, p / 100, p % 100, + M.MinSize, M.MaxSize); + p = M.TotalAccessCount * 100 / M.AllocCount; + Printf("%llu.%02llu/%llu/%llu/", p / 100, p % 100, M.MinAccessCount, + M.MaxAccessCount); + p = M.TotalLifetime * 100 / M.AllocCount; + Printf("%llu.%02llu/%u/%u/", p / 100, p % 100, M.MinLifetime, + M.MaxLifetime); + Printf("%u/%u/%u/%u\n", M.NumMigratedCpu, M.NumLifetimeOverlaps, + M.NumSameAllocCpu, M.NumSameDeallocCpu); } else { - p = M.total_size * 100 / M.alloc_count; + p = M.TotalSize * 100 / M.AllocCount; Printf("Memory allocation stack id = %llu\n", id); Printf("\talloc_count %u, size (ave/min/max) %llu.%02llu / %u / %u\n", - M.alloc_count, p / 100, p % 100, M.min_size, M.max_size); - p = M.total_access_count * 100 / M.alloc_count; + M.AllocCount, p / 100, p % 100, M.MinSize, M.MaxSize); + p = M.TotalAccessCount * 100 / M.AllocCount; Printf("\taccess_count (ave/min/max): %llu.%02llu / %llu / %llu\n", p / 100, - p % 100, M.min_access_count, M.max_access_count); - p = M.total_lifetime * 100 / M.alloc_count; + p % 100, M.MinAccessCount, M.MaxAccessCount); + p = M.TotalLifetime * 100 / M.AllocCount; Printf("\tlifetime (ave/min/max): %llu.%02llu / %u / %u\n", p / 100, - p % 100, M.min_lifetime, M.max_lifetime); + p % 100, M.MinLifetime, M.MaxLifetime); Printf("\tnum migrated: %u, num lifetime overlaps: %u, num same alloc " "cpu: %u, num same dealloc_cpu: %u\n", - M.num_migrated_cpu, M.num_lifetime_overlaps, M.num_same_alloc_cpu, - M.num_same_dealloc_cpu); + M.NumMigratedCpu, M.NumLifetimeOverlaps, M.NumSameAllocCpu, + M.NumSameDeallocCpu); } } } // namespace @@ -430,7 +430,7 @@ struct Allocator { CHECK_LE(alloc_beg + sizeof(LargeChunkHeader), chunk_beg); reinterpret_cast<LargeChunkHeader *>(alloc_beg)->Set(m); } - MEMPROF_MALLOC_HOOK(res, size); + RunMallocHooks(res, size); return res; } @@ -440,7 +440,7 @@ struct Allocator { if (p == 0) return; - MEMPROF_FREE_HOOK(ptr); + RunFreeHooks(ptr); uptr chunk_beg = p - kChunkHeaderSize; MemprofChunk *m = reinterpret_cast<MemprofChunk *>(chunk_beg); @@ -694,19 +694,6 @@ uptr memprof_malloc_usable_size(const void *ptr, uptr pc, uptr bp) { // ---------------------- Interface ---------------- {{{1 using namespace __memprof; -#if !SANITIZER_SUPPORTS_WEAK_HOOKS -// Provide default (no-op) implementation of malloc hooks. -SANITIZER_INTERFACE_WEAK_DEF(void, __sanitizer_malloc_hook, void *ptr, - uptr size) { - (void)ptr; - (void)size; -} - -SANITIZER_INTERFACE_WEAK_DEF(void, __sanitizer_free_hook, void *ptr) { - (void)ptr; -} -#endif - uptr __sanitizer_get_estimated_allocated_size(uptr size) { return size; } int __sanitizer_get_ownership(const void *p) { diff --git a/contrib/llvm-project/compiler-rt/lib/memprof/memprof_internal.h b/contrib/llvm-project/compiler-rt/lib/memprof/memprof_internal.h index 8d227887fe15..1adb368e3e41 100644 --- a/contrib/llvm-project/compiler-rt/lib/memprof/memprof_internal.h +++ b/contrib/llvm-project/compiler-rt/lib/memprof/memprof_internal.h @@ -76,21 +76,6 @@ void PlatformTSDDtor(void *tsd); void *MemprofDlSymNext(const char *sym); -// Add convenient macro for interface functions that may be represented as -// weak hooks. -#define MEMPROF_MALLOC_HOOK(ptr, size) \ - do { \ - if (&__sanitizer_malloc_hook) \ - __sanitizer_malloc_hook(ptr, size); \ - RunMallocHooks(ptr, size); \ - } while (false) -#define MEMPROF_FREE_HOOK(ptr) \ - do { \ - if (&__sanitizer_free_hook) \ - __sanitizer_free_hook(ptr); \ - RunFreeHooks(ptr); \ - } while (false) - extern int memprof_inited; extern int memprof_timestamp_inited; extern int memprof_init_done; diff --git a/contrib/llvm-project/compiler-rt/lib/memprof/memprof_rtl.cpp b/contrib/llvm-project/compiler-rt/lib/memprof/memprof_rtl.cpp index c3d1c5f096fb..21424fb4f072 100644 --- a/contrib/llvm-project/compiler-rt/lib/memprof/memprof_rtl.cpp +++ b/contrib/llvm-project/compiler-rt/lib/memprof/memprof_rtl.cpp @@ -21,6 +21,7 @@ #include "memprof_thread.h" #include "sanitizer_common/sanitizer_atomic.h" #include "sanitizer_common/sanitizer_flags.h" +#include "sanitizer_common/sanitizer_interface_internal.h" #include "sanitizer_common/sanitizer_libc.h" #include "sanitizer_common/sanitizer_symbolizer.h" @@ -38,6 +39,7 @@ static void MemprofDie() { if (atomic_fetch_add(&num_calls, 1, memory_order_relaxed) != 0) { // Don't die twice - run a busy loop. while (1) { + internal_sched_yield(); } } if (common_flags()->print_module_map >= 1) diff --git a/contrib/llvm-project/compiler-rt/lib/memprof/tests/rawprofile.cpp b/contrib/llvm-project/compiler-rt/lib/memprof/tests/rawprofile.cpp index 6181d80fadf6..7f6398d1cf86 100644 --- a/contrib/llvm-project/compiler-rt/lib/memprof/tests/rawprofile.cpp +++ b/contrib/llvm-project/compiler-rt/lib/memprof/tests/rawprofile.cpp @@ -82,8 +82,8 @@ TEST(MemProf, Basic) { // Since we want to override the constructor set vals to make it easier to // test. memset(&FakeMIB, 0, sizeof(MemInfoBlock)); - FakeMIB.alloc_count = 0x1; - FakeMIB.total_access_count = 0x2; + FakeMIB.AllocCount = 0x1; + FakeMIB.TotalAccessCount = 0x2; uint64_t FakeIds[2]; FakeIds[0] = PopulateFakeMap(FakeMIB, /*StackPCBegin=*/2, FakeMap); diff --git a/contrib/llvm-project/compiler-rt/lib/msan/msan.cpp b/contrib/llvm-project/compiler-rt/lib/msan/msan.cpp index c554a830e755..2c0f849b999a 100644 --- a/contrib/llvm-project/compiler-rt/lib/msan/msan.cpp +++ b/contrib/llvm-project/compiler-rt/lib/msan/msan.cpp @@ -12,20 +12,22 @@ //===----------------------------------------------------------------------===// #include "msan.h" + #include "msan_chained_origin_depot.h" #include "msan_origin.h" +#include "msan_poisoning.h" #include "msan_report.h" #include "msan_thread.h" -#include "msan_poisoning.h" #include "sanitizer_common/sanitizer_atomic.h" #include "sanitizer_common/sanitizer_common.h" -#include "sanitizer_common/sanitizer_flags.h" #include "sanitizer_common/sanitizer_flag_parser.h" +#include "sanitizer_common/sanitizer_flags.h" +#include "sanitizer_common/sanitizer_interface_internal.h" #include "sanitizer_common/sanitizer_libc.h" #include "sanitizer_common/sanitizer_procmaps.h" +#include "sanitizer_common/sanitizer_stackdepot.h" #include "sanitizer_common/sanitizer_stacktrace.h" #include "sanitizer_common/sanitizer_symbolizer.h" -#include "sanitizer_common/sanitizer_stackdepot.h" #include "ubsan/ubsan_flags.h" #include "ubsan/ubsan_init.h" @@ -67,8 +69,6 @@ THREADLOCAL u64 __msan_va_arg_overflow_size_tls; SANITIZER_INTERFACE_ATTRIBUTE THREADLOCAL u32 __msan_origin_tls; -static THREADLOCAL int is_in_symbolizer; - extern "C" SANITIZER_WEAK_ATTRIBUTE const int __msan_track_origins; int __msan_get_track_origins() { @@ -79,15 +79,19 @@ extern "C" SANITIZER_WEAK_ATTRIBUTE const int __msan_keep_going; namespace __msan { -void EnterSymbolizer() { ++is_in_symbolizer; } -void ExitSymbolizer() { --is_in_symbolizer; } -bool IsInSymbolizer() { return is_in_symbolizer; } +static THREADLOCAL int is_in_symbolizer_or_unwinder; +static void EnterSymbolizerOrUnwider() { ++is_in_symbolizer_or_unwinder; } +static void ExitSymbolizerOrUnwider() { --is_in_symbolizer_or_unwinder; } +bool IsInSymbolizerOrUnwider() { return is_in_symbolizer_or_unwinder; } + +struct UnwinderScope { + UnwinderScope() { EnterSymbolizerOrUnwider(); } + ~UnwinderScope() { ExitSymbolizerOrUnwider(); } +}; static Flags msan_flags; -Flags *flags() { - return &msan_flags; -} +Flags *flags() { return &msan_flags; } int msan_inited = 0; bool msan_init_is_running; @@ -299,7 +303,7 @@ u32 ChainOrigin(u32 id, StackTrace *stack) { return chained.raw_id(); } -} // namespace __msan +} // namespace __msan void __sanitizer::BufferedStackTrace::UnwindImpl( uptr pc, uptr bp, void *context, bool request_fast, u32 max_depth) { @@ -307,7 +311,7 @@ void __sanitizer::BufferedStackTrace::UnwindImpl( MsanThread *t = GetCurrentThread(); if (!t || !StackTrace::WillUseFastUnwind(request_fast)) { // Block reports from our interceptors during _Unwind_Backtrace. - SymbolizerScope sym_scope; + UnwinderScope sym_scope; return Unwind(max_depth, pc, bp, context, t ? t->stack_top() : 0, t ? t->stack_bottom() : 0, false); } @@ -460,7 +464,8 @@ void __msan_init() { Die(); } - Symbolizer::GetOrInit()->AddHooks(EnterSymbolizer, ExitSymbolizer); + Symbolizer::GetOrInit()->AddHooks(EnterSymbolizerOrUnwider, + ExitSymbolizerOrUnwider); InitializeCoverage(common_flags()->coverage, common_flags()->coverage_dir); diff --git a/contrib/llvm-project/compiler-rt/lib/msan/msan.h b/contrib/llvm-project/compiler-rt/lib/msan/msan.h index 4b2cec31756a..30efce94af54 100644 --- a/contrib/llvm-project/compiler-rt/lib/msan/msan.h +++ b/contrib/llvm-project/compiler-rt/lib/msan/msan.h @@ -314,14 +314,7 @@ void InstallAtExitHandler(); const char *GetStackOriginDescr(u32 id, uptr *pc); -void EnterSymbolizer(); -void ExitSymbolizer(); -bool IsInSymbolizer(); - -struct SymbolizerScope { - SymbolizerScope() { EnterSymbolizer(); } - ~SymbolizerScope() { ExitSymbolizer(); } -}; +bool IsInSymbolizerOrUnwider(); void PrintWarning(uptr pc, uptr bp); void PrintWarningWithOrigin(uptr pc, uptr bp, u32 origin); @@ -382,21 +375,4 @@ void MsanTSDDtor(void *tsd); } // namespace __msan -#define MSAN_MALLOC_HOOK(ptr, size) \ - do { \ - if (&__sanitizer_malloc_hook) { \ - UnpoisonParam(2); \ - __sanitizer_malloc_hook(ptr, size); \ - } \ - RunMallocHooks(ptr, size); \ - } while (false) -#define MSAN_FREE_HOOK(ptr) \ - do { \ - if (&__sanitizer_free_hook) { \ - UnpoisonParam(1); \ - __sanitizer_free_hook(ptr); \ - } \ - RunFreeHooks(ptr); \ - } while (false) - #endif // MSAN_H diff --git a/contrib/llvm-project/compiler-rt/lib/msan/msan_allocator.cpp b/contrib/llvm-project/compiler-rt/lib/msan/msan_allocator.cpp index dc006457a59f..0d5e85329850 100644 --- a/contrib/llvm-project/compiler-rt/lib/msan/msan_allocator.cpp +++ b/contrib/llvm-project/compiler-rt/lib/msan/msan_allocator.cpp @@ -194,13 +194,16 @@ static void *MsanAllocate(StackTrace *stack, uptr size, uptr alignment, __msan_set_origin(allocated, size, o.raw_id()); } } - MSAN_MALLOC_HOOK(allocated, size); + UnpoisonParam(2); + RunMallocHooks(allocated, size); return allocated; } void MsanDeallocate(StackTrace *stack, void *p) { CHECK(p); - MSAN_FREE_HOOK(p); + UnpoisonParam(1); + RunFreeHooks(p); + Metadata *meta = reinterpret_cast<Metadata *>(allocator.GetMetaData(p)); uptr size = meta->requested_size; meta->requested_size = 0; diff --git a/contrib/llvm-project/compiler-rt/lib/msan/msan_flags.inc b/contrib/llvm-project/compiler-rt/lib/msan/msan_flags.inc index e6a26015a22a..16db26bd42ed 100644 --- a/contrib/llvm-project/compiler-rt/lib/msan/msan_flags.inc +++ b/contrib/llvm-project/compiler-rt/lib/msan/msan_flags.inc @@ -24,7 +24,7 @@ MSAN_FLAG(bool, poison_heap_with_zeroes, false, "") MSAN_FLAG(bool, poison_stack_with_zeroes, false, "") MSAN_FLAG(bool, poison_in_malloc, true, "") MSAN_FLAG(bool, poison_in_free, true, "") -MSAN_FLAG(bool, poison_in_dtor, false, "") +MSAN_FLAG(bool, poison_in_dtor, true, "") MSAN_FLAG(bool, report_umrs, true, "") MSAN_FLAG(bool, wrap_signals, true, "") MSAN_FLAG(bool, print_stats, false, "") diff --git a/contrib/llvm-project/compiler-rt/lib/msan/msan_interceptors.cpp b/contrib/llvm-project/compiler-rt/lib/msan/msan_interceptors.cpp index 5317af6982a0..c4a9e88655fe 100644 --- a/contrib/llvm-project/compiler-rt/lib/msan/msan_interceptors.cpp +++ b/contrib/llvm-project/compiler-rt/lib/msan/msan_interceptors.cpp @@ -90,7 +90,8 @@ struct DlsymAlloc : public DlSymAllocator<DlsymAlloc> { #define CHECK_UNPOISONED_0(x, n) \ do { \ sptr __offset = __msan_test_shadow(x, n); \ - if (__msan::IsInSymbolizer()) break; \ + if (__msan::IsInSymbolizerOrUnwider()) \ + break; \ if (__offset >= 0 && __msan::flags()->report_umrs) { \ GET_CALLER_PC_BP_SP; \ (void)sp; \ @@ -666,6 +667,19 @@ INTERCEPTOR(int, fstat, int fd, void *buf) { #define MSAN_MAYBE_INTERCEPT_FSTAT #endif +#if SANITIZER_STAT_LINUX +INTERCEPTOR(int, fstat64, int fd, void *buf) { + ENSURE_MSAN_INITED(); + int res = REAL(fstat64)(fd, buf); + if (!res) + __msan_unpoison(buf, __sanitizer::struct_stat64_sz); + return res; +} +# define MSAN_MAYBE_INTERCEPT_FSTAT64 MSAN_INTERCEPT_FUNC(fstat64) +#else +# define MSAN_MAYBE_INTERCEPT_FSTAT64 +#endif + #if SANITIZER_GLIBC INTERCEPTOR(int, __fxstat, int magic, int fd, void *buf) { ENSURE_MSAN_INITED(); @@ -704,6 +718,19 @@ INTERCEPTOR(int, fstatat, int fd, char *pathname, void *buf, int flags) { # define MSAN_MAYBE_INTERCEPT_FSTATAT #endif +#if SANITIZER_STAT_LINUX +INTERCEPTOR(int, fstatat64, int fd, char *pathname, void *buf, int flags) { + ENSURE_MSAN_INITED(); + int res = REAL(fstatat64)(fd, pathname, buf, flags); + if (!res) + __msan_unpoison(buf, __sanitizer::struct_stat64_sz); + return res; +} +# define MSAN_MAYBE_INTERCEPT_FSTATAT64 MSAN_INTERCEPT_FUNC(fstatat64) +#else +# define MSAN_MAYBE_INTERCEPT_FSTATAT64 +#endif + #if SANITIZER_GLIBC INTERCEPTOR(int, __fxstatat, int magic, int fd, char *pathname, void *buf, int flags) { @@ -1436,6 +1463,15 @@ static uptr signal_impl(int signo, uptr cb) { #include "sanitizer_common/sanitizer_common_syscalls.inc" #include "sanitizer_common/sanitizer_syscalls_netbsd.inc" +INTERCEPTOR(const char *, strsignal, int sig) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, strsignal, sig); + const char *res = REAL(strsignal)(sig); + if (res) + __msan_unpoison(res, internal_strlen(res) + 1); + return res; +} + struct dlinfo { char *dli_fname; void *dli_fbase; @@ -1564,7 +1600,7 @@ void __msan_clear_and_unpoison(void *a, uptr size) { void *__msan_memcpy(void *dest, const void *src, SIZE_T n) { if (!msan_inited) return internal_memcpy(dest, src, n); - if (msan_init_is_running || __msan::IsInSymbolizer()) + if (msan_init_is_running || __msan::IsInSymbolizerOrUnwider()) return REAL(memcpy)(dest, src, n); ENSURE_MSAN_INITED(); GET_STORE_STACK_TRACE; @@ -1682,8 +1718,10 @@ void InitializeInterceptors() { INTERCEPT_FUNCTION(gettimeofday); MSAN_MAYBE_INTERCEPT_FCVT; MSAN_MAYBE_INTERCEPT_FSTAT; + MSAN_MAYBE_INTERCEPT_FSTAT64; MSAN_MAYBE_INTERCEPT___FXSTAT; MSAN_MAYBE_INTERCEPT_FSTATAT; + MSAN_MAYBE_INTERCEPT_FSTATAT64; MSAN_MAYBE_INTERCEPT___FXSTATAT; MSAN_MAYBE_INTERCEPT___FXSTAT64; MSAN_MAYBE_INTERCEPT___FXSTATAT64; @@ -1699,6 +1737,7 @@ void InitializeInterceptors() { INTERCEPT_FUNCTION(gethostname); MSAN_MAYBE_INTERCEPT_EPOLL_WAIT; MSAN_MAYBE_INTERCEPT_EPOLL_PWAIT; + INTERCEPT_FUNCTION(strsignal); INTERCEPT_FUNCTION(dladdr); INTERCEPT_FUNCTION(dlerror); INTERCEPT_FUNCTION(dl_iterate_phdr); diff --git a/contrib/llvm-project/compiler-rt/lib/orc/adt.h b/contrib/llvm-project/compiler-rt/lib/orc/adt.h index 3a422871c47b..64afd5d4ad56 100644 --- a/contrib/llvm-project/compiler-rt/lib/orc/adt.h +++ b/contrib/llvm-project/compiler-rt/lib/orc/adt.h @@ -15,6 +15,7 @@ #include <cstring> #include <limits> +#include <ostream> #include <string> namespace __orc_rt { @@ -76,6 +77,7 @@ public: constexpr string_view(const char *S, size_type Count) : Data(S), Size(Count) {} string_view(const char *S) : Data(S), Size(strlen(S)) {} + string_view(const std::string &S) : Data(S.data()), Size(S.size()) {} constexpr const_iterator begin() const noexcept { return Data; } constexpr const_iterator end() const noexcept { return Data + Size; } @@ -104,10 +106,23 @@ private: size_type Size = 0; }; -inline std::string to_string(string_view SV) { - return std::string(SV.data(), SV.size()); +inline std::ostream &operator<<(std::ostream &OS, string_view S) { + return OS.write(S.data(), S.size()); } } // end namespace __orc_rt +namespace std { +// Make string_view hashable. +// FIXME: This can be removed (along with the string_view class) when we move +// to C++17. +template <> struct hash<__orc_rt::string_view> { + size_t operator()(const __orc_rt::string_view &S) const { + std::string Tmp(S.data(), S.size()); + return hash<std::string>()(Tmp); + } +}; + +} // namespace std + #endif // ORC_RT_ADT_H diff --git a/contrib/llvm-project/compiler-rt/lib/orc/c_api.h b/contrib/llvm-project/compiler-rt/lib/orc/c_api.h deleted file mode 100644 index 47f46b891d96..000000000000 --- a/contrib/llvm-project/compiler-rt/lib/orc/c_api.h +++ /dev/null @@ -1,208 +0,0 @@ -/*===- c_api.h - C API for the ORC runtime ------------------------*- C -*-===*\ -|* *| -|* Part of the LLVM Project, under the Apache License v2.0 with LLVM *| -|* Exceptions. *| -|* See https://llvm.org/LICENSE.txt for license information. *| -|* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception *| -|* *| -|*===----------------------------------------------------------------------===*| -|* *| -|* This file defines the C API for the ORC runtime *| -|* *| -|* NOTE: The OrtRTWrapperFunctionResult type must be kept in sync with the *| -|* definition in llvm/include/llvm-c/OrcShared.h. *| -|* *| -\*===----------------------------------------------------------------------===*/ - -#ifndef ORC_RT_C_API_H -#define ORC_RT_C_API_H - -#include <assert.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -/* Helper to suppress strict prototype warnings. */ -#ifdef __clang__ -#define ORC_RT_C_STRICT_PROTOTYPES_BEGIN \ - _Pragma("clang diagnostic push") \ - _Pragma("clang diagnostic error \"-Wstrict-prototypes\"") -#define ORC_RT_C_STRICT_PROTOTYPES_END _Pragma("clang diagnostic pop") -#else -#define ORC_RT_C_STRICT_PROTOTYPES_BEGIN -#define ORC_RT_C_STRICT_PROTOTYPES_END -#endif - -/* Helper to wrap C code for C++ */ -#ifdef __cplusplus -#define ORC_RT_C_EXTERN_C_BEGIN \ - extern "C" { \ - ORC_RT_C_STRICT_PROTOTYPES_BEGIN -#define ORC_RT_C_EXTERN_C_END \ - ORC_RT_C_STRICT_PROTOTYPES_END \ - } -#else -#define ORC_RT_C_EXTERN_C_BEGIN ORC_RT_C_STRICT_PROTOTYPES_BEGIN -#define ORC_RT_C_EXTERN_C_END ORC_RT_C_STRICT_PROTOTYPES_END -#endif - -ORC_RT_C_EXTERN_C_BEGIN - -typedef union { - char *ValuePtr; - char Value[sizeof(char *)]; -} __orc_rt_CWrapperFunctionResultDataUnion; - -/** - * __orc_rt_CWrapperFunctionResult is a kind of C-SmallVector with an - * out-of-band error state. - * - * If Size == 0 and Data.ValuePtr is non-zero then the value is in the - * 'out-of-band error' state, and Data.ValuePtr points at a malloc-allocated, - * null-terminated string error message. - * - * If Size <= sizeof(__orc_rt_CWrapperFunctionResultData) then the value is in - * the 'small' state and the content is held in the first Size bytes of - * Data.Value. - * - * If Size > sizeof(OrtRTCWrapperFunctionResultData) then the value is in the - * 'large' state and the content is held in the first Size bytes of the - * memory pointed to by Data.ValuePtr. This memory must have been allocated by - * malloc, and will be freed with free when this value is destroyed. - */ -typedef struct { - __orc_rt_CWrapperFunctionResultDataUnion Data; - size_t Size; -} __orc_rt_CWrapperFunctionResult; - -typedef struct __orc_rt_CSharedOpaqueJITProcessControl - *__orc_rt_SharedJITProcessControlRef; - -/** - * Zero-initialize an __orc_rt_CWrapperFunctionResult. - */ -static inline void -__orc_rt_CWrapperFunctionResultInit(__orc_rt_CWrapperFunctionResult *R) { - R->Size = 0; - R->Data.ValuePtr = 0; -} - -/** - * Create an __orc_rt_CWrapperFunctionResult with an uninitialized buffer of - * size Size. The buffer is returned via the DataPtr argument. - */ -static inline __orc_rt_CWrapperFunctionResult -__orc_rt_CWrapperFunctionResultAllocate(size_t Size) { - __orc_rt_CWrapperFunctionResult R; - R.Size = Size; - // If Size is 0 ValuePtr must be 0 or it is considered an out-of-band error. - R.Data.ValuePtr = 0; - if (Size > sizeof(R.Data.Value)) - R.Data.ValuePtr = (char *)malloc(Size); - return R; -} - -/** - * Create an __orc_rt_WrapperFunctionResult from the given data range. - */ -static inline __orc_rt_CWrapperFunctionResult -__orc_rt_CreateCWrapperFunctionResultFromRange(const char *Data, size_t Size) { - __orc_rt_CWrapperFunctionResult R; - R.Size = Size; - if (R.Size > sizeof(R.Data.Value)) { - char *Tmp = (char *)malloc(Size); - memcpy(Tmp, Data, Size); - R.Data.ValuePtr = Tmp; - } else - memcpy(R.Data.Value, Data, Size); - return R; -} - -/** - * Create an __orc_rt_CWrapperFunctionResult by copying the given string, - * including the null-terminator. - * - * This function copies the input string. The client is responsible for freeing - * the ErrMsg arg. - */ -static inline __orc_rt_CWrapperFunctionResult -__orc_rt_CreateCWrapperFunctionResultFromString(const char *Source) { - return __orc_rt_CreateCWrapperFunctionResultFromRange(Source, - strlen(Source) + 1); -} - -/** - * Create an __orc_rt_CWrapperFunctionResult representing an out-of-band - * error. - * - * This function copies the input string. The client is responsible for freeing - * the ErrMsg arg. - */ -static inline __orc_rt_CWrapperFunctionResult -__orc_rt_CreateCWrapperFunctionResultFromOutOfBandError(const char *ErrMsg) { - __orc_rt_CWrapperFunctionResult R; - R.Size = 0; - char *Tmp = (char *)malloc(strlen(ErrMsg) + 1); - strcpy(Tmp, ErrMsg); - R.Data.ValuePtr = Tmp; - return R; -} - -/** - * This should be called to destroy __orc_rt_CWrapperFunctionResult values - * regardless of their state. - */ -static inline void -__orc_rt_DisposeCWrapperFunctionResult(__orc_rt_CWrapperFunctionResult *R) { - if (R->Size > sizeof(R->Data.Value) || - (R->Size == 0 && R->Data.ValuePtr)) - free(R->Data.ValuePtr); -} - -/** - * Get a pointer to the data contained in the given - * __orc_rt_CWrapperFunctionResult. - */ -static inline char * -__orc_rt_CWrapperFunctionResultData(__orc_rt_CWrapperFunctionResult *R) { - assert((R->Size != 0 || R->Data.ValuePtr == NULL) && - "Cannot get data for out-of-band error value"); - return R->Size > sizeof(R->Data.Value) ? R->Data.ValuePtr : R->Data.Value; -} - -/** - * Safely get the size of the given __orc_rt_CWrapperFunctionResult. - * - * Asserts that we're not trying to access the size of an error value. - */ -static inline size_t -__orc_rt_CWrapperFunctionResultSize(const __orc_rt_CWrapperFunctionResult *R) { - assert((R->Size != 0 || R->Data.ValuePtr == NULL) && - "Cannot get size for out-of-band error value"); - return R->Size; -} - -/** - * Returns 1 if this value is equivalent to a value just initialized by - * __orc_rt_CWrapperFunctionResultInit, 0 otherwise. - */ -static inline size_t -__orc_rt_CWrapperFunctionResultEmpty(const __orc_rt_CWrapperFunctionResult *R) { - return R->Size == 0 && R->Data.ValuePtr == 0; -} - -/** - * Returns a pointer to the out-of-band error string for this - * __orc_rt_CWrapperFunctionResult, or null if there is no error. - * - * The __orc_rt_CWrapperFunctionResult retains ownership of the error - * string, so it should be copied if the caller wishes to preserve it. - */ -static inline const char *__orc_rt_CWrapperFunctionResultGetOutOfBandError( - const __orc_rt_CWrapperFunctionResult *R) { - return R->Size == 0 ? R->Data.ValuePtr : 0; -} - -ORC_RT_C_EXTERN_C_END - -#endif /* ORC_RT_C_API_H */ diff --git a/contrib/llvm-project/compiler-rt/lib/orc/common.h b/contrib/llvm-project/compiler-rt/lib/orc/common.h index 54e613ecb42e..61ac8b91c6e2 100644 --- a/contrib/llvm-project/compiler-rt/lib/orc/common.h +++ b/contrib/llvm-project/compiler-rt/lib/orc/common.h @@ -13,8 +13,8 @@ #ifndef ORC_RT_COMMON_H #define ORC_RT_COMMON_H -#include "c_api.h" #include "compiler.h" +#include "orc/c_api.h" #include <type_traits> /// This macro should be used to define tags that will be associated with diff --git a/contrib/llvm-project/compiler-rt/lib/orc/dlfcn_wrapper.cpp b/contrib/llvm-project/compiler-rt/lib/orc/dlfcn_wrapper.cpp new file mode 100644 index 000000000000..c513aae97bb3 --- /dev/null +++ b/contrib/llvm-project/compiler-rt/lib/orc/dlfcn_wrapper.cpp @@ -0,0 +1,52 @@ +//===- dlfcn_wrapper.cpp --------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file is a part of the ORC runtime support library. +// +//===----------------------------------------------------------------------===// + +#include "adt.h" +#include "common.h" +#include "wrapper_function_utils.h" + +#include <vector> + +using namespace __orc_rt; + +extern "C" const char *__orc_rt_jit_dlerror(); +extern "C" void *__orc_rt_jit_dlopen(const char *path, int mode); +extern "C" int __orc_rt_jit_dlclose(void *dso_handle); + +ORC_RT_INTERFACE __orc_rt_CWrapperFunctionResult +__orc_rt_jit_dlerror_wrapper(const char *ArgData, size_t ArgSize) { + return WrapperFunction<SPSString()>::handle( + ArgData, ArgSize, + []() { return std::string(__orc_rt_jit_dlerror()); }) + .release(); +} + +ORC_RT_INTERFACE __orc_rt_CWrapperFunctionResult +__orc_rt_jit_dlopen_wrapper(const char *ArgData, size_t ArgSize) { + return WrapperFunction<SPSExecutorAddr(SPSString, int32_t)>::handle( + ArgData, ArgSize, + [](const std::string &Path, int32_t mode) { + return ExecutorAddr::fromPtr( + __orc_rt_jit_dlopen(Path.c_str(), mode)); + }) + .release(); +} + +ORC_RT_INTERFACE __orc_rt_CWrapperFunctionResult +__orc_rt_jit_dlclose_wrapper(const char *ArgData, size_t ArgSize) { + return WrapperFunction<int32_t(SPSExecutorAddr)>::handle( + ArgData, ArgSize, + [](ExecutorAddr &DSOHandle) { + return __orc_rt_jit_dlclose(DSOHandle.toPtr<void *>()); + }) + .release(); +} diff --git a/contrib/llvm-project/compiler-rt/lib/orc/elfnix_platform.cpp b/contrib/llvm-project/compiler-rt/lib/orc/elfnix_platform.cpp index 0352f6c4e853..6f502b20f8ca 100644 --- a/contrib/llvm-project/compiler-rt/lib/orc/elfnix_platform.cpp +++ b/contrib/llvm-project/compiler-rt/lib/orc/elfnix_platform.cpp @@ -15,6 +15,7 @@ #include "error.h" #include "wrapper_function_utils.h" +#include <algorithm> #include <map> #include <mutex> #include <sstream> @@ -29,10 +30,10 @@ ORC_RT_JIT_DISPATCH_TAG(__orc_rt_elfnix_get_initializers_tag) ORC_RT_JIT_DISPATCH_TAG(__orc_rt_elfnix_get_deinitializers_tag) ORC_RT_JIT_DISPATCH_TAG(__orc_rt_elfnix_symbol_lookup_tag) -// eh-frame registration functions. -// We expect these to be available for all processes. -extern "C" void __register_frame(const void *); -extern "C" void __deregister_frame(const void *); +// eh-frame registration functions, made available via aliases +// installed by the Platform +extern "C" void __orc_rt_register_eh_frame_section(const void *); +extern "C" void __orc_rt_deregister_eh_frame_section(const void *); namespace { @@ -133,12 +134,6 @@ private: static ELFNixPlatformRuntimeState *MOPS; - using InitSectionHandler = - Error (*)(const std::vector<ExecutorAddrRange> &Sections, - const ELFNixJITDylibInitializers &MOJDIs); - const std::vector<std::pair<const char *, InitSectionHandler>> InitSections = - {{".init_array", runInitArray}}; - void *PlatformJDDSOHandle; // FIXME: Move to thread-state. @@ -172,7 +167,8 @@ void ELFNixPlatformRuntimeState::destroy() { Error ELFNixPlatformRuntimeState::registerObjectSections( ELFNixPerObjectSectionsToRegister POSR) { if (POSR.EHFrameSection.Start) - __register_frame(POSR.EHFrameSection.Start.toPtr<const char *>()); + __orc_rt_register_eh_frame_section( + POSR.EHFrameSection.Start.toPtr<const char *>()); if (POSR.ThreadDataSection.Start) { if (auto Err = registerThreadDataSection( @@ -186,7 +182,8 @@ Error ELFNixPlatformRuntimeState::registerObjectSections( Error ELFNixPlatformRuntimeState::deregisterObjectSections( ELFNixPerObjectSectionsToRegister POSR) { if (POSR.EHFrameSection.Start) - __deregister_frame(POSR.EHFrameSection.Start.toPtr<const char *>()); + __orc_rt_deregister_eh_frame_section( + POSR.EHFrameSection.Start.toPtr<const char *>()); return Error::success(); } @@ -376,21 +373,29 @@ Expected<void *> ELFNixPlatformRuntimeState::dlopenInitialize(string_view Path, return JDS->Header; } +long getPriority(const std::string &name) { + auto pos = name.find_last_not_of("0123456789"); + if (pos == name.size() - 1) + return 65535; + else + return std::strtol(name.c_str() + pos + 1, nullptr, 10); +} + Error ELFNixPlatformRuntimeState::initializeJITDylib( ELFNixJITDylibInitializers &MOJDIs) { auto &JDS = getOrCreateJITDylibState(MOJDIs); ++JDS.RefCount; - for (auto &KV : InitSections) { - const auto &Name = KV.first; - const auto &Handler = KV.second; - auto I = MOJDIs.InitSections.find(Name); - if (I != MOJDIs.InitSections.end()) { - if (auto Err = Handler(I->second, MOJDIs)) - return Err; - } - } + using SectionList = std::vector<ExecutorAddrRange>; + std::sort(MOJDIs.InitSections.begin(), MOJDIs.InitSections.end(), + [](const std::pair<std::string, SectionList> &LHS, + const std::pair<std::string, SectionList> &RHS) -> bool { + return getPriority(LHS.first) < getPriority(RHS.first); + }); + for (auto &Entry : MOJDIs.InitSections) + if (auto Err = runInitArray(Entry.second, MOJDIs)) + return Err; return Error::success(); } diff --git a/contrib/llvm-project/compiler-rt/lib/orc/elfnix_platform.h b/contrib/llvm-project/compiler-rt/lib/orc/elfnix_platform.h index 12b9591979b7..e0ee9591dfc6 100644 --- a/contrib/llvm-project/compiler-rt/lib/orc/elfnix_platform.h +++ b/contrib/llvm-project/compiler-rt/lib/orc/elfnix_platform.h @@ -47,7 +47,7 @@ struct ELFNixJITDylibInitializers { std::string Name; ExecutorAddr DSOHandleAddress; - std::unordered_map<std::string, SectionList> InitSections; + std::vector<std::pair<std::string, SectionList>> InitSections; }; class ELFNixJITDylibDeinitializers {}; diff --git a/contrib/llvm-project/compiler-rt/lib/orc/executor_address.h b/contrib/llvm-project/compiler-rt/lib/orc/executor_address.h index 79ad9b7f1409..f8f417cb636d 100644 --- a/contrib/llvm-project/compiler-rt/lib/orc/executor_address.h +++ b/contrib/llvm-project/compiler-rt/lib/orc/executor_address.h @@ -212,4 +212,15 @@ using SPSExecutorAddrRangeSequence = SPSSequence<SPSExecutorAddrRange>; } // End namespace __orc_rt +namespace std { + +// Make ExecutorAddr hashable. +template <> struct hash<__orc_rt::ExecutorAddr> { + size_t operator()(const __orc_rt::ExecutorAddr &A) const { + return hash<uint64_t>()(A.getValue()); + } +}; + +} // namespace std + #endif // ORC_RT_EXECUTOR_ADDRESS_H diff --git a/contrib/llvm-project/compiler-rt/lib/orc/macho_ehframe_registration.cpp b/contrib/llvm-project/compiler-rt/lib/orc/macho_ehframe_registration.cpp index f077cea96820..112f0dc390a6 100644 --- a/contrib/llvm-project/compiler-rt/lib/orc/macho_ehframe_registration.cpp +++ b/contrib/llvm-project/compiler-rt/lib/orc/macho_ehframe_registration.cpp @@ -11,9 +11,9 @@ //===----------------------------------------------------------------------===// #include "adt.h" -#include "c_api.h" #include "common.h" #include "executor_address.h" +#include "orc/c_api.h" #include "wrapper_function_utils.h" using namespace __orc_rt; diff --git a/contrib/llvm-project/compiler-rt/lib/orc/macho_platform.cpp b/contrib/llvm-project/compiler-rt/lib/orc/macho_platform.cpp index f2cca8eb829a..6552b666847e 100644 --- a/contrib/llvm-project/compiler-rt/lib/orc/macho_platform.cpp +++ b/contrib/llvm-project/compiler-rt/lib/orc/macho_platform.cpp @@ -12,21 +12,26 @@ #include "macho_platform.h" #include "common.h" +#include "debug.h" #include "error.h" #include "wrapper_function_utils.h" +#include <algorithm> +#include <ios> #include <map> #include <mutex> #include <sstream> #include <unordered_map> +#include <unordered_set> #include <vector> +#define DEBUG_TYPE "macho_platform" + using namespace __orc_rt; using namespace __orc_rt::macho; // Declare function tags for functions in the JIT process. -ORC_RT_JIT_DISPATCH_TAG(__orc_rt_macho_get_initializers_tag) -ORC_RT_JIT_DISPATCH_TAG(__orc_rt_macho_get_deinitializers_tag) +ORC_RT_JIT_DISPATCH_TAG(__orc_rt_macho_push_initializers_tag) ORC_RT_JIT_DISPATCH_TAG(__orc_rt_macho_symbol_lookup_tag) // Objective-C types. @@ -66,147 +71,47 @@ extern "C" void swift_registerTypeMetadataRecords( namespace { -Error validatePointerSectionExtent(const char *SectionName, - const ExecutorAddrRange &SE) { - if (SE.size().getValue() % sizeof(uintptr_t)) { - std::ostringstream ErrMsg; - ErrMsg << std::hex << "Size of " << SectionName << " 0x" - << SE.Start.getValue() << " -- 0x" << SE.End.getValue() - << " is not a pointer multiple"; - return make_error<StringError>(ErrMsg.str()); - } - return Error::success(); -} - -Error registerObjCSelectors( - const std::vector<ExecutorAddrRange> &ObjCSelRefsSections, - const MachOJITDylibInitializers &MOJDIs) { - - if (ORC_RT_UNLIKELY(!sel_registerName)) - return make_error<StringError>("sel_registerName is not available"); - - for (const auto &ObjCSelRefs : ObjCSelRefsSections) { - - if (auto Err = validatePointerSectionExtent("__objc_selrefs", ObjCSelRefs)) - return Err; - - for (uintptr_t &SelEntry : ObjCSelRefs.toSpan<uintptr_t>()) { - const char *SelName = reinterpret_cast<const char *>(SelEntry); - auto Sel = sel_registerName(SelName); - *reinterpret_cast<SEL *>(&SelEntry) = Sel; - } - } - - return Error::success(); -} - -Error registerObjCClasses( - const std::vector<ExecutorAddrRange> &ObjCClassListSections, - const MachOJITDylibInitializers &MOJDIs) { +struct MachOJITDylibDepInfo { + bool Sealed = false; + std::vector<ExecutorAddr> DepHeaders; +}; - if (ObjCClassListSections.empty()) - return Error::success(); +using MachOJITDylibDepInfoMap = + std::unordered_map<ExecutorAddr, MachOJITDylibDepInfo>; - if (ORC_RT_UNLIKELY(!objc_msgSend)) - return make_error<StringError>("objc_msgSend is not available"); - if (ORC_RT_UNLIKELY(!objc_readClassPair)) - return make_error<StringError>("objc_readClassPair is not available"); - - struct ObjCClassCompiled { - void *Metaclass; - void *Parent; - void *Cache1; - void *Cache2; - void *Data; - }; +} // anonymous namespace - auto *ImageInfo = - MOJDIs.ObjCImageInfoAddress.toPtr<const objc_image_info *>(); - auto ClassSelector = sel_registerName("class"); +namespace __orc_rt { - for (const auto &ObjCClassList : ObjCClassListSections) { +using SPSMachOObjectPlatformSectionsMap = + SPSSequence<SPSTuple<SPSString, SPSExecutorAddrRange>>; - if (auto Err = - validatePointerSectionExtent("__objc_classlist", ObjCClassList)) - return Err; +using SPSMachOJITDylibDepInfo = SPSTuple<bool, SPSSequence<SPSExecutorAddr>>; - for (uintptr_t ClassPtr : ObjCClassList.toSpan<uintptr_t>()) { - auto *Cls = reinterpret_cast<Class>(ClassPtr); - auto *ClassCompiled = reinterpret_cast<ObjCClassCompiled *>(ClassPtr); - objc_msgSend(reinterpret_cast<id>(ClassCompiled->Parent), ClassSelector); - auto Registered = objc_readClassPair(Cls, ImageInfo); +using SPSMachOJITDylibDepInfoMap = + SPSSequence<SPSTuple<SPSExecutorAddr, SPSMachOJITDylibDepInfo>>; - // FIXME: Improve diagnostic by reporting the failed class's name. - if (Registered != Cls) - return make_error<StringError>("Unable to register Objective-C class"); - } +template <> +class SPSSerializationTraits<SPSMachOJITDylibDepInfo, MachOJITDylibDepInfo> { +public: + static size_t size(const MachOJITDylibDepInfo &JDI) { + return SPSMachOJITDylibDepInfo::AsArgList::size(JDI.Sealed, JDI.DepHeaders); } - return Error::success(); -} - -Error registerSwift5Protocols( - const std::vector<ExecutorAddrRange> &Swift5ProtocolSections, - const MachOJITDylibInitializers &MOJDIs) { - - if (ORC_RT_UNLIKELY(!Swift5ProtocolSections.empty() && - !swift_registerProtocols)) - return make_error<StringError>("swift_registerProtocols is not available"); - - for (const auto &Swift5Protocols : Swift5ProtocolSections) - swift_registerProtocols( - Swift5Protocols.Start.toPtr<const ProtocolRecord *>(), - Swift5Protocols.End.toPtr<const ProtocolRecord *>()); - - return Error::success(); -} - -Error registerSwift5ProtocolConformances( - const std::vector<ExecutorAddrRange> &Swift5ProtocolConformanceSections, - const MachOJITDylibInitializers &MOJDIs) { - - if (ORC_RT_UNLIKELY(!Swift5ProtocolConformanceSections.empty() && - !swift_registerProtocolConformances)) - return make_error<StringError>( - "swift_registerProtocolConformances is not available"); - - for (const auto &ProtoConfSec : Swift5ProtocolConformanceSections) - swift_registerProtocolConformances( - ProtoConfSec.Start.toPtr<const ProtocolConformanceRecord *>(), - ProtoConfSec.End.toPtr<const ProtocolConformanceRecord *>()); - - return Error::success(); -} - -Error registerSwift5Types(const std::vector<ExecutorAddrRange> &Sections, - const MachOJITDylibInitializers &MOJDIs) { - - if (ORC_RT_UNLIKELY(!Sections.empty() && !swift_registerTypeMetadataRecords)) - return make_error<StringError>( - "swift_registerTypeMetadataRecords is not available"); - - for (const auto &Section : Sections) - swift_registerTypeMetadataRecords( - Section.Start.toPtr<const TypeMetadataRecord *>(), - Section.End.toPtr<const TypeMetadataRecord *>()); - return Error::success(); -} - -Error runModInits(const std::vector<ExecutorAddrRange> &ModInitsSections, - const MachOJITDylibInitializers &MOJDIs) { - - for (const auto &ModInits : ModInitsSections) { - if (auto Err = validatePointerSectionExtent("__mod_inits", ModInits)) - return Err; + static bool serialize(SPSOutputBuffer &OB, const MachOJITDylibDepInfo &JDI) { + return SPSMachOJITDylibDepInfo::AsArgList::serialize(OB, JDI.Sealed, + JDI.DepHeaders); + } - using InitFunc = void (*)(); - for (auto *Init : ModInits.toSpan<InitFunc>()) - (*Init)(); + static bool deserialize(SPSInputBuffer &IB, MachOJITDylibDepInfo &JDI) { + return SPSMachOJITDylibDepInfo::AsArgList::deserialize(IB, JDI.Sealed, + JDI.DepHeaders); } +}; - return Error::success(); -} +} // namespace __orc_rt +namespace { struct TLVDescriptor { void *(*Thunk)(TLVDescriptor *) = nullptr; unsigned long Key = 0; @@ -222,11 +127,31 @@ private: using AtExitsVector = std::vector<AtExitEntry>; - struct PerJITDylibState { + struct JITDylibState { + std::string Name; void *Header = nullptr; - size_t RefCount = 0; - bool AllowReinitialization = false; + bool Sealed = false; + size_t LinkedAgainstRefCount = 0; + size_t DlRefCount = 0; + std::vector<JITDylibState *> Deps; AtExitsVector AtExits; + const objc_image_info *ObjCImageInfo = nullptr; + std::vector<span<void (*)()>> ModInitsSections; + std::vector<span<void (*)()>> ModInitsSectionsNew; + std::vector<span<uintptr_t>> ObjCClassListSections; + std::vector<span<uintptr_t>> ObjCClassListSectionsNew; + std::vector<span<uintptr_t>> ObjCSelRefsSections; + std::vector<span<uintptr_t>> ObjCSelRefsSectionsNew; + std::vector<span<char>> Swift5ProtoSections; + std::vector<span<char>> Swift5ProtoSectionsNew; + std::vector<span<char>> Swift5ProtosSections; + std::vector<span<char>> Swift5ProtosSectionsNew; + std::vector<span<char>> Swift5TypesSections; + std::vector<span<char>> Swift5TypesSectionsNew; + + bool referenced() const { + return LinkedAgainstRefCount != 0 || DlRefCount != 0; + } }; public: @@ -243,8 +168,16 @@ public: MachOPlatformRuntimeState(MachOPlatformRuntimeState &&) = delete; MachOPlatformRuntimeState &operator=(MachOPlatformRuntimeState &&) = delete; - Error registerThreadDataSection(span<const char> ThreadDataSec); - Error deregisterThreadDataSection(span<const char> ThreadDataSec); + Error registerJITDylib(std::string Name, void *Header); + Error deregisterJITDylib(void *Header); + Error registerThreadDataSection(span<const char> ThreadDataSection); + Error deregisterThreadDataSection(span<const char> ThreadDataSection); + Error registerObjectPlatformSections( + ExecutorAddr HeaderAddr, + std::vector<std::pair<string_view, ExecutorAddrRange>> Secs); + Error deregisterObjectPlatformSections( + ExecutorAddr HeaderAddr, + std::vector<std::pair<string_view, ExecutorAddrRange>> Secs); const char *dlerror(); void *dlopen(string_view Name, int Mode); @@ -252,6 +185,7 @@ public: void *dlsym(void *DSOHandle, string_view Symbol); int registerAtExit(void (*F)(void *), void *Arg, void *DSOHandle); + void runAtExits(JITDylibState &JDS); void runAtExits(void *DSOHandle); /// Returns the base address of the section containing ThreadData. @@ -259,37 +193,34 @@ public: getThreadDataSectionFor(const char *ThreadData); private: - PerJITDylibState *getJITDylibStateByHeaderAddr(void *DSOHandle); - PerJITDylibState *getJITDylibStateByName(string_view Path); - PerJITDylibState &getOrCreateJITDylibState(MachOJITDylibInitializers &MOJDIs); + JITDylibState *getJITDylibStateByHeader(void *DSOHandle); + JITDylibState *getJITDylibStateByName(string_view Path); Expected<ExecutorAddr> lookupSymbolInJITDylib(void *DSOHandle, string_view Symbol); - Expected<MachOJITDylibInitializerSequence> - getJITDylibInitializersByName(string_view Path); - Expected<void *> dlopenInitialize(string_view Path, int Mode); - Error initializeJITDylib(MachOJITDylibInitializers &MOJDIs); + static Error registerObjCSelectors(JITDylibState &JDS); + static Error registerObjCClasses(JITDylibState &JDS); + static Error registerSwift5Protocols(JITDylibState &JDS); + static Error registerSwift5ProtocolConformances(JITDylibState &JDS); + static Error registerSwift5Types(JITDylibState &JDS); + static Error runModInits(JITDylibState &JDS); - static MachOPlatformRuntimeState *MOPS; + Expected<void *> dlopenImpl(string_view Path, int Mode); + Error dlopenFull(JITDylibState &JDS); + Error dlopenInitialize(JITDylibState &JDS, MachOJITDylibDepInfoMap &DepInfo); - using InitSectionHandler = - Error (*)(const std::vector<ExecutorAddrRange> &Sections, - const MachOJITDylibInitializers &MOJDIs); - const std::vector<std::pair<const char *, InitSectionHandler>> InitSections = - {{"__DATA,__objc_selrefs", registerObjCSelectors}, - {"__DATA,__objc_classlist", registerObjCClasses}, - {"__TEXT,__swift5_protos", registerSwift5Protocols}, - {"__TEXT,__swift5_proto", registerSwift5ProtocolConformances}, - {"__TEXT,__swift5_types", registerSwift5Types}, - {"__DATA,__mod_init_func", runModInits}}; + Error dlcloseImpl(void *DSOHandle); + Error dlcloseDeinitialize(JITDylibState &JDS); + + static MachOPlatformRuntimeState *MOPS; // FIXME: Move to thread-state. std::string DLFcnError; std::recursive_mutex JDStatesMutex; - std::unordered_map<void *, PerJITDylibState> JDStates; - std::unordered_map<std::string, void *> JDNameToHeader; + std::unordered_map<void *, JITDylibState> JDStates; + std::unordered_map<string_view, void *> JDNameToHeader; std::mutex ThreadDataSectionsMutex; std::map<const char *, size_t> ThreadDataSections; @@ -312,6 +243,57 @@ void MachOPlatformRuntimeState::destroy() { delete MOPS; } +Error MachOPlatformRuntimeState::registerJITDylib(std::string Name, + void *Header) { + ORC_RT_DEBUG({ + printdbg("Registering JITDylib %s: Header = %p\n", Name.c_str(), Header); + }); + std::lock_guard<std::recursive_mutex> Lock(JDStatesMutex); + if (JDStates.count(Header)) { + std::ostringstream ErrStream; + ErrStream << "Duplicate JITDylib registration for header " << Header + << " (name = " << Name << ")"; + return make_error<StringError>(ErrStream.str()); + } + if (JDNameToHeader.count(Name)) { + std::ostringstream ErrStream; + ErrStream << "Duplicate JITDylib registration for header " << Header + << " (header = " << Header << ")"; + return make_error<StringError>(ErrStream.str()); + } + + auto &JDS = JDStates[Header]; + JDS.Name = std::move(Name); + JDS.Header = Header; + JDNameToHeader[JDS.Name] = Header; + return Error::success(); +} + +Error MachOPlatformRuntimeState::deregisterJITDylib(void *Header) { + std::lock_guard<std::recursive_mutex> Lock(JDStatesMutex); + auto I = JDStates.find(Header); + if (I == JDStates.end()) { + std::ostringstream ErrStream; + ErrStream << "Attempted to deregister unrecognized header " << Header; + return make_error<StringError>(ErrStream.str()); + } + + // Remove std::string construction once we can use C++20. + auto J = JDNameToHeader.find( + std::string(I->second.Name.data(), I->second.Name.size())); + assert(J != JDNameToHeader.end() && + "Missing JDNameToHeader entry for JITDylib"); + + ORC_RT_DEBUG({ + printdbg("Deregistering JITDylib %s: Header = %p\n", I->second.Name.c_str(), + Header); + }); + + JDNameToHeader.erase(J); + JDStates.erase(I); + return Error::success(); +} + Error MachOPlatformRuntimeState::registerThreadDataSection( span<const char> ThreadDataSection) { std::lock_guard<std::mutex> Lock(ThreadDataSectionsMutex); @@ -337,31 +319,160 @@ Error MachOPlatformRuntimeState::deregisterThreadDataSection( return Error::success(); } -const char *MachOPlatformRuntimeState::dlerror() { return DLFcnError.c_str(); } +Error MachOPlatformRuntimeState::registerObjectPlatformSections( + ExecutorAddr HeaderAddr, + std::vector<std::pair<string_view, ExecutorAddrRange>> Secs) { + ORC_RT_DEBUG({ + printdbg("MachOPlatform: Registering object sections for %p.\n", + HeaderAddr.toPtr<void *>()); + }); + + std::lock_guard<std::recursive_mutex> Lock(JDStatesMutex); + auto *JDS = getJITDylibStateByHeader(HeaderAddr.toPtr<void *>()); + if (!JDS) { + std::ostringstream ErrStream; + ErrStream << "Could not register object platform sections for " + "unrecognized header " + << HeaderAddr.toPtr<void *>(); + return make_error<StringError>(ErrStream.str()); + } + + for (auto &KV : Secs) { + // FIXME: Validate section ranges? + if (KV.first == "__DATA,__thread_data") { + if (auto Err = registerThreadDataSection(KV.second.toSpan<const char>())) + return Err; + } else if (KV.first == "__DATA,__objc_selrefs") + JDS->ObjCSelRefsSectionsNew.push_back(KV.second.toSpan<uintptr_t>()); + else if (KV.first == "__DATA,__objc_classlist") + JDS->ObjCClassListSectionsNew.push_back(KV.second.toSpan<uintptr_t>()); + else if (KV.first == "__TEXT,__swift5_protos") + JDS->Swift5ProtosSectionsNew.push_back(KV.second.toSpan<char>()); + else if (KV.first == "__TEXT,__swift5_proto") + JDS->Swift5ProtoSectionsNew.push_back(KV.second.toSpan<char>()); + else if (KV.first == "__TEXT,__swift5_types") + JDS->Swift5TypesSectionsNew.push_back(KV.second.toSpan<char>()); + else if (KV.first == "__DATA,__mod_init_func") + JDS->ModInitsSectionsNew.push_back(KV.second.toSpan<void (*)()>()); + else { + // Should this be a warning instead? + return make_error<StringError>( + "Encountered unexpected section " + + std::string(KV.first.data(), KV.first.size()) + + " while registering object platform sections"); + } + } + + return Error::success(); +} + +// Remove the given range from the given vector if present. +// Returns true if the range was removed, false otherwise. +template <typename T> +bool removeIfPresent(std::vector<span<T>> &V, ExecutorAddrRange R) { + auto RI = std::find_if( + V.rbegin(), V.rend(), + [RS = R.toSpan<T>()](const span<T> &E) { return E.data() == RS.data(); }); + if (RI != V.rend()) { + V.erase(std::next(RI).base()); + return true; + } + return false; +} + +Error MachOPlatformRuntimeState::deregisterObjectPlatformSections( + ExecutorAddr HeaderAddr, + std::vector<std::pair<string_view, ExecutorAddrRange>> Secs) { + // TODO: Make this more efficient? (maybe unnecessary if removal is rare?) + // TODO: Add a JITDylib prepare-for-teardown operation that clears all + // registered sections, causing this function to take the fast-path. + ORC_RT_DEBUG({ + printdbg("MachOPlatform: Registering object sections for %p.\n", + HeaderAddr.toPtr<void *>()); + }); -void *MachOPlatformRuntimeState::dlopen(string_view Path, int Mode) { std::lock_guard<std::recursive_mutex> Lock(JDStatesMutex); + auto *JDS = getJITDylibStateByHeader(HeaderAddr.toPtr<void *>()); + if (!JDS) { + std::ostringstream ErrStream; + ErrStream << "Could not register object platform sections for unrecognized " + "header " + << HeaderAddr.toPtr<void *>(); + return make_error<StringError>(ErrStream.str()); + } + + // FIXME: Implement faster-path by returning immediately if JDS is being + // torn down entirely? - // Use fast path if all JITDylibs are already loaded and don't require - // re-running initializers. - if (auto *JDS = getJITDylibStateByName(Path)) { - if (!JDS->AllowReinitialization) { - ++JDS->RefCount; - return JDS->Header; + for (auto &KV : Secs) { + // FIXME: Validate section ranges? + if (KV.first == "__DATA,__thread_data") { + if (auto Err = + deregisterThreadDataSection(KV.second.toSpan<const char>())) + return Err; + } else if (KV.first == "__DATA,__objc_selrefs") { + if (!removeIfPresent(JDS->ObjCSelRefsSections, KV.second)) + removeIfPresent(JDS->ObjCSelRefsSectionsNew, KV.second); + } else if (KV.first == "__DATA,__objc_classlist") { + if (!removeIfPresent(JDS->ObjCClassListSections, KV.second)) + removeIfPresent(JDS->ObjCClassListSectionsNew, KV.second); + } else if (KV.first == "__TEXT,__swift5_protos") { + if (!removeIfPresent(JDS->Swift5ProtosSections, KV.second)) + removeIfPresent(JDS->Swift5ProtosSectionsNew, KV.second); + } else if (KV.first == "__TEXT,__swift5_proto") { + if (!removeIfPresent(JDS->Swift5ProtoSections, KV.second)) + removeIfPresent(JDS->Swift5ProtoSectionsNew, KV.second); + } else if (KV.first == "__TEXT,__swift5_types") { + if (!removeIfPresent(JDS->Swift5TypesSections, KV.second)) + removeIfPresent(JDS->Swift5TypesSectionsNew, KV.second); + } else if (KV.first == "__DATA,__mod_init_func") { + if (!removeIfPresent(JDS->ModInitsSections, KV.second)) + removeIfPresent(JDS->ModInitsSectionsNew, KV.second); + } else { + // Should this be a warning instead? + return make_error<StringError>( + "Encountered unexpected section " + + std::string(KV.first.data(), KV.first.size()) + + " while deregistering object platform sections"); } } + return Error::success(); +} - auto H = dlopenInitialize(Path, Mode); - if (!H) { +const char *MachOPlatformRuntimeState::dlerror() { return DLFcnError.c_str(); } + +void *MachOPlatformRuntimeState::dlopen(string_view Path, int Mode) { + ORC_RT_DEBUG({ + std::string S(Path.data(), Path.size()); + printdbg("MachOPlatform::dlopen(\"%s\")\n", S.c_str()); + }); + std::lock_guard<std::recursive_mutex> Lock(JDStatesMutex); + if (auto H = dlopenImpl(Path, Mode)) + return *H; + else { + // FIXME: Make dlerror thread safe. DLFcnError = toString(H.takeError()); return nullptr; } - - return *H; } int MachOPlatformRuntimeState::dlclose(void *DSOHandle) { - runAtExits(DSOHandle); + ORC_RT_DEBUG({ + auto *JDS = getJITDylibStateByHeader(DSOHandle); + std::string DylibName; + if (JDS) { + std::string S; + printdbg("MachOPlatform::dlclose(%p) (%s)\n", DSOHandle, S.c_str()); + } else + printdbg("MachOPlatform::dlclose(%p) (%s)\n", DSOHandle, + "invalid handle"); + }); + std::lock_guard<std::recursive_mutex> Lock(JDStatesMutex); + if (auto Err = dlcloseImpl(DSOHandle)) { + // FIXME: Make dlerror thread safe. + DLFcnError = toString(std::move(Err)); + return -1; + } return 0; } @@ -379,30 +490,39 @@ int MachOPlatformRuntimeState::registerAtExit(void (*F)(void *), void *Arg, void *DSOHandle) { // FIXME: Handle out-of-memory errors, returning -1 if OOM. std::lock_guard<std::recursive_mutex> Lock(JDStatesMutex); - auto *JDS = getJITDylibStateByHeaderAddr(DSOHandle); - assert(JDS && "JITDylib state not initialized"); + auto *JDS = getJITDylibStateByHeader(DSOHandle); + if (!JDS) { + ORC_RT_DEBUG({ + printdbg("MachOPlatformRuntimeState::registerAtExit called with " + "unrecognized dso handle %p\n", + DSOHandle); + }); + return -1; + } JDS->AtExits.push_back({F, Arg}); return 0; } -void MachOPlatformRuntimeState::runAtExits(void *DSOHandle) { - // FIXME: Should atexits be allowed to run concurrently with access to - // JDState? - AtExitsVector V; - { - std::lock_guard<std::recursive_mutex> Lock(JDStatesMutex); - auto *JDS = getJITDylibStateByHeaderAddr(DSOHandle); - assert(JDS && "JITDlybi state not initialized"); - std::swap(V, JDS->AtExits); - } - - while (!V.empty()) { - auto &AE = V.back(); +void MachOPlatformRuntimeState::runAtExits(JITDylibState &JDS) { + while (!JDS.AtExits.empty()) { + auto &AE = JDS.AtExits.back(); AE.Func(AE.Arg); - V.pop_back(); + JDS.AtExits.pop_back(); } } +void MachOPlatformRuntimeState::runAtExits(void *DSOHandle) { + std::lock_guard<std::recursive_mutex> Lock(JDStatesMutex); + auto *JDS = getJITDylibStateByHeader(DSOHandle); + ORC_RT_DEBUG({ + printdbg("MachOPlatformRuntimeState::runAtExits called on unrecognized " + "dso_handle %p\n", + DSOHandle); + }); + if (JDS) + runAtExits(*JDS); +} + Expected<std::pair<const char *, size_t>> MachOPlatformRuntimeState::getThreadDataSectionFor(const char *ThreadData) { std::lock_guard<std::mutex> Lock(ThreadDataSectionsMutex); @@ -416,43 +536,23 @@ MachOPlatformRuntimeState::getThreadDataSectionFor(const char *ThreadData) { return *I; } -MachOPlatformRuntimeState::PerJITDylibState * -MachOPlatformRuntimeState::getJITDylibStateByHeaderAddr(void *DSOHandle) { +MachOPlatformRuntimeState::JITDylibState * +MachOPlatformRuntimeState::getJITDylibStateByHeader(void *DSOHandle) { auto I = JDStates.find(DSOHandle); - if (I == JDStates.end()) - return nullptr; + if (I == JDStates.end()) { + I = JDStates.insert(std::make_pair(DSOHandle, JITDylibState())).first; + I->second.Header = DSOHandle; + } return &I->second; } -MachOPlatformRuntimeState::PerJITDylibState * +MachOPlatformRuntimeState::JITDylibState * MachOPlatformRuntimeState::getJITDylibStateByName(string_view Name) { - // FIXME: Avoid creating string copy here. + // FIXME: Avoid creating string once we have C++20. auto I = JDNameToHeader.find(std::string(Name.data(), Name.size())); - if (I == JDNameToHeader.end()) - return nullptr; - void *H = I->second; - auto J = JDStates.find(H); - assert(J != JDStates.end() && - "JITDylib has name map entry but no header map entry"); - return &J->second; -} - -MachOPlatformRuntimeState::PerJITDylibState & -MachOPlatformRuntimeState::getOrCreateJITDylibState( - MachOJITDylibInitializers &MOJDIs) { - void *Header = MOJDIs.MachOHeaderAddress.toPtr<void *>(); - - auto &JDS = JDStates[Header]; - - // If this entry hasn't been created yet. - if (!JDS.Header) { - assert(!JDNameToHeader.count(MOJDIs.Name) && - "JITDylib has header map entry but no name map entry"); - JDNameToHeader[MOJDIs.Name] = Header; - JDS.Header = Header; - } - - return JDS; + if (I != JDNameToHeader.end()) + return getJITDylibStateByHeader(I->second); + return nullptr; } Expected<ExecutorAddr> @@ -468,60 +568,313 @@ MachOPlatformRuntimeState::lookupSymbolInJITDylib(void *DSOHandle, return Result; } -Expected<MachOJITDylibInitializerSequence> -MachOPlatformRuntimeState::getJITDylibInitializersByName(string_view Path) { - Expected<MachOJITDylibInitializerSequence> Result( - (MachOJITDylibInitializerSequence())); - std::string PathStr(Path.data(), Path.size()); - if (auto Err = - WrapperFunction<SPSExpected<SPSMachOJITDylibInitializerSequence>( - SPSString)>::call(&__orc_rt_macho_get_initializers_tag, Result, - Path)) - return std::move(Err); - return Result; +template <typename T> +static void moveAppendSections(std::vector<span<T>> &Dst, + std::vector<span<T>> &Src) { + if (Dst.empty()) { + Dst = std::move(Src); + return; + } + + Dst.reserve(Dst.size() + Src.size()); + std::copy(Src.begin(), Src.end(), std::back_inserter(Dst)); + Src.clear(); +} + +Error MachOPlatformRuntimeState::registerObjCSelectors(JITDylibState &JDS) { + + if (JDS.ObjCSelRefsSectionsNew.empty()) + return Error::success(); + + if (ORC_RT_UNLIKELY(!sel_registerName)) + return make_error<StringError>("sel_registerName is not available"); + + for (const auto &ObjCSelRefs : JDS.ObjCSelRefsSectionsNew) { + for (uintptr_t &SelEntry : ObjCSelRefs) { + const char *SelName = reinterpret_cast<const char *>(SelEntry); + auto Sel = sel_registerName(SelName); + *reinterpret_cast<SEL *>(&SelEntry) = Sel; + } + } + + moveAppendSections(JDS.ObjCSelRefsSections, JDS.ObjCSelRefsSectionsNew); + return Error::success(); +} + +Error MachOPlatformRuntimeState::registerObjCClasses(JITDylibState &JDS) { + + if (JDS.ObjCClassListSectionsNew.empty()) + return Error::success(); + + if (ORC_RT_UNLIKELY(!objc_msgSend)) + return make_error<StringError>("objc_msgSend is not available"); + if (ORC_RT_UNLIKELY(!objc_readClassPair)) + return make_error<StringError>("objc_readClassPair is not available"); + + struct ObjCClassCompiled { + void *Metaclass; + void *Parent; + void *Cache1; + void *Cache2; + void *Data; + }; + + auto ClassSelector = sel_registerName("class"); + + for (const auto &ObjCClassList : JDS.ObjCClassListSectionsNew) { + for (uintptr_t ClassPtr : ObjCClassList) { + auto *Cls = reinterpret_cast<Class>(ClassPtr); + auto *ClassCompiled = reinterpret_cast<ObjCClassCompiled *>(ClassPtr); + objc_msgSend(reinterpret_cast<id>(ClassCompiled->Parent), ClassSelector); + auto Registered = objc_readClassPair(Cls, JDS.ObjCImageInfo); + + // FIXME: Improve diagnostic by reporting the failed class's name. + if (Registered != Cls) + return make_error<StringError>("Unable to register Objective-C class"); + } + } + + moveAppendSections(JDS.ObjCClassListSections, JDS.ObjCClassListSectionsNew); + return Error::success(); } -Expected<void *> MachOPlatformRuntimeState::dlopenInitialize(string_view Path, - int Mode) { - // Either our JITDylib wasn't loaded, or it or one of its dependencies allows - // reinitialization. We need to call in to the JIT to see if there's any new - // work pending. - auto InitSeq = getJITDylibInitializersByName(Path); - if (!InitSeq) - return InitSeq.takeError(); +Error MachOPlatformRuntimeState::registerSwift5Protocols(JITDylibState &JDS) { + + if (JDS.Swift5ProtosSectionsNew.empty()) + return Error::success(); + + if (ORC_RT_UNLIKELY(!swift_registerProtocols)) + return make_error<StringError>("swift_registerProtocols is not available"); + + for (const auto &Swift5Protocols : JDS.Swift5ProtoSectionsNew) + swift_registerProtocols( + reinterpret_cast<const ProtocolRecord *>(Swift5Protocols.data()), + reinterpret_cast<const ProtocolRecord *>(Swift5Protocols.data() + + Swift5Protocols.size())); + + moveAppendSections(JDS.Swift5ProtoSections, JDS.Swift5ProtoSectionsNew); + return Error::success(); +} + +Error MachOPlatformRuntimeState::registerSwift5ProtocolConformances( + JITDylibState &JDS) { + + if (JDS.Swift5ProtosSectionsNew.empty()) + return Error::success(); - // Init sequences should be non-empty. - if (InitSeq->empty()) + if (ORC_RT_UNLIKELY(!swift_registerProtocolConformances)) return make_error<StringError>( - "__orc_rt_macho_get_initializers returned an " - "empty init sequence"); + "swift_registerProtocolConformances is not available"); + + for (const auto &ProtoConfSec : JDS.Swift5ProtosSectionsNew) + swift_registerProtocolConformances( + reinterpret_cast<const ProtocolConformanceRecord *>( + ProtoConfSec.data()), + reinterpret_cast<const ProtocolConformanceRecord *>( + ProtoConfSec.data() + ProtoConfSec.size())); + + moveAppendSections(JDS.Swift5ProtosSections, JDS.Swift5ProtosSectionsNew); + return Error::success(); +} + +Error MachOPlatformRuntimeState::registerSwift5Types(JITDylibState &JDS) { + + if (JDS.Swift5TypesSectionsNew.empty()) + return Error::success(); + + if (ORC_RT_UNLIKELY(!swift_registerTypeMetadataRecords)) + return make_error<StringError>( + "swift_registerTypeMetadataRecords is not available"); + + for (const auto &TypeSec : JDS.Swift5TypesSectionsNew) + swift_registerTypeMetadataRecords( + reinterpret_cast<const TypeMetadataRecord *>(TypeSec.data()), + reinterpret_cast<const TypeMetadataRecord *>(TypeSec.data() + + TypeSec.size())); + + moveAppendSections(JDS.Swift5TypesSections, JDS.Swift5TypesSectionsNew); + return Error::success(); +} + +Error MachOPlatformRuntimeState::runModInits(JITDylibState &JDS) { - // Otherwise register and run initializers for each JITDylib. - for (auto &MOJDIs : *InitSeq) - if (auto Err = initializeJITDylib(MOJDIs)) + for (const auto &ModInits : JDS.ModInitsSectionsNew) { + for (void (*Init)() : ModInits) + (*Init)(); + } + + moveAppendSections(JDS.ModInitsSections, JDS.ModInitsSectionsNew); + return Error::success(); +} + +Expected<void *> MachOPlatformRuntimeState::dlopenImpl(string_view Path, + int Mode) { + // Try to find JITDylib state by name. + auto *JDS = getJITDylibStateByName(Path); + + if (!JDS) + return make_error<StringError>("No registered JTIDylib for path " + + std::string(Path.data(), Path.size())); + + // If this JITDylib is unsealed, or this is the first dlopen then run + // full dlopen path (update deps, push and run initializers, update ref + // counts on all JITDylibs in the dep tree). + if (!JDS->referenced() || !JDS->Sealed) { + if (auto Err = dlopenFull(*JDS)) return std::move(Err); + } - // Return the header for the last item in the list. - auto *JDS = getJITDylibStateByHeaderAddr( - InitSeq->back().MachOHeaderAddress.toPtr<void *>()); - assert(JDS && "Missing state entry for JD"); + // Bump the ref-count on this dylib. + ++JDS->DlRefCount; + + // Return the header address. return JDS->Header; } -Error MachOPlatformRuntimeState::initializeJITDylib( - MachOJITDylibInitializers &MOJDIs) { +Error MachOPlatformRuntimeState::dlopenFull(JITDylibState &JDS) { + // Call back to the JIT to push the initializers. + Expected<MachOJITDylibDepInfoMap> DepInfo((MachOJITDylibDepInfoMap())); + if (auto Err = WrapperFunction<SPSExpected<SPSMachOJITDylibDepInfoMap>( + SPSExecutorAddr)>::call(&__orc_rt_macho_push_initializers_tag, + DepInfo, ExecutorAddr::fromPtr(JDS.Header))) + return Err; + if (!DepInfo) + return DepInfo.takeError(); + + if (auto Err = dlopenInitialize(JDS, *DepInfo)) + return Err; + + if (!DepInfo->empty()) { + ORC_RT_DEBUG({ + printdbg("Unrecognized dep-info key headers in dlopen of %s\n", + JDS.Name.c_str()); + }); + std::ostringstream ErrStream; + ErrStream << "Encountered unrecognized dep-info key headers " + "while processing dlopen of " + << JDS.Name; + return make_error<StringError>(ErrStream.str()); + } + + return Error::success(); +} - auto &JDS = getOrCreateJITDylibState(MOJDIs); - ++JDS.RefCount; +Error MachOPlatformRuntimeState::dlopenInitialize( + JITDylibState &JDS, MachOJITDylibDepInfoMap &DepInfo) { + ORC_RT_DEBUG({ + printdbg("MachOPlatformRuntimeState::dlopenInitialize(\"%s\")\n", + JDS.Name.c_str()); + }); + + // If the header is not present in the dep map then assume that we + // already processed it earlier in the dlopenInitialize traversal and + // return. + // TODO: Keep a visited set instead so that we can error out on missing + // entries? + auto I = DepInfo.find(ExecutorAddr::fromPtr(JDS.Header)); + if (I == DepInfo.end()) + return Error::success(); - for (auto &KV : InitSections) { - const auto &Name = KV.first; - const auto &Handler = KV.second; - auto I = MOJDIs.InitSections.find(Name); - if (I != MOJDIs.InitSections.end()) { - if (auto Err = Handler(I->second, MOJDIs)) - return Err; + auto DI = std::move(I->second); + DepInfo.erase(I); + + // We don't need to re-initialize sealed JITDylibs that have already been + // initialized. Just check that their dep-map entry is empty as expected. + if (JDS.Sealed) { + if (!DI.DepHeaders.empty()) { + std::ostringstream ErrStream; + ErrStream << "Sealed JITDylib " << JDS.Header + << " already has registered dependencies"; + return make_error<StringError>(ErrStream.str()); + } + if (JDS.referenced()) + return Error::success(); + } else + JDS.Sealed = DI.Sealed; + + // This is an unsealed or newly sealed JITDylib. Run initializers. + std::vector<JITDylibState *> OldDeps; + std::swap(JDS.Deps, OldDeps); + JDS.Deps.reserve(DI.DepHeaders.size()); + for (auto DepHeaderAddr : DI.DepHeaders) { + auto *DepJDS = getJITDylibStateByHeader(DepHeaderAddr.toPtr<void *>()); + if (!DepJDS) { + std::ostringstream ErrStream; + ErrStream << "Encountered unrecognized dep header " + << DepHeaderAddr.toPtr<void *>() << " while initializing " + << JDS.Name; + return make_error<StringError>(ErrStream.str()); } + ++DepJDS->LinkedAgainstRefCount; + if (auto Err = dlopenInitialize(*DepJDS, DepInfo)) + return Err; + } + + // Initialize this JITDylib. + if (auto Err = registerObjCSelectors(JDS)) + return Err; + if (auto Err = registerObjCClasses(JDS)) + return Err; + if (auto Err = registerSwift5Protocols(JDS)) + return Err; + if (auto Err = registerSwift5ProtocolConformances(JDS)) + return Err; + if (auto Err = registerSwift5Types(JDS)) + return Err; + if (auto Err = runModInits(JDS)) + return Err; + + // Decrement old deps. + // FIXME: We should probably continue and just report deinitialize errors + // here. + for (auto *DepJDS : OldDeps) { + --DepJDS->LinkedAgainstRefCount; + if (!DepJDS->referenced()) + if (auto Err = dlcloseDeinitialize(*DepJDS)) + return Err; + } + + return Error::success(); +} + +Error MachOPlatformRuntimeState::dlcloseImpl(void *DSOHandle) { + // Try to find JITDylib state by header. + auto *JDS = getJITDylibStateByHeader(DSOHandle); + + if (!JDS) { + std::ostringstream ErrStream; + ErrStream << "No registered JITDylib for " << DSOHandle; + return make_error<StringError>(ErrStream.str()); + } + + // Bump the ref-count. + --JDS->DlRefCount; + + if (!JDS->referenced()) + return dlcloseDeinitialize(*JDS); + + return Error::success(); +} + +Error MachOPlatformRuntimeState::dlcloseDeinitialize(JITDylibState &JDS) { + + ORC_RT_DEBUG({ + printdbg("MachOPlatformRuntimeState::dlcloseDeinitialize(\"%s\")\n", + JDS.Name.c_str()); + }); + + runAtExits(JDS); + + // Reset mod-inits + moveAppendSections(JDS.ModInitsSections, JDS.ModInitsSectionsNew); + JDS.ModInitsSectionsNew = std::move(JDS.ModInitsSections); + + // Deinitialize any dependencies. + for (auto *DepJDS : JDS.Deps) { + --DepJDS->LinkedAgainstRefCount; + if (!DepJDS->referenced()) + if (auto Err = dlcloseDeinitialize(*DepJDS)) + return Err; } return Error::success(); @@ -592,28 +945,57 @@ __orc_rt_macho_platform_shutdown(char *ArgData, size_t ArgSize) { } ORC_RT_INTERFACE __orc_rt_CWrapperFunctionResult -__orc_rt_macho_register_thread_data_section(char *ArgData, size_t ArgSize) { - return WrapperFunction<SPSError(SPSExecutorAddrRange)>::handle( +__orc_rt_macho_register_jitdylib(char *ArgData, size_t ArgSize) { + return WrapperFunction<SPSError(SPSString, SPSExecutorAddr)>::handle( ArgData, ArgSize, - [](ExecutorAddrRange R) { - return MachOPlatformRuntimeState::get() - .registerThreadDataSection(R.toSpan<const char>()); + [](std::string &Name, ExecutorAddr HeaderAddr) { + return MachOPlatformRuntimeState::get().registerJITDylib( + std::move(Name), HeaderAddr.toPtr<void *>()); }) .release(); } ORC_RT_INTERFACE __orc_rt_CWrapperFunctionResult -__orc_rt_macho_deregister_thread_data_section(char *ArgData, size_t ArgSize) { - return WrapperFunction<SPSError(SPSExecutorAddrRange)>::handle( +__orc_rt_macho_deregister_jitdylib(char *ArgData, size_t ArgSize) { + return WrapperFunction<SPSError(SPSExecutorAddr)>::handle( ArgData, ArgSize, - [](ExecutorAddrRange R) { - return MachOPlatformRuntimeState::get() - .deregisterThreadDataSection(R.toSpan<const char>()); + [](ExecutorAddr HeaderAddr) { + return MachOPlatformRuntimeState::get().deregisterJITDylib( + HeaderAddr.toPtr<void *>()); }) .release(); } ORC_RT_INTERFACE __orc_rt_CWrapperFunctionResult +__orc_rt_macho_register_object_platform_sections(char *ArgData, + size_t ArgSize) { + return WrapperFunction<SPSError(SPSExecutorAddr, + SPSMachOObjectPlatformSectionsMap)>:: + handle(ArgData, ArgSize, + [](ExecutorAddr HeaderAddr, + std::vector<std::pair<string_view, ExecutorAddrRange>> &Secs) { + return MachOPlatformRuntimeState::get() + .registerObjectPlatformSections(HeaderAddr, std::move(Secs)); + }) + .release(); +} + +ORC_RT_INTERFACE __orc_rt_CWrapperFunctionResult +__orc_rt_macho_deregister_object_platform_sections(char *ArgData, + size_t ArgSize) { + return WrapperFunction<SPSError(SPSExecutorAddr, + SPSMachOObjectPlatformSectionsMap)>:: + handle(ArgData, ArgSize, + [](ExecutorAddr HeaderAddr, + std::vector<std::pair<string_view, ExecutorAddrRange>> &Secs) { + return MachOPlatformRuntimeState::get() + .deregisterObjectPlatformSections(HeaderAddr, + std::move(Secs)); + }) + .release(); +} + +ORC_RT_INTERFACE __orc_rt_CWrapperFunctionResult __orc_rt_macho_run_wrapper_function_calls(char *ArgData, size_t ArgSize) { return WrapperFunction<SPSError(SPSSequence<SPSWrapperFunctionCall>)>::handle( ArgData, ArgSize, runWrapperFunctionCalls) diff --git a/contrib/llvm-project/compiler-rt/lib/orc/macho_platform.h b/contrib/llvm-project/compiler-rt/lib/orc/macho_platform.h index 5b9820a0d1f9..3b2242ab27ce 100644 --- a/contrib/llvm-project/compiler-rt/lib/orc/macho_platform.h +++ b/contrib/llvm-project/compiler-rt/lib/orc/macho_platform.h @@ -31,28 +31,6 @@ ORC_RT_INTERFACE void *__orc_rt_macho_jit_dlsym(void *dso_handle, namespace __orc_rt { namespace macho { -struct MachOJITDylibInitializers { - using SectionList = std::vector<ExecutorAddrRange>; - - MachOJITDylibInitializers() = default; - MachOJITDylibInitializers(std::string Name, ExecutorAddr MachOHeaderAddress) - : Name(std::move(Name)), - MachOHeaderAddress(std::move(MachOHeaderAddress)) {} - - std::string Name; - ExecutorAddr MachOHeaderAddress; - ExecutorAddr ObjCImageInfoAddress; - - std::unordered_map<std::string, SectionList> InitSections; -}; - -class MachOJITDylibDeinitializers {}; - -using MachOJITDylibInitializerSequence = std::vector<MachOJITDylibInitializers>; - -using MachOJITDylibDeinitializerSequence = - std::vector<MachOJITDylibDeinitializers>; - enum dlopen_mode : int { ORC_RT_RTLD_LAZY = 0x1, ORC_RT_RTLD_NOW = 0x2, @@ -61,43 +39,6 @@ enum dlopen_mode : int { }; } // end namespace macho - -using SPSNamedExecutorAddrRangeSequenceMap = - SPSSequence<SPSTuple<SPSString, SPSExecutorAddrRangeSequence>>; - -using SPSMachOJITDylibInitializers = - SPSTuple<SPSString, SPSExecutorAddr, SPSExecutorAddr, - SPSNamedExecutorAddrRangeSequenceMap>; - -using SPSMachOJITDylibInitializerSequence = - SPSSequence<SPSMachOJITDylibInitializers>; - -/// Serialization traits for MachOJITDylibInitializers. -template <> -class SPSSerializationTraits<SPSMachOJITDylibInitializers, - macho::MachOJITDylibInitializers> { -public: - static size_t size(const macho::MachOJITDylibInitializers &MOJDIs) { - return SPSMachOJITDylibInitializers::AsArgList::size( - MOJDIs.Name, MOJDIs.MachOHeaderAddress, MOJDIs.ObjCImageInfoAddress, - MOJDIs.InitSections); - } - - static bool serialize(SPSOutputBuffer &OB, - const macho::MachOJITDylibInitializers &MOJDIs) { - return SPSMachOJITDylibInitializers::AsArgList::serialize( - OB, MOJDIs.Name, MOJDIs.MachOHeaderAddress, MOJDIs.ObjCImageInfoAddress, - MOJDIs.InitSections); - } - - static bool deserialize(SPSInputBuffer &IB, - macho::MachOJITDylibInitializers &MOJDIs) { - return SPSMachOJITDylibInitializers::AsArgList::deserialize( - IB, MOJDIs.Name, MOJDIs.MachOHeaderAddress, MOJDIs.ObjCImageInfoAddress, - MOJDIs.InitSections); - } -}; - } // end namespace __orc_rt #endif // ORC_RT_MACHO_PLATFORM_H diff --git a/contrib/llvm-project/compiler-rt/lib/orc/wrapper_function_utils.h b/contrib/llvm-project/compiler-rt/lib/orc/wrapper_function_utils.h index 02ea37393276..715fcef75139 100644 --- a/contrib/llvm-project/compiler-rt/lib/orc/wrapper_function_utils.h +++ b/contrib/llvm-project/compiler-rt/lib/orc/wrapper_function_utils.h @@ -13,7 +13,7 @@ #ifndef ORC_RT_WRAPPER_FUNCTION_UTILS_H #define ORC_RT_WRAPPER_FUNCTION_UTILS_H -#include "c_api.h" +#include "orc/c_api.h" #include "common.h" #include "error.h" #include "executor_address.h" diff --git a/contrib/llvm-project/compiler-rt/lib/profile/GCDAProfiling.c b/contrib/llvm-project/compiler-rt/lib/profile/GCDAProfiling.c index 8e51f57b09ff..4aa15e9e9590 100644 --- a/contrib/llvm-project/compiler-rt/lib/profile/GCDAProfiling.c +++ b/contrib/llvm-project/compiler-rt/lib/profile/GCDAProfiling.c @@ -83,7 +83,7 @@ static HANDLE mmap_handle = NULL; #endif static int fd = -1; -typedef void (*fn_ptr)(); +typedef void (*fn_ptr)(void); typedef void* dynamic_object_id; // The address of this variable identifies a given dynamic object. @@ -183,7 +183,7 @@ static void write_64bit_value(uint64_t i) { write_32bit_value(hi); } -static uint32_t read_32bit_value() { +static uint32_t read_32bit_value(void) { uint32_t val; if (new_file) @@ -194,7 +194,7 @@ static uint32_t read_32bit_value() { return val; } -static uint64_t read_64bit_value() { +static uint64_t read_64bit_value(void) { // GCOV uses a lo-/hi-word format even on big-endian systems. // See also GCOVBuffer::readInt64 in LLVM. uint32_t lo = read_32bit_value(); @@ -218,7 +218,7 @@ static char *mangle_filename(const char *orig_filename) { return new_filename; } -static int map_file() { +static int map_file(void) { fseek(output_file, 0L, SEEK_END); file_size = ftell(output_file); @@ -262,7 +262,7 @@ static int map_file() { return 0; } -static void unmap_file() { +static void unmap_file(void) { #if defined(_WIN32) if (!FlushViewOfFile(write_buffer, file_size)) { fprintf(stderr, "profiling: %s: cannot flush mapped view: %lu\n", filename, @@ -449,7 +449,7 @@ void llvm_gcda_emit_arcs(uint32_t num_counters, uint64_t *counters) { } COMPILER_RT_VISIBILITY -void llvm_gcda_summary_info() { +void llvm_gcda_summary_info(void) { uint32_t runs = 1; static uint32_t run_counted = 0; // We only want to increase the run count once. uint32_t val = 0; @@ -513,7 +513,7 @@ void llvm_gcda_summary_info() { } COMPILER_RT_VISIBILITY -void llvm_gcda_end_file() { +void llvm_gcda_end_file(void) { /* Write out EOF record. */ if (output_file) { write_bytes("\0\0\0\0\0\0\0\0", 8); diff --git a/contrib/llvm-project/compiler-rt/lib/profile/InstrProfiling.c b/contrib/llvm-project/compiler-rt/lib/profile/InstrProfiling.c index ead5e9330734..4bf8463f1ef9 100644 --- a/contrib/llvm-project/compiler-rt/lib/profile/InstrProfiling.c +++ b/contrib/llvm-project/compiler-rt/lib/profile/InstrProfiling.c @@ -25,7 +25,7 @@ COMPILER_RT_VISIBILITY uint64_t __llvm_profile_get_magic(void) { : (INSTR_PROF_RAW_MAGIC_32); } -COMPILER_RT_VISIBILITY void __llvm_profile_set_dumped() { +COMPILER_RT_VISIBILITY void __llvm_profile_set_dumped(void) { lprofSetProfileDumped(1); } diff --git a/contrib/llvm-project/compiler-rt/lib/profile/InstrProfilingFile.c b/contrib/llvm-project/compiler-rt/lib/profile/InstrProfilingFile.c index 363ded9554ce..31cd7766ae79 100644 --- a/contrib/llvm-project/compiler-rt/lib/profile/InstrProfilingFile.c +++ b/contrib/llvm-project/compiler-rt/lib/profile/InstrProfilingFile.c @@ -141,9 +141,9 @@ static int mmapForContinuousMode(uint64_t CurrentFileOffset, FILE *File) { uint64_t FileOffsetToCounters = CurrentFileOffset + sizeof(__llvm_profile_header) + DataSize + PaddingBytesBeforeCounters; - uint64_t *CounterMmap = (uint64_t *)mmap( - (void *)CountersBegin, PageAlignedCountersLength, PROT_READ | PROT_WRITE, - MAP_FIXED | MAP_SHARED, Fileno, FileOffsetToCounters); + void *CounterMmap = mmap((void *)CountersBegin, PageAlignedCountersLength, + PROT_READ | PROT_WRITE, MAP_FIXED | MAP_SHARED, + Fileno, FileOffsetToCounters); if (CounterMmap != CountersBegin) { PROF_ERR( "Continuous counter sync mode is enabled, but mmap() failed (%s).\n" @@ -231,18 +231,18 @@ static int mmapForContinuousMode(uint64_t CurrentFileOffset, FILE *File) { } #endif -static int isProfileMergeRequested() { return ProfileMergeRequested; } +static int isProfileMergeRequested(void) { return ProfileMergeRequested; } static void setProfileMergeRequested(int EnableMerge) { ProfileMergeRequested = EnableMerge; } static FILE *ProfileFile = NULL; -static FILE *getProfileFile() { return ProfileFile; } +static FILE *getProfileFile(void) { return ProfileFile; } static void setProfileFile(FILE *File) { ProfileFile = File; } -static int getCurFilenameLength(); +static int getCurFilenameLength(void); static const char *getCurFilename(char *FilenameBuf, int ForceUseBuf); -static unsigned doMerging() { +static unsigned doMerging(void) { return lprofCurFilename.MergePoolSize || isProfileMergeRequested(); } @@ -303,7 +303,7 @@ lprofCreateBufferIOInternal(void *File, uint32_t BufferSz) { return IO; } -static void setupIOBuffer() { +static void setupIOBuffer(void) { const char *BufferSzStr = 0; BufferSzStr = getenv("LLVM_VP_BUFFER_SIZE"); if (BufferSzStr && BufferSzStr[0]) { @@ -822,7 +822,7 @@ static void parseAndSetFilename(const char *FilenamePat, * filename with PID and hostname substitutions. */ /* The length to hold uint64_t followed by 3 digits pool id including '_' */ #define SIGLEN 24 -static int getCurFilenameLength() { +static int getCurFilenameLength(void) { int Len; if (!lprofCurFilename.FilenamePat || !lprofCurFilename.FilenamePat[0]) return 0; diff --git a/contrib/llvm-project/compiler-rt/lib/profile/InstrProfilingInternal.c b/contrib/llvm-project/compiler-rt/lib/profile/InstrProfilingInternal.c index edd38ad765c5..3dd659f90510 100644 --- a/contrib/llvm-project/compiler-rt/lib/profile/InstrProfilingInternal.c +++ b/contrib/llvm-project/compiler-rt/lib/profile/InstrProfilingInternal.c @@ -15,7 +15,7 @@ static unsigned ProfileDumped = 0; -COMPILER_RT_VISIBILITY unsigned lprofProfileDumped() { +COMPILER_RT_VISIBILITY unsigned lprofProfileDumped(void) { return ProfileDumped; } diff --git a/contrib/llvm-project/compiler-rt/lib/profile/InstrProfilingMerge.c b/contrib/llvm-project/compiler-rt/lib/profile/InstrProfilingMerge.c index adf866e52cf7..4da88b7d7bdb 100644 --- a/contrib/llvm-project/compiler-rt/lib/profile/InstrProfilingMerge.c +++ b/contrib/llvm-project/compiler-rt/lib/profile/InstrProfilingMerge.c @@ -20,7 +20,7 @@ COMPILER_RT_VISIBILITY void (*VPMergeHook)(ValueProfData *, __llvm_profile_data *); COMPILER_RT_VISIBILITY -uint64_t lprofGetLoadModuleSignature() { +uint64_t lprofGetLoadModuleSignature(void) { /* A very fast way to compute a module signature. */ uint64_t Version = __llvm_profile_get_version(); uint64_t NumCounters = __llvm_profile_get_num_counters( diff --git a/contrib/llvm-project/compiler-rt/lib/profile/InstrProfilingPlatformFuchsia.c b/contrib/llvm-project/compiler-rt/lib/profile/InstrProfilingPlatformFuchsia.c index ee2bd56b4b53..fdcb82e4d72b 100644 --- a/contrib/llvm-project/compiler-rt/lib/profile/InstrProfilingPlatformFuchsia.c +++ b/contrib/llvm-project/compiler-rt/lib/profile/InstrProfilingPlatformFuchsia.c @@ -37,7 +37,7 @@ /* This variable is an external reference to symbol defined by the compiler. */ COMPILER_RT_VISIBILITY extern intptr_t INSTR_PROF_PROFILE_COUNTER_BIAS_VAR; -COMPILER_RT_VISIBILITY unsigned lprofProfileDumped() { +COMPILER_RT_VISIBILITY unsigned lprofProfileDumped(void) { return 1; } COMPILER_RT_VISIBILITY void lprofSetProfileDumped(unsigned Value) {} diff --git a/contrib/llvm-project/compiler-rt/lib/profile/InstrProfilingPlatformLinux.c b/contrib/llvm-project/compiler-rt/lib/profile/InstrProfilingPlatformLinux.c index 592c09b49d4b..3af61d24948e 100644 --- a/contrib/llvm-project/compiler-rt/lib/profile/InstrProfilingPlatformLinux.c +++ b/contrib/llvm-project/compiler-rt/lib/profile/InstrProfilingPlatformLinux.c @@ -7,10 +7,13 @@ \*===----------------------------------------------------------------------===*/ #if defined(__linux__) || defined(__FreeBSD__) || defined(__Fuchsia__) || \ - (defined(__sun__) && defined(__svr4__)) || defined(__NetBSD__) + (defined(__sun__) && defined(__svr4__)) || defined(__NetBSD__) || \ + defined(_AIX) +#if !defined(_AIX) #include <elf.h> #include <link.h> +#endif #include <stdlib.h> #include <string.h> @@ -227,4 +230,43 @@ COMPILER_RT_VISIBILITY int __llvm_write_binary_ids(ProfDataWriter *Writer) { } #endif +#if defined(_AIX) +// Empty stubs to allow linking object files using the registration-based scheme +COMPILER_RT_VISIBILITY +void __llvm_profile_register_function(void *Data_) {} + +COMPILER_RT_VISIBILITY +void __llvm_profile_register_names_function(void *NamesStart, + uint64_t NamesSize) {} + +// The __start_SECNAME and __stop_SECNAME symbols (for SECNAME \in +// {"__llvm_prf_cnts", "__llvm_prf_data", "__llvm_prf_name", "__llvm_prf_vnds"}) +// are always live when linking on AIX, regardless if the .o's being linked +// reference symbols from the profile library (for example when no files were +// compiled with -fprofile-generate). That's because these symbols are kept +// alive through references in constructor functions that are always live in the +// default linking model on AIX (-bcdtors:all). The __start_SECNAME and +// __stop_SECNAME symbols are only resolved by the linker when the SECNAME +// section exists. So for the scenario where the user objects have no such +// section (i.e. when they are compiled with -fno-profile-generate), we always +// define these zero length variables in each of the above 4 sections. +COMPILER_RT_VISIBILITY int dummy_cnts[0] COMPILER_RT_SECTION( + COMPILER_RT_SEG INSTR_PROF_CNTS_SECT_NAME); +COMPILER_RT_VISIBILITY int dummy_data[0] COMPILER_RT_SECTION( + COMPILER_RT_SEG INSTR_PROF_DATA_SECT_NAME); +COMPILER_RT_VISIBILITY const int dummy_name[0] COMPILER_RT_SECTION( + COMPILER_RT_SEG INSTR_PROF_NAME_SECT_NAME); +COMPILER_RT_VISIBILITY int dummy_vnds[0] COMPILER_RT_SECTION( + COMPILER_RT_SEG INSTR_PROF_VNODES_SECT_NAME); + +// Create a fake reference to avoid GC'ing of the dummy variables by the linker. +// Ideally, we create a ".ref" of each variable inside the function +// __llvm_profile_begin_counters(), but there's no source level construct +// that allows us to generate that. +__attribute__((destructor)) void keep() { + int volatile use = &dummy_cnts < &dummy_data && &dummy_name < &dummy_vnds; + (void)use; +} +#endif + #endif diff --git a/contrib/llvm-project/compiler-rt/lib/profile/InstrProfilingPlatformOther.c b/contrib/llvm-project/compiler-rt/lib/profile/InstrProfilingPlatformOther.c index 3e9b3ca0a045..c7b6e842c9fa 100644 --- a/contrib/llvm-project/compiler-rt/lib/profile/InstrProfilingPlatformOther.c +++ b/contrib/llvm-project/compiler-rt/lib/profile/InstrProfilingPlatformOther.c @@ -7,8 +7,8 @@ \*===----------------------------------------------------------------------===*/ #if !defined(__APPLE__) && !defined(__linux__) && !defined(__FreeBSD__) && \ - !(defined(__sun__) && defined(__svr4__)) && !defined(__NetBSD__) && \ - !defined(_WIN32) + !defined(__Fuchsia__) && !(defined(__sun__) && defined(__svr4__)) && \ + !defined(__NetBSD__) && !defined(_WIN32) && !defined(_AIX) #include <stdlib.h> #include <stdio.h> diff --git a/contrib/llvm-project/compiler-rt/lib/profile/InstrProfilingUtil.c b/contrib/llvm-project/compiler-rt/lib/profile/InstrProfilingUtil.c index d563e333aca8..cd18cba3e268 100644 --- a/contrib/llvm-project/compiler-rt/lib/profile/InstrProfilingUtil.c +++ b/contrib/llvm-project/compiler-rt/lib/profile/InstrProfilingUtil.c @@ -46,7 +46,7 @@ #include "InstrProfiling.h" #include "InstrProfilingUtil.h" -COMPILER_RT_WEAK unsigned lprofDirMode = 0755; +COMPILER_RT_VISIBILITY unsigned lprofDirMode = 0755; COMPILER_RT_VISIBILITY void __llvm_profile_recursive_mkdir(char *path) { @@ -324,7 +324,7 @@ COMPILER_RT_VISIBILITY const char *lprofFindLastDirSeparator(const char *Path) { return Sep; } -COMPILER_RT_VISIBILITY int lprofSuspendSigKill() { +COMPILER_RT_VISIBILITY int lprofSuspendSigKill(void) { #if defined(__linux__) int PDeachSig = 0; /* Temporarily suspend getting SIGKILL upon exit of the parent process. */ @@ -342,7 +342,7 @@ COMPILER_RT_VISIBILITY int lprofSuspendSigKill() { #endif } -COMPILER_RT_VISIBILITY void lprofRestoreSigKill() { +COMPILER_RT_VISIBILITY void lprofRestoreSigKill(void) { #if defined(__linux__) prctl(PR_SET_PDEATHSIG, SIGKILL); #elif defined(__FreeBSD__) diff --git a/contrib/llvm-project/compiler-rt/lib/profile/InstrProfilingValue.c b/contrib/llvm-project/compiler-rt/lib/profile/InstrProfilingValue.c index 08197fdd9ea2..c819a38553f3 100644 --- a/contrib/llvm-project/compiler-rt/lib/profile/InstrProfilingValue.c +++ b/contrib/llvm-project/compiler-rt/lib/profile/InstrProfilingValue.c @@ -39,7 +39,7 @@ COMPILER_RT_VISIBILITY ValueProfNode COMPILER_RT_VISIBILITY uint32_t VPMaxNumValsPerSite = INSTR_PROF_DEFAULT_NUM_VAL_PER_SITE; -COMPILER_RT_VISIBILITY void lprofSetupValueProfiler() { +COMPILER_RT_VISIBILITY void lprofSetupValueProfiler(void) { const char *Str = 0; Str = getenv("LLVM_VP_MAX_NUM_VALS_PER_SITE"); if (Str && Str[0]) { @@ -353,6 +353,6 @@ static VPDataReaderType TheVPDataReader = { getFirstValueProfRecord, getNumValueDataForSiteWrapper, getValueProfDataSizeWrapper, getNextNValueData}; -COMPILER_RT_VISIBILITY VPDataReaderType *lprofGetVPDataReader() { +COMPILER_RT_VISIBILITY VPDataReaderType *lprofGetVPDataReader(void) { return &TheVPDataReader; } diff --git a/contrib/llvm-project/compiler-rt/lib/safestack/safestack_platform.h b/contrib/llvm-project/compiler-rt/lib/safestack/safestack_platform.h index 81e4c2645ce2..2b1fc139baa9 100644 --- a/contrib/llvm-project/compiler-rt/lib/safestack/safestack_platform.h +++ b/contrib/llvm-project/compiler-rt/lib/safestack/safestack_platform.h @@ -94,7 +94,7 @@ inline void *Mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset) { #if SANITIZER_NETBSD return __mmap(addr, length, prot, flags, fd, 0, offset); -#elif defined(__x86_64__) && (SANITIZER_FREEBSD) +#elif SANITIZER_FREEBSD && (defined(__aarch64__) || defined(__x86_64__)) return (void *)__syscall(SYS_mmap, addr, length, prot, flags, fd, offset); #else return (void *)syscall(SYS_mmap, addr, length, prot, flags, fd, offset); diff --git a/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_allocator_report.cpp b/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_allocator_report.cpp index 1c6520819ef9..129f925e6fb6 100644 --- a/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_allocator_report.cpp +++ b/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_allocator_report.cpp @@ -128,8 +128,7 @@ void NORETURN ReportAllocationSizeTooBig(uptr user_size, uptr max_size, void NORETURN ReportOutOfMemory(uptr requested_size, const StackTrace *stack) { { ScopedAllocatorErrorReport report("out-of-memory", stack); - Report("ERROR: %s: allocator is out of memory trying to allocate 0x%zx " - "bytes\n", SanitizerToolName, requested_size); + ERROR_OOM("allocator is trying to allocate 0x%zx bytes\n", requested_size); } Die(); } diff --git a/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_atomic_clang.h b/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_atomic_clang.h index c2b22cf572a6..4318d64d16cf 100644 --- a/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_atomic_clang.h +++ b/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_atomic_clang.h @@ -95,8 +95,8 @@ inline bool atomic_compare_exchange_weak(volatile T *a, // This include provides explicit template instantiations for atomic_uint64_t // on MIPS32, which does not directly support 8 byte atomics. It has to // proceed the template definitions above. -#if defined(_MIPS_SIM) && defined(_ABIO32) - #include "sanitizer_atomic_clang_mips.h" +#if defined(_MIPS_SIM) && defined(_ABIO32) && _MIPS_SIM == _ABIO32 +# include "sanitizer_atomic_clang_mips.h" #endif #undef ATOMIC_ORDER diff --git a/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_chained_origin_depot.cpp b/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_chained_origin_depot.cpp index 472b83d63a08..e0e2bd01069f 100644 --- a/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_chained_origin_depot.cpp +++ b/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_chained_origin_depot.cpp @@ -143,4 +143,6 @@ void ChainedOriginDepot::LockAll() { depot.LockAll(); } void ChainedOriginDepot::UnlockAll() { depot.UnlockAll(); } +void ChainedOriginDepot::TestOnlyUnmap() { depot.TestOnlyUnmap(); } + } // namespace __sanitizer diff --git a/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_chained_origin_depot.h b/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_chained_origin_depot.h index 2e800964a45d..f9f192b68571 100644 --- a/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_chained_origin_depot.h +++ b/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_chained_origin_depot.h @@ -34,6 +34,7 @@ class ChainedOriginDepot { void LockAll(); void UnlockAll(); + void TestOnlyUnmap(); private: ChainedOriginDepot(const ChainedOriginDepot &) = delete; diff --git a/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_common.cpp b/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_common.cpp index e9379b7bdc96..82236453157f 100644 --- a/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_common.cpp +++ b/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_common.cpp @@ -11,10 +11,12 @@ //===----------------------------------------------------------------------===// #include "sanitizer_common.h" + #include "sanitizer_allocator_interface.h" #include "sanitizer_allocator_internal.h" #include "sanitizer_atomic.h" #include "sanitizer_flags.h" +#include "sanitizer_interface_internal.h" #include "sanitizer_libc.h" #include "sanitizer_placement_new.h" @@ -44,9 +46,15 @@ void NORETURN ReportMmapFailureAndDie(uptr size, const char *mem_type, Die(); } recursion_count++; - Report("ERROR: %s failed to " - "%s 0x%zx (%zd) bytes of %s (error code: %d)\n", - SanitizerToolName, mmap_type, size, size, mem_type, err); + if (ErrorIsOOM(err)) { + ERROR_OOM("failed to %s 0x%zx (%zd) bytes of %s (error code: %d)\n", + mmap_type, size, size, mem_type, err); + } else { + Report( + "ERROR: %s failed to " + "%s 0x%zx (%zd) bytes of %s (error code: %d)\n", + SanitizerToolName, mmap_type, size, size, mem_type, err); + } #if !SANITIZER_GO DumpProcessMap(); #endif @@ -152,7 +160,7 @@ void LoadedModule::setUuid(const char *uuid, uptr size) { void LoadedModule::clear() { InternalFree(full_name_); base_address_ = 0; - max_executable_address_ = 0; + max_address_ = 0; full_name_ = nullptr; arch_ = kModuleArchUnknown; internal_memset(uuid_, 0, kModuleUUIDSize); @@ -170,8 +178,7 @@ void LoadedModule::addAddressRange(uptr beg, uptr end, bool executable, AddressRange *r = new(mem) AddressRange(beg, end, executable, writable, name); ranges_.push_back(r); - if (executable && end > max_executable_address_) - max_executable_address_ = end; + max_address_ = Max(max_address_, end); } bool LoadedModule::containsAddress(uptr address) const { @@ -309,18 +316,22 @@ struct MallocFreeHook { static MallocFreeHook MFHooks[kMaxMallocFreeHooks]; -void RunMallocHooks(const void *ptr, uptr size) { +void RunMallocHooks(void *ptr, uptr size) { + __sanitizer_malloc_hook(ptr, size); for (int i = 0; i < kMaxMallocFreeHooks; i++) { auto hook = MFHooks[i].malloc_hook; - if (!hook) return; + if (!hook) + break; hook(ptr, size); } } -void RunFreeHooks(const void *ptr) { +void RunFreeHooks(void *ptr) { + __sanitizer_free_hook(ptr); for (int i = 0; i < kMaxMallocFreeHooks; i++) { auto hook = MFHooks[i].free_hook; - if (!hook) return; + if (!hook) + break; hook(ptr); } } @@ -346,6 +357,13 @@ void SleepForSeconds(unsigned seconds) { } void SleepForMillis(unsigned millis) { internal_usleep((u64)millis * 1000); } +void WaitForDebugger(unsigned seconds, const char *label) { + if (seconds) { + Report("Sleeping for %u second(s) %s\n", seconds, label); + SleepForSeconds(seconds); + } +} + } // namespace __sanitizer using namespace __sanitizer; @@ -368,4 +386,16 @@ int __sanitizer_install_malloc_and_free_hooks(void (*malloc_hook)(const void *, void (*free_hook)(const void *)) { return InstallMallocFreeHooks(malloc_hook, free_hook); } + +// Provide default (no-op) implementation of malloc hooks. +SANITIZER_INTERFACE_WEAK_DEF(void, __sanitizer_malloc_hook, void *ptr, + uptr size) { + (void)ptr; + (void)size; +} + +SANITIZER_INTERFACE_WEAK_DEF(void, __sanitizer_free_hook, void *ptr) { + (void)ptr; +} + } // extern "C" diff --git a/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_common.h b/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_common.h index 3302590c6771..345c262af972 100644 --- a/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_common.h +++ b/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_common.h @@ -16,7 +16,6 @@ #define SANITIZER_COMMON_H #include "sanitizer_flags.h" -#include "sanitizer_interface_internal.h" #include "sanitizer_internal_defs.h" #include "sanitizer_libc.h" #include "sanitizer_list.h" @@ -171,8 +170,8 @@ void SetShadowRegionHugePageMode(uptr addr, uptr length); bool DontDumpShadowMemory(uptr addr, uptr length); // Check if the built VMA size matches the runtime one. void CheckVMASize(); -void RunMallocHooks(const void *ptr, uptr size); -void RunFreeHooks(const void *ptr); +void RunMallocHooks(void *ptr, uptr size); +void RunFreeHooks(void *ptr); class ReservedAddressRange { public: @@ -286,7 +285,7 @@ void SetStackSizeLimitInBytes(uptr limit); bool AddressSpaceIsUnlimited(); void SetAddressSpaceUnlimited(); void AdjustStackSize(void *attr); -void PlatformPrepareForSandboxing(__sanitizer_sandbox_arguments *args); +void PlatformPrepareForSandboxing(void *args); void SetSandboxingCallback(void (*f)()); void InitializeCoverage(bool enabled, const char *coverage_dir); @@ -295,6 +294,7 @@ void InitTlsSize(); uptr GetTlsSize(); // Other +void WaitForDebugger(unsigned seconds, const char *label); void SleepForSeconds(unsigned seconds); void SleepForMillis(unsigned millis); u64 NanoTime(); @@ -311,6 +311,18 @@ void NORETURN ReportMmapFailureAndDie(uptr size, const char *mem_type, const char *mmap_type, error_t err, bool raw_report = false); +// Returns true if the platform-specific error reported is an OOM error. +bool ErrorIsOOM(error_t err); + +// This reports an error in the form: +// +// `ERROR: {{SanitizerToolName}}: out of memory: {{err_msg}}` +// +// Downstream tools that read sanitizer output will know that errors starting +// in this format are specifically OOM errors. +#define ERROR_OOM(err_msg, ...) \ + Report("ERROR: %s: out of memory: " err_msg, SanitizerToolName, __VA_ARGS__) + // Specific tools may override behavior of "Die" function to do tool-specific // job. typedef void (*DieCallbackType)(void); @@ -739,6 +751,9 @@ bool ReadFileToBuffer(const char *file_name, char **buff, uptr *buff_size, uptr *read_len, uptr max_len = kDefaultFileMaxSize, error_t *errno_p = nullptr); +int GetModuleAndOffsetForPc(uptr pc, char *module_name, uptr module_name_len, + uptr *pc_offset); + // When adding a new architecture, don't forget to also update // script/asan_symbolize.py and sanitizer_symbolizer_libcdep.cpp. inline const char *ModuleArchToString(ModuleArch arch) { @@ -780,7 +795,7 @@ class LoadedModule { LoadedModule() : full_name_(nullptr), base_address_(0), - max_executable_address_(0), + max_address_(0), arch_(kModuleArchUnknown), uuid_size_(0), instrumented_(false) { @@ -798,7 +813,7 @@ class LoadedModule { const char *full_name() const { return full_name_; } uptr base_address() const { return base_address_; } - uptr max_executable_address() const { return max_executable_address_; } + uptr max_address() const { return max_address_; } ModuleArch arch() const { return arch_; } const u8 *uuid() const { return uuid_; } uptr uuid_size() const { return uuid_size_; } @@ -828,7 +843,7 @@ class LoadedModule { private: char *full_name_; // Owned. uptr base_address_; - uptr max_executable_address_; + uptr max_address_; ModuleArch arch_; uptr uuid_size_; u8 uuid_[kModuleUUIDSize]; @@ -888,13 +903,13 @@ void WriteToSyslog(const char *buffer); #define SANITIZER_WIN_TRACE 0 #endif -#if SANITIZER_MAC || SANITIZER_WIN_TRACE +#if SANITIZER_APPLE || SANITIZER_WIN_TRACE void LogFullErrorReport(const char *buffer); #else inline void LogFullErrorReport(const char *buffer) {} #endif -#if SANITIZER_LINUX || SANITIZER_MAC +#if SANITIZER_LINUX || SANITIZER_APPLE void WriteOneLineToSyslog(const char *s); void LogMessageOnPrintf(const char *str); #else diff --git a/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc b/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc index b0ab08dff1db..60537018b889 100644 --- a/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc +++ b/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc @@ -132,14 +132,84 @@ extern const short *_toupper_tab_; extern const short *_tolower_tab_; #endif +#if SANITIZER_MUSL && \ + (defined(__i386__) || defined(__arm__) || SANITIZER_MIPS32 || SANITIZER_PPC32) +// musl 1.2.0 on existing 32-bit architectures uses new symbol names for the +// time-related functions that take 64-bit time_t values. See +// https://musl.libc.org/time64.html +#define adjtime __adjtime64 +#define adjtimex __adjtimex_time64 +#define aio_suspend __aio_suspend_time64 +#define clock_adjtime __clock_adjtime64 +#define clock_getres __clock_getres_time64 +#define clock_gettime __clock_gettime64 +#define clock_nanosleep __clock_nanosleep_time64 +#define clock_settime __clock_settime64 +#define cnd_timedwait __cnd_timedwait_time64 +#define ctime __ctime64 +#define ctime_r __ctime64_r +#define difftime __difftime64 +#define dlsym __dlsym_time64 +#define fstatat __fstatat_time64 +#define fstat __fstat_time64 +#define ftime __ftime64 +#define futimens __futimens_time64 +#define futimesat __futimesat_time64 +#define futimes __futimes_time64 +#define getitimer __getitimer_time64 +#define getrusage __getrusage_time64 +#define gettimeofday __gettimeofday_time64 +#define gmtime __gmtime64 +#define gmtime_r __gmtime64_r +#define localtime __localtime64 +#define localtime_r __localtime64_r +#define lstat __lstat_time64 +#define lutimes __lutimes_time64 +#define mktime __mktime64 +#define mq_timedreceive __mq_timedreceive_time64 +#define mq_timedsend __mq_timedsend_time64 +#define mtx_timedlock __mtx_timedlock_time64 +#define nanosleep __nanosleep_time64 +#define ppoll __ppoll_time64 +#define pselect __pselect_time64 +#define pthread_cond_timedwait __pthread_cond_timedwait_time64 +#define pthread_mutex_timedlock __pthread_mutex_timedlock_time64 +#define pthread_rwlock_timedrdlock __pthread_rwlock_timedrdlock_time64 +#define pthread_rwlock_timedwrlock __pthread_rwlock_timedwrlock_time64 +#define pthread_timedjoin_np __pthread_timedjoin_np_time64 +#define recvmmsg __recvmmsg_time64 +#define sched_rr_get_interval __sched_rr_get_interval_time64 +#define select __select_time64 +#define semtimedop __semtimedop_time64 +#define sem_timedwait __sem_timedwait_time64 +#define setitimer __setitimer_time64 +#define settimeofday __settimeofday_time64 +#define sigtimedwait __sigtimedwait_time64 +#define stat __stat_time64 +#define stime __stime64 +#define thrd_sleep __thrd_sleep_time64 +#define timegm __timegm_time64 +#define timerfd_gettime __timerfd_gettime64 +#define timerfd_settime __timerfd_settime64 +#define timer_gettime __timer_gettime64 +#define timer_settime __timer_settime64 +#define timespec_get __timespec_get_time64 +#define time __time64 +#define utimensat __utimensat_time64 +#define utimes __utimes_time64 +#define utime __utime64 +#define wait3 __wait3_time64 +#define wait4 __wait4_time64 +#endif + // Platform-specific options. -#if SANITIZER_MAC +#if SANITIZER_APPLE #define PLATFORM_HAS_DIFFERENT_MEMCPY_AND_MEMMOVE 0 #elif SANITIZER_WINDOWS64 #define PLATFORM_HAS_DIFFERENT_MEMCPY_AND_MEMMOVE 0 #else #define PLATFORM_HAS_DIFFERENT_MEMCPY_AND_MEMMOVE 1 -#endif // SANITIZER_MAC +#endif // SANITIZER_APPLE #ifndef COMMON_INTERCEPTOR_INITIALIZE_RANGE #define COMMON_INTERCEPTOR_INITIALIZE_RANGE(p, size) {} @@ -315,9 +385,11 @@ extern const short *_tolower_tab_; if (common_flags()->intercept_strndup) { \ COMMON_INTERCEPTOR_READ_STRING(ctx, s, Min(size, copy_length + 1)); \ } \ - COMMON_INTERCEPTOR_COPY_STRING(ctx, new_mem, s, copy_length); \ - internal_memcpy(new_mem, s, copy_length); \ - new_mem[copy_length] = '\0'; \ + if (new_mem) { \ + COMMON_INTERCEPTOR_COPY_STRING(ctx, new_mem, s, copy_length); \ + internal_memcpy(new_mem, s, copy_length); \ + new_mem[copy_length] = '\0'; \ + } \ return new_mem; #endif @@ -1264,7 +1336,7 @@ INTERCEPTOR_WITH_SUFFIX(int, fputs, char *s, void *file) { // libc file streams can call user-supplied functions, see fopencookie. void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, fputs, s, file); - if (!SANITIZER_MAC || s) { // `fputs(NULL, file)` is supported on Darwin. + if (!SANITIZER_APPLE || s) { // `fputs(NULL, file)` is supported on Darwin. COMMON_INTERCEPTOR_READ_RANGE(ctx, s, internal_strlen(s) + 1); } return REAL(fputs)(s, file); @@ -1279,7 +1351,7 @@ INTERCEPTOR(int, puts, char *s) { // libc file streams can call user-supplied functions, see fopencookie. void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, puts, s); - if (!SANITIZER_MAC || s) { // `puts(NULL)` is supported on Darwin. + if (!SANITIZER_APPLE || s) { // `puts(NULL)` is supported on Darwin. COMMON_INTERCEPTOR_READ_RANGE(ctx, s, internal_strlen(s) + 1); } return REAL(puts)(s); @@ -1295,12 +1367,21 @@ INTERCEPTOR(int, prctl, int option, unsigned long arg2, unsigned long arg3, void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, prctl, option, arg2, arg3, arg4, arg5); static const int PR_SET_NAME = 15; + static const int PR_SET_VMA = 0x53564d41; + static const int PR_SCHED_CORE = 62; + static const int PR_SCHED_CORE_GET = 0; + if (option == PR_SET_VMA && arg2 == 0UL) { + char *name = (char *)arg5; + COMMON_INTERCEPTOR_READ_RANGE(ctx, name, internal_strlen(name) + 1); + } int res = REAL(prctl(option, arg2, arg3, arg4, arg5)); if (option == PR_SET_NAME) { char buff[16]; internal_strncpy(buff, (char *)arg2, 15); buff[15] = 0; COMMON_INTERCEPTOR_SET_THREAD_NAME(ctx, buff); + } else if (res != -1 && option == PR_SCHED_CORE && arg2 == PR_SCHED_CORE_GET) { + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, (u64*)(arg5), sizeof(u64)); } return res; } @@ -1878,7 +1959,7 @@ UNUSED static void unpoison_passwd(void *ctx, __sanitizer_passwd *pwd) { COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwd->pw_gecos, internal_strlen(pwd->pw_gecos) + 1); #endif -#if SANITIZER_MAC || SANITIZER_FREEBSD || SANITIZER_NETBSD +#if SANITIZER_APPLE || SANITIZER_FREEBSD || SANITIZER_NETBSD if (pwd->pw_class) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwd->pw_class, internal_strlen(pwd->pw_class) + 1); @@ -2422,6 +2503,58 @@ INTERCEPTOR(int, glob64, const char *pattern, int flags, #define INIT_GLOB64 #endif // SANITIZER_INTERCEPT_GLOB64 +#if SANITIZER_INTERCEPT___B64_TO +INTERCEPTOR(int, __b64_ntop, unsigned char const *src, SIZE_T srclength, + char *target, SIZE_T targsize) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, __b64_ntop, src, srclength, target, targsize); + COMMON_INTERCEPTOR_READ_RANGE(ctx, src, srclength); + int res = REAL(__b64_ntop)(src, srclength, target, targsize); + if (res >= 0) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, target, res + 1); + return res; +} +INTERCEPTOR(int, __b64_pton, char const *src, char *target, SIZE_T targsize) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, __b64_pton, src, target, targsize); + COMMON_INTERCEPTOR_READ_RANGE(ctx, src, internal_strlen(src) + 1); + int res = REAL(__b64_pton)(src, target, targsize); + if (res >= 0) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, target, res); + return res; +} +#define INIT___B64_TO \ + COMMON_INTERCEPT_FUNCTION(__b64_ntop); \ + COMMON_INTERCEPT_FUNCTION(__b64_pton); +#else // SANITIZER_INTERCEPT___B64_TO +#define INIT___B64_TO +#endif // SANITIZER_INTERCEPT___B64_TO + +#if SANITIZER_INTERCEPT___DN_EXPAND +#if __GLIBC_PREREQ(2, 34) +// Changed with https://sourceware.org/git/?p=glibc.git;h=640bbdf +#define DN_EXPAND_INTERCEPTOR_NAME dn_expand +#else +#define DN_EXPAND_INTERCEPTOR_NAME __dn_expand +#endif + INTERCEPTOR(int, DN_EXPAND_INTERCEPTOR_NAME, unsigned char const *base, + unsigned char const *end, unsigned char const *src, char *dest, + int space) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, DN_EXPAND_INTERCEPTOR_NAME, base, end, src, dest, space); + // TODO: add read check if __dn_comp intercept added + int res = REAL(DN_EXPAND_INTERCEPTOR_NAME)(base, end, src, dest, space); + if (res >= 0) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, res + 1); + return res; +} +#define INIT___DN_EXPAND \ + COMMON_INTERCEPT_FUNCTION(DN_EXPAND_INTERCEPTOR_NAME); +#else // SANITIZER_INTERCEPT___DN_EXPAND +#define INIT___DN_EXPAND +#endif // SANITIZER_INTERCEPT___DN_EXPAND + + #if SANITIZER_INTERCEPT_POSIX_SPAWN template <class RealSpawnPtr> @@ -3839,7 +3972,7 @@ INTERCEPTOR(char *, strerror, int errnum) { // * GNU version returns message pointer, which points to either buf or some // static storage. #if ((_POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600) && !_GNU_SOURCE) || \ - SANITIZER_MAC || SANITIZER_ANDROID || SANITIZER_NETBSD || \ + SANITIZER_APPLE || SANITIZER_ANDROID || SANITIZER_NETBSD || \ SANITIZER_FREEBSD // POSIX version. Spec is not clear on whether buf is NULL-terminated. // At least on OSX, buf contents are valid even when the call fails. @@ -3872,7 +4005,7 @@ INTERCEPTOR(char *, strerror_r, int errnum, char *buf, SIZE_T buflen) { return res; } #endif //(_POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600) && !_GNU_SOURCE || - //SANITIZER_MAC + //SANITIZER_APPLE #define INIT_STRERROR_R COMMON_INTERCEPT_FUNCTION(strerror_r); #else #define INIT_STRERROR_R @@ -4841,6 +4974,27 @@ INTERCEPTOR(int, pthread_attr_getaffinity_np, void *attr, SIZE_T cpusetsize, #define INIT_PTHREAD_ATTR_GETAFFINITY_NP #endif +#if SANITIZER_INTERCEPT_PTHREAD_GETAFFINITY_NP +INTERCEPTOR(int, pthread_getaffinity_np, void *attr, SIZE_T cpusetsize, + void *cpuset) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, pthread_getaffinity_np, attr, cpusetsize, + cpuset); + // FIXME: under ASan the call below may write to freed memory and corrupt + // its metadata. See + // https://github.com/google/sanitizers/issues/321. + int res = REAL(pthread_getaffinity_np)(attr, cpusetsize, cpuset); + if (!res && cpusetsize && cpuset) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cpuset, cpusetsize); + return res; +} + +#define INIT_PTHREAD_GETAFFINITY_NP \ + COMMON_INTERCEPT_FUNCTION(pthread_getaffinity_np); +#else +#define INIT_PTHREAD_GETAFFINITY_NP +#endif + #if SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETPSHARED INTERCEPTOR_PTHREAD_MUTEXATTR_GET(pshared, sizeof(int)) #define INIT_PTHREAD_MUTEXATTR_GETPSHARED \ @@ -6871,6 +7025,23 @@ INTERCEPTOR(int, stat, const char *path, void *buf) { #define INIT_STAT #endif +#if SANITIZER_INTERCEPT_STAT64 +INTERCEPTOR(int, stat64, const char *path, void *buf) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, stat64, path, buf); + if (common_flags()->intercept_stat) + COMMON_INTERCEPTOR_READ_STRING(ctx, path, 0); + int res = REAL(stat64)(path, buf); + if (!res) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, __sanitizer::struct_stat64_sz); + return res; +} +#define INIT_STAT64 COMMON_INTERCEPT_FUNCTION(stat64) +#else +#define INIT_STAT64 +#endif + + #if SANITIZER_INTERCEPT_LSTAT INTERCEPTOR(int, lstat, const char *path, void *buf) { void *ctx; @@ -6887,6 +7058,22 @@ INTERCEPTOR(int, lstat, const char *path, void *buf) { #define INIT_LSTAT #endif +#if SANITIZER_INTERCEPT_STAT64 +INTERCEPTOR(int, lstat64, const char *path, void *buf) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, lstat64, path, buf); + if (common_flags()->intercept_stat) + COMMON_INTERCEPTOR_READ_STRING(ctx, path, 0); + int res = REAL(lstat64)(path, buf); + if (!res) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, __sanitizer::struct_stat64_sz); + return res; +} +#define INIT_LSTAT64 COMMON_INTERCEPT_FUNCTION(lstat64) +#else +#define INIT_LSTAT64 +#endif + #if SANITIZER_INTERCEPT___XSTAT INTERCEPTOR(int, __xstat, int version, const char *path, void *buf) { void *ctx; @@ -7904,7 +8091,7 @@ INTERCEPTOR(int, regcomp, void *preg, const char *pattern, int cflags) { if (pattern) COMMON_INTERCEPTOR_READ_RANGE(ctx, pattern, internal_strlen(pattern) + 1); int res = REAL(regcomp)(preg, pattern, cflags); - if (!res) + if (preg) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, preg, struct_regex_sz); return res; } @@ -10173,6 +10360,42 @@ INTERCEPTOR(int, sigaltstack, void *ss, void *oss) { #define INIT_SIGALTSTACK #endif +#if SANITIZER_INTERCEPT_PROCCTL +INTERCEPTOR(int, procctl, int idtype, u64 id, int cmd, uptr data) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, procctl, idtype, id, cmd, data); + static const int PROC_REAP_ACQUIRE = 2; + static const int PROC_REAP_RELEASE = 3; + static const int PROC_REAP_STATUS = 4; + static const int PROC_REAP_GETPIDS = 5; + static const int PROC_REAP_KILL = 6; + if (cmd < PROC_REAP_ACQUIRE || cmd > PROC_REAP_KILL) { + COMMON_INTERCEPTOR_READ_RANGE(ctx, (void *)data, sizeof(int)); + } else { + // reap_acquire/reap_release bears no arguments. + if (cmd > PROC_REAP_RELEASE) { + unsigned int reapsz; + switch (cmd) { + case PROC_REAP_STATUS: + reapsz = struct_procctl_reaper_status_sz; + break; + case PROC_REAP_GETPIDS: + reapsz = struct_procctl_reaper_pids_sz; + break; + case PROC_REAP_KILL: + reapsz = struct_procctl_reaper_kill_sz; + break; + } + COMMON_INTERCEPTOR_READ_RANGE(ctx, (void *)data, reapsz); + } + } + return REAL(procctl)(idtype, id, cmd, data); +} +#define INIT_PROCCTL COMMON_INTERCEPT_FUNCTION(procctl) +#else +#define INIT_PROCCTL +#endif + #if SANITIZER_INTERCEPT_UNAME INTERCEPTOR(int, uname, struct utsname *utsname) { #if SANITIZER_LINUX @@ -10289,6 +10512,8 @@ static void InitializeCommonInterceptors() { INIT_TIME; INIT_GLOB; INIT_GLOB64; + INIT___B64_TO; + INIT___DN_EXPAND; INIT_POSIX_SPAWN; INIT_WAIT; INIT_WAIT4; @@ -10378,6 +10603,7 @@ static void InitializeCommonInterceptors() { INIT_PTHREAD_ATTR_GET_SCHED; INIT_PTHREAD_ATTR_GETINHERITSCHED; INIT_PTHREAD_ATTR_GETAFFINITY_NP; + INIT_PTHREAD_GETAFFINITY_NP; INIT_PTHREAD_MUTEXATTR_GETPSHARED; INIT_PTHREAD_MUTEXATTR_GETTYPE; INIT_PTHREAD_MUTEXATTR_GETPROTOCOL; @@ -10446,8 +10672,10 @@ static void InitializeCommonInterceptors() { INIT_RECV_RECVFROM; INIT_SEND_SENDTO; INIT_STAT; + INIT_STAT64; INIT_EVENTFD_READ_WRITE; INIT_LSTAT; + INIT_LSTAT64; INIT___XSTAT; INIT___XSTAT64; INIT___LXSTAT; @@ -10527,6 +10755,7 @@ static void InitializeCommonInterceptors() { INIT_QSORT_R; INIT_BSEARCH; INIT_SIGALTSTACK; + INIT_PROCCTL INIT_UNAME; INIT___XUNAME; diff --git a/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors_ioctl.inc b/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors_ioctl.inc index b7da65987557..49ec4097c900 100644 --- a/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors_ioctl.inc +++ b/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors_ioctl.inc @@ -115,11 +115,19 @@ static void ioctl_table_fill() { // _(SOUND_MIXER_WRITE_MUTE, WRITE, sizeof(int)); // same as ...WRITE_ENHANCE _(BLKFLSBUF, NONE, 0); _(BLKGETSIZE, WRITE, sizeof(uptr)); - _(BLKRAGET, WRITE, sizeof(int)); + _(BLKRAGET, WRITE, sizeof(uptr)); _(BLKRASET, NONE, 0); _(BLKROGET, WRITE, sizeof(int)); _(BLKROSET, READ, sizeof(int)); _(BLKRRPART, NONE, 0); + _(BLKFRASET, NONE, 0); + _(BLKFRAGET, WRITE, sizeof(uptr)); + _(BLKSECTSET, READ, sizeof(short)); + _(BLKSECTGET, WRITE, sizeof(short)); + _(BLKSSZGET, WRITE, sizeof(int)); + _(BLKBSZGET, WRITE, sizeof(int)); + _(BLKBSZSET, READ, sizeof(uptr)); + _(BLKGETSIZE64, WRITE, sizeof(u64)); _(CDROMEJECT, NONE, 0); _(CDROMEJECT_SW, NONE, 0); _(CDROMMULTISESSION, WRITE, struct_cdrom_multisession_sz); diff --git a/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_common_libcdep.cpp b/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_common_libcdep.cpp index c4cc0e45193e..8fd398564280 100644 --- a/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_common_libcdep.cpp +++ b/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_common_libcdep.cpp @@ -14,6 +14,7 @@ #include "sanitizer_allocator_interface.h" #include "sanitizer_common.h" #include "sanitizer_flags.h" +#include "sanitizer_interface_internal.h" #include "sanitizer_procmaps.h" #include "sanitizer_stackdepot.h" @@ -97,15 +98,19 @@ void MaybeStartBackgroudThread() { } # if !SANITIZER_START_BACKGROUND_THREAD_IN_ASAN_INTERNAL +# ifdef __clang__ # pragma clang diagnostic push // We avoid global-constructors to be sure that globals are ready when // sanitizers need them. This can happend before global constructors executed. // Here we don't mind if thread is started on later stages. # pragma clang diagnostic ignored "-Wglobal-constructors" +# endif static struct BackgroudThreadStarted { BackgroudThreadStarted() { MaybeStartBackgroudThread(); } } background_thread_strarter UNUSED; +# ifdef __clang__ # pragma clang diagnostic pop +# endif # endif #else void MaybeStartBackgroudThread() {} diff --git a/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_common_nolibc.cpp b/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_common_nolibc.cpp index a20602d8b95a..67e77a877781 100644 --- a/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_common_nolibc.cpp +++ b/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_common_nolibc.cpp @@ -28,7 +28,7 @@ void Abort() { internal__exit(1); } bool CreateDir(const char *pathname) { return false; } #endif // !SANITIZER_WINDOWS -#if !SANITIZER_WINDOWS && !SANITIZER_MAC +#if !SANITIZER_WINDOWS && !SANITIZER_APPLE void ListOfModules::init() {} void InitializePlatformCommonFlags(CommonFlags *cf) {} #endif diff --git a/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_coverage_fuchsia.cpp b/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_coverage_fuchsia.cpp index 1d0dbe592b93..35c325359148 100644 --- a/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_coverage_fuchsia.cpp +++ b/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_coverage_fuchsia.cpp @@ -33,6 +33,7 @@ #include "sanitizer_atomic.h" #include "sanitizer_common.h" +#include "sanitizer_interface_internal.h" #include "sanitizer_internal_defs.h" #include "sanitizer_symbolizer_fuchsia.h" diff --git a/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_coverage_libcdep_new.cpp b/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_coverage_libcdep_new.cpp index 56220df2ac18..3dcb39f32f6c 100644 --- a/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_coverage_libcdep_new.cpp +++ b/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_coverage_libcdep_new.cpp @@ -10,11 +10,13 @@ #include "sanitizer_platform.h" #if !SANITIZER_FUCHSIA -#include "sancov_flags.h" -#include "sanitizer_allocator_internal.h" -#include "sanitizer_atomic.h" -#include "sanitizer_common.h" -#include "sanitizer_file.h" +# include "sancov_flags.h" +# include "sanitizer_allocator_internal.h" +# include "sanitizer_atomic.h" +# include "sanitizer_common.h" +# include "sanitizer_common/sanitizer_stacktrace.h" +# include "sanitizer_file.h" +# include "sanitizer_interface_internal.h" using namespace __sanitizer; @@ -72,7 +74,7 @@ static void SanitizerDumpCoverage(const uptr* unsorted_pcs, uptr len) { const uptr pc = pcs[i]; if (!pc) continue; - if (!__sanitizer_get_module_and_offset_for_pc(pc, nullptr, 0, &pcs[i])) { + if (!GetModuleAndOffsetForPc(pc, nullptr, 0, &pcs[i])) { Printf("ERROR: unknown pc 0x%zx (may happen if dlclose is used)\n", pc); continue; } @@ -87,8 +89,7 @@ static void SanitizerDumpCoverage(const uptr* unsorted_pcs, uptr len) { last_base = module_base; module_start_idx = i; module_found = true; - __sanitizer_get_module_and_offset_for_pc(pc, module_name, kMaxPathLength, - &pcs[i]); + GetModuleAndOffsetForPc(pc, module_name, kMaxPathLength, &pcs[i]); } } @@ -222,7 +223,8 @@ SANITIZER_INTERFACE_ATTRIBUTE void __sanitizer_dump_coverage(const uptr* pcs, SANITIZER_INTERFACE_WEAK_DEF(void, __sanitizer_cov_trace_pc_guard, u32* guard) { if (!*guard) return; - __sancov::pc_guard_controller.TracePcGuard(guard, GET_CALLER_PC() - 1); + __sancov::pc_guard_controller.TracePcGuard( + guard, StackTrace::GetPreviousInstructionPc(GET_CALLER_PC())); } SANITIZER_INTERFACE_WEAK_DEF(void, __sanitizer_cov_trace_pc_guard_init, diff --git a/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_errno.h b/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_errno.h index 70a6e88dbaad..46c85364cef5 100644 --- a/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_errno.h +++ b/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_errno.h @@ -21,7 +21,7 @@ #include "sanitizer_errno_codes.h" #include "sanitizer_platform.h" -#if SANITIZER_FREEBSD || SANITIZER_MAC +#if SANITIZER_FREEBSD || SANITIZER_APPLE # define __errno_location __error #elif SANITIZER_ANDROID || SANITIZER_NETBSD # define __errno_location __errno diff --git a/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_file.cpp b/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_file.cpp index 5492560df914..7ef499ce07b1 100644 --- a/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_file.cpp +++ b/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_file.cpp @@ -19,6 +19,7 @@ #include "sanitizer_common.h" #include "sanitizer_file.h" +# include "sanitizer_interface_internal.h" namespace __sanitizer { @@ -83,8 +84,12 @@ static void RecursiveCreateParentDirs(char *path) { if (!IsPathSeparator(path[i])) continue; path[i] = '\0'; - /* Some of these will fail, because the directory exists, ignore it. */ - CreateDir(path); + if (!DirExists(path) && !CreateDir(path)) { + const char *ErrorMsgPrefix = "ERROR: Can't create directory: "; + WriteToFile(kStderrFd, ErrorMsgPrefix, internal_strlen(ErrorMsgPrefix)); + WriteToFile(kStderrFd, path, internal_strlen(path)); + Die(); + } path[i] = save; } } diff --git a/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_file.h b/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_file.h index 3d7916171c1e..810c1e452f61 100644 --- a/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_file.h +++ b/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_file.h @@ -15,7 +15,6 @@ #ifndef SANITIZER_FILE_H #define SANITIZER_FILE_H -#include "sanitizer_interface_internal.h" #include "sanitizer_internal_defs.h" #include "sanitizer_libc.h" #include "sanitizer_mutex.h" @@ -78,6 +77,7 @@ bool SupportsColoredOutput(fd_t fd); // OS const char *GetPwd(); bool FileExists(const char *filename); +bool DirExists(const char *path); char *FindPathToBinary(const char *name); bool IsPathSeparator(const char c); bool IsAbsolutePath(const char *path); diff --git a/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_flags.inc b/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_flags.inc index 0ca91aff8dd4..8627ffd0d01c 100644 --- a/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_flags.inc +++ b/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_flags.inc @@ -62,7 +62,7 @@ COMMON_FLAG( COMMON_FLAG(const char *, log_suffix, nullptr, "String to append to log file name, e.g. \".txt\".") COMMON_FLAG( - bool, log_to_syslog, (bool)SANITIZER_ANDROID || (bool)SANITIZER_MAC, + bool, log_to_syslog, (bool)SANITIZER_ANDROID || (bool)SANITIZER_APPLE, "Write all sanitizer output to syslog in addition to other means of " "logging.") COMMON_FLAG( @@ -71,7 +71,7 @@ COMMON_FLAG( COMMON_FLAG(bool, strip_env, 1, "Whether to remove the sanitizer from DYLD_INSERT_LIBRARIES to " "avoid passing it to children. Default is true.") -COMMON_FLAG(bool, detect_leaks, !SANITIZER_MAC, "Enable memory leak detection.") +COMMON_FLAG(bool, detect_leaks, !SANITIZER_APPLE, "Enable memory leak detection.") COMMON_FLAG( bool, leak_check_at_exit, true, "Invoke leak checking in an atexit handler. Has no effect if " @@ -245,7 +245,7 @@ COMMON_FLAG(bool, decorate_proc_maps, (bool)SANITIZER_ANDROID, COMMON_FLAG(int, exitcode, 1, "Override the program exit status if the tool " "found an error") COMMON_FLAG( - bool, abort_on_error, (bool)SANITIZER_ANDROID || (bool)SANITIZER_MAC, + bool, abort_on_error, (bool)SANITIZER_ANDROID || (bool)SANITIZER_APPLE, "If set, the tool calls abort() instead of _exit() after printing the " "error report.") COMMON_FLAG(bool, suppress_equal_pcs, true, diff --git a/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_fuchsia.cpp b/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_fuchsia.cpp index 66a0fd64a05a..e253b67fc484 100644 --- a/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_fuchsia.cpp +++ b/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_fuchsia.cpp @@ -14,24 +14,25 @@ #include "sanitizer_fuchsia.h" #if SANITIZER_FUCHSIA -#include <pthread.h> -#include <stdlib.h> -#include <unistd.h> -#include <zircon/errors.h> -#include <zircon/process.h> -#include <zircon/syscalls.h> -#include <zircon/utc.h> - -#include "sanitizer_common.h" -#include "sanitizer_libc.h" -#include "sanitizer_mutex.h" +# include <pthread.h> +# include <stdlib.h> +# include <unistd.h> +# include <zircon/errors.h> +# include <zircon/process.h> +# include <zircon/syscalls.h> +# include <zircon/utc.h> + +# include "sanitizer_common.h" +# include "sanitizer_interface_internal.h" +# include "sanitizer_libc.h" +# include "sanitizer_mutex.h" namespace __sanitizer { void NORETURN internal__exit(int exitcode) { _zx_process_exit(exitcode); } uptr internal_sched_yield() { - zx_status_t status = _zx_nanosleep(0); + zx_status_t status = _zx_thread_legacy_yield(0u); CHECK_EQ(status, ZX_OK); return 0; // Why doesn't this return void? } @@ -89,7 +90,7 @@ void InitializePlatformEarly() {} void MaybeReexec() {} void CheckASLR() {} void CheckMPROTECT() {} -void PlatformPrepareForSandboxing(__sanitizer_sandbox_arguments *args) {} +void PlatformPrepareForSandboxing(void *args) {} void DisableCoreDumperIfNecessary() {} void InstallDeadlySignalHandlers(SignalHandlerType handler) {} void SetAlternateSignalStack() {} @@ -127,6 +128,8 @@ uptr GetMaxUserVirtualAddress() { uptr GetMaxVirtualAddress() { return GetMaxUserVirtualAddress(); } +bool ErrorIsOOM(error_t err) { return err == ZX_ERR_NO_MEMORY; } + static void *DoAnonymousMmapOrDie(uptr size, const char *mem_type, bool raw_report, bool die_for_nomem) { size = RoundUpTo(size, GetPageSize()); @@ -385,29 +388,8 @@ void GetMemoryProfile(fill_profile_f cb, uptr *stats) {} bool ReadFileToBuffer(const char *file_name, char **buff, uptr *buff_size, uptr *read_len, uptr max_len, error_t *errno_p) { - zx_handle_t vmo; - zx_status_t status = __sanitizer_get_configuration(file_name, &vmo); - if (status == ZX_OK) { - uint64_t vmo_size; - status = _zx_vmo_get_size(vmo, &vmo_size); - if (status == ZX_OK) { - if (vmo_size < max_len) - max_len = vmo_size; - size_t map_size = RoundUpTo(max_len, GetPageSize()); - uintptr_t addr; - status = _zx_vmar_map(_zx_vmar_root_self(), ZX_VM_PERM_READ, 0, vmo, 0, - map_size, &addr); - if (status == ZX_OK) { - *buff = reinterpret_cast<char *>(addr); - *buff_size = map_size; - *read_len = max_len; - } - } - _zx_handle_close(vmo); - } - if (status != ZX_OK && errno_p) - *errno_p = status; - return status == ZX_OK; + *errno_p = ZX_ERR_NOT_SUPPORTED; + return false; } void RawWrite(const char *buffer) { diff --git a/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_interface_internal.h b/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_interface_internal.h index 1600d31c30c0..e9dc78c6354e 100644 --- a/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_interface_internal.h +++ b/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_interface_internal.h @@ -20,104 +20,102 @@ #include "sanitizer_internal_defs.h" extern "C" { - // Tell the tools to write their reports to "path.<pid>" instead of stderr. - // The special values are "stdout" and "stderr". - SANITIZER_INTERFACE_ATTRIBUTE - void __sanitizer_set_report_path(const char *path); - // Tell the tools to write their reports to the provided file descriptor - // (casted to void *). - SANITIZER_INTERFACE_ATTRIBUTE - void __sanitizer_set_report_fd(void *fd); - // Get the current full report file path, if a path was specified by - // an earlier call to __sanitizer_set_report_path. Returns null otherwise. - SANITIZER_INTERFACE_ATTRIBUTE - const char *__sanitizer_get_report_path(); +// Tell the tools to write their reports to "path.<pid>" instead of stderr. +// The special values are "stdout" and "stderr". +SANITIZER_INTERFACE_ATTRIBUTE +void __sanitizer_set_report_path(const char *path); +// Tell the tools to write their reports to the provided file descriptor +// (casted to void *). +SANITIZER_INTERFACE_ATTRIBUTE +void __sanitizer_set_report_fd(void *fd); +// Get the current full report file path, if a path was specified by +// an earlier call to __sanitizer_set_report_path. Returns null otherwise. +SANITIZER_INTERFACE_ATTRIBUTE +const char *__sanitizer_get_report_path(); - typedef struct { - int coverage_sandboxed; - __sanitizer::sptr coverage_fd; - unsigned int coverage_max_block_size; - } __sanitizer_sandbox_arguments; +typedef struct { + int coverage_sandboxed; + __sanitizer::sptr coverage_fd; + unsigned int coverage_max_block_size; +} __sanitizer_sandbox_arguments; - // Notify the tools that the sandbox is going to be turned on. - SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE void - __sanitizer_sandbox_on_notify(__sanitizer_sandbox_arguments *args); +// Notify the tools that the sandbox is going to be turned on. +SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE void +__sanitizer_sandbox_on_notify(__sanitizer_sandbox_arguments *args); - // This function is called by the tool when it has just finished reporting - // an error. 'error_summary' is a one-line string that summarizes - // the error message. This function can be overridden by the client. - SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE - void __sanitizer_report_error_summary(const char *error_summary); +// This function is called by the tool when it has just finished reporting +// an error. 'error_summary' is a one-line string that summarizes +// the error message. This function can be overridden by the client. +SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE void +__sanitizer_report_error_summary(const char *error_summary); - SANITIZER_INTERFACE_ATTRIBUTE void __sanitizer_cov_dump(); - SANITIZER_INTERFACE_ATTRIBUTE void __sanitizer_dump_coverage( - const __sanitizer::uptr *pcs, const __sanitizer::uptr len); - SANITIZER_INTERFACE_ATTRIBUTE void __sanitizer_dump_trace_pc_guard_coverage(); +SANITIZER_INTERFACE_ATTRIBUTE void __sanitizer_cov_dump(); +SANITIZER_INTERFACE_ATTRIBUTE void __sanitizer_dump_coverage( + const __sanitizer::uptr *pcs, const __sanitizer::uptr len); +SANITIZER_INTERFACE_ATTRIBUTE void __sanitizer_dump_trace_pc_guard_coverage(); - SANITIZER_INTERFACE_ATTRIBUTE void __sanitizer_cov(__sanitizer::u32 *guard); +SANITIZER_INTERFACE_ATTRIBUTE void __sanitizer_cov(__sanitizer::u32 *guard); - // Returns 1 on the first call, then returns 0 thereafter. Called by the tool - // to ensure only one report is printed when multiple errors occur - // simultaneously. - SANITIZER_INTERFACE_ATTRIBUTE int __sanitizer_acquire_crash_state(); +// Returns 1 on the first call, then returns 0 thereafter. Called by the tool +// to ensure only one report is printed when multiple errors occur +// simultaneously. +SANITIZER_INTERFACE_ATTRIBUTE int __sanitizer_acquire_crash_state(); - SANITIZER_INTERFACE_ATTRIBUTE - void __sanitizer_annotate_contiguous_container(const void *beg, - const void *end, - const void *old_mid, - const void *new_mid); - SANITIZER_INTERFACE_ATTRIBUTE - int __sanitizer_verify_contiguous_container(const void *beg, const void *mid, - const void *end); - SANITIZER_INTERFACE_ATTRIBUTE - const void *__sanitizer_contiguous_container_find_bad_address( - const void *beg, const void *mid, const void *end); +SANITIZER_INTERFACE_ATTRIBUTE +void __sanitizer_annotate_contiguous_container(const void *beg, const void *end, + const void *old_mid, + const void *new_mid); +SANITIZER_INTERFACE_ATTRIBUTE +int __sanitizer_verify_contiguous_container(const void *beg, const void *mid, + const void *end); +SANITIZER_INTERFACE_ATTRIBUTE +const void *__sanitizer_contiguous_container_find_bad_address(const void *beg, + const void *mid, + const void *end); - SANITIZER_INTERFACE_ATTRIBUTE - int __sanitizer_get_module_and_offset_for_pc( - __sanitizer::uptr pc, char *module_path, - __sanitizer::uptr module_path_len, __sanitizer::uptr *pc_offset); +SANITIZER_INTERFACE_ATTRIBUTE +int __sanitizer_get_module_and_offset_for_pc(void *pc, char *module_path, + __sanitizer::uptr module_path_len, + void **pc_offset); - SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE - void __sanitizer_cov_trace_cmp(); - SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE - void __sanitizer_cov_trace_cmp1(); - SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE - void __sanitizer_cov_trace_cmp2(); - SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE - void __sanitizer_cov_trace_cmp4(); - SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE - void __sanitizer_cov_trace_cmp8(); - SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE - void __sanitizer_cov_trace_const_cmp1(); - SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE - void __sanitizer_cov_trace_const_cmp2(); - SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE - void __sanitizer_cov_trace_const_cmp4(); - SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE - void __sanitizer_cov_trace_const_cmp8(); - SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE - void __sanitizer_cov_trace_switch(); - SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE - void __sanitizer_cov_trace_div4(); - SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE - void __sanitizer_cov_trace_div8(); - SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE - void __sanitizer_cov_trace_gep(); - SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE - void __sanitizer_cov_trace_pc_indir(); - SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE - void __sanitizer_cov_trace_pc_guard(__sanitizer::u32*); - SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE - void __sanitizer_cov_trace_pc_guard_init(__sanitizer::u32*, - __sanitizer::u32*); - SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE void - __sanitizer_cov_8bit_counters_init(char *, char *); - SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE void - __sanitizer_cov_bool_flag_init(); - SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE void - __sanitizer_cov_pcs_init(const __sanitizer::uptr *, - const __sanitizer::uptr *); -} // extern "C" +SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE void +__sanitizer_cov_trace_cmp(); +SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE void +__sanitizer_cov_trace_cmp1(); +SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE void +__sanitizer_cov_trace_cmp2(); +SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE void +__sanitizer_cov_trace_cmp4(); +SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE void +__sanitizer_cov_trace_cmp8(); +SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE void +__sanitizer_cov_trace_const_cmp1(); +SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE void +__sanitizer_cov_trace_const_cmp2(); +SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE void +__sanitizer_cov_trace_const_cmp4(); +SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE void +__sanitizer_cov_trace_const_cmp8(); +SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE void +__sanitizer_cov_trace_switch(); +SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE void +__sanitizer_cov_trace_div4(); +SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE void +__sanitizer_cov_trace_div8(); +SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE void +__sanitizer_cov_trace_gep(); +SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE void +__sanitizer_cov_trace_pc_indir(); +SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE void +__sanitizer_cov_trace_pc_guard(__sanitizer::u32 *); +SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE void +__sanitizer_cov_trace_pc_guard_init(__sanitizer::u32 *, __sanitizer::u32 *); +SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE void +__sanitizer_cov_8bit_counters_init(char *, char *); +SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE void +__sanitizer_cov_bool_flag_init(); +SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE void +__sanitizer_cov_pcs_init(const __sanitizer::uptr *, const __sanitizer::uptr *); +} // extern "C" #endif // SANITIZER_INTERFACE_INTERNAL_H diff --git a/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_internal_defs.h b/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_internal_defs.h index d0db0129d4af..15738ff1e1bc 100644 --- a/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_internal_defs.h +++ b/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_internal_defs.h @@ -73,7 +73,7 @@ // Before Xcode 4.5, the Darwin linker doesn't reliably support undefined // weak symbols. Mac OS X 10.9/Darwin 13 is the first release only supported // by Xcode >= 4.5. -#elif SANITIZER_MAC && \ +#elif SANITIZER_APPLE && \ __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 1090 && !SANITIZER_GO # define SANITIZER_SUPPORTS_WEAK_HOOKS 1 #else @@ -139,7 +139,7 @@ namespace __sanitizer { typedef unsigned long long uptr; typedef signed long long sptr; #else -# if (SANITIZER_WORDSIZE == 64) || SANITIZER_MAC || SANITIZER_WINDOWS +# if (SANITIZER_WORDSIZE == 64) || SANITIZER_APPLE || SANITIZER_WINDOWS typedef unsigned long uptr; typedef signed long sptr; # else @@ -177,8 +177,9 @@ typedef long pid_t; typedef int pid_t; #endif -#if SANITIZER_FREEBSD || SANITIZER_NETBSD || SANITIZER_MAC || \ +#if SANITIZER_FREEBSD || SANITIZER_NETBSD || SANITIZER_APPLE || \ (SANITIZER_SOLARIS && (defined(_LP64) || _FILE_OFFSET_BITS == 64)) || \ + (SANITIZER_LINUX && !SANITIZER_GLIBC && !SANITIZER_ANDROID) || \ (SANITIZER_LINUX && (defined(__x86_64__) || defined(__hexagon__))) typedef u64 OFF_T; #else @@ -186,7 +187,7 @@ typedef uptr OFF_T; #endif typedef u64 OFF64_T; -#if (SANITIZER_WORDSIZE == 64) || SANITIZER_MAC +#if (SANITIZER_WORDSIZE == 64) || SANITIZER_APPLE typedef uptr operator_new_size_type; #else # if defined(__s390__) && !defined(__s390x__) @@ -260,6 +261,8 @@ typedef u64 tid_t; #if __has_cpp_attribute(clang::fallthrough) # define FALLTHROUGH [[clang::fallthrough]] +#elif __has_cpp_attribute(fallthrough) +# define FALLTHROUGH [[fallthrough]] #else # define FALLTHROUGH #endif diff --git a/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_libignore.cpp b/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_libignore.cpp index caaba3155a7b..b7fc9444cc66 100644 --- a/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_libignore.cpp +++ b/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_libignore.cpp @@ -8,7 +8,7 @@ #include "sanitizer_platform.h" -#if SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_MAC || \ +#if SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_APPLE || \ SANITIZER_NETBSD #include "sanitizer_libignore.h" @@ -125,5 +125,5 @@ void LibIgnore::OnLibraryUnloaded() { } // namespace __sanitizer -#endif // SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_MAC || +#endif // SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_APPLE || // SANITIZER_NETBSD diff --git a/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp b/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp index 778a79b1dfa3..c1acc20fe0b9 100644 --- a/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp +++ b/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp @@ -233,7 +233,7 @@ uptr internal_close(fd_t fd) { } uptr internal_open(const char *filename, int flags) { -#if SANITIZER_USES_CANONICAL_LINUX_SYSCALLS +# if SANITIZER_LINUX return internal_syscall(SYSCALL(openat), AT_FDCWD, (uptr)filename, flags); #else return internal_syscall(SYSCALL(open), (uptr)filename, flags); @@ -241,7 +241,7 @@ uptr internal_open(const char *filename, int flags) { } uptr internal_open(const char *filename, int flags, u32 mode) { -#if SANITIZER_USES_CANONICAL_LINUX_SYSCALLS +# if SANITIZER_LINUX return internal_syscall(SYSCALL(openat), AT_FDCWD, (uptr)filename, flags, mode); #else @@ -270,7 +270,7 @@ uptr internal_ftruncate(fd_t fd, uptr size) { return res; } -#if !SANITIZER_LINUX_USES_64BIT_SYSCALLS && SANITIZER_LINUX +#if (!SANITIZER_LINUX_USES_64BIT_SYSCALLS || SANITIZER_SPARC) && SANITIZER_LINUX static void stat64_to_stat(struct stat64 *in, struct stat *out) { internal_memset(out, 0, sizeof(*out)); out->st_dev = in->st_dev; @@ -342,50 +342,46 @@ static void kernel_stat_to_stat(struct kernel_stat *in, struct stat *out) { uptr internal_stat(const char *path, void *buf) { #if SANITIZER_FREEBSD return internal_syscall(SYSCALL(fstatat), AT_FDCWD, (uptr)path, (uptr)buf, 0); -#elif SANITIZER_USES_CANONICAL_LINUX_SYSCALLS +# elif SANITIZER_LINUX +# if (SANITIZER_WORDSIZE == 64 || SANITIZER_X32) && !SANITIZER_SPARC return internal_syscall(SYSCALL(newfstatat), AT_FDCWD, (uptr)path, (uptr)buf, 0); -#elif SANITIZER_LINUX_USES_64BIT_SYSCALLS -# if defined(__mips64) - // For mips64, stat syscall fills buffer in the format of kernel_stat - struct kernel_stat kbuf; - int res = internal_syscall(SYSCALL(stat), path, &kbuf); - kernel_stat_to_stat(&kbuf, (struct stat *)buf); +# else + struct stat64 buf64; + int res = internal_syscall(SYSCALL(fstatat64), AT_FDCWD, (uptr)path, + (uptr)&buf64, 0); + stat64_to_stat(&buf64, (struct stat *)buf); return res; -# else - return internal_syscall(SYSCALL(stat), (uptr)path, (uptr)buf); -# endif -#else +# endif +# else struct stat64 buf64; int res = internal_syscall(SYSCALL(stat64), path, &buf64); stat64_to_stat(&buf64, (struct stat *)buf); return res; -#endif +# endif } uptr internal_lstat(const char *path, void *buf) { #if SANITIZER_FREEBSD return internal_syscall(SYSCALL(fstatat), AT_FDCWD, (uptr)path, (uptr)buf, AT_SYMLINK_NOFOLLOW); -#elif SANITIZER_USES_CANONICAL_LINUX_SYSCALLS +# elif SANITIZER_LINUX +# if (defined(_LP64) || SANITIZER_X32) && !SANITIZER_SPARC return internal_syscall(SYSCALL(newfstatat), AT_FDCWD, (uptr)path, (uptr)buf, AT_SYMLINK_NOFOLLOW); -#elif SANITIZER_LINUX_USES_64BIT_SYSCALLS -# if SANITIZER_MIPS64 - // For mips64, lstat syscall fills buffer in the format of kernel_stat - struct kernel_stat kbuf; - int res = internal_syscall(SYSCALL(lstat), path, &kbuf); - kernel_stat_to_stat(&kbuf, (struct stat *)buf); +# else + struct stat64 buf64; + int res = internal_syscall(SYSCALL(fstatat64), AT_FDCWD, (uptr)path, + (uptr)&buf64, AT_SYMLINK_NOFOLLOW); + stat64_to_stat(&buf64, (struct stat *)buf); return res; -# else - return internal_syscall(SYSCALL(lstat), (uptr)path, (uptr)buf); -# endif -#else +# endif +# else struct stat64 buf64; int res = internal_syscall(SYSCALL(lstat64), path, &buf64); stat64_to_stat(&buf64, (struct stat *)buf); return res; -#endif +# endif } uptr internal_fstat(fd_t fd, void *buf) { @@ -419,7 +415,7 @@ uptr internal_dup(int oldfd) { } uptr internal_dup2(int oldfd, int newfd) { -#if SANITIZER_USES_CANONICAL_LINUX_SYSCALLS +# if SANITIZER_LINUX return internal_syscall(SYSCALL(dup3), oldfd, newfd, 0); #else return internal_syscall(SYSCALL(dup2), oldfd, newfd); @@ -427,7 +423,7 @@ uptr internal_dup2(int oldfd, int newfd) { } uptr internal_readlink(const char *path, char *buf, uptr bufsize) { -#if SANITIZER_USES_CANONICAL_LINUX_SYSCALLS +# if SANITIZER_LINUX return internal_syscall(SYSCALL(readlinkat), AT_FDCWD, (uptr)path, (uptr)buf, bufsize); #else @@ -436,7 +432,7 @@ uptr internal_readlink(const char *path, char *buf, uptr bufsize) { } uptr internal_unlink(const char *path) { -#if SANITIZER_USES_CANONICAL_LINUX_SYSCALLS +# if SANITIZER_LINUX return internal_syscall(SYSCALL(unlinkat), AT_FDCWD, (uptr)path, 0); #else return internal_syscall(SYSCALL(unlink), (uptr)path); @@ -447,12 +443,12 @@ uptr internal_rename(const char *oldpath, const char *newpath) { #if defined(__riscv) && defined(__linux__) return internal_syscall(SYSCALL(renameat2), AT_FDCWD, (uptr)oldpath, AT_FDCWD, (uptr)newpath, 0); -#elif SANITIZER_USES_CANONICAL_LINUX_SYSCALLS +# elif SANITIZER_LINUX return internal_syscall(SYSCALL(renameat), AT_FDCWD, (uptr)oldpath, AT_FDCWD, (uptr)newpath); -#else +# else return internal_syscall(SYSCALL(rename), (uptr)oldpath, (uptr)newpath); -#endif +# endif } uptr internal_sched_yield() { @@ -489,17 +485,20 @@ bool FileExists(const char *filename) { if (ShouldMockFailureToOpen(filename)) return false; struct stat st; -#if SANITIZER_USES_CANONICAL_LINUX_SYSCALLS - if (internal_syscall(SYSCALL(newfstatat), AT_FDCWD, filename, &st, 0)) -#else if (internal_stat(filename, &st)) -#endif return false; // Sanity check: filename is a regular file. return S_ISREG(st.st_mode); } -#if !SANITIZER_NETBSD +bool DirExists(const char *path) { + struct stat st; + if (internal_stat(path, &st)) + return false; + return S_ISDIR(st.st_mode); +} + +# if !SANITIZER_NETBSD tid_t GetTid() { #if SANITIZER_FREEBSD long Tid; @@ -698,17 +697,17 @@ void FutexWake(atomic_uint32_t *p, u32 count) { // Not used #else struct linux_dirent { -#if SANITIZER_X32 || defined(__aarch64__) || SANITIZER_RISCV64 +# if SANITIZER_X32 || SANITIZER_LINUX u64 d_ino; u64 d_off; -#else +# else unsigned long d_ino; unsigned long d_off; -#endif +# endif unsigned short d_reclen; -#if defined(__aarch64__) || SANITIZER_RISCV64 +# if SANITIZER_LINUX unsigned char d_type; -#endif +# endif char d_name[256]; }; #endif @@ -744,11 +743,11 @@ int internal_dlinfo(void *handle, int request, void *p) { uptr internal_getdents(fd_t fd, struct linux_dirent *dirp, unsigned int count) { #if SANITIZER_FREEBSD return internal_syscall(SYSCALL(getdirentries), fd, (uptr)dirp, count, NULL); -#elif SANITIZER_USES_CANONICAL_LINUX_SYSCALLS +# elif SANITIZER_LINUX return internal_syscall(SYSCALL(getdents64), fd, (uptr)dirp, count); -#else +# else return internal_syscall(SYSCALL(getdents), fd, (uptr)dirp, count); -#endif +# endif } uptr internal_lseek(fd_t fd, OFF_T offset, int whence) { @@ -766,11 +765,15 @@ uptr internal_sigaltstack(const void *ss, void *oss) { } int internal_fork() { -#if SANITIZER_USES_CANONICAL_LINUX_SYSCALLS +# if SANITIZER_LINUX +# if SANITIZER_S390 + return internal_syscall(SYSCALL(clone), 0, SIGCHLD); +# else return internal_syscall(SYSCALL(clone), SIGCHLD, 0); -#else +# endif +# else return internal_syscall(SYSCALL(fork)); -#endif +# endif } #if SANITIZER_FREEBSD @@ -898,6 +901,10 @@ bool internal_sigismember(__sanitizer_sigset_t *set, int signum) { return k_set->sig[idx] & ((uptr)1 << bit); } #elif SANITIZER_FREEBSD +uptr internal_procctl(int type, int id, int cmd, void *data) { + return internal_syscall(SYSCALL(procctl), type, id, cmd, data); +} + void internal_sigdelset(__sanitizer_sigset_t *set, int signum) { sigset_t *rset = reinterpret_cast<sigset_t *>(set); sigdelset(rset, signum); @@ -1786,7 +1793,7 @@ void *internal_start_thread(void *(*func)(void *), void *arg) { return 0; } void internal_join_thread(void *th) {} #endif -#if defined(__aarch64__) +#if SANITIZER_LINUX && defined(__aarch64__) // Android headers in the older NDK releases miss this definition. struct __sanitizer_esr_context { struct _aarch64_ctx head; @@ -1807,6 +1814,11 @@ static bool Aarch64GetESR(ucontext_t *ucontext, u64 *esr) { } return false; } +#elif SANITIZER_FREEBSD && defined(__aarch64__) +// FreeBSD doesn't provide ESR in the ucontext. +static bool Aarch64GetESR(ucontext_t *ucontext, u64 *esr) { + return false; +} #endif using Context = ucontext_t; @@ -2032,10 +2044,17 @@ static void GetPcSpBp(void *context, uptr *pc, uptr *sp, uptr *bp) { *bp = ucontext->uc_mcontext.arm_fp; *sp = ucontext->uc_mcontext.arm_sp; #elif defined(__aarch64__) +# if SANITIZER_FREEBSD + ucontext_t *ucontext = (ucontext_t*)context; + *pc = ucontext->uc_mcontext.mc_gpregs.gp_elr; + *bp = ucontext->uc_mcontext.mc_gpregs.gp_x[29]; + *sp = ucontext->uc_mcontext.mc_gpregs.gp_sp; +# else ucontext_t *ucontext = (ucontext_t*)context; *pc = ucontext->uc_mcontext.pc; *bp = ucontext->uc_mcontext.regs[29]; *sp = ucontext->uc_mcontext.sp; +# endif #elif defined(__hppa__) ucontext_t *ucontext = (ucontext_t*)context; *pc = ucontext->uc_mcontext.sc_iaoq[0]; @@ -2183,7 +2202,8 @@ void CheckASLR() { } #elif SANITIZER_FREEBSD int aslr_status; - if (UNLIKELY(procctl(P_PID, 0, PROC_ASLR_STATUS, &aslr_status) == -1)) { + int r = internal_procctl(P_PID, 0, PROC_ASLR_STATUS, &aslr_status); + if (UNLIKELY(r == -1)) { // We're making things less 'dramatic' here since // the cmd is not necessarily guaranteed to be here // just yet regarding FreeBSD release @@ -2209,9 +2229,9 @@ void CheckASLR() { CHECK_NE(personality(old_personality | ADDR_NO_RANDOMIZE), -1); ReExec(); } -#else +# else // Do nothing -#endif +# endif } void CheckMPROTECT() { @@ -2233,9 +2253,9 @@ void CheckMPROTECT() { Printf("This sanitizer is not compatible with enabled MPROTECT\n"); Die(); } -# else +#else // Do nothing -# endif +#endif } void CheckNoDeepBind(const char *filename, int flag) { diff --git a/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_linux.h b/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_linux.h index ebd60e0b10f2..45d8c921da12 100644 --- a/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_linux.h +++ b/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_linux.h @@ -82,6 +82,7 @@ uptr internal_clone(int (*fn)(void *), void *child_stack, int flags, void *arg, #endif int internal_uname(struct utsname *buf); #elif SANITIZER_FREEBSD +uptr internal_procctl(int type, int id, int cmd, void *data); void internal_sigdelset(__sanitizer_sigset_t *set, int signum); #elif SANITIZER_NETBSD void internal_sigdelset(__sanitizer_sigset_t *set, int signum); diff --git a/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cpp b/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cpp index 15a6a4998bd0..f723a629a60b 100644 --- a/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cpp +++ b/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cpp @@ -218,7 +218,8 @@ void InitTlsSize() { } // On glibc x86_64, ThreadDescriptorSize() needs to be precise due to the usage // of g_tls_size. On other targets, ThreadDescriptorSize() is only used by lsan // to get the pointer to thread-specific data keys in the thread control block. -#if (SANITIZER_FREEBSD || SANITIZER_LINUX) && !SANITIZER_ANDROID && !SANITIZER_GO +#if (SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_SOLARIS) && \ + !SANITIZER_ANDROID && !SANITIZER_GO // sizeof(struct pthread) from glibc. static atomic_uintptr_t thread_descriptor_size; @@ -463,7 +464,11 @@ static void GetTls(uptr *addr, uptr *size) { #elif SANITIZER_GLIBC && defined(__x86_64__) // For aarch64 and x86-64, use an O(1) approach which requires relatively // precise ThreadDescriptorSize. g_tls_size was initialized in InitTlsSize. +# if SANITIZER_X32 + asm("mov %%fs:8,%0" : "=r"(*addr)); +# else asm("mov %%fs:16,%0" : "=r"(*addr)); +# endif *size = g_tls_size; *addr -= *size; *addr += ThreadDescriptorSize(); @@ -478,7 +483,7 @@ static void GetTls(uptr *addr, uptr *size) { const uptr pre_tcb_size = TlsPreTcbSize(); *addr = tp - pre_tcb_size; *size = g_tls_size + pre_tcb_size; -#elif SANITIZER_FREEBSD || SANITIZER_LINUX +#elif SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_SOLARIS uptr align; GetStaticTlsBoundary(addr, size, &align); #if defined(__x86_64__) || defined(__i386__) || defined(__s390__) || \ @@ -539,11 +544,6 @@ static void GetTls(uptr *addr, uptr *size) { *addr = (uptr)tcb->tcb_dtv[1]; } } -#elif SANITIZER_SOLARIS - // FIXME - *addr = 0; - *size = 0; -#else #error "Unknown OS" #endif } diff --git a/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_mac.cpp b/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_mac.cpp index 3b20e1c5e2af..327c7167dcf5 100644 --- a/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_mac.cpp +++ b/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_mac.cpp @@ -11,7 +11,7 @@ //===----------------------------------------------------------------------===// #include "sanitizer_platform.h" -#if SANITIZER_MAC +#if SANITIZER_APPLE #include "sanitizer_mac.h" #include "interception/interception.h" @@ -25,6 +25,7 @@ #include "sanitizer_common.h" #include "sanitizer_file.h" #include "sanitizer_flags.h" +#include "sanitizer_interface_internal.h" #include "sanitizer_internal_defs.h" #include "sanitizer_libc.h" #include "sanitizer_platform_limits_posix.h" @@ -392,6 +393,13 @@ bool FileExists(const char *filename) { return S_ISREG(st.st_mode); } +bool DirExists(const char *path) { + struct stat st; + if (stat(path, &st)) + return false; + return S_ISDIR(st.st_mode); +} + tid_t GetTid() { tid_t tid; pthread_threadid_np(nullptr, &tid); @@ -872,6 +880,9 @@ SignalContext::WriteFlag SignalContext::GetWriteFlag() const { #if defined(__x86_64__) || defined(__i386__) ucontext_t *ucontext = static_cast<ucontext_t*>(context); return ucontext->uc_mcontext->__es.__err & 2 /*T_PF_WRITE*/ ? Write : Read; +#elif defined(__arm64__) + ucontext_t *ucontext = static_cast<ucontext_t*>(context); + return ucontext->uc_mcontext->__es.__esr & 0x40 /*ISS_DA_WNR*/ ? Write : Read; #else return Unknown; #endif @@ -895,11 +906,7 @@ static void GetPcSpBp(void *context, uptr *pc, uptr *sp, uptr *bp) { ucontext_t *ucontext = (ucontext_t*)context; # if defined(__aarch64__) *pc = AARCH64_GET_REG(pc); -# if defined(__IPHONE_8_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_8_0 *bp = AARCH64_GET_REG(fp); -# else - *bp = AARCH64_GET_REG(lr); -# endif *sp = AARCH64_GET_REG(sp); # elif defined(__x86_64__) *pc = ucontext->uc_mcontext->__ss.__rip; @@ -1051,12 +1058,12 @@ void MaybeReexec() { } // Verify that interceptors really work. We'll use dlsym to locate - // "pthread_create", if interceptors are working, it should really point to - // "wrap_pthread_create" within our own dylib. - Dl_info info_pthread_create; - void *dlopen_addr = dlsym(RTLD_DEFAULT, "pthread_create"); - RAW_CHECK(dladdr(dlopen_addr, &info_pthread_create)); - if (internal_strcmp(info.dli_fname, info_pthread_create.dli_fname) != 0) { + // "puts", if interceptors are working, it should really point to + // "wrap_puts" within our own dylib. + Dl_info info_puts; + void *dlopen_addr = dlsym(RTLD_DEFAULT, "puts"); + RAW_CHECK(dladdr(dlopen_addr, &info_puts)); + if (internal_strcmp(info.dli_fname, info_puts.dli_fname) != 0) { Report( "ERROR: Interceptors are not working. This may be because %s is " "loaded too late (e.g. via dlopen). Please launch the executable " @@ -1396,7 +1403,7 @@ void DumpProcessMap() { char uuid_str[128]; FormatUUID(uuid_str, sizeof(uuid_str), modules[i].uuid()); Printf("0x%zx-0x%zx %s (%s) %s\n", modules[i].base_address(), - modules[i].max_executable_address(), modules[i].full_name(), + modules[i].max_address(), modules[i].full_name(), ModuleArchToString(modules[i].arch()), uuid_str); } Printf("End of module map.\n"); @@ -1422,4 +1429,4 @@ void InitializePlatformCommonFlags(CommonFlags *cf) {} } // namespace __sanitizer -#endif // SANITIZER_MAC +#endif // SANITIZER_APPLE diff --git a/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_mac.h b/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_mac.h index 0b6af5a3c0ed..a8b274e8c82c 100644 --- a/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_mac.h +++ b/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_mac.h @@ -9,12 +9,12 @@ // This file is shared between various sanitizers' runtime libraries and // provides definitions for OSX-specific functions. //===----------------------------------------------------------------------===// -#ifndef SANITIZER_MAC_H -#define SANITIZER_MAC_H +#ifndef SANITIZER_APPLE_H +#define SANITIZER_APPLE_H #include "sanitizer_common.h" #include "sanitizer_platform.h" -#if SANITIZER_MAC +#if SANITIZER_APPLE #include "sanitizer_posix.h" namespace __sanitizer { @@ -64,5 +64,5 @@ void RestrictMemoryToMaxAddress(uptr max_address); } // namespace __sanitizer -#endif // SANITIZER_MAC -#endif // SANITIZER_MAC_H +#endif // SANITIZER_APPLE +#endif // SANITIZER_APPLE_H diff --git a/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_mac_libcdep.cpp b/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_mac_libcdep.cpp index ac7e328946bf..b452dc4a49e2 100644 --- a/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_mac_libcdep.cpp +++ b/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_mac_libcdep.cpp @@ -11,7 +11,7 @@ //===----------------------------------------------------------------------===// #include "sanitizer_platform.h" -#if SANITIZER_MAC +#if SANITIZER_APPLE #include "sanitizer_mac.h" #include <sys/mman.h> @@ -26,4 +26,4 @@ void RestrictMemoryToMaxAddress(uptr max_address) { } // namespace __sanitizer -#endif // SANITIZER_MAC +#endif // SANITIZER_APPLE diff --git a/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_malloc_mac.inc b/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_malloc_mac.inc index 764e2cef5e74..fe76b3f8aa05 100644 --- a/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_malloc_mac.inc +++ b/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_malloc_mac.inc @@ -12,7 +12,7 @@ //===----------------------------------------------------------------------===// #include "sanitizer_common/sanitizer_platform.h" -#if !SANITIZER_MAC +#if !SANITIZER_APPLE #error "This file should only be compiled on Darwin." #endif diff --git a/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_mutex.h b/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_mutex.h index c16f5cdc1d71..b1a58e421d81 100644 --- a/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_mutex.h +++ b/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_mutex.h @@ -101,7 +101,7 @@ enum { // THREADLOCAL variables they are not usable early on during process init when // `__sanitizer::Mutex` is used. #define SANITIZER_CHECK_DEADLOCKS \ - (SANITIZER_DEBUG && !SANITIZER_GO && SANITIZER_SUPPORTS_THREADLOCAL && !SANITIZER_MAC) + (SANITIZER_DEBUG && !SANITIZER_GO && SANITIZER_SUPPORTS_THREADLOCAL && !SANITIZER_APPLE) #if SANITIZER_CHECK_DEADLOCKS struct MutexMeta { @@ -208,6 +208,20 @@ class SANITIZER_MUTEX Mutex : CheckedMutex { } } + bool TryLock() SANITIZER_TRY_ACQUIRE(true) { + u64 state = atomic_load_relaxed(&state_); + for (;;) { + if (UNLIKELY(state & (kWriterLock | kReaderLockMask))) + return false; + // The mutex is not read-/write-locked, try to lock. + if (LIKELY(atomic_compare_exchange_weak( + &state_, &state, state | kWriterLock, memory_order_acquire))) { + CheckedMutex::Lock(); + return true; + } + } + } + void Unlock() SANITIZER_RELEASE() { CheckedMutex::Unlock(); bool wake_writer; diff --git a/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_openbsd.cpp b/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_openbsd.cpp deleted file mode 100644 index e69de29bb2d1..000000000000 --- a/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_openbsd.cpp +++ /dev/null diff --git a/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_platform.h b/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_platform.h index 8de765cf6669..7676e1ca264d 100644 --- a/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_platform.h +++ b/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_platform.h @@ -55,8 +55,18 @@ # define SANITIZER_SOLARIS 0 #endif +// - SANITIZER_APPLE: all Apple code +// - TARGET_OS_OSX: macOS +// - SANITIZER_IOS: devices (iOS and iOS-like) +// - SANITIZER_WATCHOS +// - SANITIZER_TVOS +// - SANITIZER_IOSSIM: simulators (iOS and iOS-like) +// - SANITIZER_DRIVERKIT #if defined(__APPLE__) -# define SANITIZER_MAC 1 +# define SANITIZER_APPLE 1 +// SANITIZER_MAC will be deprecated/removed in the future +# define SANITIZER_MAC \ + error "SANITIZER_MAC will be removed, please use SANITIZER_APPLE" # include <TargetConditionals.h> # if TARGET_OS_OSX # define SANITIZER_OSX 1 @@ -68,28 +78,36 @@ # else # define SANITIZER_IOS 0 # endif +# if TARGET_OS_WATCH +# define SANITIZER_WATCHOS 1 +# else +# define SANITIZER_WATCHOS 0 +# endif +# if TARGET_OS_TV +# define SANITIZER_TVOS 1 +# else +# define SANITIZER_TVOS 0 +# endif # if TARGET_OS_SIMULATOR # define SANITIZER_IOSSIM 1 # else # define SANITIZER_IOSSIM 0 # endif +# if TARGET_OS_DRIVERKIT +# define SANITIZER_DRIVERKIT 1 +# else +# define SANITIZER_DRIVERKIT 0 +# endif #else -# define SANITIZER_MAC 0 -# define SANITIZER_IOS 0 -# define SANITIZER_IOSSIM 0 +# define SANITIZER_APPLE 0 +# define SANITIZER_MAC \ + error "SANITIZER_MAC will be removed, please use SANITIZER_APPLE" # define SANITIZER_OSX 0 -#endif - -#if defined(__APPLE__) && TARGET_OS_IPHONE && TARGET_OS_WATCH -# define SANITIZER_WATCHOS 1 -#else +# define SANITIZER_IOS 0 # define SANITIZER_WATCHOS 0 -#endif - -#if defined(__APPLE__) && TARGET_OS_IPHONE && TARGET_OS_TV -# define SANITIZER_TVOS 1 -#else # define SANITIZER_TVOS 0 +# define SANITIZER_IOSSIM 0 +# define SANITIZER_DRIVERKIT 0 #endif #if defined(_WIN32) @@ -116,8 +134,15 @@ # define SANITIZER_FUCHSIA 0 #endif +// Assume linux that is not glibc or android is musl libc. +#if SANITIZER_LINUX && !SANITIZER_GLIBC && !SANITIZER_ANDROID +# define SANITIZER_MUSL 1 +#else +# define SANITIZER_MUSL 0 +#endif + #define SANITIZER_POSIX \ - (SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_MAC || \ + (SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_APPLE || \ SANITIZER_NETBSD || SANITIZER_SOLARIS) #if __LP64__ || defined(_WIN64) @@ -180,6 +205,21 @@ # define SANITIZER_S390_64 0 #endif +#if defined(__sparc__) +# define SANITIZER_SPARC 1 +# if defined(__arch64__) +# define SANITIZER_SPARC32 0 +# define SANITIZER_SPARC64 1 +# else +# define SANITIZER_SPARC32 1 +# define SANITIZER_SPARC64 0 +# endif +#else +# define SANITIZER_SPARC 0 +# define SANITIZER_SPARC32 0 +# define SANITIZER_SPARC64 0 +#endif + #if defined(__powerpc__) # define SANITIZER_PPC 1 # if defined(__powerpc64__) @@ -245,7 +285,8 @@ #ifndef SANITIZER_CAN_USE_ALLOCATOR64 # if (SANITIZER_ANDROID && defined(__aarch64__)) || SANITIZER_FUCHSIA # define SANITIZER_CAN_USE_ALLOCATOR64 1 -# elif defined(__mips64) || defined(__aarch64__) +# elif defined(__mips64) || defined(__aarch64__) || defined(__i386__) || \ + defined(__arm__) || SANITIZER_RISCV64 || defined(__hexagon__) # define SANITIZER_CAN_USE_ALLOCATOR64 0 # else # define SANITIZER_CAN_USE_ALLOCATOR64 (SANITIZER_WORDSIZE == 64) @@ -264,7 +305,7 @@ #elif SANITIZER_RISCV64 # define SANITIZER_MMAP_RANGE_SIZE FIRST_32_SECOND_64(1ULL << 32, 1ULL << 38) #elif defined(__aarch64__) -# if SANITIZER_MAC +# if SANITIZER_APPLE # if SANITIZER_OSX || SANITIZER_IOSSIM # define SANITIZER_MMAP_RANGE_SIZE \ FIRST_32_SECOND_64(1ULL << 32, 1ULL << 47) @@ -291,18 +332,6 @@ # define SANITIZER_SIGN_EXTENDED_ADDRESSES 0 #endif -// The AArch64 and RISC-V linux ports use the canonical syscall set as -// mandated by the upstream linux community for all new ports. Other ports -// may still use legacy syscalls. -#ifndef SANITIZER_USES_CANONICAL_LINUX_SYSCALLS -# if (defined(__aarch64__) || defined(__riscv) || defined(__hexagon__)) && \ - SANITIZER_LINUX -# define SANITIZER_USES_CANONICAL_LINUX_SYSCALLS 1 -# else -# define SANITIZER_USES_CANONICAL_LINUX_SYSCALLS 0 -# endif -#endif - // udi16 syscalls can only be used when the following conditions are // met: // * target is one of arm32, x86-32, sparc32, sh or m68k @@ -333,7 +362,7 @@ # define MSC_PREREQ(version) 0 #endif -#if SANITIZER_MAC && !(defined(__arm64__) && SANITIZER_IOS) +#if SANITIZER_APPLE && defined(__x86_64__) # define SANITIZER_NON_UNIQUE_TYPEINFO 0 #else # define SANITIZER_NON_UNIQUE_TYPEINFO 1 @@ -361,7 +390,7 @@ # define SANITIZER_SUPPRESS_LEAK_ON_PTHREAD_EXIT 0 #endif -#if SANITIZER_FREEBSD || SANITIZER_MAC || SANITIZER_NETBSD || SANITIZER_SOLARIS +#if SANITIZER_FREEBSD || SANITIZER_APPLE || SANITIZER_NETBSD || SANITIZER_SOLARIS # define SANITIZER_MADVISE_DONTNEED MADV_FREE #else # define SANITIZER_MADVISE_DONTNEED MADV_DONTNEED @@ -385,7 +414,7 @@ // Enable ability to support sanitizer initialization that is // compatible with the sanitizer library being loaded via // `dlopen()`. -#if SANITIZER_MAC +#if SANITIZER_APPLE # define SANITIZER_SUPPORTS_INIT_FOR_DLOPEN 1 #else # define SANITIZER_SUPPORTS_INIT_FOR_DLOPEN 0 diff --git a/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h b/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h index 14610f2df78d..ffa7e272b7e0 100644 --- a/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h +++ b/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h @@ -76,7 +76,7 @@ #define SI_LINUX 0 #endif -#if SANITIZER_MAC +#if SANITIZER_APPLE #define SI_MAC 1 #define SI_NOT_MAC 0 #else @@ -126,7 +126,7 @@ #define SI_SOLARIS32 0 #endif -#if SANITIZER_POSIX && !SANITIZER_MAC +#if SANITIZER_POSIX && !SANITIZER_APPLE #define SI_POSIX_NOT_MAC 1 #else #define SI_POSIX_NOT_MAC 0 @@ -235,6 +235,8 @@ #define SANITIZER_INTERCEPT_TIME SI_POSIX #define SANITIZER_INTERCEPT_GLOB (SI_GLIBC || SI_SOLARIS) #define SANITIZER_INTERCEPT_GLOB64 SI_GLIBC +#define SANITIZER_INTERCEPT___B64_TO SI_LINUX_NOT_ANDROID +#define SANITIZER_INTERCEPT___DN_EXPAND SI_LINUX_NOT_ANDROID #define SANITIZER_INTERCEPT_POSIX_SPAWN SI_POSIX #define SANITIZER_INTERCEPT_WAIT SI_POSIX #define SANITIZER_INTERCEPT_INET SI_POSIX @@ -328,8 +330,7 @@ #define SANITIZER_INTERCEPT_GETMNTENT_R SI_LINUX_NOT_ANDROID #define SANITIZER_INTERCEPT_STATFS \ (SI_FREEBSD || SI_MAC || SI_LINUX_NOT_ANDROID || SI_SOLARIS) -#define SANITIZER_INTERCEPT_STATFS64 \ - (((SI_MAC && !TARGET_CPU_ARM64) && !SI_IOS) || SI_LINUX_NOT_ANDROID) +#define SANITIZER_INTERCEPT_STATFS64 SI_LINUX_NOT_ANDROID && SANITIZER_HAS_STATFS64 #define SANITIZER_INTERCEPT_STATVFS \ (SI_FREEBSD || SI_NETBSD || SI_LINUX_NOT_ANDROID) #define SANITIZER_INTERCEPT_STATVFS64 SI_LINUX_NOT_ANDROID @@ -346,6 +347,7 @@ #define SANITIZER_INTERCEPT_PTHREAD_ATTR_GETINHERITSCHED \ (SI_FREEBSD || SI_NETBSD || SI_MAC || SI_LINUX_NOT_ANDROID || SI_SOLARIS) #define SANITIZER_INTERCEPT_PTHREAD_ATTR_GETAFFINITY_NP SI_GLIBC +#define SANITIZER_INTERCEPT_PTHREAD_GETAFFINITY_NP SI_LINUX_NOT_ANDROID #define SANITIZER_INTERCEPT_PTHREAD_ATTR_GET_SCHED SI_POSIX #define SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETPSHARED \ (SI_POSIX && !SI_NETBSD) @@ -465,6 +467,7 @@ #define SANITIZER_INTERCEPT_STAT \ (SI_FREEBSD || SI_MAC || SI_ANDROID || SI_NETBSD || SI_SOLARIS || \ SI_STAT_LINUX) +#define SANITIZER_INTERCEPT_STAT64 SI_STAT_LINUX && SANITIZER_HAS_STAT64 #define SANITIZER_INTERCEPT_LSTAT (SI_NETBSD || SI_FREEBSD || SI_STAT_LINUX) #define SANITIZER_INTERCEPT___XSTAT \ ((!SANITIZER_INTERCEPT_STAT && SI_POSIX) || SI_STAT_LINUX) @@ -585,10 +588,11 @@ // sigaltstack on i386 macOS cannot be intercepted due to setjmp() // calling it and assuming that it does not clobber registers. #define SANITIZER_INTERCEPT_SIGALTSTACK \ - (SI_POSIX && !(SANITIZER_MAC && SANITIZER_I386)) + (SI_POSIX && !(SANITIZER_APPLE && SANITIZER_I386)) #define SANITIZER_INTERCEPT_UNAME (SI_POSIX && !SI_FREEBSD) #define SANITIZER_INTERCEPT___XUNAME SI_FREEBSD #define SANITIZER_INTERCEPT_FLOPEN SI_FREEBSD +#define SANITIZER_INTERCEPT_PROCCTL SI_FREEBSD // This macro gives a way for downstream users to override the above // interceptor macros irrespective of the platform they are on. They have diff --git a/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_freebsd.cpp b/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_freebsd.cpp index 0d25fa80e2ed..37e72cd5d45e 100644 --- a/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_freebsd.cpp +++ b/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_freebsd.cpp @@ -205,6 +205,10 @@ unsigned struct_audio_buf_info_sz = sizeof(struct audio_buf_info); unsigned struct_ppp_stats_sz = sizeof(struct ppp_stats); unsigned struct_sioc_sg_req_sz = sizeof(struct sioc_sg_req); unsigned struct_sioc_vif_req_sz = sizeof(struct sioc_vif_req); +unsigned struct_procctl_reaper_status_sz = sizeof(struct __sanitizer_procctl_reaper_status); +unsigned struct_procctl_reaper_pidinfo_sz = sizeof(struct __sanitizer_procctl_reaper_pidinfo); +unsigned struct_procctl_reaper_pids_sz = sizeof(struct __sanitizer_procctl_reaper_pids); +unsigned struct_procctl_reaper_kill_sz = sizeof(struct __sanitizer_procctl_reaper_kill); const unsigned long __sanitizer_bufsiz = BUFSIZ; const unsigned IOCTL_NOT_PRESENT = 0; diff --git a/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_freebsd.h b/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_freebsd.h index 9859c52ec69f..daef1177a2db 100644 --- a/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_freebsd.h +++ b/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_freebsd.h @@ -424,6 +424,38 @@ struct __sanitizer__ttyent { char *ty_group; }; +// procctl reaper data for PROCCTL_REAPER flags +struct __sanitizer_procctl_reaper_status { + unsigned int rs_flags; + unsigned int rs_children; + unsigned int rs_descendants; + pid_t rs_reaper; + pid_t rs_pid; + unsigned int rs_pad0[15]; +}; + +struct __sanitizer_procctl_reaper_pidinfo { + pid_t pi_pid; + pid_t pi_subtree; + unsigned int pi_flags; + unsigned int pi_pad0[15]; +}; + +struct __sanitizer_procctl_reaper_pids { + unsigned int rp_count; + unsigned int rp_pad0[15]; + struct __sanitize_procctl_reapper_pidinfo *rp_pids; +}; + +struct __sanitizer_procctl_reaper_kill { + int rk_sig; + unsigned int rk_flags; + pid_t rk_subtree; + unsigned int rk_killed; + pid_t rk_fpid; + unsigned int rk_pad[15]; +}; + # define IOC_NRBITS 8 # define IOC_TYPEBITS 8 # if defined(__powerpc__) || defined(__powerpc64__) || defined(__mips__) @@ -480,6 +512,11 @@ extern unsigned struct_ppp_stats_sz; extern unsigned struct_sioc_sg_req_sz; extern unsigned struct_sioc_vif_req_sz; +extern unsigned struct_procctl_reaper_status_sz; +extern unsigned struct_procctl_reaper_pidinfo_sz; +extern unsigned struct_procctl_reaper_pids_sz; +extern unsigned struct_procctl_reaper_kill_sz; + // ioctl request identifiers // A special value to mark ioctls that are not present on the target platform, diff --git a/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_linux.cpp b/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_linux.cpp index 9d577570ea1e..06bafd68dc74 100644 --- a/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_linux.cpp +++ b/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_linux.cpp @@ -57,12 +57,6 @@ using namespace __sanitizer; -namespace __sanitizer { -#if !SANITIZER_ANDROID - unsigned struct_statfs64_sz = sizeof(struct statfs64); -#endif -} // namespace __sanitizer - # if !defined(__powerpc64__) && !defined(__x86_64__) && \ !defined(__aarch64__) && !defined(__mips__) && !defined(__s390__) && \ !defined(__sparc__) && !defined(__riscv) && !defined(__hexagon__) diff --git a/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.cpp b/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.cpp index 32b8f47ed633..4bd425435d56 100644 --- a/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.cpp +++ b/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.cpp @@ -23,7 +23,7 @@ // Must go after undef _FILE_OFFSET_BITS. #include "sanitizer_platform.h" -#if SANITIZER_LINUX || SANITIZER_MAC +#if SANITIZER_LINUX || SANITIZER_APPLE // Must go after undef _FILE_OFFSET_BITS. #include "sanitizer_glibc_version.h" @@ -51,7 +51,7 @@ #include <time.h> #include <wchar.h> #include <regex.h> -#if !SANITIZER_MAC +#if !SANITIZER_APPLE #include <utmp.h> #endif @@ -152,7 +152,6 @@ typedef struct user_fpregs elf_fpregset_t; #include <linux/serial.h> #include <sys/msg.h> #include <sys/ipc.h> -#include <crypt.h> #endif // SANITIZER_ANDROID #include <link.h> @@ -163,7 +162,7 @@ typedef struct user_fpregs elf_fpregset_t; #include <fstab.h> #endif // SANITIZER_LINUX -#if SANITIZER_MAC +#if SANITIZER_APPLE #include <net/ethernet.h> #include <sys/filio.h> #include <sys/sockio.h> @@ -172,14 +171,19 @@ typedef struct user_fpregs elf_fpregset_t; // Include these after system headers to avoid name clashes and ambiguities. # include "sanitizer_common.h" # include "sanitizer_internal_defs.h" +# include "sanitizer_platform_interceptors.h" # include "sanitizer_platform_limits_posix.h" +#if SANITIZER_INTERCEPT_CRYPT_R +#include <crypt.h> +#endif + namespace __sanitizer { unsigned struct_utsname_sz = sizeof(struct utsname); unsigned struct_stat_sz = sizeof(struct stat); -#if !SANITIZER_IOS && !(SANITIZER_MAC && TARGET_CPU_ARM64) +#if SANITIZER_HAS_STAT64 unsigned struct_stat64_sz = sizeof(struct stat64); -#endif // !SANITIZER_IOS && !(SANITIZER_MAC && TARGET_CPU_ARM64) +#endif // SANITIZER_HAS_STAT64 unsigned struct_rusage_sz = sizeof(struct rusage); unsigned struct_tm_sz = sizeof(struct tm); unsigned struct_passwd_sz = sizeof(struct passwd); @@ -204,20 +208,24 @@ namespace __sanitizer { unsigned struct_regex_sz = sizeof(regex_t); unsigned struct_regmatch_sz = sizeof(regmatch_t); -#if (SANITIZER_MAC && !TARGET_CPU_ARM64) && !SANITIZER_IOS +#if SANITIZER_HAS_STATFS64 unsigned struct_statfs64_sz = sizeof(struct statfs64); -#endif // (SANITIZER_MAC && !TARGET_CPU_ARM64) && !SANITIZER_IOS +#endif // SANITIZER_HAS_STATFS64 -#if SANITIZER_GLIBC || SANITIZER_FREEBSD || SANITIZER_NETBSD || SANITIZER_MAC +#if SANITIZER_GLIBC || SANITIZER_FREEBSD || SANITIZER_NETBSD || SANITIZER_APPLE unsigned struct_fstab_sz = sizeof(struct fstab); #endif // SANITIZER_GLIBC || SANITIZER_FREEBSD || SANITIZER_NETBSD || - // SANITIZER_MAC + // SANITIZER_APPLE #if !SANITIZER_ANDROID unsigned struct_statfs_sz = sizeof(struct statfs); unsigned struct_sockaddr_sz = sizeof(struct sockaddr); unsigned ucontext_t_sz(void *ctx) { # if SANITIZER_GLIBC && SANITIZER_X64 + // Added in Linux kernel 3.4.0, merged to glibc in 2.16 +# ifndef FP_XSTATE_MAGIC1 +# define FP_XSTATE_MAGIC1 0x46505853U +# endif // See kernel arch/x86/kernel/fpu/signal.c for details. const auto *fpregs = static_cast<ucontext_t *>(ctx)->uc_mcontext.fpregs; // The member names differ across header versions, but the actual layout @@ -267,9 +275,12 @@ namespace __sanitizer { unsigned struct_ustat_sz = SIZEOF_STRUCT_USTAT; unsigned struct_rlimit64_sz = sizeof(struct rlimit64); unsigned struct_statvfs64_sz = sizeof(struct statvfs64); - unsigned struct_crypt_data_sz = sizeof(struct crypt_data); #endif // SANITIZER_LINUX && !SANITIZER_ANDROID +#if SANITIZER_INTERCEPT_CRYPT_R + unsigned struct_crypt_data_sz = sizeof(struct crypt_data); +#endif + #if SANITIZER_LINUX && !SANITIZER_ANDROID unsigned struct_timex_sz = sizeof(struct timex); unsigned struct_msqid_ds_sz = sizeof(struct msqid_ds); @@ -296,7 +307,7 @@ namespace __sanitizer { int shmctl_shm_stat = (int)SHM_STAT; #endif -#if !SANITIZER_MAC && !SANITIZER_FREEBSD +#if !SANITIZER_APPLE && !SANITIZER_FREEBSD unsigned struct_utmp_sz = sizeof(struct utmp); #endif #if !SANITIZER_ANDROID @@ -504,7 +515,7 @@ unsigned struct_ElfW_Phdr_sz = sizeof(Elf_Phdr); unsigned struct_ppp_stats_sz = sizeof(struct ppp_stats); #endif // SANITIZER_GLIBC -#if !SANITIZER_ANDROID && !SANITIZER_MAC +#if !SANITIZER_ANDROID && !SANITIZER_APPLE unsigned struct_sioc_sg_req_sz = sizeof(struct sioc_sg_req); unsigned struct_sioc_vif_req_sz = sizeof(struct sioc_vif_req); #endif @@ -590,6 +601,14 @@ unsigned struct_ElfW_Phdr_sz = sizeof(Elf_Phdr); unsigned IOCTL_BLKROGET = BLKROGET; unsigned IOCTL_BLKROSET = BLKROSET; unsigned IOCTL_BLKRRPART = BLKRRPART; + unsigned IOCTL_BLKFRASET = BLKFRASET; + unsigned IOCTL_BLKFRAGET = BLKFRAGET; + unsigned IOCTL_BLKSECTSET = BLKSECTSET; + unsigned IOCTL_BLKSECTGET = BLKSECTGET; + unsigned IOCTL_BLKSSZGET = BLKSSZGET; + unsigned IOCTL_BLKBSZGET = BLKBSZGET; + unsigned IOCTL_BLKBSZSET = BLKBSZSET; + unsigned IOCTL_BLKGETSIZE64 = BLKGETSIZE64; unsigned IOCTL_CDROMAUDIOBUFSIZ = CDROMAUDIOBUFSIZ; unsigned IOCTL_CDROMEJECT = CDROMEJECT; unsigned IOCTL_CDROMEJECT_SW = CDROMEJECT_SW; @@ -1055,7 +1074,7 @@ CHECK_SIZE_AND_OFFSET(mmsghdr, msg_len); COMPILER_CHECK(sizeof(__sanitizer_dirent) <= sizeof(dirent)); CHECK_SIZE_AND_OFFSET(dirent, d_ino); -#if SANITIZER_MAC +#if SANITIZER_APPLE CHECK_SIZE_AND_OFFSET(dirent, d_seekoff); #elif SANITIZER_FREEBSD // There is no 'd_off' field on FreeBSD. @@ -1237,7 +1256,7 @@ CHECK_SIZE_AND_OFFSET(passwd, pw_shell); CHECK_SIZE_AND_OFFSET(passwd, pw_gecos); #endif -#if SANITIZER_MAC +#if SANITIZER_APPLE CHECK_SIZE_AND_OFFSET(passwd, pw_change); CHECK_SIZE_AND_OFFSET(passwd, pw_expire); CHECK_SIZE_AND_OFFSET(passwd, pw_class); @@ -1305,4 +1324,4 @@ CHECK_TYPE_SIZE(sem_t); COMPILER_CHECK(ARM_VFPREGS_SIZE == ARM_VFPREGS_SIZE_ASAN); #endif -#endif // SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_MAC +#endif // SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_APPLE diff --git a/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h b/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h index 89f323dd2c72..8899749624d4 100644 --- a/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h +++ b/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h @@ -14,11 +14,26 @@ #ifndef SANITIZER_PLATFORM_LIMITS_POSIX_H #define SANITIZER_PLATFORM_LIMITS_POSIX_H -#if SANITIZER_LINUX || SANITIZER_MAC +#if SANITIZER_LINUX || SANITIZER_APPLE #include "sanitizer_internal_defs.h" #include "sanitizer_platform.h" +#if SANITIZER_APPLE +#include <sys/cdefs.h> +#if !__DARWIN_ONLY_64_BIT_INO_T +#define SANITIZER_HAS_STAT64 1 +#define SANITIZER_HAS_STATFS64 1 +#else +#define SANITIZER_HAS_STAT64 0 +#define SANITIZER_HAS_STATFS64 0 +#endif +#else +// Must be SANITIZER_LINUX then +#define SANITIZER_HAS_STAT64 1 +#define SANITIZER_HAS_STATFS64 1 +#endif + #if defined(__sparc__) // FIXME: This can't be included from tsan which does not support sparc yet. #include "sanitizer_glibc_version.h" @@ -29,7 +44,7 @@ namespace __sanitizer { extern unsigned struct_utsname_sz; extern unsigned struct_stat_sz; -#if !SANITIZER_IOS +#if SANITIZER_HAS_STAT64 extern unsigned struct_stat64_sz; #endif extern unsigned struct_rusage_sz; @@ -49,7 +64,9 @@ extern unsigned struct_itimerspec_sz; extern unsigned struct_sigevent_sz; extern unsigned struct_stack_t_sz; extern unsigned struct_sched_param_sz; +#if SANITIZER_HAS_STATFS64 extern unsigned struct_statfs64_sz; +#endif extern unsigned struct_regex_sz; extern unsigned struct_regmatch_sz; @@ -322,7 +339,7 @@ struct __sanitizer_ifaddrs { }; #endif // !SANITIZER_ANDROID -#if SANITIZER_MAC +#if SANITIZER_APPLE typedef unsigned long __sanitizer_pthread_key_t; #else typedef unsigned __sanitizer_pthread_key_t; @@ -349,7 +366,7 @@ struct __sanitizer_passwd { char *pw_passwd; int pw_uid; int pw_gid; -#if SANITIZER_MAC +#if SANITIZER_APPLE long pw_change; char *pw_class; #endif @@ -358,7 +375,7 @@ struct __sanitizer_passwd { #endif char *pw_dir; char *pw_shell; -#if SANITIZER_MAC +#if SANITIZER_APPLE long pw_expire; #endif }; @@ -370,7 +387,8 @@ struct __sanitizer_group { char **gr_mem; }; -# if (defined(__x86_64__) && !defined(_LP64)) || defined(__hexagon__) +# if (SANITIZER_LINUX && !SANITIZER_GLIBC && !SANITIZER_ANDROID) || \ + (defined(__x86_64__) && !defined(_LP64)) || defined(__hexagon__) typedef long long __sanitizer_time_t; #else typedef long __sanitizer_time_t; @@ -430,7 +448,7 @@ struct __sanitizer_file_handle { }; #endif -#if SANITIZER_MAC +#if SANITIZER_APPLE struct __sanitizer_msghdr { void *msg_name; unsigned msg_namelen; @@ -471,14 +489,15 @@ struct __sanitizer_mmsghdr { }; #endif -#if SANITIZER_MAC +#if SANITIZER_APPLE struct __sanitizer_dirent { unsigned long long d_ino; unsigned long long d_seekoff; unsigned short d_reclen; // more fields that we don't care about }; -# elif SANITIZER_ANDROID || defined(__x86_64__) || defined(__hexagon__) +# elif (SANITIZER_LINUX && !SANITIZER_GLIBC) || defined(__x86_64__) || \ + defined(__hexagon__) struct __sanitizer_dirent { unsigned long long d_ino; unsigned long long d_off; @@ -555,7 +574,7 @@ typedef unsigned long __sanitizer_sigset_t[16 / sizeof(unsigned long)]; # else typedef unsigned long __sanitizer_sigset_t; # endif -#elif SANITIZER_MAC +#elif SANITIZER_APPLE typedef unsigned __sanitizer_sigset_t; #elif SANITIZER_LINUX struct __sanitizer_sigset_t { @@ -727,7 +746,7 @@ struct __sanitizer_addrinfo { int ai_family; int ai_socktype; int ai_protocol; -#if SANITIZER_ANDROID || SANITIZER_MAC +#if SANITIZER_ANDROID || SANITIZER_APPLE unsigned ai_addrlen; char *ai_canonname; void *ai_addr; @@ -753,7 +772,7 @@ struct __sanitizer_pollfd { short revents; }; -#if SANITIZER_ANDROID || SANITIZER_MAC +#if SANITIZER_ANDROID || SANITIZER_APPLE typedef unsigned __sanitizer_nfds_t; #else typedef unsigned long __sanitizer_nfds_t; @@ -853,7 +872,7 @@ extern int shmctl_shm_info; extern int shmctl_shm_stat; #endif -#if !SANITIZER_MAC && !SANITIZER_FREEBSD +#if !SANITIZER_APPLE && !SANITIZER_FREEBSD extern unsigned struct_utmp_sz; #endif #if !SANITIZER_ANDROID @@ -868,7 +887,7 @@ struct __sanitizer_ifconf { union { void *ifcu_req; } ifc_ifcu; -#if SANITIZER_MAC +#if SANITIZER_APPLE } __attribute__((packed)); #else }; @@ -1021,7 +1040,7 @@ extern unsigned struct_audio_buf_info_sz; extern unsigned struct_ppp_stats_sz; #endif // (SANITIZER_LINUX || SANITIZER_FREEBSD) && !SANITIZER_ANDROID -#if !SANITIZER_ANDROID && !SANITIZER_MAC +#if !SANITIZER_ANDROID && !SANITIZER_APPLE extern unsigned struct_sioc_sg_req_sz; extern unsigned struct_sioc_vif_req_sz; #endif @@ -1108,6 +1127,14 @@ extern unsigned IOCTL_BLKRASET; extern unsigned IOCTL_BLKROGET; extern unsigned IOCTL_BLKROSET; extern unsigned IOCTL_BLKRRPART; +extern unsigned IOCTL_BLKFRASET; +extern unsigned IOCTL_BLKFRAGET; +extern unsigned IOCTL_BLKSECTSET; +extern unsigned IOCTL_BLKSECTGET; +extern unsigned IOCTL_BLKSSZGET; +extern unsigned IOCTL_BLKBSZGET; +extern unsigned IOCTL_BLKBSZSET; +extern unsigned IOCTL_BLKGETSIZE64; extern unsigned IOCTL_CDROMAUDIOBUFSIZ; extern unsigned IOCTL_CDROMEJECT; extern unsigned IOCTL_CDROMEJECT_SW; @@ -1454,6 +1481,6 @@ extern const int si_SEGV_ACCERR; #define SIGACTION_SYMNAME sigaction -#endif // SANITIZER_LINUX || SANITIZER_MAC +#endif // SANITIZER_LINUX || SANITIZER_APPLE #endif diff --git a/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_posix.cpp b/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_posix.cpp index f8457a6aac41..b0e32b50c076 100644 --- a/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_posix.cpp +++ b/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_posix.cpp @@ -41,6 +41,8 @@ uptr GetMmapGranularity() { return GetPageSize(); } +bool ErrorIsOOM(error_t err) { return err == ENOMEM; } + void *MmapOrDie(uptr size, const char *mem_type, bool raw_report) { size = RoundUpTo(size, GetPageSizeCached()); uptr res = MmapNamed(nullptr, size, PROT_READ | PROT_WRITE, @@ -95,6 +97,7 @@ void *MmapAlignedOrDieOnFatalError(uptr size, uptr alignment, UnmapOrDie((void*)map_res, res - map_res); } uptr end = res + size; + end = RoundUpTo(end, GetPageSizeCached()); if (end != map_end) UnmapOrDie((void*)end, map_end - end); return (void*)res; @@ -146,7 +149,7 @@ bool MprotectReadOnly(uptr addr, uptr size) { return 0 == internal_mprotect((void *)addr, size, PROT_READ); } -#if !SANITIZER_MAC +#if !SANITIZER_APPLE void MprotectMallocZones(void *addr, int prot) {} #endif @@ -239,7 +242,7 @@ bool MemoryRangeIsAvailable(uptr range_start, uptr range_end) { return true; } -#if !SANITIZER_MAC +#if !SANITIZER_APPLE void DumpProcessMap() { MemoryMappingLayout proc_maps(/*cache_enabled*/true); const sptr kBufSize = 4095; diff --git a/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_posix_libcdep.cpp b/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_posix_libcdep.cpp index eed02ce4f6aa..46e41c669738 100644 --- a/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_posix_libcdep.cpp +++ b/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_posix_libcdep.cpp @@ -290,7 +290,7 @@ bool IsAccessibleMemoryRange(uptr beg, uptr size) { return result; } -void PlatformPrepareForSandboxing(__sanitizer_sandbox_arguments *args) { +void PlatformPrepareForSandboxing(void *args) { // Some kinds of sandboxes may forbid filesystem access, so we won't be able // to read the file mappings from /proc/self/maps. Luckily, neither the // process will be able to load additional libraries, so it's fine to use the @@ -384,7 +384,7 @@ real_pthread_attr_getstack(void *attr, void **addr, size_t *size); } // extern "C" int my_pthread_attr_getstack(void *attr, void **addr, uptr *size) { -#if !SANITIZER_GO && !SANITIZER_MAC +#if !SANITIZER_GO && !SANITIZER_APPLE if (&real_pthread_attr_getstack) return real_pthread_attr_getstack((pthread_attr_t *)attr, addr, (size_t *)size); diff --git a/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_procmaps.h b/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_procmaps.h index 055af366ef06..19bad158387c 100644 --- a/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_procmaps.h +++ b/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_procmaps.h @@ -16,7 +16,7 @@ #include "sanitizer_platform.h" #if SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_NETBSD || \ - SANITIZER_MAC || SANITIZER_SOLARIS || \ + SANITIZER_APPLE || SANITIZER_SOLARIS || \ SANITIZER_FUCHSIA #include "sanitizer_common.h" diff --git a/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_procmaps_mac.cpp b/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_procmaps_mac.cpp index 62b2e5e03216..66f4935bb62d 100644 --- a/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_procmaps_mac.cpp +++ b/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_procmaps_mac.cpp @@ -10,7 +10,7 @@ //===----------------------------------------------------------------------===// #include "sanitizer_platform.h" -#if SANITIZER_MAC +#if SANITIZER_APPLE #include "sanitizer_common.h" #include "sanitizer_placement_new.h" #include "sanitizer_procmaps.h" @@ -136,13 +136,19 @@ void MemoryMappingLayout::LoadFromCache() { // No-op on Mac for now. } +static bool IsDyldHdr(const mach_header *hdr) { + return (hdr->magic == MH_MAGIC || hdr->magic == MH_MAGIC_64) && + hdr->filetype == MH_DYLINKER; +} + // _dyld_get_image_header() and related APIs don't report dyld itself. // We work around this by manually recursing through the memory map // until we hit a Mach header matching dyld instead. These recurse // calls are expensive, but the first memory map generation occurs // early in the process, when dyld is one of the only images loaded, -// so it will be hit after only a few iterations. -static mach_header *get_dyld_image_header() { +// so it will be hit after only a few iterations. These assumptions don't hold +// on macOS 13+ anymore (dyld itself has moved into the shared cache). +static mach_header *GetDyldImageHeaderViaVMRegion() { vm_address_t address = 0; while (true) { @@ -157,8 +163,7 @@ static mach_header *get_dyld_image_header() { if (size >= sizeof(mach_header) && info.protection & kProtectionRead) { mach_header *hdr = (mach_header *)address; - if ((hdr->magic == MH_MAGIC || hdr->magic == MH_MAGIC_64) && - hdr->filetype == MH_DYLINKER) { + if (IsDyldHdr(hdr)) { return hdr; } } @@ -166,8 +171,69 @@ static mach_header *get_dyld_image_header() { } } +extern "C" { +struct dyld_shared_cache_dylib_text_info { + uint64_t version; // current version 2 + // following fields all exist in version 1 + uint64_t loadAddressUnslid; + uint64_t textSegmentSize; + uuid_t dylibUuid; + const char *path; // pointer invalid at end of iterations + // following fields all exist in version 2 + uint64_t textSegmentOffset; // offset from start of cache +}; +typedef struct dyld_shared_cache_dylib_text_info + dyld_shared_cache_dylib_text_info; + +extern bool _dyld_get_shared_cache_uuid(uuid_t uuid); +extern const void *_dyld_get_shared_cache_range(size_t *length); +extern int dyld_shared_cache_iterate_text( + const uuid_t cacheUuid, + void (^callback)(const dyld_shared_cache_dylib_text_info *info)); +} // extern "C" + +static mach_header *GetDyldImageHeaderViaSharedCache() { + uuid_t uuid; + bool hasCache = _dyld_get_shared_cache_uuid(uuid); + if (!hasCache) + return nullptr; + + size_t cacheLength; + __block uptr cacheStart = (uptr)_dyld_get_shared_cache_range(&cacheLength); + CHECK(cacheStart && cacheLength); + + __block mach_header *dyldHdr = nullptr; + int res = dyld_shared_cache_iterate_text( + uuid, ^(const dyld_shared_cache_dylib_text_info *info) { + CHECK_GE(info->version, 2); + mach_header *hdr = + (mach_header *)(cacheStart + info->textSegmentOffset); + if (IsDyldHdr(hdr)) + dyldHdr = hdr; + }); + CHECK_EQ(res, 0); + + return dyldHdr; +} + const mach_header *get_dyld_hdr() { - if (!dyld_hdr) dyld_hdr = get_dyld_image_header(); + if (!dyld_hdr) { + // On macOS 13+, dyld itself has moved into the shared cache. Looking it up + // via vm_region_recurse_64() causes spins/hangs/crashes. + if (GetMacosAlignedVersion() >= MacosVersion(13, 0)) { + dyld_hdr = GetDyldImageHeaderViaSharedCache(); + if (!dyld_hdr) { + Printf( + "Failed to lookup the dyld image header in the shared cache on " + "macOS 13+ (or no shared cache in use). Falling back to lookup via" + "vm_region_recurse_64().\n"); + dyld_hdr = GetDyldImageHeaderViaVMRegion(); + } + } else { + dyld_hdr = GetDyldImageHeaderViaVMRegion(); + } + CHECK(dyld_hdr); + } return dyld_hdr; } @@ -376,4 +442,4 @@ void MemoryMappingLayout::DumpListOfModules( } // namespace __sanitizer -#endif // SANITIZER_MAC +#endif // SANITIZER_APPLE diff --git a/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_ring_buffer.h b/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_ring_buffer.h index 2a46e933b75d..f22e40cac284 100644 --- a/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_ring_buffer.h +++ b/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_ring_buffer.h @@ -86,10 +86,13 @@ class CompactRingBuffer { // Lower bytes store the address of the next buffer element. static constexpr int kPageSizeBits = 12; static constexpr int kSizeShift = 56; + static constexpr int kSizeBits = 64 - kSizeShift; static constexpr uptr kNextMask = (1ULL << kSizeShift) - 1; uptr GetStorageSize() const { return (long_ >> kSizeShift) << kPageSizeBits; } + static uptr SignExtend(uptr x) { return ((sptr)x) << kSizeBits >> kSizeBits; } + void Init(void *storage, uptr size) { CHECK_EQ(sizeof(CompactRingBuffer<T>), sizeof(void *)); CHECK(IsPowerOfTwo(size)); @@ -97,12 +100,14 @@ class CompactRingBuffer { CHECK_LE(size, 128 << kPageSizeBits); CHECK_EQ(size % 4096, 0); CHECK_EQ(size % sizeof(T), 0); - CHECK_EQ((uptr)storage % (size * 2), 0); - long_ = (uptr)storage | ((size >> kPageSizeBits) << kSizeShift); + uptr st = (uptr)storage; + CHECK_EQ(st % (size * 2), 0); + CHECK_EQ(st, SignExtend(st & kNextMask)); + long_ = (st & kNextMask) | ((size >> kPageSizeBits) << kSizeShift); } void SetNext(const T *next) { - long_ = (long_ & ~kNextMask) | (uptr)next; + long_ = (long_ & ~kNextMask) | ((uptr)next & kNextMask); } public: @@ -119,7 +124,7 @@ class CompactRingBuffer { SetNext((const T *)storage + Idx); } - T *Next() const { return (T *)(long_ & kNextMask); } + T *Next() const { return (T *)(SignExtend(long_ & kNextMask)); } void *StartOfStorage() const { return (void *)((uptr)Next() & ~(GetStorageSize() - 1)); diff --git a/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_stackdepot.cpp b/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_stackdepot.cpp index ac87fab3eaf1..a746d4621936 100644 --- a/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_stackdepot.cpp +++ b/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_stackdepot.cpp @@ -75,16 +75,18 @@ uptr StackDepotNode::allocated() { } static void CompressStackStore() { - u64 start = MonotonicNanoTime(); + u64 start = Verbosity() >= 1 ? MonotonicNanoTime() : 0; uptr diff = stackStore.Pack(static_cast<StackStore::Compression>( Abs(common_flags()->compress_stack_depot))); if (!diff) return; - u64 finish = MonotonicNanoTime(); - uptr total_before = theDepot.GetStats().allocated + diff; - VPrintf(1, "%s: StackDepot released %zu KiB out of %zu KiB in %llu ms\n", - SanitizerToolName, diff >> 10, total_before >> 10, - (finish - start) / 1000000); + if (Verbosity() >= 1) { + u64 finish = MonotonicNanoTime(); + uptr total_before = theDepot.GetStats().allocated + diff; + VPrintf(1, "%s: StackDepot released %zu KiB out of %zu KiB in %llu ms\n", + SanitizerToolName, diff >> 10, total_before >> 10, + (finish - start) / 1000000); + } } namespace { diff --git a/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace.cpp b/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace.cpp index 37e9e6dd08d7..3013a0c4abdf 100644 --- a/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace.cpp +++ b/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace.cpp @@ -20,11 +20,10 @@ namespace __sanitizer { uptr StackTrace::GetNextInstructionPc(uptr pc) { -#if defined(__sparc__) || defined(__mips__) - return pc + 8; -#elif defined(__powerpc__) || defined(__arm__) || defined(__aarch64__) || \ - defined(__hexagon__) +#if defined(__aarch64__) return STRIP_PAC_PC((void *)pc) + 4; +#elif defined(__sparc__) || defined(__mips__) + return pc + 8; #elif SANITIZER_RISCV64 // Current check order is 4 -> 2 -> 6 -> 8 u8 InsnByte = *(u8 *)(pc); @@ -47,8 +46,10 @@ uptr StackTrace::GetNextInstructionPc(uptr pc) { } // bail-out if could not figure out the instruction size return 0; -#else +#elif SANITIZER_S390 || SANITIZER_I386 || SANITIZER_X32 || SANITIZER_X64 return pc + 1; +#else + return pc + 4; #endif } diff --git a/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace.h b/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace.h index aebd504669d2..ee996c3e07ea 100644 --- a/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace.h +++ b/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace.h @@ -33,7 +33,7 @@ static const u32 kStackTraceMax = 255; // Fast unwind is the only option on Mac for now; we will need to // revisit this macro when slow unwind works on Mac, see // https://github.com/google/sanitizers/issues/137 -#if SANITIZER_MAC +#if SANITIZER_APPLE # define SANITIZER_CAN_SLOW_UNWIND 0 #else # define SANITIZER_CAN_SLOW_UNWIND 1 @@ -88,9 +88,6 @@ uptr StackTrace::GetPreviousInstructionPc(uptr pc) { // so we return (pc-2) in that case in order to be safe. // For A32 mode we return (pc-4) because all instructions are 32 bit long. return (pc - 3) & (~1); -#elif defined(__powerpc__) || defined(__powerpc64__) || defined(__aarch64__) - // PCs are always 4 byte aligned. - return pc - 4; #elif defined(__sparc__) || defined(__mips__) return pc - 8; #elif SANITIZER_RISCV64 @@ -101,8 +98,10 @@ uptr StackTrace::GetPreviousInstructionPc(uptr pc) { // It seems difficult to figure out the exact instruction length - // pc - 2 seems like a safe option for the purposes of stack tracing return pc - 2; -#else +#elif SANITIZER_S390 || SANITIZER_I386 || SANITIZER_X32 || SANITIZER_X64 return pc - 1; +#else + return pc - 4; #endif } diff --git a/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace_libcdep.cpp b/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace_libcdep.cpp index 2d1c03f73221..47983ee7ec71 100644 --- a/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace_libcdep.cpp +++ b/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace_libcdep.cpp @@ -166,8 +166,8 @@ void BufferedStackTrace::Unwind(u32 max_depth, uptr pc, uptr bp, void *context, UnwindFast(pc, bp, stack_top, stack_bottom, max_depth); } -static int GetModuleAndOffsetForPc(uptr pc, char *module_name, - uptr module_name_len, uptr *pc_offset) { +int GetModuleAndOffsetForPc(uptr pc, char *module_name, uptr module_name_len, + uptr *pc_offset) { const char *found_module_name = nullptr; bool ok = Symbolizer::GetOrInit()->GetModuleNameAndOffsetForPC( pc, &found_module_name, pc_offset); @@ -216,10 +216,11 @@ void __sanitizer_symbolize_global(uptr data_addr, const char *fmt, } SANITIZER_INTERFACE_ATTRIBUTE -int __sanitizer_get_module_and_offset_for_pc(uptr pc, char *module_name, +int __sanitizer_get_module_and_offset_for_pc(void *pc, char *module_name, uptr module_name_len, - uptr *pc_offset) { - return __sanitizer::GetModuleAndOffsetForPc(pc, module_name, module_name_len, - pc_offset); + void **pc_offset) { + return __sanitizer::GetModuleAndOffsetForPc( + reinterpret_cast<uptr>(pc), module_name, module_name_len, + reinterpret_cast<uptr *>(pc_offset)); } } // extern "C" diff --git a/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_stoptheworld_mac.cpp b/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_stoptheworld_mac.cpp index 5ec30803b7ad..c87674ff7b76 100644 --- a/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_stoptheworld_mac.cpp +++ b/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_stoptheworld_mac.cpp @@ -12,7 +12,7 @@ #include "sanitizer_platform.h" -#if SANITIZER_MAC && (defined(__x86_64__) || defined(__aarch64__) || \ +#if SANITIZER_APPLE && (defined(__x86_64__) || defined(__aarch64__) || \ defined(__i386)) #include <mach/mach.h> @@ -176,5 +176,5 @@ PtraceRegistersStatus SuspendedThreadsListMac::GetRegistersAndSP( } // namespace __sanitizer -#endif // SANITIZER_MAC && (defined(__x86_64__) || defined(__aarch64__)) || +#endif // SANITIZER_APPLE && (defined(__x86_64__) || defined(__aarch64__)) || // defined(__i386)) diff --git a/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_internal.h b/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_internal.h index df122ed3425c..29a08386d0b9 100644 --- a/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_internal.h +++ b/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_internal.h @@ -90,9 +90,10 @@ class SymbolizerProcess { // Customizable by subclasses. virtual bool StartSymbolizerSubprocess(); - virtual bool ReadFromSymbolizer(char *buffer, uptr max_length); + virtual bool ReadFromSymbolizer(); // Return the environment to run the symbolizer in. virtual char **GetEnvP() { return GetEnviron(); } + InternalMmapVector<char> &GetBuff() { return buffer_; } private: virtual bool ReachedEndOfOutput(const char *buffer, uptr length) const { @@ -113,8 +114,7 @@ class SymbolizerProcess { fd_t input_fd_; fd_t output_fd_; - static const uptr kBufferSize = 16 * 1024; - char buffer_[kBufferSize]; + InternalMmapVector<char> buffer_; static const uptr kMaxTimesRestarted = 5; static const int kSymbolizerStartupTimeMillis = 10; diff --git a/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_libcdep.cpp b/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_libcdep.cpp index 8bbd4af0c7c2..461fe9661368 100644 --- a/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_libcdep.cpp +++ b/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_libcdep.cpp @@ -237,7 +237,7 @@ const LoadedModule *Symbolizer::FindModuleForAddress(uptr address) { class LLVMSymbolizerProcess final : public SymbolizerProcess { public: explicit LLVMSymbolizerProcess(const char *path) - : SymbolizerProcess(path, /*use_posix_spawn=*/SANITIZER_MAC) {} + : SymbolizerProcess(path, /*use_posix_spawn=*/SANITIZER_APPLE) {} private: bool ReachedEndOfOutput(const char *buffer, uptr length) const override { @@ -363,14 +363,21 @@ void ParseSymbolizePCOutput(const char *str, SymbolizedStack *res) { } } -// Parses a two-line string in the following format: +// Parses a two- or three-line string in the following format: // <symbol_name> // <start_address> <size> -// Used by LLVMSymbolizer and InternalSymbolizer. +// <filename>:<column> +// Used by LLVMSymbolizer and InternalSymbolizer. LLVMSymbolizer added support +// for symbolizing the third line in D123538, but we support the older two-line +// information as well. void ParseSymbolizeDataOutput(const char *str, DataInfo *info) { str = ExtractToken(str, "\n", &info->name); str = ExtractUptr(str, " ", &info->start); str = ExtractUptr(str, "\n", &info->size); + // Note: If the third line isn't present, these calls will set info.{file, + // line} to empty strings. + str = ExtractToken(str, ":", &info->file); + str = ExtractUptr(str, "\n", &info->line); } static void ParseSymbolizeFrameOutput(const char *str, @@ -500,9 +507,9 @@ const char *SymbolizerProcess::SendCommandImpl(const char *command) { return nullptr; if (!WriteToSymbolizer(command, internal_strlen(command))) return nullptr; - if (!ReadFromSymbolizer(buffer_, kBufferSize)) - return nullptr; - return buffer_; + if (!ReadFromSymbolizer()) + return nullptr; + return buffer_.data(); } bool SymbolizerProcess::Restart() { @@ -513,31 +520,33 @@ bool SymbolizerProcess::Restart() { return StartSymbolizerSubprocess(); } -bool SymbolizerProcess::ReadFromSymbolizer(char *buffer, uptr max_length) { - if (max_length == 0) - return true; - uptr read_len = 0; - while (true) { +bool SymbolizerProcess::ReadFromSymbolizer() { + buffer_.clear(); + constexpr uptr max_length = 1024; + bool ret = true; + do { uptr just_read = 0; - bool success = ReadFromFile(input_fd_, buffer + read_len, - max_length - read_len - 1, &just_read); + uptr size_before = buffer_.size(); + buffer_.resize(size_before + max_length); + buffer_.resize(buffer_.capacity()); + bool ret = ReadFromFile(input_fd_, &buffer_[size_before], + buffer_.size() - size_before, &just_read); + + if (!ret) + just_read = 0; + + buffer_.resize(size_before + just_read); + // We can't read 0 bytes, as we don't expect external symbolizer to close // its stdout. - if (!success || just_read == 0) { + if (just_read == 0) { Report("WARNING: Can't read from symbolizer at fd %d\n", input_fd_); - return false; - } - read_len += just_read; - if (ReachedEndOfOutput(buffer, read_len)) - break; - if (read_len + 1 == max_length) { - Report("WARNING: Symbolizer buffer too small\n"); - read_len = 0; + ret = false; break; } - } - buffer[read_len] = '\0'; - return true; + } while (!ReachedEndOfOutput(buffer_.data(), buffer_.size())); + buffer_.push_back('\0'); + return ret; } bool SymbolizerProcess::WriteToSymbolizer(const char *buffer, uptr length) { diff --git a/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_mac.cpp b/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_mac.cpp index ac811c8a9136..f4f2a036a1e7 100644 --- a/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_mac.cpp +++ b/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_mac.cpp @@ -12,7 +12,7 @@ //===----------------------------------------------------------------------===// #include "sanitizer_platform.h" -#if SANITIZER_MAC +#if SANITIZER_APPLE #include "sanitizer_allocator_internal.h" #include "sanitizer_mac.h" @@ -202,4 +202,4 @@ bool AtosSymbolizer::SymbolizeData(uptr addr, DataInfo *info) { } // namespace __sanitizer -#endif // SANITIZER_MAC +#endif // SANITIZER_APPLE diff --git a/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_mac.h b/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_mac.h index d5abe9d98c1f..cea244182907 100644 --- a/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_mac.h +++ b/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_mac.h @@ -15,7 +15,7 @@ #define SANITIZER_SYMBOLIZER_MAC_H #include "sanitizer_platform.h" -#if SANITIZER_MAC +#if SANITIZER_APPLE #include "sanitizer_symbolizer_internal.h" @@ -42,6 +42,6 @@ class AtosSymbolizer final : public SymbolizerTool { } // namespace __sanitizer -#endif // SANITIZER_MAC +#endif // SANITIZER_APPLE #endif // SANITIZER_SYMBOLIZER_MAC_H diff --git a/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cpp b/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cpp index 5f6e4cc3180e..8be7709b6038 100644 --- a/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cpp +++ b/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cpp @@ -155,7 +155,7 @@ bool SymbolizerProcess::StartSymbolizerSubprocess() { } if (use_posix_spawn_) { -#if SANITIZER_MAC +#if SANITIZER_APPLE fd_t fd = internal_spawn(argv, const_cast<const char **>(GetEnvP()), &pid); if (fd == kInvalidFd) { Report("WARNING: failed to spawn external symbolizer (errno: %d)\n", @@ -165,9 +165,9 @@ bool SymbolizerProcess::StartSymbolizerSubprocess() { input_fd_ = fd; output_fd_ = fd; -#else // SANITIZER_MAC +#else // SANITIZER_APPLE UNIMPLEMENTED(); -#endif // SANITIZER_MAC +#endif // SANITIZER_APPLE } else { fd_t infd[2] = {}, outfd[2] = {}; if (!CreateTwoHighNumberedPipes(infd, outfd)) { @@ -225,24 +225,24 @@ class Addr2LineProcess final : public SymbolizerProcess { bool ReachedEndOfOutput(const char *buffer, uptr length) const override; - bool ReadFromSymbolizer(char *buffer, uptr max_length) override { - if (!SymbolizerProcess::ReadFromSymbolizer(buffer, max_length)) + bool ReadFromSymbolizer() override { + if (!SymbolizerProcess::ReadFromSymbolizer()) return false; - // The returned buffer is empty when output is valid, but exceeds - // max_length. - if (*buffer == '\0') - return true; + auto &buff = GetBuff(); // We should cut out output_terminator_ at the end of given buffer, // appended by addr2line to mark the end of its meaningful output. // We cannot scan buffer from it's beginning, because it is legal for it // to start with output_terminator_ in case given offset is invalid. So, // scanning from second character. - char *garbage = internal_strstr(buffer + 1, output_terminator_); + char *garbage = internal_strstr(buff.data() + 1, output_terminator_); // This should never be NULL since buffer must end up with // output_terminator_. CHECK(garbage); + // Trim the buffer. - garbage[0] = '\0'; + uintptr_t new_size = garbage - buff.data(); + GetBuff().resize(new_size); + GetBuff().push_back('\0'); return true; } @@ -427,13 +427,13 @@ static SymbolizerTool *ChooseExternalSymbolizer(LowLevelAllocator *allocator) { VReport(2, "Using llvm-symbolizer at user-specified path: %s\n", path); return new(*allocator) LLVMSymbolizer(path, allocator); } else if (!internal_strcmp(binary_name, "atos")) { -#if SANITIZER_MAC +#if SANITIZER_APPLE VReport(2, "Using atos at user-specified path: %s\n", path); return new(*allocator) AtosSymbolizer(path, allocator); -#else // SANITIZER_MAC +#else // SANITIZER_APPLE Report("ERROR: Using `atos` is only supported on Darwin.\n"); Die(); -#endif // SANITIZER_MAC +#endif // SANITIZER_APPLE } else if (!internal_strcmp(binary_name, "addr2line")) { VReport(2, "Using addr2line at user-specified path: %s\n", path); return new(*allocator) Addr2LinePool(path, allocator); @@ -446,12 +446,12 @@ static SymbolizerTool *ChooseExternalSymbolizer(LowLevelAllocator *allocator) { // Otherwise symbolizer program is unknown, let's search $PATH CHECK(path == nullptr); -#if SANITIZER_MAC +#if SANITIZER_APPLE if (const char *found_path = FindPathToBinary("atos")) { VReport(2, "Using atos found at: %s\n", found_path); return new(*allocator) AtosSymbolizer(found_path, allocator); } -#endif // SANITIZER_MAC +#endif // SANITIZER_APPLE if (const char *found_path = FindPathToBinary("llvm-symbolizer")) { VReport(2, "Using llvm-symbolizer found at: %s\n", found_path); return new(*allocator) LLVMSymbolizer(found_path, allocator); @@ -488,10 +488,10 @@ static void ChooseSymbolizerTools(IntrusiveList<SymbolizerTool> *list, list->push_back(tool); } -#if SANITIZER_MAC +#if SANITIZER_APPLE VReport(2, "Using dladdr symbolizer.\n"); list->push_back(new(*allocator) DlAddrSymbolizer()); -#endif // SANITIZER_MAC +#endif // SANITIZER_APPLE } Symbolizer *Symbolizer::PlatformInit() { diff --git a/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_report.cpp b/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_report.cpp index ac855c8be1c8..d5c028e3640d 100644 --- a/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_report.cpp +++ b/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_report.cpp @@ -94,7 +94,7 @@ void ReportMmapWriteExec(int prot, int flags) { if ((prot & pflags) != pflags) return; -# if SANITIZER_MAC && defined(MAP_JIT) +# if SANITIZER_APPLE && defined(MAP_JIT) if ((flags & MAP_JIT) == MAP_JIT) return; # endif diff --git a/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_syscall_generic.inc b/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_syscall_generic.inc index 8829985b5b07..e7f95d33ad0d 100644 --- a/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_syscall_generic.inc +++ b/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_syscall_generic.inc @@ -13,13 +13,14 @@ // NetBSD uses libc calls directly #if !SANITIZER_NETBSD -#if SANITIZER_FREEBSD || SANITIZER_MAC || SANITIZER_SOLARIS +#if SANITIZER_FREEBSD || SANITIZER_APPLE || SANITIZER_SOLARIS # define SYSCALL(name) SYS_ ## name #else # define SYSCALL(name) __NR_ ## name #endif -#if defined(__x86_64__) && (SANITIZER_FREEBSD || SANITIZER_MAC) +#if (defined(__x86_64__) && (SANITIZER_FREEBSD || SANITIZER_APPLE)) || \ + (defined(__aarch64__) && SANITIZER_FREEBSD) # define internal_syscall __syscall # else # define internal_syscall syscall diff --git a/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_unwind_linux_libcdep.cpp b/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_unwind_linux_libcdep.cpp index b2628dcc4dc1..72f025a7d307 100644 --- a/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_unwind_linux_libcdep.cpp +++ b/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_unwind_linux_libcdep.cpp @@ -58,7 +58,7 @@ unwind_backtrace_signal_arch_func unwind_backtrace_signal_arch; #endif uptr Unwind_GetIP(struct _Unwind_Context *ctx) { -#if defined(__arm__) && !SANITIZER_MAC +#if defined(__arm__) && !SANITIZER_APPLE uptr val; _Unwind_VRS_Result res = _Unwind_VRS_Get(ctx, _UVRSC_CORE, 15 /* r15 = PC */, _UVRSD_UINT32, &val); diff --git a/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_win.cpp b/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_win.cpp index 7c84cdc22ce4..c997514cfed7 100644 --- a/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_win.cpp +++ b/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_win.cpp @@ -93,6 +93,11 @@ bool FileExists(const char *filename) { return ::GetFileAttributesA(filename) != INVALID_FILE_ATTRIBUTES; } +bool DirExists(const char *path) { + auto attr = ::GetFileAttributesA(path); + return (attr != INVALID_FILE_ATTRIBUTES) && (attr & FILE_ATTRIBUTE_DIRECTORY); +} + uptr internal_getpid() { return GetProcessId(GetCurrentProcess()); } @@ -126,6 +131,11 @@ void GetThreadStackTopAndBottom(bool at_initialization, uptr *stack_top, } #endif // #if !SANITIZER_GO +bool ErrorIsOOM(error_t err) { + // TODO: This should check which `err`s correspond to OOM. + return false; +} + void *MmapOrDie(uptr size, const char *mem_type, bool raw_report) { void *rv = VirtualAlloc(0, size, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); if (rv == 0) @@ -517,7 +527,7 @@ void ReExec() { UNIMPLEMENTED(); } -void PlatformPrepareForSandboxing(__sanitizer_sandbox_arguments *args) {} +void PlatformPrepareForSandboxing(void *args) {} bool StackSizeIsUnlimited() { UNIMPLEMENTED(); diff --git a/contrib/llvm-project/compiler-rt/lib/sanitizer_common/symbolizer/sanitizer_symbolize.cpp b/contrib/llvm-project/compiler-rt/lib/sanitizer_common/symbolizer/sanitizer_symbolize.cpp index 80cab36426c5..bca12d42f90a 100644 --- a/contrib/llvm-project/compiler-rt/lib/sanitizer_common/symbolizer/sanitizer_symbolize.cpp +++ b/contrib/llvm-project/compiler-rt/lib/sanitizer_common/symbolizer/sanitizer_symbolize.cpp @@ -10,6 +10,7 @@ // //===----------------------------------------------------------------------===// +#include <inttypes.h> #include <stdio.h> #include <string> @@ -41,7 +42,7 @@ static llvm::symbolize::PrinterConfig getDefaultPrinterConfig() { } namespace __sanitizer { -int internal_snprintf(char *buffer, unsigned long length, const char *format, +int internal_snprintf(char *buffer, uintptr_t length, const char *format, ...); } // namespace __sanitizer diff --git a/contrib/llvm-project/compiler-rt/lib/sanitizer_common/symbolizer/sanitizer_wrappers.cpp b/contrib/llvm-project/compiler-rt/lib/sanitizer_common/symbolizer/sanitizer_wrappers.cpp index d3c59e357d46..cdac2333706d 100644 --- a/contrib/llvm-project/compiler-rt/lib/sanitizer_common/symbolizer/sanitizer_wrappers.cpp +++ b/contrib/llvm-project/compiler-rt/lib/sanitizer_common/symbolizer/sanitizer_wrappers.cpp @@ -13,6 +13,7 @@ #include <dlfcn.h> #include <errno.h> #include <fcntl.h> +#include <inttypes.h> #include <stdarg.h> #include <stdio.h> #include <unistd.h> @@ -27,11 +28,11 @@ unsigned long internal_stat(const char *path, void *buf); unsigned long internal_lstat(const char *path, void *buf); unsigned long internal_fstat(int fd, void *buf); size_t internal_strlen(const char *s); -unsigned long internal_mmap(void *addr, unsigned long length, int prot, - int flags, int fd, unsigned long long offset); +unsigned long internal_mmap(void *addr, uintptr_t length, int prot, int flags, + int fd, unsigned long long offset); void *internal_memcpy(void *dest, const void *src, unsigned long n); // Used to propagate errno. -bool internal_iserror(unsigned long retval, int *rverrno = 0); +bool internal_iserror(uintptr_t retval, int *rverrno = 0); } // namespace __sanitizer namespace { @@ -154,8 +155,8 @@ size_t strlen(const char *s) { return __sanitizer::internal_strlen(s); } void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset) { - unsigned long res = __sanitizer::internal_mmap( - addr, (unsigned long)length, prot, flags, fd, (unsigned long long)offset); + unsigned long res = + __sanitizer::internal_mmap(addr, length, prot, flags, fd, offset); RETURN_OR_SET_ERRNO(void *, res); } diff --git a/contrib/llvm-project/compiler-rt/lib/sanitizer_common/symbolizer/scripts/ar_to_bc.sh b/contrib/llvm-project/compiler-rt/lib/sanitizer_common/symbolizer/scripts/ar_to_bc.sh deleted file mode 100755 index fa05d61a7c6d..000000000000 --- a/contrib/llvm-project/compiler-rt/lib/sanitizer_common/symbolizer/scripts/ar_to_bc.sh +++ /dev/null @@ -1,39 +0,0 @@ -#!/usr/bin/env bash - -function usage() { - echo "Usage: $0 INPUT... OUTPUT" - exit 1 -} - -if [ "$#" -le 1 ]; then - usage -fi - -[[ $AR == /* ]] || AR=$PWD/$AR -[[ $LINK == /* ]] || LINK=$PWD/$LINK - -INPUTS= -OUTPUT= -for ARG in $@; do - INPUTS="$INPUTS $OUTPUT" - OUTPUT=$(readlink -f $ARG) -done - -echo Inputs: $INPUTS -echo Output: $OUTPUT - -SCRATCH_DIR=$(mktemp -d) -ln -s $INPUTS $SCRATCH_DIR/ - -pushd $SCRATCH_DIR - -for INPUT in *; do - for OBJ in $($AR t $INPUT); do - $AR x $INPUT $OBJ - mv -f $OBJ $(basename $INPUT).$OBJ - done -done - -$LINK *.o -o $OUTPUT - -rm -rf $SCRATCH_DIR diff --git a/contrib/llvm-project/compiler-rt/lib/sanitizer_common/symbolizer/scripts/build_symbolizer.sh b/contrib/llvm-project/compiler-rt/lib/sanitizer_common/symbolizer/scripts/build_symbolizer.sh index 599f063b45c9..b6f731566c19 100755 --- a/contrib/llvm-project/compiler-rt/lib/sanitizer_common/symbolizer/scripts/build_symbolizer.sh +++ b/contrib/llvm-project/compiler-rt/lib/sanitizer_common/symbolizer/scripts/build_symbolizer.sh @@ -69,8 +69,8 @@ CC=$CLANG_DIR/clang CXX=$CLANG_DIR/clang++ TBLGEN=$CLANG_DIR/llvm-tblgen OPT=$CLANG_DIR/opt -export AR=$CLANG_DIR/llvm-ar -export LINK=$CLANG_DIR/llvm-link +AR=$CLANG_DIR/llvm-ar +LINK=$CLANG_DIR/llvm-link TARGET_TRIPLE=$($CC -print-target-triple) for F in $CC $CXX $TBLGEN $LINK $OPT $AR; do @@ -118,6 +118,7 @@ if [[ ! -d ${LIBCXX_BUILD} ]]; then -DLIBCXX_ENABLE_EXCEPTIONS=OFF \ -DLIBCXX_ENABLE_RTTI=OFF \ -DLIBCXX_ENABLE_SHARED=OFF \ + -DLLVM_DEFAULT_TARGET_TRIPLE="${TARGET_TRIPLE}" \ $LLVM_SRC fi cd ${LIBCXX_BUILD} @@ -137,6 +138,7 @@ if [[ ! -d ${LLVM_BUILD} ]]; then -DCMAKE_C_FLAGS_RELEASE="${LLVM_FLAGS}" \ -DCMAKE_CXX_FLAGS_RELEASE="${LLVM_FLAGS}" \ -DLLVM_TABLEGEN=$TBLGEN \ + -DLLVM_DEFAULT_TARGET_TRIPLE="${TARGET_TRIPLE}" \ -DLLVM_ENABLE_ZLIB=ON \ -DLLVM_ENABLE_TERMINFO=OFF \ -DLLVM_ENABLE_THREADS=OFF \ @@ -165,23 +167,23 @@ SYMBOLIZER_API_LIST+=,__sanitizer_symbolize_set_inline_frames LIBCXX_ARCHIVE_DIR=$(dirname $(find $LIBCXX_BUILD -name libc++.a | head -n1)) # Merge all the object files together and copy the resulting library back. -$SCRIPT_DIR/ar_to_bc.sh $LIBCXX_ARCHIVE_DIR/libc++.a \ - $LIBCXX_ARCHIVE_DIR/libc++abi.a \ - $LLVM_BUILD/lib/libLLVMSymbolize.a \ - $LLVM_BUILD/lib/libLLVMObject.a \ - $LLVM_BUILD/lib/libLLVMBinaryFormat.a \ - $LLVM_BUILD/lib/libLLVMDebugInfoDWARF.a \ - $LLVM_BUILD/lib/libLLVMSupport.a \ - $LLVM_BUILD/lib/libLLVMDebugInfoPDB.a \ - $LLVM_BUILD/lib/libLLVMDebugInfoMSF.a \ - $LLVM_BUILD/lib/libLLVMDebugInfoCodeView.a \ - $LLVM_BUILD/lib/libLLVMDebuginfod.a \ - $LLVM_BUILD/lib/libLLVMDemangle.a \ - $LLVM_BUILD/lib/libLLVMMC.a \ - $LLVM_BUILD/lib/libLLVMTextAPI.a \ - $ZLIB_BUILD/libz.a \ - symbolizer.a \ - all.bc +$LINK $LIBCXX_ARCHIVE_DIR/libc++.a \ + $LIBCXX_ARCHIVE_DIR/libc++abi.a \ + $LLVM_BUILD/lib/libLLVMSymbolize.a \ + $LLVM_BUILD/lib/libLLVMObject.a \ + $LLVM_BUILD/lib/libLLVMBinaryFormat.a \ + $LLVM_BUILD/lib/libLLVMDebugInfoDWARF.a \ + $LLVM_BUILD/lib/libLLVMSupport.a \ + $LLVM_BUILD/lib/libLLVMDebugInfoPDB.a \ + $LLVM_BUILD/lib/libLLVMDebugInfoMSF.a \ + $LLVM_BUILD/lib/libLLVMDebugInfoCodeView.a \ + $LLVM_BUILD/lib/libLLVMDebuginfod.a \ + $LLVM_BUILD/lib/libLLVMDemangle.a \ + $LLVM_BUILD/lib/libLLVMMC.a \ + $LLVM_BUILD/lib/libLLVMTextAPI.a \ + $ZLIB_BUILD/libz.a \ + symbolizer.a \ + -ignore-non-bitcode -o all.bc echo "Optimizing..." $OPT -internalize -internalize-public-api-list=${SYMBOLIZER_API_LIST} all.bc -o opt.bc diff --git a/contrib/llvm-project/compiler-rt/lib/sanitizer_common/symbolizer/scripts/global_symbols.txt b/contrib/llvm-project/compiler-rt/lib/sanitizer_common/symbolizer/scripts/global_symbols.txt index 071dbbb279c6..8e8013853f7e 100644 --- a/contrib/llvm-project/compiler-rt/lib/sanitizer_common/symbolizer/scripts/global_symbols.txt +++ b/contrib/llvm-project/compiler-rt/lib/sanitizer_common/symbolizer/scripts/global_symbols.txt @@ -1,4 +1,5 @@ _GLOBAL_OFFSET_TABLE_ U +_ZN11__sanitizer13internal_mmapEPvjiiiy U _ZN11__sanitizer13internal_mmapEPvmiiiy U _ZN11__sanitizer13internal_openEPKcij U _ZN11__sanitizer13internal_statEPKcPv U @@ -6,7 +7,9 @@ _ZN11__sanitizer14internal_closeEi U _ZN11__sanitizer14internal_fstatEiPv U _ZN11__sanitizer14internal_lstatEPKcPv U _ZN11__sanitizer15internal_strlenEPKc U +_ZN11__sanitizer16internal_iserrorEjPi U _ZN11__sanitizer16internal_iserrorEmPi U +_ZN11__sanitizer17internal_snprintfEPcjPKcz U _ZN11__sanitizer17internal_snprintfEPcmPKcz U __ctype_b_loc U __ctype_get_mb_cur_max U @@ -110,6 +113,7 @@ mkdir U munmap U newlocale U perror U +posix_madvise U posix_spawn U posix_spawn_file_actions_adddup2 U posix_spawn_file_actions_addopen U diff --git a/contrib/llvm-project/compiler-rt/lib/scudo/standalone/checksum.cpp b/contrib/llvm-project/compiler-rt/lib/scudo/standalone/checksum.cpp index 05d4ba54bfc8..2c277391a2ec 100644 --- a/contrib/llvm-project/compiler-rt/lib/scudo/standalone/checksum.cpp +++ b/contrib/llvm-project/compiler-rt/lib/scudo/standalone/checksum.cpp @@ -8,6 +8,7 @@ #include "checksum.h" #include "atomic_helpers.h" +#include "chunk.h" #if defined(__x86_64__) || defined(__i386__) #include <cpuid.h> diff --git a/contrib/llvm-project/compiler-rt/lib/scudo/standalone/checksum.h b/contrib/llvm-project/compiler-rt/lib/scudo/standalone/checksum.h index 0f787ce2b5cd..f8eda81fd912 100644 --- a/contrib/llvm-project/compiler-rt/lib/scudo/standalone/checksum.h +++ b/contrib/llvm-project/compiler-rt/lib/scudo/standalone/checksum.h @@ -20,7 +20,8 @@ #if defined(__CRC32__) // NB: clang has <crc32intrin.h> but GCC does not #include <smmintrin.h> -#define CRC32_INTRINSIC FIRST_32_SECOND_64(__builtin_ia32_crc32si, __builtin_ia32_crc32di) +#define CRC32_INTRINSIC \ + FIRST_32_SECOND_64(__builtin_ia32_crc32si, __builtin_ia32_crc32di) #elif defined(__SSE4_2__) #include <smmintrin.h> #define CRC32_INTRINSIC FIRST_32_SECOND_64(_mm_crc32_u32, _mm_crc32_u64) diff --git a/contrib/llvm-project/compiler-rt/lib/scudo/standalone/chunk.h b/contrib/llvm-project/compiler-rt/lib/scudo/standalone/chunk.h index 0581420dfc99..88bada8c2d19 100644 --- a/contrib/llvm-project/compiler-rt/lib/scudo/standalone/chunk.h +++ b/contrib/llvm-project/compiler-rt/lib/scudo/standalone/chunk.h @@ -42,7 +42,8 @@ inline u16 computeChecksum(u32 Seed, uptr Value, uptr *Array, uptr ArraySize) { Checksum = computeBSDChecksum(Checksum, Array[I]); return Checksum; } -#endif // defined(__CRC32__) || defined(__SSE4_2__) || defined(__ARM_FEATURE_CRC32) +#endif // defined(__CRC32__) || defined(__SSE4_2__) || + // defined(__ARM_FEATURE_CRC32) } namespace Chunk { diff --git a/contrib/llvm-project/compiler-rt/lib/scudo/standalone/combined.h b/contrib/llvm-project/compiler-rt/lib/scudo/standalone/combined.h index 371fb783a06e..365720d4a5f4 100644 --- a/contrib/llvm-project/compiler-rt/lib/scudo/standalone/combined.h +++ b/contrib/llvm-project/compiler-rt/lib/scudo/standalone/combined.h @@ -1271,8 +1271,8 @@ private: } static const size_t NumErrorReports = - sizeof(((scudo_error_info *)0)->reports) / - sizeof(((scudo_error_info *)0)->reports[0]); + sizeof(((scudo_error_info *)nullptr)->reports) / + sizeof(((scudo_error_info *)nullptr)->reports[0]); static void getInlineErrorInfo(struct scudo_error_info *ErrorInfo, size_t &NextErrorReport, uintptr_t FaultAddr, diff --git a/contrib/llvm-project/compiler-rt/lib/scudo/standalone/crc32_hw.cpp b/contrib/llvm-project/compiler-rt/lib/scudo/standalone/crc32_hw.cpp index d13c615498ff..73f2ae000c63 100644 --- a/contrib/llvm-project/compiler-rt/lib/scudo/standalone/crc32_hw.cpp +++ b/contrib/llvm-project/compiler-rt/lib/scudo/standalone/crc32_hw.cpp @@ -14,6 +14,7 @@ namespace scudo { u32 computeHardwareCRC32(u32 Crc, uptr Data) { return static_cast<u32>(CRC32_INTRINSIC(Crc, Data)); } -#endif // defined(__CRC32__) || defined(__SSE4_2__) || defined(__ARM_FEATURE_CRC32) +#endif // defined(__CRC32__) || defined(__SSE4_2__) || + // defined(__ARM_FEATURE_CRC32) } // namespace scudo diff --git a/contrib/llvm-project/compiler-rt/lib/scudo/standalone/fuchsia.cpp b/contrib/llvm-project/compiler-rt/lib/scudo/standalone/fuchsia.cpp index 3b473bc9e22d..8ab2b382a36a 100644 --- a/contrib/llvm-project/compiler-rt/lib/scudo/standalone/fuchsia.cpp +++ b/contrib/llvm-project/compiler-rt/lib/scudo/standalone/fuchsia.cpp @@ -17,6 +17,7 @@ #include <lib/sync/mutex.h> // for sync_mutex_t #include <stdlib.h> // for getenv() #include <zircon/compiler.h> +#include <zircon/process.h> #include <zircon/sanitizer.h> #include <zircon/syscalls.h> @@ -88,6 +89,8 @@ void *map(void *Addr, uptr Size, const char *Name, uptr Flags, uintptr_t P; zx_vm_option_t MapFlags = ZX_VM_PERM_READ | ZX_VM_PERM_WRITE | ZX_VM_ALLOW_FAULTS; + if (Addr) + DCHECK(Data); const uint64_t Offset = Addr ? reinterpret_cast<uintptr_t>(Addr) - Data->VmarBase : 0; if (Offset) diff --git a/contrib/llvm-project/compiler-rt/lib/scudo/standalone/fuchsia.h b/contrib/llvm-project/compiler-rt/lib/scudo/standalone/fuchsia.h index d6993f892140..c1dfd7638ec5 100644 --- a/contrib/llvm-project/compiler-rt/lib/scudo/standalone/fuchsia.h +++ b/contrib/llvm-project/compiler-rt/lib/scudo/standalone/fuchsia.h @@ -13,7 +13,8 @@ #if SCUDO_FUCHSIA -#include <zircon/process.h> +#include <stdint.h> +#include <zircon/types.h> namespace scudo { diff --git a/contrib/llvm-project/compiler-rt/lib/scudo/standalone/memtag.h b/contrib/llvm-project/compiler-rt/lib/scudo/standalone/memtag.h index df346bce1bd4..7f14a30fee12 100644 --- a/contrib/llvm-project/compiler-rt/lib/scudo/standalone/memtag.h +++ b/contrib/llvm-project/compiler-rt/lib/scudo/standalone/memtag.h @@ -18,7 +18,8 @@ namespace scudo { -#if (__clang_major__ >= 12 && defined(__aarch64__)) || defined(SCUDO_FUZZ) +#if (__clang_major__ >= 12 && defined(__aarch64__) && !defined(__ILP32__)) || \ + defined(SCUDO_FUZZ) // We assume that Top-Byte Ignore is enabled if the architecture supports memory // tagging. Not all operating systems enable TBI, so we only claim architectural @@ -41,23 +42,23 @@ inline uint8_t extractTag(uptr Ptr) { return (Ptr >> 56) & 0xf; } inline constexpr bool archSupportsMemoryTagging() { return false; } -inline uptr archMemoryTagGranuleSize() { +inline NORETURN uptr archMemoryTagGranuleSize() { UNREACHABLE("memory tagging not supported"); } -inline uptr untagPointer(uptr Ptr) { +inline NORETURN uptr untagPointer(uptr Ptr) { (void)Ptr; UNREACHABLE("memory tagging not supported"); } -inline uint8_t extractTag(uptr Ptr) { +inline NORETURN uint8_t extractTag(uptr Ptr) { (void)Ptr; UNREACHABLE("memory tagging not supported"); } #endif -#if __clang_major__ >= 12 && defined(__aarch64__) +#if __clang_major__ >= 12 && defined(__aarch64__) && !defined(__ILP32__) #if SCUDO_LINUX @@ -109,11 +110,11 @@ inline void enableSystemMemoryTaggingTestOnly() { inline bool systemSupportsMemoryTagging() { return false; } -inline bool systemDetectsMemoryTagFaultsTestOnly() { +inline NORETURN bool systemDetectsMemoryTagFaultsTestOnly() { UNREACHABLE("memory tagging not supported"); } -inline void enableSystemMemoryTaggingTestOnly() { +inline NORETURN void enableSystemMemoryTaggingTestOnly() { UNREACHABLE("memory tagging not supported"); } @@ -255,15 +256,15 @@ inline uptr loadTag(uptr Ptr) { #else -inline bool systemSupportsMemoryTagging() { +inline NORETURN bool systemSupportsMemoryTagging() { UNREACHABLE("memory tagging not supported"); } -inline bool systemDetectsMemoryTagFaultsTestOnly() { +inline NORETURN bool systemDetectsMemoryTagFaultsTestOnly() { UNREACHABLE("memory tagging not supported"); } -inline void enableSystemMemoryTaggingTestOnly() { +inline NORETURN void enableSystemMemoryTaggingTestOnly() { UNREACHABLE("memory tagging not supported"); } @@ -271,41 +272,44 @@ struct ScopedDisableMemoryTagChecks { ScopedDisableMemoryTagChecks() {} }; -inline uptr selectRandomTag(uptr Ptr, uptr ExcludeMask) { +inline NORETURN uptr selectRandomTag(uptr Ptr, uptr ExcludeMask) { (void)Ptr; (void)ExcludeMask; UNREACHABLE("memory tagging not supported"); } -inline uptr addFixedTag(uptr Ptr, uptr Tag) { +inline NORETURN uptr addFixedTag(uptr Ptr, uptr Tag) { (void)Ptr; (void)Tag; UNREACHABLE("memory tagging not supported"); } -inline uptr storeTags(uptr Begin, uptr End) { +inline NORETURN uptr storeTags(uptr Begin, uptr End) { (void)Begin; (void)End; UNREACHABLE("memory tagging not supported"); } -inline void storeTag(uptr Ptr) { +inline NORETURN void storeTag(uptr Ptr) { (void)Ptr; UNREACHABLE("memory tagging not supported"); } -inline uptr loadTag(uptr Ptr) { +inline NORETURN uptr loadTag(uptr Ptr) { (void)Ptr; UNREACHABLE("memory tagging not supported"); } #endif +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wmissing-noreturn" inline void setRandomTag(void *Ptr, uptr Size, uptr ExcludeMask, uptr *TaggedBegin, uptr *TaggedEnd) { *TaggedBegin = selectRandomTag(reinterpret_cast<uptr>(Ptr), ExcludeMask); *TaggedEnd = storeTags(*TaggedBegin, *TaggedBegin + Size); } +#pragma GCC diagnostic pop inline void *untagPointer(void *Ptr) { return reinterpret_cast<void *>(untagPointer(reinterpret_cast<uptr>(Ptr))); diff --git a/contrib/llvm-project/compiler-rt/lib/scudo/standalone/platform.h b/contrib/llvm-project/compiler-rt/lib/scudo/standalone/platform.h index 36378d14d844..db4217ddab9f 100644 --- a/contrib/llvm-project/compiler-rt/lib/scudo/standalone/platform.h +++ b/contrib/llvm-project/compiler-rt/lib/scudo/standalone/platform.h @@ -37,7 +37,7 @@ #define SCUDO_TRUSTY 0 #endif -#if __LP64__ +#if defined(__LP64__) #define SCUDO_WORDSIZE 64U #else #define SCUDO_WORDSIZE 32U diff --git a/contrib/llvm-project/compiler-rt/lib/scudo/standalone/primary64.h b/contrib/llvm-project/compiler-rt/lib/scudo/standalone/primary64.h index 6c1785512c65..14784ee8f377 100644 --- a/contrib/llvm-project/compiler-rt/lib/scudo/standalone/primary64.h +++ b/contrib/llvm-project/compiler-rt/lib/scudo/standalone/primary64.h @@ -89,7 +89,9 @@ public: RegionInfo *Region = getRegionInfo(I); *Region = {}; } - unmap(reinterpret_cast<void *>(PrimaryBase), PrimarySize, UNMAP_ALL, &Data); + if (PrimaryBase) + unmap(reinterpret_cast<void *>(PrimaryBase), PrimarySize, UNMAP_ALL, + &Data); PrimaryBase = 0U; } diff --git a/contrib/llvm-project/compiler-rt/lib/scudo/standalone/secondary.h b/contrib/llvm-project/compiler-rt/lib/scudo/standalone/secondary.h index abb58a2882af..2d1775762588 100644 --- a/contrib/llvm-project/compiler-rt/lib/scudo/standalone/secondary.h +++ b/contrib/llvm-project/compiler-rt/lib/scudo/standalone/secondary.h @@ -113,6 +113,19 @@ void mapSecondary(Options Options, uptr CommitBase, uptr CommitSize, } } +// Template specialization to avoid producing zero-length array +template <typename T, size_t Size> class NonZeroLengthArray { +public: + T &operator[](uptr Idx) { return values[Idx]; } + +private: + T values[Size]; +}; +template <typename T> class NonZeroLengthArray<T, 0> { +public: + T &operator[](uptr UNUSED Idx) { UNREACHABLE("Unsupported!"); } +}; + template <typename Config> class MapAllocatorCache { public: // Ensure the default maximum specified fits the array. @@ -219,7 +232,7 @@ public: const u32 MaxCount = atomic_load_relaxed(&MaxEntriesCount); bool Found = false; CachedBlock Entry; - uptr HeaderPos; + uptr HeaderPos = 0; { ScopedLock L(Mutex); if (EntriesCount == 0) @@ -395,7 +408,8 @@ private: atomic_s32 ReleaseToOsIntervalMs = {}; CachedBlock Entries[Config::SecondaryCacheEntriesArraySize] = {}; - CachedBlock Quarantine[Config::SecondaryCacheQuarantineSize] = {}; + NonZeroLengthArray<CachedBlock, Config::SecondaryCacheQuarantineSize> + Quarantine = {}; }; template <typename Config> class MapAllocator { @@ -445,7 +459,7 @@ public: } } - uptr canCache(uptr Size) { return Cache.canCache(Size); } + bool canCache(uptr Size) { return Cache.canCache(Size); } bool setOption(Option O, sptr Value) { return Cache.setOption(O, Value); } diff --git a/contrib/llvm-project/compiler-rt/lib/scudo/standalone/size_class_map.h b/contrib/llvm-project/compiler-rt/lib/scudo/standalone/size_class_map.h index 28b16d976e5e..6b060950abe1 100644 --- a/contrib/llvm-project/compiler-rt/lib/scudo/standalone/size_class_map.h +++ b/contrib/llvm-project/compiler-rt/lib/scudo/standalone/size_class_map.h @@ -345,7 +345,7 @@ template <typename SCMap> inline void printMap() { Buffer.output(); } -template <typename SCMap> static void validateMap() { +template <typename SCMap> static UNUSED void validateMap() { for (uptr C = 0; C < SCMap::NumClasses; C++) { if (C == SCMap::BatchClassId) continue; diff --git a/contrib/llvm-project/compiler-rt/lib/scudo/standalone/tsd_exclusive.h b/contrib/llvm-project/compiler-rt/lib/scudo/standalone/tsd_exclusive.h index bba0c277c6a7..d49427b2005b 100644 --- a/contrib/llvm-project/compiler-rt/lib/scudo/standalone/tsd_exclusive.h +++ b/contrib/llvm-project/compiler-rt/lib/scudo/standalone/tsd_exclusive.h @@ -15,7 +15,7 @@ namespace scudo { struct ThreadState { bool DisableMemInit : 1; - enum { + enum : unsigned { NotInitialized = 0, Initialized, TornDown, @@ -87,7 +87,7 @@ template <class Allocator> struct TSDRegistryExT { Mutex.unlock(); } - bool setOption(Option O, UNUSED sptr Value) { + bool setOption(Option O, sptr Value) { if (O == Option::ThreadDisableMemInit) State.DisableMemInit = Value; if (O == Option::MaxTSDsCount) diff --git a/contrib/llvm-project/compiler-rt/lib/scudo/standalone/wrappers_c.cpp b/contrib/llvm-project/compiler-rt/lib/scudo/standalone/wrappers_c.cpp index 81c7dd60ee33..b4d51be716cc 100644 --- a/contrib/llvm-project/compiler-rt/lib/scudo/standalone/wrappers_c.cpp +++ b/contrib/llvm-project/compiler-rt/lib/scudo/standalone/wrappers_c.cpp @@ -21,8 +21,6 @@ #define SCUDO_PREFIX(name) name #define SCUDO_ALLOCATOR Allocator -extern "C" void SCUDO_PREFIX(malloc_postinit)(); - // Export the static allocator so that the C++ wrappers can access it. // Technically we could have a completely separated heap for C & C++ but in // reality the amount of cross pollination between the two is staggering. diff --git a/contrib/llvm-project/compiler-rt/lib/scudo/standalone/wrappers_c.h b/contrib/llvm-project/compiler-rt/lib/scudo/standalone/wrappers_c.h index 5f7f51f3cedf..08dc679b34ca 100644 --- a/contrib/llvm-project/compiler-rt/lib/scudo/standalone/wrappers_c.h +++ b/contrib/llvm-project/compiler-rt/lib/scudo/standalone/wrappers_c.h @@ -54,4 +54,9 @@ struct __scudo_mallinfo2 { #define SCUDO_MALLINFO __scudo_mallinfo #endif +#if !SCUDO_ANDROID || !_BIONIC +extern "C" void malloc_postinit(); +extern HIDDEN scudo::Allocator<scudo::Config, malloc_postinit> Allocator; +#endif + #endif // SCUDO_WRAPPERS_C_H_ diff --git a/contrib/llvm-project/compiler-rt/lib/scudo/standalone/wrappers_c_checks.h b/contrib/llvm-project/compiler-rt/lib/scudo/standalone/wrappers_c_checks.h index ec9c1a104e83..815d40023b6a 100644 --- a/contrib/llvm-project/compiler-rt/lib/scudo/standalone/wrappers_c_checks.h +++ b/contrib/llvm-project/compiler-rt/lib/scudo/standalone/wrappers_c_checks.h @@ -47,9 +47,12 @@ inline bool checkPosixMemalignAlignment(uptr Alignment) { // costly division. inline bool checkForCallocOverflow(uptr Size, uptr N, uptr *Product) { #if __has_builtin(__builtin_umull_overflow) && (SCUDO_WORDSIZE == 64U) - return __builtin_umull_overflow(Size, N, Product); + return __builtin_umull_overflow(Size, N, + reinterpret_cast<unsigned long *>(Product)); #elif __has_builtin(__builtin_umul_overflow) && (SCUDO_WORDSIZE == 32U) - return __builtin_umul_overflow(Size, N, Product); + // On, e.g. armv7, uptr/uintptr_t may be defined as unsigned long + return __builtin_umul_overflow(Size, N, + reinterpret_cast<unsigned int *>(Product)); #else *Product = Size * N; if (!Size) diff --git a/contrib/llvm-project/compiler-rt/lib/scudo/standalone/wrappers_cpp.cpp b/contrib/llvm-project/compiler-rt/lib/scudo/standalone/wrappers_cpp.cpp index adb104118123..374e36d72b3d 100644 --- a/contrib/llvm-project/compiler-rt/lib/scudo/standalone/wrappers_cpp.cpp +++ b/contrib/llvm-project/compiler-rt/lib/scudo/standalone/wrappers_cpp.cpp @@ -12,12 +12,10 @@ #if !SCUDO_ANDROID || !_BIONIC #include "allocator_config.h" +#include "wrappers_c.h" #include <stdint.h> -extern "C" void malloc_postinit(); -extern HIDDEN scudo::Allocator<scudo::Config, malloc_postinit> Allocator; - namespace std { struct nothrow_t {}; enum class align_val_t : size_t {}; @@ -56,26 +54,28 @@ INTERFACE WEAK void *operator new[](size_t size, std::align_val_t align, static_cast<scudo::uptr>(align)); } -INTERFACE WEAK void operator delete(void *ptr)NOEXCEPT { +INTERFACE WEAK void operator delete(void *ptr) NOEXCEPT { Allocator.deallocate(ptr, scudo::Chunk::Origin::New); } INTERFACE WEAK void operator delete[](void *ptr) NOEXCEPT { Allocator.deallocate(ptr, scudo::Chunk::Origin::NewArray); } -INTERFACE WEAK void operator delete(void *ptr, std::nothrow_t const &)NOEXCEPT { +INTERFACE WEAK void operator delete(void *ptr, + std::nothrow_t const &) NOEXCEPT { Allocator.deallocate(ptr, scudo::Chunk::Origin::New); } INTERFACE WEAK void operator delete[](void *ptr, std::nothrow_t const &) NOEXCEPT { Allocator.deallocate(ptr, scudo::Chunk::Origin::NewArray); } -INTERFACE WEAK void operator delete(void *ptr, size_t size)NOEXCEPT { +INTERFACE WEAK void operator delete(void *ptr, size_t size) NOEXCEPT { Allocator.deallocate(ptr, scudo::Chunk::Origin::New, size); } INTERFACE WEAK void operator delete[](void *ptr, size_t size) NOEXCEPT { Allocator.deallocate(ptr, scudo::Chunk::Origin::NewArray, size); } -INTERFACE WEAK void operator delete(void *ptr, std::align_val_t align)NOEXCEPT { +INTERFACE WEAK void operator delete(void *ptr, + std::align_val_t align) NOEXCEPT { Allocator.deallocate(ptr, scudo::Chunk::Origin::New, 0, static_cast<scudo::uptr>(align)); } @@ -85,7 +85,7 @@ INTERFACE WEAK void operator delete[](void *ptr, static_cast<scudo::uptr>(align)); } INTERFACE WEAK void operator delete(void *ptr, std::align_val_t align, - std::nothrow_t const &)NOEXCEPT { + std::nothrow_t const &) NOEXCEPT { Allocator.deallocate(ptr, scudo::Chunk::Origin::New, 0, static_cast<scudo::uptr>(align)); } @@ -95,7 +95,7 @@ INTERFACE WEAK void operator delete[](void *ptr, std::align_val_t align, static_cast<scudo::uptr>(align)); } INTERFACE WEAK void operator delete(void *ptr, size_t size, - std::align_val_t align)NOEXCEPT { + std::align_val_t align) NOEXCEPT { Allocator.deallocate(ptr, scudo::Chunk::Origin::New, size, static_cast<scudo::uptr>(align)); } diff --git a/contrib/llvm-project/compiler-rt/lib/tsan/go/test.c b/contrib/llvm-project/compiler-rt/lib/tsan/go/test.c index 787b4c5b7dc1..1b0d828c9044 100644 --- a/contrib/llvm-project/compiler-rt/lib/tsan/go/test.c +++ b/contrib/llvm-project/compiler-rt/lib/tsan/go/test.c @@ -6,7 +6,7 @@ // //===----------------------------------------------------------------------===// // -// Sanity test for Go runtime. +// Test for Go runtime. // //===----------------------------------------------------------------------===// diff --git a/contrib/llvm-project/compiler-rt/lib/tsan/rtl-old/tsan_dispatch_defs.h b/contrib/llvm-project/compiler-rt/lib/tsan/rtl-old/tsan_dispatch_defs.h index 94e0b50fed36..54c0b0ba4b40 100644 --- a/contrib/llvm-project/compiler-rt/lib/tsan/rtl-old/tsan_dispatch_defs.h +++ b/contrib/llvm-project/compiler-rt/lib/tsan/rtl-old/tsan_dispatch_defs.h @@ -56,7 +56,7 @@ extern const dispatch_block_t _dispatch_data_destructor_munmap; # define DISPATCH_NOESCAPE #endif -#if SANITIZER_MAC +#if SANITIZER_APPLE # define SANITIZER_WEAK_IMPORT extern "C" __attribute((weak_import)) #else # define SANITIZER_WEAK_IMPORT extern "C" __attribute((weak)) diff --git a/contrib/llvm-project/compiler-rt/lib/tsan/rtl-old/tsan_flags.cpp b/contrib/llvm-project/compiler-rt/lib/tsan/rtl-old/tsan_flags.cpp index ee89862d17bd..2e8add3c8d43 100644 --- a/contrib/llvm-project/compiler-rt/lib/tsan/rtl-old/tsan_flags.cpp +++ b/contrib/llvm-project/compiler-rt/lib/tsan/rtl-old/tsan_flags.cpp @@ -97,7 +97,7 @@ void InitializeFlags(Flags *f, const char *env, const char *env_option_name) { ubsan_parser.ParseStringFromEnv("UBSAN_OPTIONS"); #endif - // Sanity check. + // Check flags. if (!f->report_bugs) { f->report_thread_leaks = false; f->report_destroy_locked = false; diff --git a/contrib/llvm-project/compiler-rt/lib/tsan/rtl-old/tsan_flags.inc b/contrib/llvm-project/compiler-rt/lib/tsan/rtl-old/tsan_flags.inc index 7954a4307fa1..423370285187 100644 --- a/contrib/llvm-project/compiler-rt/lib/tsan/rtl-old/tsan_flags.inc +++ b/contrib/llvm-project/compiler-rt/lib/tsan/rtl-old/tsan_flags.inc @@ -75,9 +75,9 @@ TSAN_FLAG(int, io_sync, 1, TSAN_FLAG(bool, die_after_fork, true, "Die after multi-threaded fork if the child creates new threads.") TSAN_FLAG(const char *, suppressions, "", "Suppressions file name.") -TSAN_FLAG(bool, ignore_interceptors_accesses, SANITIZER_MAC ? true : false, +TSAN_FLAG(bool, ignore_interceptors_accesses, SANITIZER_APPLE ? true : false, "Ignore reads and writes from all interceptors.") -TSAN_FLAG(bool, ignore_noninstrumented_modules, SANITIZER_MAC ? true : false, +TSAN_FLAG(bool, ignore_noninstrumented_modules, SANITIZER_APPLE ? true : false, "Interceptors should only detect races when called from instrumented " "modules.") TSAN_FLAG(bool, shared_ptr_interceptor, true, diff --git a/contrib/llvm-project/compiler-rt/lib/tsan/rtl-old/tsan_interceptors_libdispatch.cpp b/contrib/llvm-project/compiler-rt/lib/tsan/rtl-old/tsan_interceptors_libdispatch.cpp index cbbb7ecb2397..88d5f0a48119 100644 --- a/contrib/llvm-project/compiler-rt/lib/tsan/rtl-old/tsan_interceptors_libdispatch.cpp +++ b/contrib/llvm-project/compiler-rt/lib/tsan/rtl-old/tsan_interceptors_libdispatch.cpp @@ -19,7 +19,7 @@ #include "BlocksRuntime/Block.h" #include "tsan_dispatch_defs.h" -#if SANITIZER_MAC +#if SANITIZER_APPLE # include <Availability.h> #endif @@ -225,7 +225,7 @@ DISPATCH_INTERCEPT(dispatch_barrier, true) // dispatch_async_and_wait() and friends were introduced in macOS 10.14. // Linking of these interceptors fails when using an older SDK. -#if !SANITIZER_MAC || defined(__MAC_10_14) +#if !SANITIZER_APPLE || defined(__MAC_10_14) // macOS 10.14 is greater than our minimal deployment target. To ensure we // generate a weak reference so the TSan dylib continues to work on older // systems, we need to forward declare the intercepted functions as "weak diff --git a/contrib/llvm-project/compiler-rt/lib/tsan/rtl-old/tsan_interceptors_mac.cpp b/contrib/llvm-project/compiler-rt/lib/tsan/rtl-old/tsan_interceptors_mac.cpp index ed064150d005..1ee47bcd1237 100644 --- a/contrib/llvm-project/compiler-rt/lib/tsan/rtl-old/tsan_interceptors_mac.cpp +++ b/contrib/llvm-project/compiler-rt/lib/tsan/rtl-old/tsan_interceptors_mac.cpp @@ -12,7 +12,7 @@ //===----------------------------------------------------------------------===// #include "sanitizer_common/sanitizer_platform.h" -#if SANITIZER_MAC +#if SANITIZER_APPLE #include "interception/interception.h" #include "tsan_interceptors.h" @@ -518,4 +518,4 @@ STDCXX_INTERCEPTOR(void, _ZNSt3__111__call_onceERVmPvPFvS2_E, void *flag, } // namespace __tsan -#endif // SANITIZER_MAC +#endif // SANITIZER_APPLE diff --git a/contrib/llvm-project/compiler-rt/lib/tsan/rtl-old/tsan_interceptors_posix.cpp b/contrib/llvm-project/compiler-rt/lib/tsan/rtl-old/tsan_interceptors_posix.cpp index cf3dc90d96a1..61204f982df8 100644 --- a/contrib/llvm-project/compiler-rt/lib/tsan/rtl-old/tsan_interceptors_posix.cpp +++ b/contrib/llvm-project/compiler-rt/lib/tsan/rtl-old/tsan_interceptors_posix.cpp @@ -35,7 +35,7 @@ using namespace __tsan; -#if SANITIZER_FREEBSD || SANITIZER_MAC +#if SANITIZER_FREEBSD || SANITIZER_APPLE #define stdout __stdoutp #define stderr __stderrp #endif @@ -102,14 +102,14 @@ extern __sanitizer_FILE __sF[]; #else extern __sanitizer_FILE *stdout, *stderr; #endif -#if !SANITIZER_FREEBSD && !SANITIZER_MAC && !SANITIZER_NETBSD +#if !SANITIZER_FREEBSD && !SANITIZER_APPLE && !SANITIZER_NETBSD const int PTHREAD_MUTEX_RECURSIVE = 1; const int PTHREAD_MUTEX_RECURSIVE_NP = 1; #else const int PTHREAD_MUTEX_RECURSIVE = 2; const int PTHREAD_MUTEX_RECURSIVE_NP = 2; #endif -#if !SANITIZER_FREEBSD && !SANITIZER_MAC && !SANITIZER_NETBSD +#if !SANITIZER_FREEBSD && !SANITIZER_APPLE && !SANITIZER_NETBSD const int EPOLL_CTL_ADD = 1; #endif const int SIGILL = 4; @@ -119,7 +119,7 @@ const int SIGFPE = 8; const int SIGSEGV = 11; const int SIGPIPE = 13; const int SIGTERM = 15; -#if defined(__mips__) || SANITIZER_FREEBSD || SANITIZER_MAC || SANITIZER_NETBSD +#if defined(__mips__) || SANITIZER_FREEBSD || SANITIZER_APPLE || SANITIZER_NETBSD const int SIGBUS = 10; const int SIGSYS = 12; #else @@ -129,7 +129,7 @@ const int SIGSYS = 31; void *const MAP_FAILED = (void*)-1; #if SANITIZER_NETBSD const int PTHREAD_BARRIER_SERIAL_THREAD = 1234567; -#elif !SANITIZER_MAC +#elif !SANITIZER_APPLE const int PTHREAD_BARRIER_SERIAL_THREAD = -1; #endif const int MAP_FIXED = 0x10; @@ -142,7 +142,7 @@ typedef __sanitizer::u16 mode_t; # define F_TLOCK 2 /* Test and lock a region for exclusive use. */ # define F_TEST 3 /* Test a region for other processes locks. */ -#if SANITIZER_FREEBSD || SANITIZER_MAC || SANITIZER_NETBSD +#if SANITIZER_FREEBSD || SANITIZER_APPLE || SANITIZER_NETBSD const int SA_SIGINFO = 0x40; const int SIG_SETMASK = 3; #elif defined(__mips__) @@ -189,7 +189,7 @@ struct InterceptorContext { // in a single cache line if possible (it's accessed in every interceptor). ALIGNED(64) LibIgnore libignore; __sanitizer_sigaction sigactions[kSigCount]; -#if !SANITIZER_MAC && !SANITIZER_NETBSD +#if !SANITIZER_APPLE && !SANITIZER_NETBSD unsigned finalize_key; #endif @@ -456,7 +456,7 @@ static int setup_at_exit_wrapper(ThreadState *thr, uptr pc, void(*f)(), return res; } -#if !SANITIZER_MAC && !SANITIZER_NETBSD +#if !SANITIZER_APPLE && !SANITIZER_NETBSD static void on_exit_callback_installed_at(int status, void *arg) { ThreadState *thr = cur_thread(); AtExitCtx *ctx = (AtExitCtx*)arg; @@ -548,11 +548,11 @@ static void LongJmp(ThreadState *thr, uptr *env) { // FIXME: put everything below into a common extern "C" block? extern "C" void __tsan_setjmp(uptr sp) { SetJmp(cur_thread_init(), sp); } -#if SANITIZER_MAC +#if SANITIZER_APPLE TSAN_INTERCEPTOR(int, setjmp, void *env); TSAN_INTERCEPTOR(int, _setjmp, void *env); TSAN_INTERCEPTOR(int, sigsetjmp, void *env); -#else // SANITIZER_MAC +#else // SANITIZER_APPLE #if SANITIZER_NETBSD #define setjmp_symname __setjmp14 @@ -614,7 +614,7 @@ DEFINE_REAL(int, sigsetjmp_symname, void *env) #if !SANITIZER_NETBSD DEFINE_REAL(int, __sigsetjmp, void *env) #endif -#endif // SANITIZER_MAC +#endif // SANITIZER_APPLE #if SANITIZER_NETBSD #define longjmp_symname __longjmp14 @@ -653,7 +653,7 @@ TSAN_INTERCEPTOR(void, _longjmp, uptr *env, int val) { } #endif -#if !SANITIZER_MAC +#if !SANITIZER_APPLE TSAN_INTERCEPTOR(void*, malloc, uptr size) { if (in_symbolizer()) return InternalAlloc(size); @@ -811,7 +811,7 @@ TSAN_INTERCEPTOR(void*, memalign, uptr align, uptr sz) { #define TSAN_MAYBE_INTERCEPT_MEMALIGN #endif -#if !SANITIZER_MAC +#if !SANITIZER_APPLE TSAN_INTERCEPTOR(void*, aligned_alloc, uptr align, uptr sz) { if (in_symbolizer()) return InternalAlloc(sz, nullptr, align); @@ -842,7 +842,7 @@ TSAN_INTERCEPTOR(void*, pvalloc, uptr sz) { #define TSAN_MAYBE_INTERCEPT_PVALLOC #endif -#if !SANITIZER_MAC +#if !SANITIZER_APPLE TSAN_INTERCEPTOR(int, posix_memalign, void **memptr, uptr align, uptr sz) { if (in_symbolizer()) { void *p = InternalAlloc(sz, nullptr, align); @@ -914,7 +914,7 @@ static void guard_release(ThreadState *thr, uptr pc, atomic_uint32_t *g, // these interceptors with INTERFACE_ATTRIBUTE. // On OS X, we don't support statically linking, so we just use a regular // interceptor. -#if SANITIZER_MAC +#if SANITIZER_APPLE #define STDCXX_INTERCEPTOR TSAN_INTERCEPTOR #else #define STDCXX_INTERCEPTOR(rettype, name, ...) \ @@ -957,7 +957,7 @@ void PlatformCleanUpThreadState(ThreadState *thr) { } } // namespace __tsan -#if !SANITIZER_MAC && !SANITIZER_NETBSD && !SANITIZER_FREEBSD +#if !SANITIZER_APPLE && !SANITIZER_NETBSD && !SANITIZER_FREEBSD static void thread_finalize(void *v) { uptr iter = (uptr)v; if (iter > 1) { @@ -989,7 +989,7 @@ extern "C" void *__tsan_thread_start_func(void *arg) { ThreadState *thr = cur_thread_init(); // Thread-local state is not initialized yet. ScopedIgnoreInterceptors ignore; -#if !SANITIZER_MAC && !SANITIZER_NETBSD && !SANITIZER_FREEBSD +#if !SANITIZER_APPLE && !SANITIZER_NETBSD && !SANITIZER_FREEBSD ThreadIgnoreBegin(thr, 0); if (pthread_setspecific(interceptor_ctx()->finalize_key, (void *)GetPthreadDestructorIterations())) { @@ -1097,7 +1097,7 @@ TSAN_INTERCEPTOR(int, pthread_detach, void *th) { TSAN_INTERCEPTOR(void, pthread_exit, void *retval) { { SCOPED_INTERCEPTOR_RAW(pthread_exit, retval); -#if !SANITIZER_MAC && !SANITIZER_ANDROID +#if !SANITIZER_APPLE && !SANITIZER_ANDROID CHECK_EQ(thr, &cur_thread_placeholder); #endif } @@ -1266,7 +1266,7 @@ INTERCEPTOR(int, pthread_cond_clockwait, void *c, void *m, #define TSAN_MAYBE_PTHREAD_COND_CLOCKWAIT #endif -#if SANITIZER_MAC +#if SANITIZER_APPLE INTERCEPTOR(int, pthread_cond_timedwait_relative_np, void *c, void *m, void *reltime) { void *cond = init_cond(c); @@ -1343,7 +1343,7 @@ TSAN_INTERCEPTOR(int, pthread_mutex_trylock, void *m) { return res; } -#if !SANITIZER_MAC +#if !SANITIZER_APPLE TSAN_INTERCEPTOR(int, pthread_mutex_timedlock, void *m, void *abstime) { SCOPED_TSAN_INTERCEPTOR(pthread_mutex_timedlock, m, abstime); int res = REAL(pthread_mutex_timedlock)(m, abstime); @@ -1354,7 +1354,7 @@ TSAN_INTERCEPTOR(int, pthread_mutex_timedlock, void *m, void *abstime) { } #endif -#if !SANITIZER_MAC +#if !SANITIZER_APPLE TSAN_INTERCEPTOR(int, pthread_spin_init, void *m, int pshared) { SCOPED_TSAN_INTERCEPTOR(pthread_spin_init, m, pshared); int res = REAL(pthread_spin_init)(m, pshared); @@ -1437,7 +1437,7 @@ TSAN_INTERCEPTOR(int, pthread_rwlock_tryrdlock, void *m) { return res; } -#if !SANITIZER_MAC +#if !SANITIZER_APPLE TSAN_INTERCEPTOR(int, pthread_rwlock_timedrdlock, void *m, void *abstime) { SCOPED_TSAN_INTERCEPTOR(pthread_rwlock_timedrdlock, m, abstime); int res = REAL(pthread_rwlock_timedrdlock)(m, abstime); @@ -1467,7 +1467,7 @@ TSAN_INTERCEPTOR(int, pthread_rwlock_trywrlock, void *m) { return res; } -#if !SANITIZER_MAC +#if !SANITIZER_APPLE TSAN_INTERCEPTOR(int, pthread_rwlock_timedwrlock, void *m, void *abstime) { SCOPED_TSAN_INTERCEPTOR(pthread_rwlock_timedwrlock, m, abstime); int res = REAL(pthread_rwlock_timedwrlock)(m, abstime); @@ -1485,7 +1485,7 @@ TSAN_INTERCEPTOR(int, pthread_rwlock_unlock, void *m) { return res; } -#if !SANITIZER_MAC +#if !SANITIZER_APPLE TSAN_INTERCEPTOR(int, pthread_barrier_init, void *b, void *a, unsigned count) { SCOPED_TSAN_INTERCEPTOR(pthread_barrier_init, b, a, count); MemoryAccess(thr, pc, (uptr)b, 1, kAccessWrite); @@ -1519,7 +1519,7 @@ TSAN_INTERCEPTOR(int, pthread_once, void *o, void (*f)()) { return errno_EINVAL; atomic_uint32_t *a; - if (SANITIZER_MAC) + if (SANITIZER_APPLE) a = static_cast<atomic_uint32_t*>((void *)((char *)o + sizeof(long_t))); else if (SANITIZER_NETBSD) a = static_cast<atomic_uint32_t*> @@ -1529,7 +1529,7 @@ TSAN_INTERCEPTOR(int, pthread_once, void *o, void (*f)()) { // Mac OS X appears to use pthread_once() where calling BlockingRegion hooks // result in crashes due to too little stack space. - if (guard_acquire(thr, pc, a, !SANITIZER_MAC)) { + if (guard_acquire(thr, pc, a, !SANITIZER_APPLE)) { (*f)(); guard_release(thr, pc, a, kGuardDone); } @@ -1549,7 +1549,7 @@ TSAN_INTERCEPTOR(int, __fxstat, int version, int fd, void *buf) { #endif TSAN_INTERCEPTOR(int, fstat, int fd, void *buf) { -#if SANITIZER_FREEBSD || SANITIZER_MAC || SANITIZER_ANDROID || SANITIZER_NETBSD +#if SANITIZER_FREEBSD || SANITIZER_APPLE || SANITIZER_ANDROID || SANITIZER_NETBSD SCOPED_TSAN_INTERCEPTOR(fstat, fd, buf); if (fd > 0) FdAccess(thr, pc, fd); @@ -1656,7 +1656,7 @@ TSAN_INTERCEPTOR(int, dup2, int oldfd, int newfd) { return newfd2; } -#if !SANITIZER_MAC +#if !SANITIZER_APPLE TSAN_INTERCEPTOR(int, dup3, int oldfd, int newfd, int flags) { SCOPED_TSAN_INTERCEPTOR(dup3, oldfd, newfd, flags); int newfd2 = REAL(dup3)(oldfd, newfd, flags); @@ -1805,7 +1805,7 @@ TSAN_INTERCEPTOR(int, pipe, int *pipefd) { return res; } -#if !SANITIZER_MAC +#if !SANITIZER_APPLE TSAN_INTERCEPTOR(int, pipe2, int *pipefd, int flags) { SCOPED_TSAN_INTERCEPTOR(pipe2, pipefd, flags); int res = REAL(pipe2)(pipefd, flags); @@ -2257,7 +2257,7 @@ TSAN_INTERCEPTOR(int, clone, int (*fn)(void *), void *stack, int flags, } #endif -#if !SANITIZER_MAC && !SANITIZER_ANDROID +#if !SANITIZER_APPLE && !SANITIZER_ANDROID typedef int (*dl_iterate_phdr_cb_t)(__sanitizer_dl_phdr_info *info, SIZE_T size, void *data); struct dl_iterate_phdr_data { @@ -2314,7 +2314,7 @@ struct TsanInterceptorContext { const uptr pc; }; -#if !SANITIZER_MAC +#if !SANITIZER_APPLE static void HandleRecvmsg(ThreadState *thr, uptr pc, __sanitizer_msghdr *msg) { int fds[64]; @@ -2454,7 +2454,7 @@ static void HandleRecvmsg(ThreadState *thr, uptr pc, off); \ } while (false) -#if !SANITIZER_MAC +#if !SANITIZER_APPLE #define COMMON_INTERCEPTOR_HANDLE_RECVMSG(ctx, msg) \ HandleRecvmsg(((TsanInterceptorContext *)ctx)->thr, \ ((TsanInterceptorContext *)ctx)->pc, msg) @@ -2515,7 +2515,7 @@ int sigaction_impl(int sig, const __sanitizer_sigaction *act, sigactions[sig].sa_flags = *(volatile int const *)&act->sa_flags; internal_memcpy(&sigactions[sig].sa_mask, &act->sa_mask, sizeof(sigactions[sig].sa_mask)); -#if !SANITIZER_FREEBSD && !SANITIZER_MAC && !SANITIZER_NETBSD +#if !SANITIZER_FREEBSD && !SANITIZER_APPLE && !SANITIZER_NETBSD sigactions[sig].sa_restorer = act->sa_restorer; #endif internal_memcpy(&newact, act, sizeof(newact)); @@ -2562,7 +2562,7 @@ struct ScopedSyscall { } }; -#if !SANITIZER_FREEBSD && !SANITIZER_MAC +#if !SANITIZER_FREEBSD && !SANITIZER_APPLE static void syscall_access_range(uptr pc, uptr p, uptr s, bool write) { TSAN_SYSCALL(); MemoryAccessRange(thr, pc, p, s, write); @@ -2746,7 +2746,7 @@ static void finalize(void *arg) { Die(); } -#if !SANITIZER_MAC && !SANITIZER_ANDROID +#if !SANITIZER_APPLE && !SANITIZER_ANDROID static void unreachable() { Report("FATAL: ThreadSanitizer: unreachable called\n"); Die(); @@ -2757,7 +2757,7 @@ static void unreachable() { SANITIZER_WEAK_ATTRIBUTE void InitializeLibdispatchInterceptors() {} void InitializeInterceptors() { -#if !SANITIZER_MAC +#if !SANITIZER_APPLE // We need to setup it early, because functions like dlsym() can call it. REAL(memset) = internal_memset; REAL(memcpy) = internal_memcpy; @@ -2769,7 +2769,7 @@ void InitializeInterceptors() { InitializeSignalInterceptors(); InitializeLibdispatchInterceptors(); -#if !SANITIZER_MAC +#if !SANITIZER_APPLE // We can not use TSAN_INTERCEPT to get setjmp addr, // because it does &setjmp and setjmp is not present in some versions of libc. using __interception::InterceptFunction; @@ -2922,7 +2922,7 @@ void InitializeInterceptors() { TSAN_MAYBE_INTERCEPT__LWP_EXIT; TSAN_MAYBE_INTERCEPT_THR_EXIT; -#if !SANITIZER_MAC && !SANITIZER_ANDROID +#if !SANITIZER_APPLE && !SANITIZER_ANDROID // Need to setup it, because interceptors check that the function is resolved. // But atexit is emitted directly into the module, so can't be resolved. REAL(atexit) = (int(*)(void(*)()))unreachable; @@ -2937,7 +2937,7 @@ void InitializeInterceptors() { Die(); } -#if !SANITIZER_MAC && !SANITIZER_NETBSD && !SANITIZER_FREEBSD +#if !SANITIZER_APPLE && !SANITIZER_NETBSD && !SANITIZER_FREEBSD if (pthread_key_create(&interceptor_ctx()->finalize_key, &thread_finalize)) { Printf("ThreadSanitizer: failed to create thread key\n"); Die(); diff --git a/contrib/llvm-project/compiler-rt/lib/tsan/rtl-old/tsan_malloc_mac.cpp b/contrib/llvm-project/compiler-rt/lib/tsan/rtl-old/tsan_malloc_mac.cpp index 0e861bf1f962..ac844ae8a44a 100644 --- a/contrib/llvm-project/compiler-rt/lib/tsan/rtl-old/tsan_malloc_mac.cpp +++ b/contrib/llvm-project/compiler-rt/lib/tsan/rtl-old/tsan_malloc_mac.cpp @@ -12,7 +12,7 @@ //===----------------------------------------------------------------------===// #include "sanitizer_common/sanitizer_platform.h" -#if SANITIZER_MAC +#if SANITIZER_APPLE #include "sanitizer_common/sanitizer_errno.h" #include "tsan_interceptors.h" diff --git a/contrib/llvm-project/compiler-rt/lib/tsan/rtl-old/tsan_mman.cpp b/contrib/llvm-project/compiler-rt/lib/tsan/rtl-old/tsan_mman.cpp index 86a3dcd332b2..38b21a0cde98 100644 --- a/contrib/llvm-project/compiler-rt/lib/tsan/rtl-old/tsan_mman.cpp +++ b/contrib/llvm-project/compiler-rt/lib/tsan/rtl-old/tsan_mman.cpp @@ -20,18 +20,6 @@ #include "tsan_report.h" #include "tsan_flags.h" -// May be overriden by front-end. -SANITIZER_WEAK_DEFAULT_IMPL -void __sanitizer_malloc_hook(void *ptr, uptr size) { - (void)ptr; - (void)size; -} - -SANITIZER_WEAK_DEFAULT_IMPL -void __sanitizer_free_hook(void *ptr) { - (void)ptr; -} - namespace __tsan { struct MapUnmapCallback { @@ -356,7 +344,6 @@ void invoke_malloc_hook(void *ptr, uptr size) { ThreadState *thr = cur_thread(); if (ctx == 0 || !ctx->initialized || thr->ignore_interceptors) return; - __sanitizer_malloc_hook(ptr, size); RunMallocHooks(ptr, size); } @@ -364,7 +351,6 @@ void invoke_free_hook(void *ptr) { ThreadState *thr = cur_thread(); if (ctx == 0 || !ctx->initialized || thr->ignore_interceptors) return; - __sanitizer_free_hook(ptr); RunFreeHooks(ptr); } diff --git a/contrib/llvm-project/compiler-rt/lib/tsan/rtl-old/tsan_platform.h b/contrib/llvm-project/compiler-rt/lib/tsan/rtl-old/tsan_platform.h index 7ff0acace8f6..4b4812af7318 100644 --- a/contrib/llvm-project/compiler-rt/lib/tsan/rtl-old/tsan_platform.h +++ b/contrib/llvm-project/compiler-rt/lib/tsan/rtl-old/tsan_platform.h @@ -648,7 +648,7 @@ ALWAYS_INLINE auto SelectMapping(Arg arg) { return Func::template Apply<MappingGo48>(arg); # endif #else // SANITIZER_GO -# if defined(__x86_64__) || SANITIZER_IOSSIM || SANITIZER_MAC && !SANITIZER_IOS +# if defined(__x86_64__) || SANITIZER_IOSSIM || SANITIZER_APPLE && !SANITIZER_IOS return Func::template Apply<Mapping48AddressSpace>(arg); # elif defined(__aarch64__) && defined(__APPLE__) return Func::template Apply<MappingAppleAarch64>(arg); diff --git a/contrib/llvm-project/compiler-rt/lib/tsan/rtl-old/tsan_platform_mac.cpp b/contrib/llvm-project/compiler-rt/lib/tsan/rtl-old/tsan_platform_mac.cpp index 1465f9953c19..e9c0f3b91924 100644 --- a/contrib/llvm-project/compiler-rt/lib/tsan/rtl-old/tsan_platform_mac.cpp +++ b/contrib/llvm-project/compiler-rt/lib/tsan/rtl-old/tsan_platform_mac.cpp @@ -12,7 +12,7 @@ //===----------------------------------------------------------------------===// #include "sanitizer_common/sanitizer_platform.h" -#if SANITIZER_MAC +#if SANITIZER_APPLE #include "sanitizer_common/sanitizer_atomic.h" #include "sanitizer_common/sanitizer_common.h" @@ -323,4 +323,4 @@ int call_pthread_cancel_with_cleanup(int (*fn)(void *arg), } // namespace __tsan -#endif // SANITIZER_MAC +#endif // SANITIZER_APPLE diff --git a/contrib/llvm-project/compiler-rt/lib/tsan/rtl-old/tsan_report.cpp b/contrib/llvm-project/compiler-rt/lib/tsan/rtl-old/tsan_report.cpp index a926c3761ccf..91f4d0cfd355 100644 --- a/contrib/llvm-project/compiler-rt/lib/tsan/rtl-old/tsan_report.cpp +++ b/contrib/llvm-project/compiler-rt/lib/tsan/rtl-old/tsan_report.cpp @@ -98,7 +98,7 @@ static const char *ReportTypeString(ReportType typ, uptr tag) { UNREACHABLE("missing case"); } -#if SANITIZER_MAC +#if SANITIZER_APPLE static const char *const kInterposedFunctionPrefix = "wrap_"; #else static const char *const kInterposedFunctionPrefix = "__interceptor_"; diff --git a/contrib/llvm-project/compiler-rt/lib/tsan/rtl-old/tsan_rtl.cpp b/contrib/llvm-project/compiler-rt/lib/tsan/rtl-old/tsan_rtl.cpp index 5b46d5f5e2bc..5a8d877af724 100644 --- a/contrib/llvm-project/compiler-rt/lib/tsan/rtl-old/tsan_rtl.cpp +++ b/contrib/llvm-project/compiler-rt/lib/tsan/rtl-old/tsan_rtl.cpp @@ -44,7 +44,7 @@ void (*on_initialize)(void); int (*on_finalize)(int); #endif -#if !SANITIZER_GO && !SANITIZER_MAC +#if !SANITIZER_GO && !SANITIZER_APPLE __attribute__((tls_model("initial-exec"))) THREADLOCAL char cur_thread_placeholder[sizeof(ThreadState)] ALIGNED( SANITIZER_CACHE_LINE_SIZE); diff --git a/contrib/llvm-project/compiler-rt/lib/tsan/rtl-old/tsan_rtl.h b/contrib/llvm-project/compiler-rt/lib/tsan/rtl-old/tsan_rtl.h index c71b27e1cbf5..8958f9dd5541 100644 --- a/contrib/llvm-project/compiler-rt/lib/tsan/rtl-old/tsan_rtl.h +++ b/contrib/llvm-project/compiler-rt/lib/tsan/rtl-old/tsan_rtl.h @@ -222,7 +222,7 @@ struct ThreadState { } ALIGNED(SANITIZER_CACHE_LINE_SIZE); #if !SANITIZER_GO -#if SANITIZER_MAC || SANITIZER_ANDROID +#if SANITIZER_APPLE || SANITIZER_ANDROID ThreadState *cur_thread(); void set_cur_thread(ThreadState *thr); void cur_thread_finalize(); @@ -243,7 +243,7 @@ inline void set_cur_thread(ThreadState *thr) { reinterpret_cast<ThreadState *>(cur_thread_placeholder)->current = thr; } inline void cur_thread_finalize() { } -# endif // SANITIZER_MAC || SANITIZER_ANDROID +# endif // SANITIZER_APPLE || SANITIZER_ANDROID #endif // SANITIZER_GO class ThreadContext final : public ThreadContextBase { @@ -586,7 +586,7 @@ void AcquireReleaseImpl(ThreadState *thr, uptr pc, SyncClock *c); // The trick is that the call preserves all registers and the compiler // does not treat it as a call. // If it does not work for you, use normal call. -#if !SANITIZER_DEBUG && defined(__x86_64__) && !SANITIZER_MAC +#if !SANITIZER_DEBUG && defined(__x86_64__) && !SANITIZER_APPLE // The caller may not create the stack frame for itself at all, // so we create a reserve stack frame for it (1024b must be enough). #define HACKY_CALL(f) \ diff --git a/contrib/llvm-project/compiler-rt/lib/tsan/rtl-old/tsan_shadow.h b/contrib/llvm-project/compiler-rt/lib/tsan/rtl-old/tsan_shadow.h index 8b7bc341713e..566584fd3203 100644 --- a/contrib/llvm-project/compiler-rt/lib/tsan/rtl-old/tsan_shadow.h +++ b/contrib/llvm-project/compiler-rt/lib/tsan/rtl-old/tsan_shadow.h @@ -94,6 +94,7 @@ class FastState { // Shadow (from most significant bit): // freed : 1 // tid : kTidBits +// unused : 1 // is_atomic : 1 // is_read : 1 // size_log : 2 diff --git a/contrib/llvm-project/compiler-rt/lib/tsan/rtl/tsan_defs.h b/contrib/llvm-project/compiler-rt/lib/tsan/rtl/tsan_defs.h index 2e13e0e5486b..1ffa3d6aec40 100644 --- a/contrib/llvm-project/compiler-rt/lib/tsan/rtl/tsan_defs.h +++ b/contrib/llvm-project/compiler-rt/lib/tsan/rtl/tsan_defs.h @@ -176,6 +176,7 @@ enum : AccessType { kAccessExternalPC = 1 << 4, // access PC can have kExternalPCBit set kAccessCheckOnly = 1 << 5, // check for races, but don't store kAccessNoRodata = 1 << 6, // don't check for .rodata marker + kAccessSlotLocked = 1 << 7, // memory access with TidSlot locked }; // Descriptor of user's memory block. diff --git a/contrib/llvm-project/compiler-rt/lib/tsan/rtl/tsan_dispatch_defs.h b/contrib/llvm-project/compiler-rt/lib/tsan/rtl/tsan_dispatch_defs.h index 94e0b50fed36..54c0b0ba4b40 100644 --- a/contrib/llvm-project/compiler-rt/lib/tsan/rtl/tsan_dispatch_defs.h +++ b/contrib/llvm-project/compiler-rt/lib/tsan/rtl/tsan_dispatch_defs.h @@ -56,7 +56,7 @@ extern const dispatch_block_t _dispatch_data_destructor_munmap; # define DISPATCH_NOESCAPE #endif -#if SANITIZER_MAC +#if SANITIZER_APPLE # define SANITIZER_WEAK_IMPORT extern "C" __attribute((weak_import)) #else # define SANITIZER_WEAK_IMPORT extern "C" __attribute((weak)) diff --git a/contrib/llvm-project/compiler-rt/lib/tsan/rtl/tsan_fd.cpp b/contrib/llvm-project/compiler-rt/lib/tsan/rtl/tsan_fd.cpp index 9a6400c2e9f9..cf8f491fdbf0 100644 --- a/contrib/llvm-project/compiler-rt/lib/tsan/rtl/tsan_fd.cpp +++ b/contrib/llvm-project/compiler-rt/lib/tsan/rtl/tsan_fd.cpp @@ -29,6 +29,9 @@ struct FdSync { struct FdDesc { FdSync *sync; + // This is used to establish write -> epoll_wait synchronization + // where epoll_wait receives notification about the write. + atomic_uintptr_t aux_sync; // FdSync* Tid creation_tid; StackID creation_stack; }; @@ -103,6 +106,10 @@ static void init(ThreadState *thr, uptr pc, int fd, FdSync *s, unref(thr, pc, d->sync); d->sync = 0; } + unref(thr, pc, + reinterpret_cast<FdSync *>( + atomic_load(&d->aux_sync, memory_order_relaxed))); + atomic_store(&d->aux_sync, 0, memory_order_relaxed); if (flags()->io_sync == 0) { unref(thr, pc, s); } else if (flags()->io_sync == 1) { @@ -113,12 +120,17 @@ static void init(ThreadState *thr, uptr pc, int fd, FdSync *s, } d->creation_tid = thr->tid; d->creation_stack = CurrentStackId(thr, pc); + // This prevents false positives on fd_close_norace3.cpp test. + // The mechanics of the false positive are not completely clear, + // but it happens only if global reset is enabled (flush_memory_ms=1) + // and may be related to lost writes during asynchronous MADV_DONTNEED. + SlotLocker locker(thr); if (write) { // To catch races between fd usage and open. MemoryRangeImitateWrite(thr, pc, (uptr)d, 8); } else { // See the dup-related comment in FdClose. - MemoryAccess(thr, pc, (uptr)d, 8, kAccessRead); + MemoryAccess(thr, pc, (uptr)d, 8, kAccessRead | kAccessSlotLocked); } } @@ -180,6 +192,8 @@ void FdRelease(ThreadState *thr, uptr pc, int fd) { MemoryAccess(thr, pc, (uptr)d, 8, kAccessRead); if (s) Release(thr, pc, (uptr)s); + if (uptr aux_sync = atomic_load(&d->aux_sync, memory_order_acquire)) + Release(thr, pc, aux_sync); } void FdAccess(ThreadState *thr, uptr pc, int fd) { @@ -195,27 +209,39 @@ void FdClose(ThreadState *thr, uptr pc, int fd, bool write) { if (bogusfd(fd)) return; FdDesc *d = fddesc(thr, pc, fd); - if (!MustIgnoreInterceptor(thr)) { - if (write) { - // To catch races between fd usage and close. - MemoryAccess(thr, pc, (uptr)d, 8, kAccessWrite); - } else { - // This path is used only by dup2/dup3 calls. - // We do read instead of write because there is a number of legitimate - // cases where write would lead to false positives: - // 1. Some software dups a closed pipe in place of a socket before closing - // the socket (to prevent races actually). - // 2. Some daemons dup /dev/null in place of stdin/stdout. - // On the other hand we have not seen cases when write here catches real - // bugs. - MemoryAccess(thr, pc, (uptr)d, 8, kAccessRead); + { + // Need to lock the slot to make MemoryAccess and MemoryResetRange atomic + // with respect to global reset. See the comment in MemoryRangeFreed. + SlotLocker locker(thr); + if (!MustIgnoreInterceptor(thr)) { + if (write) { + // To catch races between fd usage and close. + MemoryAccess(thr, pc, (uptr)d, 8, + kAccessWrite | kAccessCheckOnly | kAccessSlotLocked); + } else { + // This path is used only by dup2/dup3 calls. + // We do read instead of write because there is a number of legitimate + // cases where write would lead to false positives: + // 1. Some software dups a closed pipe in place of a socket before + // closing + // the socket (to prevent races actually). + // 2. Some daemons dup /dev/null in place of stdin/stdout. + // On the other hand we have not seen cases when write here catches real + // bugs. + MemoryAccess(thr, pc, (uptr)d, 8, + kAccessRead | kAccessCheckOnly | kAccessSlotLocked); + } } + // We need to clear it, because if we do not intercept any call out there + // that creates fd, we will hit false postives. + MemoryResetRange(thr, pc, (uptr)d, 8); } - // We need to clear it, because if we do not intercept any call out there - // that creates fd, we will hit false postives. - MemoryResetRange(thr, pc, (uptr)d, 8); unref(thr, pc, d->sync); d->sync = 0; + unref(thr, pc, + reinterpret_cast<FdSync *>( + atomic_load(&d->aux_sync, memory_order_relaxed))); + atomic_store(&d->aux_sync, 0, memory_order_relaxed); d->creation_tid = kInvalidTid; d->creation_stack = kInvalidStackID; } @@ -274,6 +300,30 @@ void FdPollCreate(ThreadState *thr, uptr pc, int fd) { init(thr, pc, fd, allocsync(thr, pc)); } +void FdPollAdd(ThreadState *thr, uptr pc, int epfd, int fd) { + DPrintf("#%d: FdPollAdd(%d, %d)\n", thr->tid, epfd, fd); + if (bogusfd(epfd) || bogusfd(fd)) + return; + FdDesc *d = fddesc(thr, pc, fd); + // Associate fd with epoll fd only once. + // While an fd can be associated with multiple epolls at the same time, + // or with different epolls during different phases of lifetime, + // synchronization semantics (and examples) of this are unclear. + // So we don't support this for now. + // If we change the association, it will also create lifetime management + // problem for FdRelease which accesses the aux_sync. + if (atomic_load(&d->aux_sync, memory_order_relaxed)) + return; + FdDesc *epd = fddesc(thr, pc, epfd); + FdSync *s = epd->sync; + if (!s) + return; + uptr cmp = 0; + if (atomic_compare_exchange_strong( + &d->aux_sync, &cmp, reinterpret_cast<uptr>(s), memory_order_release)) + ref(s); +} + void FdSocketCreate(ThreadState *thr, uptr pc, int fd) { DPrintf("#%d: FdSocketCreate(%d)\n", thr->tid, fd); if (bogusfd(fd)) diff --git a/contrib/llvm-project/compiler-rt/lib/tsan/rtl/tsan_fd.h b/contrib/llvm-project/compiler-rt/lib/tsan/rtl/tsan_fd.h index d9648178481c..92625dc4b4a1 100644 --- a/contrib/llvm-project/compiler-rt/lib/tsan/rtl/tsan_fd.h +++ b/contrib/llvm-project/compiler-rt/lib/tsan/rtl/tsan_fd.h @@ -49,6 +49,7 @@ void FdEventCreate(ThreadState *thr, uptr pc, int fd); void FdSignalCreate(ThreadState *thr, uptr pc, int fd); void FdInotifyCreate(ThreadState *thr, uptr pc, int fd); void FdPollCreate(ThreadState *thr, uptr pc, int fd); +void FdPollAdd(ThreadState *thr, uptr pc, int epfd, int fd); void FdSocketCreate(ThreadState *thr, uptr pc, int fd); void FdSocketAccept(ThreadState *thr, uptr pc, int fd, int newfd); void FdSocketConnecting(ThreadState *thr, uptr pc, int fd); diff --git a/contrib/llvm-project/compiler-rt/lib/tsan/rtl/tsan_flags.cpp b/contrib/llvm-project/compiler-rt/lib/tsan/rtl/tsan_flags.cpp index 54bed9f9a6be..ee78f25cc65c 100644 --- a/contrib/llvm-project/compiler-rt/lib/tsan/rtl/tsan_flags.cpp +++ b/contrib/llvm-project/compiler-rt/lib/tsan/rtl/tsan_flags.cpp @@ -97,7 +97,7 @@ void InitializeFlags(Flags *f, const char *env, const char *env_option_name) { ubsan_parser.ParseStringFromEnv("UBSAN_OPTIONS"); #endif - // Sanity check. + // Check flags. if (!f->report_bugs) { f->report_thread_leaks = false; f->report_destroy_locked = false; diff --git a/contrib/llvm-project/compiler-rt/lib/tsan/rtl/tsan_flags.inc b/contrib/llvm-project/compiler-rt/lib/tsan/rtl/tsan_flags.inc index b1691452d022..c6a5fb8bc984 100644 --- a/contrib/llvm-project/compiler-rt/lib/tsan/rtl/tsan_flags.inc +++ b/contrib/llvm-project/compiler-rt/lib/tsan/rtl/tsan_flags.inc @@ -74,10 +74,13 @@ TSAN_FLAG(int, io_sync, 1, TSAN_FLAG(bool, die_after_fork, true, "Die after multi-threaded fork if the child creates new threads.") TSAN_FLAG(const char *, suppressions, "", "Suppressions file name.") -TSAN_FLAG(bool, ignore_interceptors_accesses, SANITIZER_MAC ? true : false, +TSAN_FLAG(bool, ignore_interceptors_accesses, SANITIZER_APPLE ? true : false, "Ignore reads and writes from all interceptors.") -TSAN_FLAG(bool, ignore_noninstrumented_modules, SANITIZER_MAC ? true : false, +TSAN_FLAG(bool, ignore_noninstrumented_modules, SANITIZER_APPLE ? true : false, "Interceptors should only detect races when called from instrumented " "modules.") TSAN_FLAG(bool, shared_ptr_interceptor, true, "Track atomic reference counting in libc++ shared_ptr and weak_ptr.") +TSAN_FLAG(bool, print_full_thread_history, false, + "If set, prints thread creation stacks for the threads involved in " + "the report and their ancestors up to the main thread.") diff --git a/contrib/llvm-project/compiler-rt/lib/tsan/rtl/tsan_interceptors_libdispatch.cpp b/contrib/llvm-project/compiler-rt/lib/tsan/rtl/tsan_interceptors_libdispatch.cpp index cbbb7ecb2397..88d5f0a48119 100644 --- a/contrib/llvm-project/compiler-rt/lib/tsan/rtl/tsan_interceptors_libdispatch.cpp +++ b/contrib/llvm-project/compiler-rt/lib/tsan/rtl/tsan_interceptors_libdispatch.cpp @@ -19,7 +19,7 @@ #include "BlocksRuntime/Block.h" #include "tsan_dispatch_defs.h" -#if SANITIZER_MAC +#if SANITIZER_APPLE # include <Availability.h> #endif @@ -225,7 +225,7 @@ DISPATCH_INTERCEPT(dispatch_barrier, true) // dispatch_async_and_wait() and friends were introduced in macOS 10.14. // Linking of these interceptors fails when using an older SDK. -#if !SANITIZER_MAC || defined(__MAC_10_14) +#if !SANITIZER_APPLE || defined(__MAC_10_14) // macOS 10.14 is greater than our minimal deployment target. To ensure we // generate a weak reference so the TSan dylib continues to work on older // systems, we need to forward declare the intercepted functions as "weak diff --git a/contrib/llvm-project/compiler-rt/lib/tsan/rtl/tsan_interceptors_mac.cpp b/contrib/llvm-project/compiler-rt/lib/tsan/rtl/tsan_interceptors_mac.cpp index ed064150d005..1ee47bcd1237 100644 --- a/contrib/llvm-project/compiler-rt/lib/tsan/rtl/tsan_interceptors_mac.cpp +++ b/contrib/llvm-project/compiler-rt/lib/tsan/rtl/tsan_interceptors_mac.cpp @@ -12,7 +12,7 @@ //===----------------------------------------------------------------------===// #include "sanitizer_common/sanitizer_platform.h" -#if SANITIZER_MAC +#if SANITIZER_APPLE #include "interception/interception.h" #include "tsan_interceptors.h" @@ -518,4 +518,4 @@ STDCXX_INTERCEPTOR(void, _ZNSt3__111__call_onceERVmPvPFvS2_E, void *flag, } // namespace __tsan -#endif // SANITIZER_MAC +#endif // SANITIZER_APPLE diff --git a/contrib/llvm-project/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp b/contrib/llvm-project/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp index ea99c3843075..17f6b1f472d8 100644 --- a/contrib/llvm-project/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp +++ b/contrib/llvm-project/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp @@ -35,7 +35,7 @@ using namespace __tsan; -#if SANITIZER_FREEBSD || SANITIZER_MAC +#if SANITIZER_FREEBSD || SANITIZER_APPLE #define stdout __stdoutp #define stderr __stderrp #endif @@ -102,14 +102,14 @@ extern __sanitizer_FILE __sF[]; #else extern __sanitizer_FILE *stdout, *stderr; #endif -#if !SANITIZER_FREEBSD && !SANITIZER_MAC && !SANITIZER_NETBSD +#if !SANITIZER_FREEBSD && !SANITIZER_APPLE && !SANITIZER_NETBSD const int PTHREAD_MUTEX_RECURSIVE = 1; const int PTHREAD_MUTEX_RECURSIVE_NP = 1; #else const int PTHREAD_MUTEX_RECURSIVE = 2; const int PTHREAD_MUTEX_RECURSIVE_NP = 2; #endif -#if !SANITIZER_FREEBSD && !SANITIZER_MAC && !SANITIZER_NETBSD +#if !SANITIZER_FREEBSD && !SANITIZER_APPLE && !SANITIZER_NETBSD const int EPOLL_CTL_ADD = 1; #endif const int SIGILL = 4; @@ -119,7 +119,7 @@ const int SIGFPE = 8; const int SIGSEGV = 11; const int SIGPIPE = 13; const int SIGTERM = 15; -#if defined(__mips__) || SANITIZER_FREEBSD || SANITIZER_MAC || SANITIZER_NETBSD +#if defined(__mips__) || SANITIZER_FREEBSD || SANITIZER_APPLE || SANITIZER_NETBSD const int SIGBUS = 10; const int SIGSYS = 12; #else @@ -129,7 +129,7 @@ const int SIGSYS = 31; void *const MAP_FAILED = (void*)-1; #if SANITIZER_NETBSD const int PTHREAD_BARRIER_SERIAL_THREAD = 1234567; -#elif !SANITIZER_MAC +#elif !SANITIZER_APPLE const int PTHREAD_BARRIER_SERIAL_THREAD = -1; #endif const int MAP_FIXED = 0x10; @@ -142,7 +142,7 @@ typedef __sanitizer::u16 mode_t; # define F_TLOCK 2 /* Test and lock a region for exclusive use. */ # define F_TEST 3 /* Test a region for other processes locks. */ -#if SANITIZER_FREEBSD || SANITIZER_MAC || SANITIZER_NETBSD +#if SANITIZER_FREEBSD || SANITIZER_APPLE || SANITIZER_NETBSD const int SA_SIGINFO = 0x40; const int SIG_SETMASK = 3; #elif defined(__mips__) @@ -189,7 +189,7 @@ struct InterceptorContext { // in a single cache line if possible (it's accessed in every interceptor). ALIGNED(64) LibIgnore libignore; __sanitizer_sigaction sigactions[kSigCount]; -#if !SANITIZER_MAC && !SANITIZER_NETBSD +#if !SANITIZER_APPLE && !SANITIZER_NETBSD unsigned finalize_key; #endif @@ -461,7 +461,7 @@ static int setup_at_exit_wrapper(ThreadState *thr, uptr pc, void(*f)(), return res; } -#if !SANITIZER_MAC && !SANITIZER_NETBSD +#if !SANITIZER_APPLE && !SANITIZER_NETBSD static void on_exit_callback_installed_at(int status, void *arg) { ThreadState *thr = cur_thread(); AtExitCtx *ctx = (AtExitCtx*)arg; @@ -553,11 +553,11 @@ static void LongJmp(ThreadState *thr, uptr *env) { // FIXME: put everything below into a common extern "C" block? extern "C" void __tsan_setjmp(uptr sp) { SetJmp(cur_thread_init(), sp); } -#if SANITIZER_MAC +#if SANITIZER_APPLE TSAN_INTERCEPTOR(int, setjmp, void *env); TSAN_INTERCEPTOR(int, _setjmp, void *env); TSAN_INTERCEPTOR(int, sigsetjmp, void *env); -#else // SANITIZER_MAC +#else // SANITIZER_APPLE #if SANITIZER_NETBSD #define setjmp_symname __setjmp14 @@ -619,7 +619,7 @@ DEFINE_REAL(int, sigsetjmp_symname, void *env) #if !SANITIZER_NETBSD DEFINE_REAL(int, __sigsetjmp, void *env) #endif -#endif // SANITIZER_MAC +#endif // SANITIZER_APPLE #if SANITIZER_NETBSD #define longjmp_symname __longjmp14 @@ -658,7 +658,7 @@ TSAN_INTERCEPTOR(void, _longjmp, uptr *env, int val) { } #endif -#if !SANITIZER_MAC +#if !SANITIZER_APPLE TSAN_INTERCEPTOR(void*, malloc, uptr size) { if (in_symbolizer()) return InternalAlloc(size); @@ -816,7 +816,7 @@ TSAN_INTERCEPTOR(void*, memalign, uptr align, uptr sz) { #define TSAN_MAYBE_INTERCEPT_MEMALIGN #endif -#if !SANITIZER_MAC +#if !SANITIZER_APPLE TSAN_INTERCEPTOR(void*, aligned_alloc, uptr align, uptr sz) { if (in_symbolizer()) return InternalAlloc(sz, nullptr, align); @@ -847,7 +847,7 @@ TSAN_INTERCEPTOR(void*, pvalloc, uptr sz) { #define TSAN_MAYBE_INTERCEPT_PVALLOC #endif -#if !SANITIZER_MAC +#if !SANITIZER_APPLE TSAN_INTERCEPTOR(int, posix_memalign, void **memptr, uptr align, uptr sz) { if (in_symbolizer()) { void *p = InternalAlloc(sz, nullptr, align); @@ -919,7 +919,7 @@ static void guard_release(ThreadState *thr, uptr pc, atomic_uint32_t *g, // these interceptors with INTERFACE_ATTRIBUTE. // On OS X, we don't support statically linking, so we just use a regular // interceptor. -#if SANITIZER_MAC +#if SANITIZER_APPLE #define STDCXX_INTERCEPTOR TSAN_INTERCEPTOR #else #define STDCXX_INTERCEPTOR(rettype, name, ...) \ @@ -962,7 +962,7 @@ void PlatformCleanUpThreadState(ThreadState *thr) { } } // namespace __tsan -#if !SANITIZER_MAC && !SANITIZER_NETBSD && !SANITIZER_FREEBSD +#if !SANITIZER_APPLE && !SANITIZER_NETBSD && !SANITIZER_FREEBSD static void thread_finalize(void *v) { uptr iter = (uptr)v; if (iter > 1) { @@ -994,7 +994,7 @@ extern "C" void *__tsan_thread_start_func(void *arg) { ThreadState *thr = cur_thread_init(); // Thread-local state is not initialized yet. ScopedIgnoreInterceptors ignore; -#if !SANITIZER_MAC && !SANITIZER_NETBSD && !SANITIZER_FREEBSD +#if !SANITIZER_APPLE && !SANITIZER_NETBSD && !SANITIZER_FREEBSD ThreadIgnoreBegin(thr, 0); if (pthread_setspecific(interceptor_ctx()->finalize_key, (void *)GetPthreadDestructorIterations())) { @@ -1102,7 +1102,7 @@ TSAN_INTERCEPTOR(int, pthread_detach, void *th) { TSAN_INTERCEPTOR(void, pthread_exit, void *retval) { { SCOPED_INTERCEPTOR_RAW(pthread_exit, retval); -#if !SANITIZER_MAC && !SANITIZER_ANDROID +#if !SANITIZER_APPLE && !SANITIZER_ANDROID CHECK_EQ(thr, &cur_thread_placeholder); #endif } @@ -1271,7 +1271,7 @@ INTERCEPTOR(int, pthread_cond_clockwait, void *c, void *m, #define TSAN_MAYBE_PTHREAD_COND_CLOCKWAIT #endif -#if SANITIZER_MAC +#if SANITIZER_APPLE INTERCEPTOR(int, pthread_cond_timedwait_relative_np, void *c, void *m, void *reltime) { void *cond = init_cond(c); @@ -1348,7 +1348,7 @@ TSAN_INTERCEPTOR(int, pthread_mutex_trylock, void *m) { return res; } -#if !SANITIZER_MAC +#if !SANITIZER_APPLE TSAN_INTERCEPTOR(int, pthread_mutex_timedlock, void *m, void *abstime) { SCOPED_TSAN_INTERCEPTOR(pthread_mutex_timedlock, m, abstime); int res = REAL(pthread_mutex_timedlock)(m, abstime); @@ -1359,7 +1359,7 @@ TSAN_INTERCEPTOR(int, pthread_mutex_timedlock, void *m, void *abstime) { } #endif -#if !SANITIZER_MAC +#if !SANITIZER_APPLE TSAN_INTERCEPTOR(int, pthread_spin_init, void *m, int pshared) { SCOPED_TSAN_INTERCEPTOR(pthread_spin_init, m, pshared); int res = REAL(pthread_spin_init)(m, pshared); @@ -1442,7 +1442,7 @@ TSAN_INTERCEPTOR(int, pthread_rwlock_tryrdlock, void *m) { return res; } -#if !SANITIZER_MAC +#if !SANITIZER_APPLE TSAN_INTERCEPTOR(int, pthread_rwlock_timedrdlock, void *m, void *abstime) { SCOPED_TSAN_INTERCEPTOR(pthread_rwlock_timedrdlock, m, abstime); int res = REAL(pthread_rwlock_timedrdlock)(m, abstime); @@ -1472,7 +1472,7 @@ TSAN_INTERCEPTOR(int, pthread_rwlock_trywrlock, void *m) { return res; } -#if !SANITIZER_MAC +#if !SANITIZER_APPLE TSAN_INTERCEPTOR(int, pthread_rwlock_timedwrlock, void *m, void *abstime) { SCOPED_TSAN_INTERCEPTOR(pthread_rwlock_timedwrlock, m, abstime); int res = REAL(pthread_rwlock_timedwrlock)(m, abstime); @@ -1490,7 +1490,7 @@ TSAN_INTERCEPTOR(int, pthread_rwlock_unlock, void *m) { return res; } -#if !SANITIZER_MAC +#if !SANITIZER_APPLE TSAN_INTERCEPTOR(int, pthread_barrier_init, void *b, void *a, unsigned count) { SCOPED_TSAN_INTERCEPTOR(pthread_barrier_init, b, a, count); MemoryAccess(thr, pc, (uptr)b, 1, kAccessWrite); @@ -1524,7 +1524,7 @@ TSAN_INTERCEPTOR(int, pthread_once, void *o, void (*f)()) { return errno_EINVAL; atomic_uint32_t *a; - if (SANITIZER_MAC) + if (SANITIZER_APPLE) a = static_cast<atomic_uint32_t*>((void *)((char *)o + sizeof(long_t))); else if (SANITIZER_NETBSD) a = static_cast<atomic_uint32_t*> @@ -1534,7 +1534,7 @@ TSAN_INTERCEPTOR(int, pthread_once, void *o, void (*f)()) { // Mac OS X appears to use pthread_once() where calling BlockingRegion hooks // result in crashes due to too little stack space. - if (guard_acquire(thr, pc, a, !SANITIZER_MAC)) { + if (guard_acquire(thr, pc, a, !SANITIZER_APPLE)) { (*f)(); guard_release(thr, pc, a, kGuardDone); } @@ -1661,7 +1661,7 @@ TSAN_INTERCEPTOR(int, dup2, int oldfd, int newfd) { return newfd2; } -#if !SANITIZER_MAC +#if !SANITIZER_APPLE TSAN_INTERCEPTOR(int, dup3, int oldfd, int newfd, int flags) { SCOPED_TSAN_INTERCEPTOR(dup3, oldfd, newfd, flags); int newfd2 = REAL(dup3)(oldfd, newfd, flags); @@ -1767,7 +1767,8 @@ TSAN_INTERCEPTOR(int, listen, int fd, int backlog) { TSAN_INTERCEPTOR(int, close, int fd) { SCOPED_INTERCEPTOR_RAW(close, fd); - FdClose(thr, pc, fd); + if (!in_symbolizer()) + FdClose(thr, pc, fd); return REAL(close)(fd); } @@ -1804,7 +1805,7 @@ TSAN_INTERCEPTOR(int, pipe, int *pipefd) { return res; } -#if !SANITIZER_MAC +#if !SANITIZER_APPLE TSAN_INTERCEPTOR(int, pipe2, int *pipefd, int flags) { SCOPED_TSAN_INTERCEPTOR(pipe2, pipefd, flags); int res = REAL(pipe2)(pipefd, flags); @@ -1900,8 +1901,10 @@ TSAN_INTERCEPTOR(int, epoll_ctl, int epfd, int op, int fd, void *ev) { FdAccess(thr, pc, epfd); if (epfd >= 0 && fd >= 0) FdAccess(thr, pc, fd); - if (op == EPOLL_CTL_ADD && epfd >= 0) + if (op == EPOLL_CTL_ADD && epfd >= 0) { + FdPollAdd(thr, pc, epfd, fd); FdRelease(thr, pc, epfd); + } int res = REAL(epoll_ctl)(epfd, op, fd, ev); return res; } @@ -1964,13 +1967,14 @@ TSAN_INTERCEPTOR(int, pthread_sigmask, int how, const __sanitizer_sigset_t *set, namespace __tsan { -static void ReportErrnoSpoiling(ThreadState *thr, uptr pc) { +static void ReportErrnoSpoiling(ThreadState *thr, uptr pc, int sig) { VarSizeStackTrace stack; // StackTrace::GetNestInstructionPc(pc) is used because return address is // expected, OutputReport() will undo this. ObtainCurrentStack(thr, StackTrace::GetNextInstructionPc(pc), &stack); ThreadRegistryLock l(&ctx->thread_registry); ScopedReport rep(ReportTypeErrnoInSignal); + rep.SetSigNum(sig); if (!IsFiredSuppression(ctx, ReportTypeErrnoInSignal, stack)) { rep.AddStack(stack, true); OutputReport(thr, rep); @@ -2037,7 +2041,7 @@ static void CallUserSignalHandler(ThreadState *thr, bool sync, bool acquire, // signal; and it looks too fragile to intercept all ways to reraise a signal. if (ShouldReport(thr, ReportTypeErrnoInSignal) && !sync && sig != SIGTERM && errno != 99) - ReportErrnoSpoiling(thr, pc); + ReportErrnoSpoiling(thr, pc, sig); errno = saved_errno; } @@ -2259,7 +2263,7 @@ TSAN_INTERCEPTOR(int, clone, int (*fn)(void *), void *stack, int flags, } #endif -#if !SANITIZER_MAC && !SANITIZER_ANDROID +#if !SANITIZER_APPLE && !SANITIZER_ANDROID typedef int (*dl_iterate_phdr_cb_t)(__sanitizer_dl_phdr_info *info, SIZE_T size, void *data); struct dl_iterate_phdr_data { @@ -2316,7 +2320,7 @@ struct TsanInterceptorContext { const uptr pc; }; -#if !SANITIZER_MAC +#if !SANITIZER_APPLE static void HandleRecvmsg(ThreadState *thr, uptr pc, __sanitizer_msghdr *msg) { int fds[64]; @@ -2456,7 +2460,7 @@ static void HandleRecvmsg(ThreadState *thr, uptr pc, off); \ } while (false) -#if !SANITIZER_MAC +#if !SANITIZER_APPLE #define COMMON_INTERCEPTOR_HANDLE_RECVMSG(ctx, msg) \ HandleRecvmsg(((TsanInterceptorContext *)ctx)->thr, \ ((TsanInterceptorContext *)ctx)->pc, msg) @@ -2517,7 +2521,7 @@ int sigaction_impl(int sig, const __sanitizer_sigaction *act, sigactions[sig].sa_flags = *(volatile int const *)&act->sa_flags; internal_memcpy(&sigactions[sig].sa_mask, &act->sa_mask, sizeof(sigactions[sig].sa_mask)); -#if !SANITIZER_FREEBSD && !SANITIZER_MAC && !SANITIZER_NETBSD +#if !SANITIZER_FREEBSD && !SANITIZER_APPLE && !SANITIZER_NETBSD sigactions[sig].sa_restorer = act->sa_restorer; #endif internal_memcpy(&newact, act, sizeof(newact)); @@ -2564,7 +2568,7 @@ struct ScopedSyscall { } }; -#if !SANITIZER_FREEBSD && !SANITIZER_MAC +#if !SANITIZER_FREEBSD && !SANITIZER_APPLE static void syscall_access_range(uptr pc, uptr p, uptr s, bool write) { TSAN_SYSCALL(); MemoryAccessRange(thr, pc, p, s, write); @@ -2768,7 +2772,7 @@ static void finalize(void *arg) { Die(); } -#if !SANITIZER_MAC && !SANITIZER_ANDROID +#if !SANITIZER_APPLE && !SANITIZER_ANDROID static void unreachable() { Report("FATAL: ThreadSanitizer: unreachable called\n"); Die(); @@ -2779,7 +2783,7 @@ static void unreachable() { SANITIZER_WEAK_ATTRIBUTE void InitializeLibdispatchInterceptors() {} void InitializeInterceptors() { -#if !SANITIZER_MAC +#if !SANITIZER_APPLE // We need to setup it early, because functions like dlsym() can call it. REAL(memset) = internal_memset; REAL(memcpy) = internal_memcpy; @@ -2791,7 +2795,7 @@ void InitializeInterceptors() { InitializeSignalInterceptors(); InitializeLibdispatchInterceptors(); -#if !SANITIZER_MAC +#if !SANITIZER_APPLE // We can not use TSAN_INTERCEPT to get setjmp addr, // because it does &setjmp and setjmp is not present in some versions of libc. using __interception::InterceptFunction; @@ -2944,7 +2948,7 @@ void InitializeInterceptors() { TSAN_MAYBE_INTERCEPT__LWP_EXIT; TSAN_MAYBE_INTERCEPT_THR_EXIT; -#if !SANITIZER_MAC && !SANITIZER_ANDROID +#if !SANITIZER_APPLE && !SANITIZER_ANDROID // Need to setup it, because interceptors check that the function is resolved. // But atexit is emitted directly into the module, so can't be resolved. REAL(atexit) = (int(*)(void(*)()))unreachable; @@ -2959,7 +2963,7 @@ void InitializeInterceptors() { Die(); } -#if !SANITIZER_MAC && !SANITIZER_NETBSD && !SANITIZER_FREEBSD +#if !SANITIZER_APPLE && !SANITIZER_NETBSD && !SANITIZER_FREEBSD if (pthread_key_create(&interceptor_ctx()->finalize_key, &thread_finalize)) { Printf("ThreadSanitizer: failed to create thread key\n"); Die(); diff --git a/contrib/llvm-project/compiler-rt/lib/tsan/rtl/tsan_malloc_mac.cpp b/contrib/llvm-project/compiler-rt/lib/tsan/rtl/tsan_malloc_mac.cpp index 0e861bf1f962..ac844ae8a44a 100644 --- a/contrib/llvm-project/compiler-rt/lib/tsan/rtl/tsan_malloc_mac.cpp +++ b/contrib/llvm-project/compiler-rt/lib/tsan/rtl/tsan_malloc_mac.cpp @@ -12,7 +12,7 @@ //===----------------------------------------------------------------------===// #include "sanitizer_common/sanitizer_platform.h" -#if SANITIZER_MAC +#if SANITIZER_APPLE #include "sanitizer_common/sanitizer_errno.h" #include "tsan_interceptors.h" diff --git a/contrib/llvm-project/compiler-rt/lib/tsan/rtl/tsan_mman.cpp b/contrib/llvm-project/compiler-rt/lib/tsan/rtl/tsan_mman.cpp index 00cc3a306fd3..0937e521193f 100644 --- a/contrib/llvm-project/compiler-rt/lib/tsan/rtl/tsan_mman.cpp +++ b/contrib/llvm-project/compiler-rt/lib/tsan/rtl/tsan_mman.cpp @@ -20,18 +20,6 @@ #include "tsan_report.h" #include "tsan_flags.h" -// May be overriden by front-end. -SANITIZER_WEAK_DEFAULT_IMPL -void __sanitizer_malloc_hook(void *ptr, uptr size) { - (void)ptr; - (void)size; -} - -SANITIZER_WEAK_DEFAULT_IMPL -void __sanitizer_free_hook(void *ptr) { - (void)ptr; -} - namespace __tsan { struct MapUnmapCallback { @@ -378,7 +366,6 @@ void invoke_malloc_hook(void *ptr, uptr size) { ThreadState *thr = cur_thread(); if (ctx == 0 || !ctx->initialized || thr->ignore_interceptors) return; - __sanitizer_malloc_hook(ptr, size); RunMallocHooks(ptr, size); } @@ -386,7 +373,6 @@ void invoke_free_hook(void *ptr) { ThreadState *thr = cur_thread(); if (ctx == 0 || !ctx->initialized || thr->ignore_interceptors) return; - __sanitizer_free_hook(ptr); RunFreeHooks(ptr); } diff --git a/contrib/llvm-project/compiler-rt/lib/tsan/rtl/tsan_platform.h b/contrib/llvm-project/compiler-rt/lib/tsan/rtl/tsan_platform.h index 233bf0a39df0..12643f7f512c 100644 --- a/contrib/llvm-project/compiler-rt/lib/tsan/rtl/tsan_platform.h +++ b/contrib/llvm-project/compiler-rt/lib/tsan/rtl/tsan_platform.h @@ -587,7 +587,7 @@ ALWAYS_INLINE auto SelectMapping(Arg arg) { #else // SANITIZER_GO # if SANITIZER_IOS && !SANITIZER_IOSSIM return Func::template Apply<MappingAppleAarch64>(arg); -# elif defined(__x86_64__) || SANITIZER_MAC +# elif defined(__x86_64__) || SANITIZER_APPLE return Func::template Apply<Mapping48AddressSpace>(arg); # elif defined(__aarch64__) switch (vmaSize) { diff --git a/contrib/llvm-project/compiler-rt/lib/tsan/rtl/tsan_platform_linux.cpp b/contrib/llvm-project/compiler-rt/lib/tsan/rtl/tsan_platform_linux.cpp index 17dbdff8a539..807f6be2eee3 100644 --- a/contrib/llvm-project/compiler-rt/lib/tsan/rtl/tsan_platform_linux.cpp +++ b/contrib/llvm-project/compiler-rt/lib/tsan/rtl/tsan_platform_linux.cpp @@ -402,7 +402,11 @@ static uptr UnmangleLongJmpSp(uptr mangled_sp) { #elif defined(__powerpc__) # define LONG_JMP_SP_ENV_SLOT 0 #elif SANITIZER_FREEBSD -# define LONG_JMP_SP_ENV_SLOT 2 +# ifdef __aarch64__ +# define LONG_JMP_SP_ENV_SLOT 1 +# else +# define LONG_JMP_SP_ENV_SLOT 2 +# endif #elif SANITIZER_LINUX # ifdef __aarch64__ # define LONG_JMP_SP_ENV_SLOT 13 diff --git a/contrib/llvm-project/compiler-rt/lib/tsan/rtl/tsan_platform_mac.cpp b/contrib/llvm-project/compiler-rt/lib/tsan/rtl/tsan_platform_mac.cpp index 44b98d46cfbc..68ce5f83bdbd 100644 --- a/contrib/llvm-project/compiler-rt/lib/tsan/rtl/tsan_platform_mac.cpp +++ b/contrib/llvm-project/compiler-rt/lib/tsan/rtl/tsan_platform_mac.cpp @@ -12,7 +12,7 @@ //===----------------------------------------------------------------------===// #include "sanitizer_common/sanitizer_platform.h" -#if SANITIZER_MAC +#if SANITIZER_APPLE #include "sanitizer_common/sanitizer_atomic.h" #include "sanitizer_common/sanitizer_common.h" @@ -316,4 +316,4 @@ int call_pthread_cancel_with_cleanup(int (*fn)(void *arg), } // namespace __tsan -#endif // SANITIZER_MAC +#endif // SANITIZER_APPLE diff --git a/contrib/llvm-project/compiler-rt/lib/tsan/rtl/tsan_report.cpp b/contrib/llvm-project/compiler-rt/lib/tsan/rtl/tsan_report.cpp index 10d9c761b8ee..3b0bddc33a43 100644 --- a/contrib/llvm-project/compiler-rt/lib/tsan/rtl/tsan_report.cpp +++ b/contrib/llvm-project/compiler-rt/lib/tsan/rtl/tsan_report.cpp @@ -98,7 +98,7 @@ static const char *ReportTypeString(ReportType typ, uptr tag) { UNREACHABLE("missing case"); } -#if SANITIZER_MAC +#if SANITIZER_APPLE static const char *const kInterposedFunctionPrefix = "wrap_"; #else static const char *const kInterposedFunctionPrefix = "__interceptor_"; @@ -306,6 +306,9 @@ void PrintReport(const ReportDesc *rep) { (int)internal_getpid()); Printf("%s", d.Default()); + if (rep->typ == ReportTypeErrnoInSignal) + Printf(" Signal %u handler invoked at:\n", rep->signum); + if (rep->typ == ReportTypeDeadlock) { char thrbuf[kThreadBufSize]; Printf(" Cycle in lock order graph: "); diff --git a/contrib/llvm-project/compiler-rt/lib/tsan/rtl/tsan_report.h b/contrib/llvm-project/compiler-rt/lib/tsan/rtl/tsan_report.h index 3b367f38e266..718eacde7ec4 100644 --- a/contrib/llvm-project/compiler-rt/lib/tsan/rtl/tsan_report.h +++ b/contrib/llvm-project/compiler-rt/lib/tsan/rtl/tsan_report.h @@ -108,6 +108,7 @@ class ReportDesc { Vector<Tid> unique_tids; ReportStack *sleep; int count; + int signum = 0; ReportDesc(); ~ReportDesc(); diff --git a/contrib/llvm-project/compiler-rt/lib/tsan/rtl/tsan_rtl.cpp b/contrib/llvm-project/compiler-rt/lib/tsan/rtl/tsan_rtl.cpp index c068d8e486b0..3977d60c36e5 100644 --- a/contrib/llvm-project/compiler-rt/lib/tsan/rtl/tsan_rtl.cpp +++ b/contrib/llvm-project/compiler-rt/lib/tsan/rtl/tsan_rtl.cpp @@ -16,6 +16,7 @@ #include "sanitizer_common/sanitizer_atomic.h" #include "sanitizer_common/sanitizer_common.h" #include "sanitizer_common/sanitizer_file.h" +#include "sanitizer_common/sanitizer_interface_internal.h" #include "sanitizer_common/sanitizer_libc.h" #include "sanitizer_common/sanitizer_placement_new.h" #include "sanitizer_common/sanitizer_stackdepot.h" @@ -44,7 +45,7 @@ void (*on_initialize)(void); int (*on_finalize)(int); #endif -#if !SANITIZER_GO && !SANITIZER_MAC +#if !SANITIZER_GO && !SANITIZER_APPLE __attribute__((tls_model("initial-exec"))) THREADLOCAL char cur_thread_placeholder[sizeof(ThreadState)] ALIGNED( SANITIZER_CACHE_LINE_SIZE); @@ -721,8 +722,10 @@ void MaybeSpawnBackgroundThread() { int Finalize(ThreadState *thr) { bool failed = false; +#if !SANITIZER_GO if (common_flags()->print_module_map == 1) DumpProcessMap(); +#endif if (flags()->atexit_sleep_ms > 0 && ThreadCount(thr) > 1) internal_usleep(u64(flags()->atexit_sleep_ms) * 1000); @@ -935,7 +938,7 @@ void TraceSwitchPartImpl(ThreadState* thr) { // Pathologically large stacks may not fit into the part. // In these cases we log only fixed number of top frames. const uptr kMaxFrames = 1000; - // Sanity check that kMaxFrames won't consume the whole part. + // Check that kMaxFrames won't consume the whole part. static_assert(kMaxFrames < TracePart::kSize / 2, "kMaxFrames is too big"); uptr* pos = Max(&thr->shadow_stack[0], thr->shadow_stack_pos - kMaxFrames); for (; pos < thr->shadow_stack_pos; pos++) { diff --git a/contrib/llvm-project/compiler-rt/lib/tsan/rtl/tsan_rtl.h b/contrib/llvm-project/compiler-rt/lib/tsan/rtl/tsan_rtl.h index fbf02806e34b..c8d3c48a0c0c 100644 --- a/contrib/llvm-project/compiler-rt/lib/tsan/rtl/tsan_rtl.h +++ b/contrib/llvm-project/compiler-rt/lib/tsan/rtl/tsan_rtl.h @@ -235,7 +235,7 @@ struct ThreadState { } ALIGNED(SANITIZER_CACHE_LINE_SIZE); #if !SANITIZER_GO -#if SANITIZER_MAC || SANITIZER_ANDROID +#if SANITIZER_APPLE || SANITIZER_ANDROID ThreadState *cur_thread(); void set_cur_thread(ThreadState *thr); void cur_thread_finalize(); @@ -256,7 +256,7 @@ inline void set_cur_thread(ThreadState *thr) { reinterpret_cast<ThreadState *>(cur_thread_placeholder)->current = thr; } inline void cur_thread_finalize() { } -# endif // SANITIZER_MAC || SANITIZER_ANDROID +# endif // SANITIZER_APPLE || SANITIZER_ANDROID #endif // SANITIZER_GO class ThreadContext final : public ThreadContextBase { @@ -376,6 +376,7 @@ class ScopedReportBase { void AddLocation(uptr addr, uptr size); void AddSleep(StackID stack_id); void SetCount(int count); + void SetSigNum(int sig); const ReportDesc *GetReport() const; diff --git a/contrib/llvm-project/compiler-rt/lib/tsan/rtl/tsan_rtl_access.cpp b/contrib/llvm-project/compiler-rt/lib/tsan/rtl/tsan_rtl_access.cpp index e77bfba277a5..7d771bfaad7f 100644 --- a/contrib/llvm-project/compiler-rt/lib/tsan/rtl/tsan_rtl_access.cpp +++ b/contrib/llvm-project/compiler-rt/lib/tsan/rtl/tsan_rtl_access.cpp @@ -170,10 +170,10 @@ NOINLINE void DoReportRace(ThreadState* thr, RawShadow* shadow_mem, Shadow cur, // the slot locked because of the fork. But MemoryRangeFreed is not // called during fork because fork sets ignore_reads_and_writes, // so simply unlocking the slot should be fine. - if (typ & kAccessFree) + if (typ & kAccessSlotLocked) SlotUnlock(thr); ReportRace(thr, shadow_mem, cur, Shadow(old), typ); - if (typ & kAccessFree) + if (typ & kAccessSlotLocked) SlotLock(thr); } @@ -611,8 +611,8 @@ void MemoryRangeFreed(ThreadState* thr, uptr pc, uptr addr, uptr size) { // can cause excessive memory consumption (user does not necessary touch // the whole range) and most likely unnecessary. size = Min<uptr>(size, 1024); - const AccessType typ = - kAccessWrite | kAccessFree | kAccessCheckOnly | kAccessNoRodata; + const AccessType typ = kAccessWrite | kAccessFree | kAccessSlotLocked | + kAccessCheckOnly | kAccessNoRodata; TraceMemoryAccessRange(thr, pc, addr, size, typ); RawShadow* shadow_mem = MemToShadow(addr); Shadow cur(thr->fast_state, 0, kShadowCell, typ); diff --git a/contrib/llvm-project/compiler-rt/lib/tsan/rtl/tsan_rtl_mutex.cpp b/contrib/llvm-project/compiler-rt/lib/tsan/rtl/tsan_rtl_mutex.cpp index 5d31005c2af0..2e978852ea7d 100644 --- a/contrib/llvm-project/compiler-rt/lib/tsan/rtl/tsan_rtl_mutex.cpp +++ b/contrib/llvm-project/compiler-rt/lib/tsan/rtl/tsan_rtl_mutex.cpp @@ -128,7 +128,8 @@ void MutexDestroy(ThreadState *thr, uptr pc, uptr addr, u32 flagz) { } // Imitate a memory write to catch unlock-destroy races. if (pc && IsAppMem(addr)) - MemoryAccess(thr, pc, addr, 1, kAccessWrite | kAccessFree); + MemoryAccess(thr, pc, addr, 1, + kAccessWrite | kAccessFree | kAccessSlotLocked); } if (unlock_locked && ShouldReport(thr, ReportTypeMutexDestroyLocked)) ReportDestroyLocked(thr, pc, addr, last_lock, creation_stack_id); diff --git a/contrib/llvm-project/compiler-rt/lib/tsan/rtl/tsan_rtl_report.cpp b/contrib/llvm-project/compiler-rt/lib/tsan/rtl/tsan_rtl_report.cpp index 58949ead07b3..4cf8816489df 100644 --- a/contrib/llvm-project/compiler-rt/lib/tsan/rtl/tsan_rtl_report.cpp +++ b/contrib/llvm-project/compiler-rt/lib/tsan/rtl/tsan_rtl_report.cpp @@ -340,6 +340,8 @@ void ScopedReportBase::AddSleep(StackID stack_id) { void ScopedReportBase::SetCount(int count) { rep_->count = count; } +void ScopedReportBase::SetSigNum(int sig) { rep_->signum = sig; } + const ReportDesc *ScopedReportBase::GetReport() const { return rep_; } ScopedReport::ScopedReport(ReportType typ, uptr tag) @@ -821,6 +823,18 @@ void ReportRace(ThreadState *thr, RawShadow *shadow_mem, Shadow cur, Shadow old, rep.AddLocation(addr_min, addr_max - addr_min); + if (flags()->print_full_thread_history) { + const ReportDesc *rep_desc = rep.GetReport(); + for (uptr i = 0; i < rep_desc->threads.Size(); i++) { + Tid parent_tid = rep_desc->threads[i]->parent_tid; + if (parent_tid == kMainTid || parent_tid == kInvalidTid) + continue; + ThreadContext *parent_tctx = static_cast<ThreadContext *>( + ctx->thread_registry.GetThreadLocked(parent_tid)); + rep.AddThread(parent_tctx); + } + } + #if !SANITIZER_GO if (!((typ0 | typ1) & kAccessFree) && s[1].epoch() <= thr->last_sleep_clock.Get(s[1].sid())) diff --git a/contrib/llvm-project/compiler-rt/lib/tsan/rtl/tsan_rtl_thread.cpp b/contrib/llvm-project/compiler-rt/lib/tsan/rtl/tsan_rtl_thread.cpp index 86c8b3764cc7..77488f843285 100644 --- a/contrib/llvm-project/compiler-rt/lib/tsan/rtl/tsan_rtl_thread.cpp +++ b/contrib/llvm-project/compiler-rt/lib/tsan/rtl/tsan_rtl_thread.cpp @@ -53,7 +53,7 @@ static void CollectThreadLeaks(ThreadContextBase *tctx_base, void *arg) { // Disabled on Mac because lldb test TestTsanBasic fails: // https://reviews.llvm.org/D112603#3163158 -#if !SANITIZER_GO && !SANITIZER_MAC +#if !SANITIZER_GO && !SANITIZER_APPLE static void ReportIgnoresEnabled(ThreadContext *tctx, IgnoreSet *set) { if (tctx->tid == kMainTid) { Printf("ThreadSanitizer: main thread finished with ignores enabled\n"); diff --git a/contrib/llvm-project/compiler-rt/lib/tsan/rtl/tsan_shadow.h b/contrib/llvm-project/compiler-rt/lib/tsan/rtl/tsan_shadow.h index 843573ecf5d3..b222acf9e6c5 100644 --- a/contrib/llvm-project/compiler-rt/lib/tsan/rtl/tsan_shadow.h +++ b/contrib/llvm-project/compiler-rt/lib/tsan/rtl/tsan_shadow.h @@ -88,10 +88,13 @@ class Shadow { if (size) *size = part_.access_ == kFreeAccess ? kShadowCell : __builtin_popcount(part_.access_); - if (typ) - *typ = (part_.is_read_ ? kAccessRead : kAccessWrite) | - (part_.is_atomic_ ? kAccessAtomic : 0) | - (part_.access_ == kFreeAccess ? kAccessFree : 0); + if (typ) { + *typ = part_.is_read_ ? kAccessRead : kAccessWrite; + if (part_.is_atomic_) + *typ |= kAccessAtomic; + if (part_.access_ == kFreeAccess) + *typ |= kAccessFree; + } } ALWAYS_INLINE diff --git a/contrib/llvm-project/compiler-rt/lib/ubsan/ubsan_diag.cpp b/contrib/llvm-project/compiler-rt/lib/ubsan/ubsan_diag.cpp index 8de51bc18770..3673e66539d0 100644 --- a/contrib/llvm-project/compiler-rt/lib/ubsan/ubsan_diag.cpp +++ b/contrib/llvm-project/compiler-rt/lib/ubsan/ubsan_diag.cpp @@ -32,15 +32,13 @@ using namespace __ubsan; // Windows. // TODO(yln): This is a temporary workaround. GetStackTrace functions will be // removed in the future. -void ubsan_GetStackTrace(BufferedStackTrace *stack, uptr max_depth, - uptr pc, uptr bp, void *context, bool fast) { +void ubsan_GetStackTrace(BufferedStackTrace *stack, uptr max_depth, uptr pc, + uptr bp, void *context, bool request_fast) { uptr top = 0; uptr bottom = 0; - if (StackTrace::WillUseFastUnwind(fast)) { - GetThreadStackTopAndBottom(false, &top, &bottom); - stack->Unwind(max_depth, pc, bp, nullptr, top, bottom, true); - } else - stack->Unwind(max_depth, pc, bp, context, 0, 0, false); + GetThreadStackTopAndBottom(false, &top, &bottom); + bool fast = StackTrace::WillUseFastUnwind(request_fast); + stack->Unwind(max_depth, pc, bp, context, top, bottom, fast); } static void MaybePrintStackTrace(uptr pc, uptr bp) { diff --git a/contrib/llvm-project/compiler-rt/lib/ubsan/ubsan_init.cpp b/contrib/llvm-project/compiler-rt/lib/ubsan/ubsan_init.cpp index 9931d85bf40c..5802d58896f0 100644 --- a/contrib/llvm-project/compiler-rt/lib/ubsan/ubsan_init.cpp +++ b/contrib/llvm-project/compiler-rt/lib/ubsan/ubsan_init.cpp @@ -12,13 +12,14 @@ #include "ubsan_platform.h" #if CAN_SANITIZE_UB -#include "ubsan_diag.h" -#include "ubsan_init.h" -#include "ubsan_flags.h" #include "sanitizer_common/sanitizer_common.h" +#include "sanitizer_common/sanitizer_interface_internal.h" #include "sanitizer_common/sanitizer_libc.h" #include "sanitizer_common/sanitizer_mutex.h" #include "sanitizer_common/sanitizer_symbolizer.h" +#include "ubsan_diag.h" +#include "ubsan_flags.h" +#include "ubsan_init.h" using namespace __ubsan; diff --git a/contrib/llvm-project/compiler-rt/lib/ubsan/ubsan_value.cpp b/contrib/llvm-project/compiler-rt/lib/ubsan/ubsan_value.cpp index 40042bf3a903..5a93a0d7fc2d 100644 --- a/contrib/llvm-project/compiler-rt/lib/ubsan/ubsan_value.cpp +++ b/contrib/llvm-project/compiler-rt/lib/ubsan/ubsan_value.cpp @@ -18,7 +18,7 @@ #include "sanitizer_common/sanitizer_libc.h" #include "sanitizer_common/sanitizer_mutex.h" -// TODO(dliew): Prefer '__APPLE__' here over 'SANITIZER_MAC', as the latter is +// TODO(dliew): Prefer '__APPLE__' here over 'SANITIZER_APPLE', as the latter is // unclear. rdar://58124919 tracks using a more obviously portable guard. #if defined(__APPLE__) #include <dlfcn.h> diff --git a/contrib/llvm-project/compiler-rt/lib/xray/xray_basic_logging.cpp b/contrib/llvm-project/compiler-rt/lib/xray/xray_basic_logging.cpp index 6e83252a0516..6ac5417bef75 100644 --- a/contrib/llvm-project/compiler-rt/lib/xray/xray_basic_logging.cpp +++ b/contrib/llvm-project/compiler-rt/lib/xray/xray_basic_logging.cpp @@ -18,7 +18,7 @@ #include <fcntl.h> #include <pthread.h> #include <sys/stat.h> -#if SANITIZER_FREEBSD || SANITIZER_NETBSD || SANITIZER_MAC +#if SANITIZER_FREEBSD || SANITIZER_NETBSD || SANITIZER_APPLE #include <sys/syscall.h> #endif #include <sys/types.h> diff --git a/contrib/llvm-project/compiler-rt/lib/xray/xray_init.cpp b/contrib/llvm-project/compiler-rt/lib/xray/xray_init.cpp index 00ba5fe4a52b..f22a31b95686 100644 --- a/contrib/llvm-project/compiler-rt/lib/xray/xray_init.cpp +++ b/contrib/llvm-project/compiler-rt/lib/xray/xray_init.cpp @@ -27,7 +27,7 @@ extern const XRaySledEntry __stop_xray_instr_map[] __attribute__((weak)); extern const XRayFunctionSledIndex __start_xray_fn_idx[] __attribute__((weak)); extern const XRayFunctionSledIndex __stop_xray_fn_idx[] __attribute__((weak)); -#if SANITIZER_MAC +#if SANITIZER_APPLE // HACK: This is a temporary workaround to make XRay build on // Darwin, but it will probably not work at runtime. const XRaySledEntry __start_xray_instr_map[] = {}; diff --git a/contrib/llvm-project/compiler-rt/lib/xray/xray_x86_64.cpp b/contrib/llvm-project/compiler-rt/lib/xray/xray_x86_64.cpp index 669d2e85bede..1bf241c1223f 100644 --- a/contrib/llvm-project/compiler-rt/lib/xray/xray_x86_64.cpp +++ b/contrib/llvm-project/compiler-rt/lib/xray/xray_x86_64.cpp @@ -6,7 +6,7 @@ #include "xray_defs.h" #include "xray_interface_internal.h" -#if SANITIZER_FREEBSD || SANITIZER_NETBSD || SANITIZER_MAC +#if SANITIZER_FREEBSD || SANITIZER_NETBSD || SANITIZER_APPLE #include <sys/types.h> #include <sys/sysctl.h> #elif SANITIZER_FUCHSIA @@ -82,11 +82,11 @@ uint64_t getTSCFrequency() XRAY_NEVER_INSTRUMENT { } return TSCFrequency == -1 ? 0 : static_cast<uint64_t>(TSCFrequency); } -#elif SANITIZER_FREEBSD || SANITIZER_NETBSD || SANITIZER_MAC +#elif SANITIZER_FREEBSD || SANITIZER_NETBSD || SANITIZER_APPLE uint64_t getTSCFrequency() XRAY_NEVER_INSTRUMENT { long long TSCFrequency = -1; size_t tscfreqsz = sizeof(TSCFrequency); -#if SANITIZER_MAC +#if SANITIZER_APPLE if (internal_sysctlbyname("machdep.tsc.frequency", &TSCFrequency, &tscfreqsz, NULL, 0) != -1) { |