forked from OSchip/llvm-project
[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
This commit is contained in:
parent
0c4863a253
commit
686fe293e6
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue