From e99c11856df5dafb54e92af12c0858d187dc2ad2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20R=C3=B8nne=20Petersen?= Date: Wed, 5 Feb 2025 13:36:56 +0100 Subject: [PATCH] libtsan: Update to LLVM 20. --- lib/tsan/builtins/assembly.h | 12 + lib/tsan/interception/interception.h | 25 +- .../interception/interception_type_test.cpp | 31 +- lib/tsan/interception/interception_win.cpp | 438 +++++++-- lib/tsan/interception/interception_win.h | 3 + .../sanitizer_common/sanitizer_allocator.cpp | 5 +- .../sanitizer_allocator_dlsym.h | 27 +- .../sanitizer_allocator_primary64.h | 12 +- lib/tsan/sanitizer_common/sanitizer_common.h | 27 +- .../sanitizer_common_interceptors.inc | 410 ++++---- ...izer_common_interceptors_memintrinsics.inc | 34 +- ...er_common_interceptors_vfork_aarch64.inc.S | 48 + ...itizer_common_interceptors_vfork_arm.inc.S | 49 + ...tizer_common_interceptors_vfork_i386.inc.S | 64 ++ ...ommon_interceptors_vfork_loongarch64.inc.S | 57 ++ ...er_common_interceptors_vfork_riscv64.inc.S | 56 ++ ...zer_common_interceptors_vfork_x86_64.inc.S | 42 + .../sanitizer_common_interface.inc | 8 + .../sanitizer_common_libcdep.cpp | 28 +- .../sanitizer_common_nolibc.cpp | 7 +- .../sanitizer_common_syscalls.inc | 33 +- .../sanitizer_coverage_win_dll_thunk.cpp | 20 - ...zer_coverage_win_dynamic_runtime_thunk.cpp | 26 - ...nitizer_coverage_win_weak_interception.cpp | 23 - .../sanitizer_deadlock_detector.h | 2 +- .../sanitizer_common/sanitizer_dense_map.h | 72 +- lib/tsan/sanitizer_common/sanitizer_errno.cpp | 1 + .../sanitizer_common/sanitizer_errno_codes.h | 1 + .../sanitizer_common/sanitizer_fuchsia.cpp | 7 +- .../sanitizer_common/sanitizer_getauxval.h | 21 +- .../sanitizer_interface_internal.h | 10 + .../sanitizer_internal_defs.h | 40 +- .../sanitizer_common/sanitizer_libignore.cpp | 28 +- .../sanitizer_common/sanitizer_libignore.h | 35 +- lib/tsan/sanitizer_common/sanitizer_linux.cpp | 396 ++++++-- lib/tsan/sanitizer_common/sanitizer_linux.h | 8 +- .../sanitizer_linux_libcdep.cpp | 304 +++--- lib/tsan/sanitizer_common/sanitizer_mac.cpp | 64 +- .../sanitizer_platform_interceptors.h | 52 +- .../sanitizer_platform_limits_netbsd.cpp | 3 +- .../sanitizer_platform_limits_netbsd.h | 3 +- .../sanitizer_platform_limits_posix.cpp | 61 +- .../sanitizer_platform_limits_posix.h | 62 +- .../sanitizer_platform_limits_solaris.cpp | 3 + .../sanitizer_platform_limits_solaris.h | 2 + lib/tsan/sanitizer_common/sanitizer_posix.cpp | 10 +- lib/tsan/sanitizer_common/sanitizer_posix.h | 6 +- .../sanitizer_posix_libcdep.cpp | 100 +- .../sanitizer_procmaps_mac.cpp | 4 +- .../sanitizer_procmaps_solaris.cpp | 4 + .../sanitizer_redefine_builtins.h | 8 +- .../sanitizer_stoptheworld_linux_libcdep.cpp | 15 +- .../sanitizer_common/sanitizer_symbolizer.h | 8 +- .../sanitizer_symbolizer_mac.cpp | 4 +- .../sanitizer_symbolizer_report.cpp | 15 +- .../sanitizer_symbolizer_win.cpp | 13 +- .../sanitizer_thread_history.cpp | 72 ++ .../sanitizer_thread_history.h | 24 + .../sanitizer_thread_registry.cpp | 51 +- .../sanitizer_thread_registry.h | 11 +- .../sanitizer_tls_get_addr.cpp | 74 +- .../sanitizer_common/sanitizer_tls_get_addr.h | 4 - lib/tsan/sanitizer_common/sanitizer_win.cpp | 101 +- .../sanitizer_win_dll_thunk.cpp | 101 -- .../sanitizer_win_dll_thunk.h | 181 ---- .../sanitizer_win_dynamic_runtime_thunk.cpp | 26 - .../sanitizer_win_immortalize.h | 71 ++ .../sanitizer_win_interception.cpp | 156 +++ .../sanitizer_win_interception.h | 32 + .../sanitizer_win_weak_interception.cpp | 94 -- .../sanitizer_win_weak_interception.h | 32 - lib/tsan/tsan_interceptors_mac.cpp | 208 ++-- lib/tsan/tsan_interceptors_posix.cpp | 62 +- lib/tsan/tsan_interface.h | 151 +-- lib/tsan/tsan_interface_atomic.cpp | 916 +++++++++--------- lib/tsan/tsan_mman.cpp | 2 +- lib/tsan/tsan_platform_linux.cpp | 1 - lib/tsan/tsan_rtl.cpp | 5 +- lib/tsan/tsan_rtl.h | 2 +- lib/tsan/tsan_rtl_report.cpp | 10 +- lib/tsan/tsan_rtl_thread.cpp | 10 +- lib/tsan/tsan_spinlock_defs_mac.h | 45 - src/libtsan.zig | 8 +- 83 files changed, 3246 insertions(+), 2051 deletions(-) create mode 100644 lib/tsan/sanitizer_common/sanitizer_common_interceptors_vfork_aarch64.inc.S create mode 100644 lib/tsan/sanitizer_common/sanitizer_common_interceptors_vfork_arm.inc.S create mode 100644 lib/tsan/sanitizer_common/sanitizer_common_interceptors_vfork_i386.inc.S create mode 100644 lib/tsan/sanitizer_common/sanitizer_common_interceptors_vfork_loongarch64.inc.S create mode 100644 lib/tsan/sanitizer_common/sanitizer_common_interceptors_vfork_riscv64.inc.S create mode 100644 lib/tsan/sanitizer_common/sanitizer_common_interceptors_vfork_x86_64.inc.S delete mode 100644 lib/tsan/sanitizer_common/sanitizer_coverage_win_dll_thunk.cpp delete mode 100644 lib/tsan/sanitizer_common/sanitizer_coverage_win_dynamic_runtime_thunk.cpp delete mode 100644 lib/tsan/sanitizer_common/sanitizer_coverage_win_weak_interception.cpp create mode 100644 lib/tsan/sanitizer_common/sanitizer_thread_history.cpp create mode 100644 lib/tsan/sanitizer_common/sanitizer_thread_history.h delete mode 100644 lib/tsan/sanitizer_common/sanitizer_win_dll_thunk.cpp delete mode 100644 lib/tsan/sanitizer_common/sanitizer_win_dll_thunk.h delete mode 100644 lib/tsan/sanitizer_common/sanitizer_win_dynamic_runtime_thunk.cpp create mode 100644 lib/tsan/sanitizer_common/sanitizer_win_immortalize.h create mode 100644 lib/tsan/sanitizer_common/sanitizer_win_interception.cpp create mode 100644 lib/tsan/sanitizer_common/sanitizer_win_interception.h delete mode 100644 lib/tsan/sanitizer_common/sanitizer_win_weak_interception.cpp delete mode 100644 lib/tsan/sanitizer_common/sanitizer_win_weak_interception.h delete mode 100644 lib/tsan/tsan_spinlock_defs_mac.h diff --git a/lib/tsan/builtins/assembly.h b/lib/tsan/builtins/assembly.h index 8c42fc7734..34c7124152 100644 --- a/lib/tsan/builtins/assembly.h +++ b/lib/tsan/builtins/assembly.h @@ -290,4 +290,16 @@ CFI_END #endif +#ifdef __arm__ +#include "int_endianness.h" + +#if _YUGA_BIG_ENDIAN +#define VMOV_TO_DOUBLE(dst, src0, src1) vmov dst, src1, src0 SEPARATOR +#define VMOV_FROM_DOUBLE(dst0, dst1, src) vmov dst1, dst0, src SEPARATOR +#else +#define VMOV_TO_DOUBLE(dst, src0, src1) vmov dst, src0, src1 SEPARATOR +#define VMOV_FROM_DOUBLE(dst0, dst1, src) vmov dst0, dst1, src SEPARATOR +#endif +#endif + #endif // COMPILERRT_ASSEMBLY_H diff --git a/lib/tsan/interception/interception.h b/lib/tsan/interception/interception.h index 38c152952e..3cb6b44663 100644 --- a/lib/tsan/interception/interception.h +++ b/lib/tsan/interception/interception.h @@ -25,8 +25,19 @@ // These typedefs should be used only in the interceptor definitions to replace // the standard system types (e.g. SSIZE_T instead of ssize_t) -typedef __sanitizer::uptr SIZE_T; -typedef __sanitizer::sptr SSIZE_T; +// On Windows the system headers (basetsd.h) provide a conflicting definition +// of SIZE_T/SSIZE_T that do not match the real size_t/ssize_t for 32-bit +// systems (using long instead of the expected int). Work around the typedef +// redefinition by #defining SIZE_T instead of using a typedef. +// TODO: We should be using __sanitizer::usize (and a new ssize) instead of +// these new macros as long as we ensure they match the real system definitions. +#if SANITIZER_WINDOWS +// Ensure that (S)SIZE_T were already defined as we are about to override them. +# include +#endif + +#define SIZE_T __sanitizer::usize +#define SSIZE_T __sanitizer::ssize typedef __sanitizer::sptr PTRDIFF_T; typedef __sanitizer::s64 INTMAX_T; typedef __sanitizer::u64 UINTMAX_T; @@ -338,16 +349,8 @@ const interpose_substitution substitution_##func_name[] \ #endif // ISO C++ forbids casting between pointer-to-function and pointer-to-object, -// so we use casting via an integral type __interception::uptr, -// assuming that system is POSIX-compliant. Using other hacks seem -// challenging, as we don't even pass function type to -// INTERCEPT_FUNCTION macro, only its name. +// so we use casts via uintptr_t (the local __sanitizer::uptr equivalent). namespace __interception { -#if defined(_WIN64) -typedef unsigned long long uptr; -#else -typedef unsigned long uptr; -#endif // _WIN64 #if defined(__ELF__) && !SANITIZER_FUCHSIA // The use of interceptors makes many sanitizers unusable for static linking. diff --git a/lib/tsan/interception/interception_type_test.cpp b/lib/tsan/interception/interception_type_test.cpp index 7c3de82a1e..41041ce6f9 100644 --- a/lib/tsan/interception/interception_type_test.cpp +++ b/lib/tsan/interception/interception_type_test.cpp @@ -12,28 +12,35 @@ //===----------------------------------------------------------------------===// #include "interception.h" +#include "sanitizer_common/sanitizer_type_traits.h" -#if SANITIZER_LINUX || SANITIZER_APPLE - -#include +#if __has_include() +# include +#endif #include #include -COMPILER_CHECK(sizeof(::SIZE_T) == sizeof(size_t)); -COMPILER_CHECK(sizeof(::SSIZE_T) == sizeof(ssize_t)); -COMPILER_CHECK(sizeof(::PTRDIFF_T) == sizeof(ptrdiff_t)); +COMPILER_CHECK((__sanitizer::is_same<__sanitizer::uptr, ::uintptr_t>::value)); +COMPILER_CHECK((__sanitizer::is_same<__sanitizer::sptr, ::intptr_t>::value)); +COMPILER_CHECK((__sanitizer::is_same<__sanitizer::usize, ::size_t>::value)); +COMPILER_CHECK((__sanitizer::is_same<::PTRDIFF_T, ::ptrdiff_t>::value)); +COMPILER_CHECK((__sanitizer::is_same<::SIZE_T, ::size_t>::value)); +#if !SANITIZER_WINDOWS +// No ssize_t on Windows. +COMPILER_CHECK((__sanitizer::is_same<::SSIZE_T, ::ssize_t>::value)); +#endif +// TODO: These are not actually the same type on Linux (long vs long long) COMPILER_CHECK(sizeof(::INTMAX_T) == sizeof(intmax_t)); +COMPILER_CHECK(sizeof(::UINTMAX_T) == sizeof(uintmax_t)); -# if SANITIZER_GLIBC || SANITIZER_ANDROID +#if SANITIZER_GLIBC || SANITIZER_ANDROID COMPILER_CHECK(sizeof(::OFF64_T) == sizeof(off64_t)); -# endif +#endif // The following are the cases when pread (and friends) is used instead of // pread64. In those cases we need OFF_T to match off_t. We don't care about the // rest (they depend on _FILE_OFFSET_BITS setting when building an application). -# if SANITIZER_ANDROID || !defined _FILE_OFFSET_BITS || \ - _FILE_OFFSET_BITS != 64 +#if !SANITIZER_WINDOWS && (SANITIZER_ANDROID || !defined _FILE_OFFSET_BITS || \ + _FILE_OFFSET_BITS != 64) COMPILER_CHECK(sizeof(::OFF_T) == sizeof(off_t)); -# endif - #endif diff --git a/lib/tsan/interception/interception_win.cpp b/lib/tsan/interception/interception_win.cpp index a638e66ecc..002b37468a 100644 --- a/lib/tsan/interception/interception_win.cpp +++ b/lib/tsan/interception/interception_win.cpp @@ -27,7 +27,7 @@ // // 1) Detour // -// The Detour hooking technique is assuming the presence of an header with +// The Detour hooking technique is assuming the presence of a header with // padding and an overridable 2-bytes nop instruction (mov edi, edi). The // nop instruction can safely be replaced by a 2-bytes jump without any need // to save the instruction. A jump to the target is encoded in the function @@ -47,7 +47,7 @@ // // func: jmp