From a40cdad18c06fd377622c47aa34564df7ea959b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20R=C3=B8nne=20Petersen?= Date: Tue, 24 Sep 2024 13:47:29 +0200 Subject: [PATCH] tsan: Update to LLVM 19.1.0. --- lib/tsan/builtins/assembly.h | 293 +++ lib/tsan/interception/interception.h | 29 +- lib/tsan/interception/interception_linux.h | 16 +- lib/tsan/interception/interception_win.cpp | 83 +- .../sanitizer_common/sanitizer_allocator.cpp | 10 +- .../sanitizer_allocator_interface.h | 2 + .../sanitizer_allocator_primary32.h | 2 +- .../sanitizer_allocator_primary64.h | 16 +- lib/tsan/sanitizer_common/sanitizer_asm.h | 43 +- lib/tsan/sanitizer_common/sanitizer_atomic.h | 14 +- .../sanitizer_common/sanitizer_atomic_clang.h | 91 +- .../sanitizer_atomic_clang_mips.h | 117 -- .../sanitizer_atomic_clang_other.h | 85 - .../sanitizer_atomic_clang_x86.h | 113 -- .../sanitizer_common/sanitizer_atomic_msvc.h | 8 +- .../sanitizer_common/sanitizer_bitvector.h | 8 +- .../sanitizer_chained_origin_depot.cpp | 6 +- .../sanitizer_chained_origin_depot.h | 4 +- .../sanitizer_common/sanitizer_common.cpp | 20 +- lib/tsan/sanitizer_common/sanitizer_common.h | 45 +- .../sanitizer_common_interceptors.inc | 203 +- .../sanitizer_common_interceptors_format.inc | 15 +- .../sanitizer_common_interface.inc | 1 + .../sanitizer_common_interface_posix.inc | 1 + .../sanitizer_common_libcdep.cpp | 10 +- .../sanitizer_common_syscalls.inc | 35 + lib/tsan/sanitizer_common/sanitizer_dl.cpp | 37 + lib/tsan/sanitizer_common/sanitizer_dl.h | 26 + lib/tsan/sanitizer_common/sanitizer_file.cpp | 4 +- lib/tsan/sanitizer_common/sanitizer_file.h | 2 +- .../sanitizer_flag_parser.cpp | 7 +- .../sanitizer_common/sanitizer_flag_parser.h | 4 +- lib/tsan/sanitizer_common/sanitizer_flags.cpp | 4 +- lib/tsan/sanitizer_common/sanitizer_flags.inc | 13 + .../sanitizer_common/sanitizer_flat_map.h | 4 + lib/tsan/sanitizer_common/sanitizer_freebsd.h | 137 -- .../sanitizer_common/sanitizer_fuchsia.cpp | 107 +- lib/tsan/sanitizer_common/sanitizer_hash.h | 2 +- .../sanitizer_internal_defs.h | 34 +- lib/tsan/sanitizer_common/sanitizer_libc.cpp | 16 + lib/tsan/sanitizer_common/sanitizer_libc.h | 3 +- .../sanitizer_common/sanitizer_libignore.cpp | 4 +- lib/tsan/sanitizer_common/sanitizer_linux.cpp | 1782 +++++++++-------- lib/tsan/sanitizer_common/sanitizer_linux.h | 112 +- .../sanitizer_linux_libcdep.cpp | 481 ++--- .../sanitizer_common/sanitizer_linux_s390.cpp | 156 +- lib/tsan/sanitizer_common/sanitizer_mac.cpp | 8 +- .../sanitizer_common/sanitizer_mallinfo.h | 4 + .../sanitizer_common/sanitizer_malloc_mac.inc | 2 +- lib/tsan/sanitizer_common/sanitizer_mutex.cpp | 6 +- .../sanitizer_placement_new.h | 4 +- .../sanitizer_common/sanitizer_platform.h | 24 +- .../sanitizer_platform_interceptors.h | 16 +- .../sanitizer_platform_limits_freebsd.cpp | 2 + .../sanitizer_platform_limits_freebsd.h | 26 +- .../sanitizer_platform_limits_openbsd.cpp | 0 .../sanitizer_platform_limits_openbsd.h | 0 .../sanitizer_platform_limits_posix.h | 1 + lib/tsan/sanitizer_common/sanitizer_posix.cpp | 12 +- lib/tsan/sanitizer_common/sanitizer_posix.h | 26 +- .../sanitizer_posix_libcdep.cpp | 33 +- .../sanitizer_common/sanitizer_printf.cpp | 11 +- .../sanitizer_procmaps_bsd.cpp | 45 +- .../sanitizer_procmaps_common.cpp | 2 +- lib/tsan/sanitizer_common/sanitizer_ptrauth.h | 46 +- .../sanitizer_redefine_builtins.h | 16 +- .../sanitizer_common/sanitizer_ring_buffer.h | 4 +- .../sanitizer_stack_store.cpp | 9 +- .../sanitizer_common/sanitizer_stackdepot.cpp | 8 +- .../sanitizer_common/sanitizer_stackdepot.h | 4 +- .../sanitizer_stackdepotbase.h | 31 +- .../sanitizer_stacktrace_libcdep.cpp | 42 +- .../sanitizer_stacktrace_printer.cpp | 133 +- .../sanitizer_stacktrace_printer.h | 133 +- .../sanitizer_stacktrace_sparc.cpp | 11 +- .../sanitizer_stoptheworld_linux_libcdep.cpp | 10 +- .../sanitizer_stoptheworld_netbsd_libcdep.cpp | 4 +- .../sanitizer_suppressions.cpp | 7 +- .../sanitizer_common/sanitizer_symbolizer.cpp | 5 +- .../sanitizer_common/sanitizer_symbolizer.h | 27 +- .../sanitizer_symbolizer_internal.h | 9 + .../sanitizer_symbolizer_libbacktrace.cpp | 2 +- .../sanitizer_symbolizer_libcdep.cpp | 20 +- .../sanitizer_symbolizer_mac.cpp | 5 +- .../sanitizer_symbolizer_markup.cpp | 228 ++- .../sanitizer_symbolizer_markup.h | 79 + ...> sanitizer_symbolizer_markup_constants.h} | 19 +- .../sanitizer_symbolizer_markup_fuchsia.cpp | 85 + .../sanitizer_symbolizer_posix_libcdep.cpp | 67 +- .../sanitizer_symbolizer_report.cpp | 80 +- .../sanitizer_symbolizer_report_fuchsia.cpp | 33 + .../sanitizer_symbolizer_win.cpp | 6 +- .../sanitizer_syscall_linux_hexagon.inc | 131 ++ .../sanitizer_syscall_linux_loongarch64.inc | 171 ++ .../sanitizer_syscall_linux_riscv64.inc | 174 ++ .../sanitizer_thread_arg_retval.cpp | 23 +- .../sanitizer_thread_arg_retval.h | 1 + .../sanitizer_tls_get_addr.cpp | 15 +- .../sanitizer_unwind_fuchsia.cpp | 66 + .../sanitizer_common/sanitizer_unwind_win.cpp | 7 + lib/tsan/sanitizer_common/sanitizer_win.cpp | 25 +- lib/tsan/tsan_debugging.cpp | 4 +- lib/tsan/tsan_defs.h | 2 +- lib/tsan/tsan_dispatch_defs.h | 7 - lib/tsan/tsan_interceptors_posix.cpp | 143 +- lib/tsan/tsan_interface.h | 8 + lib/tsan/tsan_interface_ann.cpp | 24 +- lib/tsan/tsan_interface_atomic.cpp | 24 + lib/tsan/tsan_mman.cpp | 27 +- lib/tsan/tsan_mman.h | 4 +- lib/tsan/tsan_platform.h | 151 +- lib/tsan/tsan_platform_linux.cpp | 220 +- lib/tsan/tsan_platform_mac.cpp | 9 +- lib/tsan/tsan_platform_posix.cpp | 43 +- lib/tsan/tsan_preinit.cpp | 10 +- lib/tsan/tsan_report.cpp | 38 +- lib/tsan/tsan_report.h | 3 +- lib/tsan/tsan_rtl.cpp | 24 +- lib/tsan/tsan_rtl.h | 12 +- lib/tsan/tsan_rtl_aarch64.S | 7 + lib/tsan/tsan_rtl_access.cpp | 22 +- lib/tsan/tsan_rtl_loongarch64.S | 196 ++ lib/tsan/tsan_rtl_mutex.cpp | 2 +- lib/tsan/tsan_rtl_riscv64.S | 203 ++ lib/tsan/tsan_rtl_s390x.S | 49 + lib/tsan/tsan_rtl_thread.cpp | 10 +- lib/tsan/tsan_suppressions.cpp | 3 +- lib/tsan/tsan_vector_clock.h | 2 +- src/libtsan.zig | 16 +- 129 files changed, 4880 insertions(+), 2546 deletions(-) create mode 100644 lib/tsan/builtins/assembly.h delete mode 100644 lib/tsan/sanitizer_common/sanitizer_atomic_clang_mips.h delete mode 100644 lib/tsan/sanitizer_common/sanitizer_atomic_clang_other.h delete mode 100644 lib/tsan/sanitizer_common/sanitizer_atomic_clang_x86.h create mode 100644 lib/tsan/sanitizer_common/sanitizer_dl.cpp create mode 100644 lib/tsan/sanitizer_common/sanitizer_dl.h delete mode 100644 lib/tsan/sanitizer_common/sanitizer_freebsd.h delete mode 100644 lib/tsan/sanitizer_common/sanitizer_platform_limits_openbsd.cpp delete mode 100644 lib/tsan/sanitizer_common/sanitizer_platform_limits_openbsd.h create mode 100644 lib/tsan/sanitizer_common/sanitizer_symbolizer_markup.h rename lib/tsan/sanitizer_common/{sanitizer_symbolizer_fuchsia.h => sanitizer_symbolizer_markup_constants.h} (69%) create mode 100644 lib/tsan/sanitizer_common/sanitizer_symbolizer_markup_fuchsia.cpp create mode 100644 lib/tsan/sanitizer_common/sanitizer_symbolizer_report_fuchsia.cpp create mode 100644 lib/tsan/sanitizer_common/sanitizer_syscall_linux_hexagon.inc create mode 100644 lib/tsan/sanitizer_common/sanitizer_syscall_linux_loongarch64.inc create mode 100644 lib/tsan/sanitizer_common/sanitizer_syscall_linux_riscv64.inc create mode 100644 lib/tsan/sanitizer_common/sanitizer_unwind_fuchsia.cpp create mode 100644 lib/tsan/tsan_rtl_loongarch64.S create mode 100644 lib/tsan/tsan_rtl_riscv64.S create mode 100644 lib/tsan/tsan_rtl_s390x.S diff --git a/lib/tsan/builtins/assembly.h b/lib/tsan/builtins/assembly.h new file mode 100644 index 0000000000..8c42fc7734 --- /dev/null +++ b/lib/tsan/builtins/assembly.h @@ -0,0 +1,293 @@ +//===-- assembly.h - compiler-rt assembler support macros -----------------===// +// +// 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 macros for use in compiler-rt assembler source. +// This file is not part of the interface of this library. +// +//===----------------------------------------------------------------------===// + +#ifndef COMPILERRT_ASSEMBLY_H +#define COMPILERRT_ASSEMBLY_H + +#if defined(__linux__) && defined(__CET__) +#if __has_include() +#include +#endif +#endif + +#if defined(__APPLE__) && defined(__aarch64__) +#define SEPARATOR %% +#else +#define SEPARATOR ; +#endif + +#if defined(__APPLE__) +#define HIDDEN(name) .private_extern name +#define LOCAL_LABEL(name) L_##name +// tell linker it can break up file at label boundaries +#define FILE_LEVEL_DIRECTIVE .subsections_via_symbols +#define SYMBOL_IS_FUNC(name) +#define CONST_SECTION .const + +#define NO_EXEC_STACK_DIRECTIVE + +#elif defined(__ELF__) + +#define HIDDEN(name) .hidden name +#define LOCAL_LABEL(name) .L_##name +#define FILE_LEVEL_DIRECTIVE +#if defined(__arm__) || defined(__aarch64__) +#define SYMBOL_IS_FUNC(name) .type name,%function +#else +#define SYMBOL_IS_FUNC(name) .type name,@function +#endif +#define CONST_SECTION .section .rodata + +#if defined(__GNU__) || defined(__FreeBSD__) || defined(__Fuchsia__) || \ + defined(__linux__) +#define NO_EXEC_STACK_DIRECTIVE .section .note.GNU-stack,"",%progbits +#else +#define NO_EXEC_STACK_DIRECTIVE +#endif + +#else // !__APPLE__ && !__ELF__ + +#define HIDDEN(name) +#define LOCAL_LABEL(name) .L ## name +#define FILE_LEVEL_DIRECTIVE +#define SYMBOL_IS_FUNC(name) \ + .def name SEPARATOR \ + .scl 2 SEPARATOR \ + .type 32 SEPARATOR \ + .endef +#define CONST_SECTION .section .rdata,"rd" + +#define NO_EXEC_STACK_DIRECTIVE + +#endif + +#if defined(__arm__) || defined(__aarch64__) +#define FUNC_ALIGN \ + .text SEPARATOR \ + .balign 16 SEPARATOR +#else +#define FUNC_ALIGN +#endif + +// BTI and PAC gnu property note +#define NT_GNU_PROPERTY_TYPE_0 5 +#define GNU_PROPERTY_AARCH64_FEATURE_1_AND 0xc0000000 +#define GNU_PROPERTY_AARCH64_FEATURE_1_BTI 1 +#define GNU_PROPERTY_AARCH64_FEATURE_1_PAC 2 + +#if defined(__ARM_FEATURE_BTI_DEFAULT) +#define BTI_FLAG GNU_PROPERTY_AARCH64_FEATURE_1_BTI +#else +#define BTI_FLAG 0 +#endif + +#if __ARM_FEATURE_PAC_DEFAULT & 3 +#define PAC_FLAG GNU_PROPERTY_AARCH64_FEATURE_1_PAC +#else +#define PAC_FLAG 0 +#endif + +#define GNU_PROPERTY(type, value) \ + .pushsection .note.gnu.property, "a" SEPARATOR \ + .p2align 3 SEPARATOR \ + .word 4 SEPARATOR \ + .word 16 SEPARATOR \ + .word NT_GNU_PROPERTY_TYPE_0 SEPARATOR \ + .asciz "GNU" SEPARATOR \ + .word type SEPARATOR \ + .word 4 SEPARATOR \ + .word value SEPARATOR \ + .word 0 SEPARATOR \ + .popsection + +#if BTI_FLAG != 0 +#define BTI_C hint #34 +#define BTI_J hint #36 +#else +#define BTI_C +#define BTI_J +#endif + +#if (BTI_FLAG | PAC_FLAG) != 0 +#define GNU_PROPERTY_BTI_PAC \ + GNU_PROPERTY(GNU_PROPERTY_AARCH64_FEATURE_1_AND, BTI_FLAG | PAC_FLAG) +#else +#define GNU_PROPERTY_BTI_PAC +#endif + +#if defined(__clang__) || defined(__GCC_HAVE_DWARF2_CFI_ASM) +#define CFI_START .cfi_startproc +#define CFI_END .cfi_endproc +#else +#define CFI_START +#define CFI_END +#endif + +#if defined(__arm__) + +// Determine actual [ARM][THUMB[1][2]] ISA using compiler predefined macros: +// - for '-mthumb -march=armv6' compiler defines '__thumb__' +// - for '-mthumb -march=armv7' compiler defines '__thumb__' and '__thumb2__' +#if defined(__thumb2__) || defined(__thumb__) +#define DEFINE_CODE_STATE .thumb SEPARATOR +#define DECLARE_FUNC_ENCODING .thumb_func SEPARATOR +#if defined(__thumb2__) +#define USE_THUMB_2 +#define IT(cond) it cond +#define ITT(cond) itt cond +#define ITE(cond) ite cond +#else +#define USE_THUMB_1 +#define IT(cond) +#define ITT(cond) +#define ITE(cond) +#endif // defined(__thumb__2) +#else // !defined(__thumb2__) && !defined(__thumb__) +#define DEFINE_CODE_STATE .arm SEPARATOR +#define DECLARE_FUNC_ENCODING +#define IT(cond) +#define ITT(cond) +#define ITE(cond) +#endif + +#if defined(USE_THUMB_1) && defined(USE_THUMB_2) +#error "USE_THUMB_1 and USE_THUMB_2 can't be defined together." +#endif + +#if defined(__ARM_ARCH_4T__) || __ARM_ARCH >= 5 +#define ARM_HAS_BX +#endif +#if !defined(__ARM_FEATURE_CLZ) && !defined(USE_THUMB_1) && \ + (__ARM_ARCH >= 6 || (__ARM_ARCH == 5 && !defined(__ARM_ARCH_5__))) +#define __ARM_FEATURE_CLZ +#endif + +#ifdef ARM_HAS_BX +#define JMP(r) bx r +#define JMPc(r, c) bx##c r +#else +#define JMP(r) mov pc, r +#define JMPc(r, c) mov##c pc, r +#endif + +// pop {pc} can't switch Thumb mode on ARMv4T +#if __ARM_ARCH >= 5 +#define POP_PC() pop {pc} +#else +#define POP_PC() \ + pop {ip}; \ + JMP(ip) +#endif + +#if defined(USE_THUMB_2) +#define WIDE(op) op.w +#else +#define WIDE(op) op +#endif +#else // !defined(__arm) +#define DECLARE_FUNC_ENCODING +#define DEFINE_CODE_STATE +#endif + +#define GLUE2_(a, b) a##b +#define GLUE(a, b) GLUE2_(a, b) +#define GLUE2(a, b) GLUE2_(a, b) +#define GLUE3_(a, b, c) a##b##c +#define GLUE3(a, b, c) GLUE3_(a, b, c) +#define GLUE4_(a, b, c, d) a##b##c##d +#define GLUE4(a, b, c, d) GLUE4_(a, b, c, d) + +#define SYMBOL_NAME(name) GLUE(__USER_LABEL_PREFIX__, name) + +#ifdef VISIBILITY_HIDDEN +#define DECLARE_SYMBOL_VISIBILITY(name) \ + HIDDEN(SYMBOL_NAME(name)) SEPARATOR +#define DECLARE_SYMBOL_VISIBILITY_UNMANGLED(name) \ + HIDDEN(name) SEPARATOR +#else +#define DECLARE_SYMBOL_VISIBILITY(name) +#define DECLARE_SYMBOL_VISIBILITY_UNMANGLED(name) +#endif + +#define DEFINE_COMPILERRT_FUNCTION(name) \ + DEFINE_CODE_STATE \ + FILE_LEVEL_DIRECTIVE SEPARATOR \ + .globl SYMBOL_NAME(name) SEPARATOR \ + SYMBOL_IS_FUNC(SYMBOL_NAME(name)) SEPARATOR \ + DECLARE_SYMBOL_VISIBILITY(name) \ + DECLARE_FUNC_ENCODING \ + SYMBOL_NAME(name): + +#define DEFINE_COMPILERRT_THUMB_FUNCTION(name) \ + DEFINE_CODE_STATE \ + FILE_LEVEL_DIRECTIVE SEPARATOR \ + .globl SYMBOL_NAME(name) SEPARATOR \ + SYMBOL_IS_FUNC(SYMBOL_NAME(name)) SEPARATOR \ + DECLARE_SYMBOL_VISIBILITY(name) SEPARATOR \ + .thumb_func SEPARATOR \ + SYMBOL_NAME(name): + +#define DEFINE_COMPILERRT_PRIVATE_FUNCTION(name) \ + DEFINE_CODE_STATE \ + FILE_LEVEL_DIRECTIVE SEPARATOR \ + .globl SYMBOL_NAME(name) SEPARATOR \ + SYMBOL_IS_FUNC(SYMBOL_NAME(name)) SEPARATOR \ + HIDDEN(SYMBOL_NAME(name)) SEPARATOR \ + DECLARE_FUNC_ENCODING \ + SYMBOL_NAME(name): + +#define DEFINE_COMPILERRT_PRIVATE_FUNCTION_UNMANGLED(name) \ + DEFINE_CODE_STATE \ + .globl name SEPARATOR \ + SYMBOL_IS_FUNC(name) SEPARATOR \ + HIDDEN(name) SEPARATOR \ + DECLARE_FUNC_ENCODING \ + name: + +#define DEFINE_COMPILERRT_OUTLINE_FUNCTION_UNMANGLED(name) \ + DEFINE_CODE_STATE \ + FUNC_ALIGN \ + .globl name SEPARATOR \ + SYMBOL_IS_FUNC(name) SEPARATOR \ + DECLARE_SYMBOL_VISIBILITY_UNMANGLED(name) SEPARATOR \ + DECLARE_FUNC_ENCODING \ + name: \ + SEPARATOR CFI_START \ + SEPARATOR BTI_C + +#define DEFINE_COMPILERRT_FUNCTION_ALIAS(name, target) \ + .globl SYMBOL_NAME(name) SEPARATOR \ + SYMBOL_IS_FUNC(SYMBOL_NAME(name)) SEPARATOR \ + DECLARE_SYMBOL_VISIBILITY(name) SEPARATOR \ + .set SYMBOL_NAME(name), SYMBOL_NAME(target) SEPARATOR + +#if defined(__ARM_EABI__) +#define DEFINE_AEABI_FUNCTION_ALIAS(aeabi_name, name) \ + DEFINE_COMPILERRT_FUNCTION_ALIAS(aeabi_name, name) +#else +#define DEFINE_AEABI_FUNCTION_ALIAS(aeabi_name, name) +#endif + +#ifdef __ELF__ +#define END_COMPILERRT_FUNCTION(name) \ + .size SYMBOL_NAME(name), . - SYMBOL_NAME(name) +#define END_COMPILERRT_OUTLINE_FUNCTION(name) \ + CFI_END SEPARATOR \ + .size SYMBOL_NAME(name), . - SYMBOL_NAME(name) +#else +#define END_COMPILERRT_FUNCTION(name) +#define END_COMPILERRT_OUTLINE_FUNCTION(name) \ + CFI_END +#endif + +#endif // COMPILERRT_ASSEMBLY_H diff --git a/lib/tsan/interception/interception.h b/lib/tsan/interception/interception.h index 069f73d276..38c152952e 100644 --- a/lib/tsan/interception/interception.h +++ b/lib/tsan/interception/interception.h @@ -185,6 +185,11 @@ const interpose_substitution substitution_##func_name[] \ # else # define __ASM_WEAK_WRAPPER(func) ".weak " #func "\n" # endif // SANITIZER_FREEBSD || SANITIZER_NETBSD +# if defined(__arm__) || defined(__aarch64__) +# define ASM_TYPE_FUNCTION_STR "%function" +# else +# define ASM_TYPE_FUNCTION_STR "@function" +# endif // Keep trampoline implementation in sync with sanitizer_common/sanitizer_asm.h # define DECLARE_WRAPPER(ret_type, func, ...) \ extern "C" ret_type func(__VA_ARGS__); \ @@ -196,12 +201,14 @@ const interpose_substitution substitution_##func_name[] \ __ASM_WEAK_WRAPPER(func) \ ".set " #func ", " SANITIZER_STRINGIFY(TRAMPOLINE(func)) "\n" \ ".globl " SANITIZER_STRINGIFY(TRAMPOLINE(func)) "\n" \ - ".type " SANITIZER_STRINGIFY(TRAMPOLINE(func)) ", %function\n" \ + ".type " SANITIZER_STRINGIFY(TRAMPOLINE(func)) ", " \ + ASM_TYPE_FUNCTION_STR "\n" \ SANITIZER_STRINGIFY(TRAMPOLINE(func)) ":\n" \ - SANITIZER_STRINGIFY(CFI_STARTPROC) "\n" \ - SANITIZER_STRINGIFY(ASM_TAIL_CALL) " __interceptor_" \ - SANITIZER_STRINGIFY(ASM_PREEMPTIBLE_SYM(func)) "\n" \ - SANITIZER_STRINGIFY(CFI_ENDPROC) "\n" \ + C_ASM_STARTPROC "\n" \ + C_ASM_TAIL_CALL(SANITIZER_STRINGIFY(TRAMPOLINE(func)), \ + "__interceptor_" \ + SANITIZER_STRINGIFY(ASM_PREEMPTIBLE_SYM(func))) "\n" \ + C_ASM_ENDPROC "\n" \ ".size " SANITIZER_STRINGIFY(TRAMPOLINE(func)) ", " \ ".-" SANITIZER_STRINGIFY(TRAMPOLINE(func)) "\n" \ ); @@ -341,6 +348,18 @@ 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. +// Define a function, if called, will cause a linker error (undefined _DYNAMIC). +// However, -static-pie (which is not common) cannot be detected at link time. +extern uptr kDynamic[] asm("_DYNAMIC"); +inline void DoesNotSupportStaticLinking() { + [[maybe_unused]] volatile auto x = &kDynamic; +} +#else +inline void DoesNotSupportStaticLinking() {} +#endif } // namespace __interception #define INCLUDED_FROM_INTERCEPTION_LIB diff --git a/lib/tsan/interception/interception_linux.h b/lib/tsan/interception/interception_linux.h index 433a3d9bd7..2e01ff4457 100644 --- a/lib/tsan/interception/interception_linux.h +++ b/lib/tsan/interception/interception_linux.h @@ -28,12 +28,14 @@ bool InterceptFunction(const char *name, const char *ver, uptr *ptr_to_real, uptr func, uptr trampoline); } // namespace __interception -#define INTERCEPT_FUNCTION_LINUX_OR_FREEBSD(func) \ - ::__interception::InterceptFunction( \ - #func, \ - (::__interception::uptr *)&REAL(func), \ - (::__interception::uptr)&(func), \ - (::__interception::uptr)&TRAMPOLINE(func)) +// Cast func to type of REAL(func) before casting to uptr in case it is an +// overloaded function, which is the case for some glibc functions when +// _FORTIFY_SOURCE is used. This disambiguates which overload to use. +#define INTERCEPT_FUNCTION_LINUX_OR_FREEBSD(func) \ + ::__interception::InterceptFunction( \ + #func, (::__interception::uptr *)&REAL(func), \ + (::__interception::uptr)(decltype(REAL(func)))&(func), \ + (::__interception::uptr) &TRAMPOLINE(func)) // dlvsym is a GNU extension supported by some other platforms. #if SANITIZER_GLIBC || SANITIZER_FREEBSD || SANITIZER_NETBSD @@ -41,7 +43,7 @@ bool InterceptFunction(const char *name, const char *ver, uptr *ptr_to_real, ::__interception::InterceptFunction( \ #func, symver, \ (::__interception::uptr *)&REAL(func), \ - (::__interception::uptr)&(func), \ + (::__interception::uptr)(decltype(REAL(func)))&(func), \ (::__interception::uptr)&TRAMPOLINE(func)) #else #define INTERCEPT_FUNCTION_VER_LINUX_OR_FREEBSD(func, symver) \ diff --git a/lib/tsan/interception/interception_win.cpp b/lib/tsan/interception/interception_win.cpp index 00c317510e..a638e66ecc 100644 --- a/lib/tsan/interception/interception_win.cpp +++ b/lib/tsan/interception/interception_win.cpp @@ -1,4 +1,4 @@ -//===-- interception_linux.cpp ----------------------------------*- C++ -*-===// +//===-- interception_win.cpp ------------------------------------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -339,7 +339,7 @@ struct TrampolineMemoryRegion { uptr max_size; }; -UNUSED static const uptr kTrampolineScanLimitRange = 1 << 31; // 2 gig +UNUSED static const uptr kTrampolineScanLimitRange = 1ull << 31; // 2 gig static const int kMaxTrampolineRegion = 1024; static TrampolineMemoryRegion TrampolineRegions[kMaxTrampolineRegion]; @@ -431,7 +431,8 @@ static uptr AllocateMemoryForTrampoline(uptr image_address, size_t size) { // The following prologues cannot be patched because of the short jump // jumping to the patching region. -#if SANITIZER_WINDOWS64 +// Short jump patterns below are only for x86_64. +# if SANITIZER_WINDOWS_x64 // ntdll!wcslen in Win11 // 488bc1 mov rax,rcx // 0fb710 movzx edx,word ptr [rax] @@ -457,7 +458,12 @@ static const u8 kPrologueWithShortJump2[] = { // Returns 0 on error. static size_t GetInstructionSize(uptr address, size_t* rel_offset = nullptr) { -#if SANITIZER_WINDOWS64 +#if SANITIZER_ARM64 + // An ARM64 instruction is 4 bytes long. + return 4; +#endif + +# if SANITIZER_WINDOWS_x64 if (memcmp((u8*)address, kPrologueWithShortJump1, sizeof(kPrologueWithShortJump1)) == 0 || memcmp((u8*)address, kPrologueWithShortJump2, @@ -473,6 +479,8 @@ static size_t GetInstructionSize(uptr address, size_t* rel_offset = nullptr) { switch (*(u8*)address) { case 0x90: // 90 : nop + case 0xC3: // C3 : ret (for small/empty function interception + case 0xCC: // CC : int 3 i.e. registering weak functions) return 1; case 0x50: // push eax / rax @@ -496,7 +504,6 @@ static size_t GetInstructionSize(uptr address, size_t* rel_offset = nullptr) { // Cannot overwrite control-instruction. Return 0 to indicate failure. case 0xE9: // E9 XX XX XX XX : jmp