diff options
Diffstat (limited to 'compiler-rt/lib')
-rw-r--r-- | compiler-rt/lib/builtins/cpu_model/aarch64.c | 11 | ||||
-rw-r--r-- | compiler-rt/lib/builtins/cpu_model/aarch64/hwcap.inc | 5 | ||||
-rw-r--r-- | compiler-rt/lib/builtins/cpu_model/aarch64/lse_atomics/android.inc | 1 | ||||
-rw-r--r-- | compiler-rt/lib/builtins/cpu_model/aarch64/lse_atomics/getauxval.inc | 2 | ||||
-rw-r--r-- | compiler-rt/lib/orc/coff_platform.cpp | 72 | ||||
-rw-r--r-- | compiler-rt/lib/orc/coff_platform.h | 1 | ||||
-rw-r--r-- | compiler-rt/lib/orc/dlfcn_wrapper.cpp | 2 | ||||
-rw-r--r-- | compiler-rt/lib/sanitizer_common/sanitizer_mac.cpp | 10 | ||||
-rw-r--r-- | compiler-rt/lib/tsan/rtl/tsan_flags.cpp | 37 | ||||
-rw-r--r-- | compiler-rt/lib/tsan/rtl/tsan_flags.h | 8 | ||||
-rw-r--r-- | compiler-rt/lib/tsan/rtl/tsan_flags.inc | 12 | ||||
-rw-r--r-- | compiler-rt/lib/tsan/rtl/tsan_interceptors.h | 10 | ||||
-rw-r--r-- | compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp | 11 | ||||
-rw-r--r-- | compiler-rt/lib/tsan/rtl/tsan_rtl.cpp | 14 | ||||
-rw-r--r-- | compiler-rt/lib/tsan/rtl/tsan_rtl.h | 4 |
15 files changed, 184 insertions, 16 deletions
diff --git a/compiler-rt/lib/builtins/cpu_model/aarch64.c b/compiler-rt/lib/builtins/cpu_model/aarch64.c index be29c90..06bc7c4a 100644 --- a/compiler-rt/lib/builtins/cpu_model/aarch64.c +++ b/compiler-rt/lib/builtins/cpu_model/aarch64.c @@ -32,19 +32,21 @@ typedef struct __ifunc_arg_t { _Bool __aarch64_have_lse_atomics __attribute__((visibility("hidden"), nocommon)) = false; +// The formatter wants to re-order these includes, but doing so is incorrect: +// clang-format off #if defined(__FreeBSD__) || defined(__OpenBSD__) -// clang-format off: should not reorder sys/auxv.h alphabetically #include <sys/auxv.h> -// clang-format on #include "aarch64/hwcap.inc" #include "aarch64/lse_atomics/elf_aux_info.inc" #elif defined(__Fuchsia__) #include "aarch64/hwcap.inc" #include "aarch64/lse_atomics/fuchsia.inc" #elif defined(__ANDROID__) +#include <sys/auxv.h> #include "aarch64/hwcap.inc" #include "aarch64/lse_atomics/android.inc" -#elif defined(__linux__) && __has_include(<sys/auxv.h>) +#elif defined(__linux__) +#include <sys/auxv.h> #include "aarch64/hwcap.inc" #include "aarch64/lse_atomics/getauxval.inc" #elif defined(_WIN32) @@ -52,6 +54,7 @@ _Bool __aarch64_have_lse_atomics #else // When unimplemented, we leave __aarch64_have_lse_atomics initialized to false. #endif +// clang-format on #if !defined(DISABLE_AARCH64_FMV) @@ -74,7 +77,7 @@ struct { #elif defined(__ANDROID__) #include "aarch64/fmv/hwcap.inc" #include "aarch64/fmv/android.inc" -#elif defined(__linux__) && __has_include(<sys/auxv.h>) +#elif defined(__linux__) #include "aarch64/fmv/hwcap.inc" #include "aarch64/fmv/getauxval.inc" #elif defined(_WIN32) diff --git a/compiler-rt/lib/builtins/cpu_model/aarch64/hwcap.inc b/compiler-rt/lib/builtins/cpu_model/aarch64/hwcap.inc index 159c617..1c53191 100644 --- a/compiler-rt/lib/builtins/cpu_model/aarch64/hwcap.inc +++ b/compiler-rt/lib/builtins/cpu_model/aarch64/hwcap.inc @@ -1,8 +1,3 @@ -#if __has_include(<sys/hwcap.h>) -#include <sys/hwcap.h> -#define HAVE_SYS_HWCAP_H -#endif - #ifndef _IFUNC_ARG_HWCAP #define _IFUNC_ARG_HWCAP (1ULL << 62) #endif diff --git a/compiler-rt/lib/builtins/cpu_model/aarch64/lse_atomics/android.inc b/compiler-rt/lib/builtins/cpu_model/aarch64/lse_atomics/android.inc index 94bf64a..8d8a913 100644 --- a/compiler-rt/lib/builtins/cpu_model/aarch64/lse_atomics/android.inc +++ b/compiler-rt/lib/builtins/cpu_model/aarch64/lse_atomics/android.inc @@ -1,5 +1,4 @@ #include <string.h> -#include <sys/auxv.h> #include <sys/system_properties.h> static bool __isExynos9810(void) { diff --git a/compiler-rt/lib/builtins/cpu_model/aarch64/lse_atomics/getauxval.inc b/compiler-rt/lib/builtins/cpu_model/aarch64/lse_atomics/getauxval.inc index 6642c1f..670aba5 100644 --- a/compiler-rt/lib/builtins/cpu_model/aarch64/lse_atomics/getauxval.inc +++ b/compiler-rt/lib/builtins/cpu_model/aarch64/lse_atomics/getauxval.inc @@ -1,5 +1,3 @@ -#include <sys/auxv.h> - static void CONSTRUCTOR_ATTRIBUTE init_have_lse_atomics(void) { unsigned long hwcap = getauxval(AT_HWCAP); __aarch64_have_lse_atomics = (hwcap & HWCAP_ATOMICS) != 0; diff --git a/compiler-rt/lib/orc/coff_platform.cpp b/compiler-rt/lib/orc/coff_platform.cpp index 78144ec..4cce20e 100644 --- a/compiler-rt/lib/orc/coff_platform.cpp +++ b/compiler-rt/lib/orc/coff_platform.cpp @@ -110,6 +110,7 @@ public: const char *dlerror(); void *dlopen(std::string_view Name, int Mode); + int dlupdate(void *DSOHandle); int dlclose(void *Header); void *dlsym(void *Header, std::string_view Symbol); @@ -141,6 +142,10 @@ private: Error dlopenFull(JITDylibState &JDS); Error dlopenInitialize(JITDylibState &JDS, COFFJITDylibDepInfoMap &DepInfo); + Error dlupdateImpl(void *DSOHandle); + Error dlupdateFull(JITDylibState &JDS); + Error dlupdateInitialize(JITDylibState &JDS); + Error dlcloseImpl(void *DSOHandle); Error dlcloseDeinitialize(JITDylibState &JDS); @@ -265,6 +270,20 @@ void *COFFPlatformRuntimeState::dlopen(std::string_view Path, int Mode) { } } +int COFFPlatformRuntimeState::dlupdate(void *DSOHandle) { + ORC_RT_DEBUG({ + std::string S; + printdbg("COFFPlatform::dlupdate(%p) (%s)\n", DSOHandle, S.c_str()); + }); + std::lock_guard<std::recursive_mutex> Lock(JDStatesMutex); + if (auto Err = dlupdateImpl(DSOHandle)) { + // FIXME: Make dlerror thread safe. + DLFcnError = toString(std::move(Err)); + return -1; + } + return 0; +} + int COFFPlatformRuntimeState::dlclose(void *DSOHandle) { ORC_RT_DEBUG({ auto *JDS = getJITDylibStateByHeader(DSOHandle); @@ -390,6 +409,55 @@ Error COFFPlatformRuntimeState::dlopenInitialize( return Error::success(); } +Error COFFPlatformRuntimeState::dlupdateImpl(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()); + } + + if (!JDS->referenced()) + return make_error<StringError>("dlupdate failed, JITDylib must be open."); + + if (auto Err = dlupdateFull(*JDS)) + return Err; + + return Error::success(); +} + +Error COFFPlatformRuntimeState::dlupdateFull(JITDylibState &JDS) { + // Call back to the JIT to push the initializers. + Expected<COFFJITDylibDepInfoMap> DepInfoMap((COFFJITDylibDepInfoMap())); + if (auto Err = WrapperFunction<SPSExpected<SPSCOFFJITDylibDepInfoMap>( + SPSExecutorAddr)>:: + call(JITDispatch(&__orc_rt_coff_push_initializers_tag), DepInfoMap, + ExecutorAddr::fromPtr(JDS.Header))) + return Err; + if (!DepInfoMap) + return DepInfoMap.takeError(); + + if (auto Err = dlupdateInitialize(JDS)) + return Err; + + return Error::success(); +} + +Error COFFPlatformRuntimeState::dlupdateInitialize(JITDylibState &JDS) { + ORC_RT_DEBUG({ + printdbg("COFFPlatformRuntimeState::dlupdateInitialize(\"%s\")\n", + JDS.Name.c_str()); + }); + + // Run static initializers. + JDS.CInitSection.RunAllNewAndFlush(); + JDS.CXXInitSection.RunAllNewAndFlush(); + + return Error::success(); +} + Error COFFPlatformRuntimeState::dlcloseImpl(void *DSOHandle) { // Try to find JITDylib state by header. auto *JDS = getJITDylibStateByHeader(DSOHandle); @@ -667,6 +735,10 @@ void *__orc_rt_coff_jit_dlopen(const char *path, int mode) { return COFFPlatformRuntimeState::get().dlopen(path, mode); } +int __orc_rt_coff_jit_dlupdate(void *dso_handle) { + return COFFPlatformRuntimeState::get().dlupdate(dso_handle); +} + int __orc_rt_coff_jit_dlclose(void *header) { return COFFPlatformRuntimeState::get().dlclose(header); } diff --git a/compiler-rt/lib/orc/coff_platform.h b/compiler-rt/lib/orc/coff_platform.h index aae57bc..e9891f0b 100644 --- a/compiler-rt/lib/orc/coff_platform.h +++ b/compiler-rt/lib/orc/coff_platform.h @@ -19,6 +19,7 @@ // dlfcn functions. ORC_RT_INTERFACE const char *__orc_rt_coff_jit_dlerror(); ORC_RT_INTERFACE void *__orc_rt_coff_jit_dlopen(const char *path, int mode); +ORC_RT_INTERFACE int __orc_rt_coff_jit_dlupdate(void *dso_handle); ORC_RT_INTERFACE int __orc_rt_coff_jit_dlclose(void *header); ORC_RT_INTERFACE void *__orc_rt_coff_jit_dlsym(void *header, const char *symbol); diff --git a/compiler-rt/lib/orc/dlfcn_wrapper.cpp b/compiler-rt/lib/orc/dlfcn_wrapper.cpp index 02e3796..cb92a1f 100644 --- a/compiler-rt/lib/orc/dlfcn_wrapper.cpp +++ b/compiler-rt/lib/orc/dlfcn_wrapper.cpp @@ -42,7 +42,6 @@ __orc_rt_jit_dlopen_wrapper(const char *ArgData, size_t ArgSize) { .release(); } -#ifndef _WIN32 ORC_RT_INTERFACE orc_rt_WrapperFunctionResult __orc_rt_jit_dlupdate_wrapper(const char *ArgData, size_t ArgSize) { return WrapperFunction<int32_t(SPSExecutorAddr)>::handle( @@ -52,7 +51,6 @@ __orc_rt_jit_dlupdate_wrapper(const char *ArgData, size_t ArgSize) { }) .release(); } -#endif ORC_RT_INTERFACE orc_rt_WrapperFunctionResult __orc_rt_jit_dlclose_wrapper(const char *ArgData, size_t ArgSize) { diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_mac.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_mac.cpp index 721c39d..0040f79 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_mac.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_mac.cpp @@ -105,6 +105,10 @@ extern "C" { mach_msg_type_number_t *infoCnt); } +// Weak symbol no-op when TSan is not linked +SANITIZER_WEAK_ATTRIBUTE extern void __tsan_set_in_internal_write_call( + bool value) {} + namespace __sanitizer { #include "sanitizer_syscall_generic.inc" @@ -175,7 +179,11 @@ uptr internal_read(fd_t fd, void *buf, uptr count) { } uptr internal_write(fd_t fd, const void *buf, uptr count) { - return write(fd, buf, count); + // We need to disable interceptors when writing in TSan + __tsan_set_in_internal_write_call(true); + uptr res = write(fd, buf, count); + __tsan_set_in_internal_write_call(false); + return res; } uptr internal_stat(const char *path, void *buf) { diff --git a/compiler-rt/lib/tsan/rtl/tsan_flags.cpp b/compiler-rt/lib/tsan/rtl/tsan_flags.cpp index 3fd58f4..50632d2 100644 --- a/compiler-rt/lib/tsan/rtl/tsan_flags.cpp +++ b/compiler-rt/lib/tsan/rtl/tsan_flags.cpp @@ -20,6 +20,43 @@ #include "tsan_rtl.h" #include "ubsan/ubsan_flags.h" +#if SANITIZER_APPLE +namespace __sanitizer { + +template <> +inline bool FlagHandler<LockDuringWriteSetting>::Parse(const char *value) { + if (internal_strcmp(value, "on") == 0) { + *t_ = kLockDuringAllWrites; + return true; + } + if (internal_strcmp(value, "disable_for_current_process") == 0) { + *t_ = kNoLockDuringWritesCurrentProcess; + return true; + } + if (internal_strcmp(value, "disable_for_all_processes") == 0) { + *t_ = kNoLockDuringWritesAllProcesses; + return true; + } + Printf("ERROR: Invalid value for signal handler option: '%s'\n", value); + return false; +} + +template <> +inline bool FlagHandler<LockDuringWriteSetting>::Format(char *buffer, + uptr size) { + switch (*t_) { + case kLockDuringAllWrites: + return FormatString(buffer, size, "on"); + case kNoLockDuringWritesCurrentProcess: + return FormatString(buffer, size, "disable_for_current_process"); + case kNoLockDuringWritesAllProcesses: + return FormatString(buffer, size, "disable_for_all_processes"); + } +} + +} // namespace __sanitizer +#endif + namespace __tsan { // Can be overriden in frontend. diff --git a/compiler-rt/lib/tsan/rtl/tsan_flags.h b/compiler-rt/lib/tsan/rtl/tsan_flags.h index da27d5b..477d08d 100644 --- a/compiler-rt/lib/tsan/rtl/tsan_flags.h +++ b/compiler-rt/lib/tsan/rtl/tsan_flags.h @@ -16,6 +16,14 @@ #include "sanitizer_common/sanitizer_flags.h" #include "sanitizer_common/sanitizer_deadlock_detector_interface.h" +#if SANITIZER_APPLE +enum LockDuringWriteSetting { + kLockDuringAllWrites, + kNoLockDuringWritesCurrentProcess, + kNoLockDuringWritesAllProcesses, +}; +#endif + namespace __tsan { struct Flags : DDFlags { diff --git a/compiler-rt/lib/tsan/rtl/tsan_flags.inc b/compiler-rt/lib/tsan/rtl/tsan_flags.inc index 731d776..64cc091 100644 --- a/compiler-rt/lib/tsan/rtl/tsan_flags.inc +++ b/compiler-rt/lib/tsan/rtl/tsan_flags.inc @@ -80,3 +80,15 @@ TSAN_FLAG(bool, shared_ptr_interceptor, true, 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.") + +#if SANITIZER_APPLE +TSAN_FLAG(LockDuringWriteSetting, lock_during_write, kLockDuringAllWrites, + "Determines whether to obtain a lock while writing logs or error " + "reports. " + "\"on\" - [default] lock during all writes. " + "\"disable_for_current_process\" - don't lock during all writes in " + "the current process, but do lock for all writes in child " + "processes." + "\"disable_for_all_processes\" - don't lock during all writes in " + "the current process and it's children processes.") +#endif diff --git a/compiler-rt/lib/tsan/rtl/tsan_interceptors.h b/compiler-rt/lib/tsan/rtl/tsan_interceptors.h index a357a87..d4b65ab 100644 --- a/compiler-rt/lib/tsan/rtl/tsan_interceptors.h +++ b/compiler-rt/lib/tsan/rtl/tsan_interceptors.h @@ -1,6 +1,9 @@ #ifndef TSAN_INTERCEPTORS_H #define TSAN_INTERCEPTORS_H +#if SANITIZER_APPLE +# include "sanitizer_common/sanitizer_mac.h" +#endif #include "sanitizer_common/sanitizer_stacktrace.h" #include "tsan_rtl.h" @@ -43,7 +46,12 @@ inline bool in_symbolizer() { #endif inline bool MustIgnoreInterceptor(ThreadState *thr) { - return !thr->is_inited || thr->ignore_interceptors || thr->in_ignored_lib; + return !thr->is_inited || thr->ignore_interceptors || thr->in_ignored_lib +#if SANITIZER_APPLE + || (flags()->lock_during_write != kLockDuringAllWrites && + thr->in_internal_write_call) +#endif + ; } } // namespace __tsan diff --git a/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp b/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp index 37c69b1..0c35804 100644 --- a/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp +++ b/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp @@ -31,6 +31,9 @@ #include "sanitizer_common/sanitizer_tls_get_addr.h" #include "sanitizer_common/sanitizer_vector.h" #include "tsan_fd.h" +#if SANITIZER_APPLE +# include "tsan_flags.h" +#endif #include "tsan_interceptors.h" #include "tsan_interface.h" #include "tsan_mman.h" @@ -1665,6 +1668,14 @@ TSAN_INTERCEPTOR(int, pthread_barrier_wait, void *b) { TSAN_INTERCEPTOR(int, pthread_once, void *o, void (*f)()) { SCOPED_INTERCEPTOR_RAW(pthread_once, o, f); +#if SANITIZER_APPLE + if (flags()->lock_during_write != kLockDuringAllWrites && + cur_thread_init()->in_internal_write_call) { + // This is needed to make it through process launch without hanging + f(); + return 0; + } +#endif if (o == 0 || f == 0) return errno_EINVAL; atomic_uint32_t *a; diff --git a/compiler-rt/lib/tsan/rtl/tsan_rtl.cpp b/compiler-rt/lib/tsan/rtl/tsan_rtl.cpp index 0d7247a..b8041d7 100644 --- a/compiler-rt/lib/tsan/rtl/tsan_rtl.cpp +++ b/compiler-rt/lib/tsan/rtl/tsan_rtl.cpp @@ -40,6 +40,13 @@ SANITIZER_WEAK_DEFAULT_IMPL void __tsan_test_only_on_fork() {} #endif +#if SANITIZER_APPLE +// Override weak symbol from sanitizer_common +extern void __tsan_set_in_internal_write_call(bool value) { + __tsan::cur_thread_init()->in_internal_write_call = value; +} +#endif + namespace __tsan { #if !SANITIZER_GO @@ -893,6 +900,13 @@ void ForkChildAfter(ThreadState* thr, uptr pc, bool start_thread) { ThreadIgnoreBegin(thr, pc); ThreadIgnoreSyncBegin(thr, pc); } + +# if SANITIZER_APPLE + // This flag can have inheritance disabled - we are the child so act + // accordingly + if (flags()->lock_during_write == kNoLockDuringWritesCurrentProcess) + flags()->lock_during_write = kLockDuringAllWrites; +# endif } #endif diff --git a/compiler-rt/lib/tsan/rtl/tsan_rtl.h b/compiler-rt/lib/tsan/rtl/tsan_rtl.h index 0b6d5f0..77390f0 100644 --- a/compiler-rt/lib/tsan/rtl/tsan_rtl.h +++ b/compiler-rt/lib/tsan/rtl/tsan_rtl.h @@ -236,6 +236,10 @@ struct alignas(SANITIZER_CACHE_LINE_SIZE) ThreadState { const ReportDesc *current_report; +#if SANITIZER_APPLE + bool in_internal_write_call; +#endif + explicit ThreadState(Tid tid); }; |