[compiler-rt] 686fe29 - [TSan][libdispatch] Ensure TSan dylib works on old systems
Julian Lettner via llvm-commits
llvm-commits at lists.llvm.org
Tue Aug 18 18:35:31 PDT 2020
Author: Julian Lettner
Date: 2020-08-18T18:34:14-07:00
New Revision: 686fe293e6c5fd51fa0a3c86a43c2d9a652d53b1
URL: https://github.com/llvm/llvm-project/commit/686fe293e6c5fd51fa0a3c86a43c2d9a652d53b1
DIFF: https://github.com/llvm/llvm-project/commit/686fe293e6c5fd51fa0a3c86a43c2d9a652d53b1.diff
LOG: [TSan][libdispatch] Ensure TSan dylib works on old systems
`dispatch_async_and_wait()` was introduced in macOS 10.14, which is
greater than our minimal deployment target. We need to forward declare
it as a "weak import" to ensure we generate a weak reference so the TSan
dylib continues to work on older systems. We cannot simply `#include
<dispatch.h>` or use the Darwin availability macros since this file is
multi-platform.
In addition, we want to prevent building these interceptors at all when
building with older SDKs because linking always fails.
Before:
```
➤ dyldinfo -bind ./lib/clang/12.0.0/lib/darwin/libclang_rt.tsan_osx_dynamic.dylib | grep dispatch_async_and_wait
__DATA __interpose 0x000F5E68 pointer 0 libSystem _dispatch_async_and_wait_f
```
After:
```
➤ dyldinfo -bind ./lib/clang/12.0.0/lib/darwin/libclang_rt.tsan_osx_dynamic.dylib | grep dispatch_async_and_wait
__DATA __got 0x000EC0A8 pointer 0 libSystem _dispatch_async_and_wait (weak import)
__DATA __interpose 0x000F5E78 pointer 0 libSystem _dispatch_async_and_wait (weak import)
```
This is a follow-up to D85854 and should fix:
https://reviews.llvm.org/D85854#2221529
Reviewed By: kubamracek
Differential Revision: https://reviews.llvm.org/D86103
Added:
Modified:
compiler-rt/lib/tsan/rtl/tsan_dispatch_defs.h
compiler-rt/lib/tsan/rtl/tsan_interceptors_libdispatch.cpp
Removed:
################################################################################
diff --git a/compiler-rt/lib/tsan/rtl/tsan_dispatch_defs.h b/compiler-rt/lib/tsan/rtl/tsan_dispatch_defs.h
index 298297af31eb..94e0b50fed36 100644
--- a/compiler-rt/lib/tsan/rtl/tsan_dispatch_defs.h
+++ b/compiler-rt/lib/tsan/rtl/tsan_dispatch_defs.h
@@ -51,11 +51,18 @@ extern const dispatch_block_t _dispatch_data_destructor_munmap;
#define DISPATCH_DATA_DESTRUCTOR_MUNMAP _dispatch_data_destructor_munmap
#if __has_attribute(noescape)
- #define DISPATCH_NOESCAPE __attribute__((__noescape__))
+# define DISPATCH_NOESCAPE __attribute__((__noescape__))
#else
- #define DISPATCH_NOESCAPE
+# define DISPATCH_NOESCAPE
#endif
+#if SANITIZER_MAC
+# define SANITIZER_WEAK_IMPORT extern "C" __attribute((weak_import))
+#else
+# define SANITIZER_WEAK_IMPORT extern "C" __attribute((weak))
+#endif
+
+
// Data types used in dispatch APIs
typedef unsigned long size_t;
typedef unsigned long uintptr_t;
diff --git a/compiler-rt/lib/tsan/rtl/tsan_interceptors_libdispatch.cpp b/compiler-rt/lib/tsan/rtl/tsan_interceptors_libdispatch.cpp
index 292ea5fbb239..99ec27501100 100644
--- a/compiler-rt/lib/tsan/rtl/tsan_interceptors_libdispatch.cpp
+++ b/compiler-rt/lib/tsan/rtl/tsan_interceptors_libdispatch.cpp
@@ -19,6 +19,10 @@
#include "BlocksRuntime/Block.h"
#include "tsan_dispatch_defs.h"
+#if SANITIZER_MAC
+# include <Availability.h>
+#endif
+
namespace __tsan {
typedef u16 uint16_t;
@@ -219,8 +223,23 @@ static void invoke_and_release_block(void *param) {
DISPATCH_INTERCEPT(dispatch, false)
DISPATCH_INTERCEPT(dispatch_barrier, true)
-DISPATCH_INTERCEPT_SYNC_F(dispatch_async_and_wait_f, false)
+// 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)
+// 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
+// imports". Note that this file is multi-platform, so we cannot include the
+// actual header file (#include <dispatch/dispatch.h>).
+SANITIZER_WEAK_IMPORT void dispatch_async_and_wait(
+ dispatch_queue_t queue, DISPATCH_NOESCAPE dispatch_block_t block);
+SANITIZER_WEAK_IMPORT void dispatch_async_and_wait_f(
+ dispatch_queue_t queue, void *context, dispatch_function_t work);
+
DISPATCH_INTERCEPT_SYNC_B(dispatch_async_and_wait, false)
+DISPATCH_INTERCEPT_SYNC_F(dispatch_async_and_wait_f, false)
+#endif
+
DECLARE_REAL(void, dispatch_after_f, dispatch_time_t when,
dispatch_queue_t queue, void *context, dispatch_function_t work)
More information about the llvm-commits
mailing list