1414#include " sanitizer_common/sanitizer_platform.h"
1515#if SANITIZER_APPLE
1616
17- #include " interception/interception.h "
18- #include " tsan_interceptors.h "
19- #include " tsan_interface.h "
20- #include " tsan_interface_ann.h "
21- #include " tsan_spinlock_defs_mac.h "
22- # include " sanitizer_common/sanitizer_addrhashmap.h "
23-
24- #include < errno.h >
25- #include < libkern/OSAtomic.h >
26- #include < objc/objc-sync.h >
27- #include < os/lock.h >
28- #include < sys/ucontext.h >
29-
30- #if defined(__has_include) && __has_include(<xpc/xpc.h>)
31- #include < xpc/xpc.h>
32- #endif // #if defined(__has_include) && __has_include(<xpc/xpc.h>)
17+ # include < errno.h >
18+ # include < libkern/OSAtomic.h >
19+ # include < objc/objc-sync.h >
20+ # include < os/lock.h >
21+ # include < sys/ucontext.h >
22+
23+ # include " interception/interception.h "
24+ # include " sanitizer_common/sanitizer_addrhashmap.h "
25+ # include " tsan_interceptors.h "
26+ # include " tsan_interface.h "
27+ # include " tsan_interface_ann.h "
28+ # include " tsan_spinlock_defs_mac.h "
29+
30+ # if defined(__has_include) && __has_include(<xpc/xpc.h>)
31+ # include < xpc/xpc.h>
32+ # endif // #if defined(__has_include) && __has_include(<xpc/xpc.h>)
3333
3434typedef long long_t ;
3535
@@ -49,55 +49,56 @@ static constexpr morder kMacOrderBarrier = mo_acq_rel;
4949static constexpr morder kMacOrderNonBarrier = mo_acq_rel;
5050static constexpr morder kMacFailureOrder = mo_relaxed;
5151
52- #define OSATOMIC_INTERCEPTOR (return_t, t, tsan_t, f, tsan_atomic_f, mo ) \
53- TSAN_INTERCEPTOR (return_t , f, t x, volatile t *ptr) { \
54- SCOPED_TSAN_INTERCEPTOR (f, x, ptr); \
55- return tsan_atomic_f ((volatile tsan_t *)ptr, x, mo); \
56- }
52+ # define OSATOMIC_INTERCEPTOR (return_t, t, tsan_t, f, tsan_atomic_f, mo ) \
53+ TSAN_INTERCEPTOR (return_t , f, t x, volatile t *ptr) { \
54+ SCOPED_TSAN_INTERCEPTOR (f, x, ptr); \
55+ return tsan_atomic_f ((volatile tsan_t *)ptr, x, mo); \
56+ }
5757
58- #define OSATOMIC_INTERCEPTOR_PLUS_X (return_t, t, tsan_t, f, tsan_atomic_f, mo ) \
59- TSAN_INTERCEPTOR (return_t , f, t x, volatile t *ptr) { \
60- SCOPED_TSAN_INTERCEPTOR (f, x, ptr); \
61- return tsan_atomic_f ((volatile tsan_t *)ptr, x, mo) + x; \
62- }
58+ # define OSATOMIC_INTERCEPTOR_PLUS_X (return_t , t, tsan_t , f, tsan_atomic_f, \
59+ mo) \
60+ TSAN_INTERCEPTOR (return_t , f, t x, volatile t *ptr) { \
61+ SCOPED_TSAN_INTERCEPTOR (f, x, ptr); \
62+ return tsan_atomic_f ((volatile tsan_t *)ptr, x, mo) + x; \
63+ }
6364
64- #define OSATOMIC_INTERCEPTOR_PLUS_1 (return_t, t, tsan_t, f, tsan_atomic_f, mo ) \
65- TSAN_INTERCEPTOR (return_t , f, volatile t *ptr) { \
66- SCOPED_TSAN_INTERCEPTOR (f, ptr); \
67- return tsan_atomic_f ((volatile tsan_t *)ptr, 1 , mo) + 1 ; \
68- }
65+ # define OSATOMIC_INTERCEPTOR_PLUS_1 (return_t , t, tsan_t , f, tsan_atomic_f, \
66+ mo) \
67+ TSAN_INTERCEPTOR (return_t , f, volatile t *ptr) { \
68+ SCOPED_TSAN_INTERCEPTOR (f, ptr); \
69+ return tsan_atomic_f ((volatile tsan_t *)ptr, 1 , mo) + 1 ; \
70+ }
6971
70- #define OSATOMIC_INTERCEPTOR_MINUS_1 (return_t , t, tsan_t , f, tsan_atomic_f, \
71- mo) \
72- TSAN_INTERCEPTOR (return_t , f, volatile t *ptr) { \
73- SCOPED_TSAN_INTERCEPTOR (f, ptr); \
74- return tsan_atomic_f ((volatile tsan_t *)ptr, 1 , mo) - 1 ; \
75- }
72+ # define OSATOMIC_INTERCEPTOR_MINUS_1 (return_t , t, tsan_t , f, tsan_atomic_f, \
73+ mo) \
74+ TSAN_INTERCEPTOR (return_t , f, volatile t *ptr) { \
75+ SCOPED_TSAN_INTERCEPTOR (f, ptr); \
76+ return tsan_atomic_f ((volatile tsan_t *)ptr, 1 , mo) - 1 ; \
77+ }
7678
77- #define OSATOMIC_INTERCEPTORS_ARITHMETIC (f, tsan_atomic_f, m ) \
78- m (int32_t , int32_t , a32, f##32 , __tsan_atomic32_##tsan_atomic_f, \
79- kMacOrderNonBarrier ) \
80- m (int32_t , int32_t , a32, f##32 ##Barrier, __tsan_atomic32_##tsan_atomic_f, \
81- kMacOrderBarrier ) \
82- m (int64_t , int64_t , a64, f##64 , __tsan_atomic64_##tsan_atomic_f, \
83- kMacOrderNonBarrier ) \
84- m (int64_t , int64_t , a64, f##64 ##Barrier, __tsan_atomic64_##tsan_atomic_f, \
85- kMacOrderBarrier )
86-
87- #define OSATOMIC_INTERCEPTORS_BITWISE (f, tsan_atomic_f, m, m_orig ) \
88- m (int32_t , uint32_t , a32, f##32 , __tsan_atomic32_##tsan_atomic_f, \
89- kMacOrderNonBarrier ) \
90- m (int32_t , uint32_t , a32, f##32 ##Barrier, __tsan_atomic32_##tsan_atomic_f, \
91- kMacOrderBarrier ) \
92- m_orig (int32_t , uint32_t , a32, f##32 ##Orig, __tsan_atomic32_##tsan_atomic_f, \
93- kMacOrderNonBarrier ) \
94- m_orig (int32_t , uint32_t , a32, f##32 ##OrigBarrier, \
95- __tsan_atomic32_##tsan_atomic_f, kMacOrderBarrier )
96-
97-
98- #pragma clang diagnostic push
79+ # define OSATOMIC_INTERCEPTORS_ARITHMETIC (f, tsan_atomic_f, m ) \
80+ m (int32_t , int32_t , a32, f##32 , __tsan_atomic32_##tsan_atomic_f, \
81+ kMacOrderNonBarrier ) \
82+ m (int32_t , int32_t , a32, f##32 ##Barrier, \
83+ __tsan_atomic32_##tsan_atomic_f, kMacOrderBarrier ) \
84+ m (int64_t , int64_t , a64, f##64 , __tsan_atomic64_##tsan_atomic_f, \
85+ kMacOrderNonBarrier ) \
86+ m (int64_t , int64_t , a64, f##64 ##Barrier, \
87+ __tsan_atomic64_##tsan_atomic_f, kMacOrderBarrier )
88+
89+ # define OSATOMIC_INTERCEPTORS_BITWISE (f, tsan_atomic_f, m, m_orig ) \
90+ m (int32_t , uint32_t , a32, f##32 , __tsan_atomic32_##tsan_atomic_f, \
91+ kMacOrderNonBarrier ) \
92+ m (int32_t , uint32_t , a32, f##32 ##Barrier, \
93+ __tsan_atomic32_##tsan_atomic_f, kMacOrderBarrier ) \
94+ m_orig (int32_t , uint32_t , a32, f##32 ##Orig, \
95+ __tsan_atomic32_##tsan_atomic_f, kMacOrderNonBarrier ) \
96+ m_orig (int32_t , uint32_t , a32, f##32 ##OrigBarrier, \
97+ __tsan_atomic32_##tsan_atomic_f, kMacOrderBarrier )
98+
99+ # pragma clang diagnostic push
99100// OSAtomic* functions are deprecated.
100- #pragma clang diagnostic ignored "-Wdeprecated-declarations"
101+ # pragma clang diagnostic ignored "-Wdeprecated-declarations"
101102OSATOMIC_INTERCEPTORS_ARITHMETIC (OSAtomicAdd, fetch_add,
102103 OSATOMIC_INTERCEPTOR_PLUS_X)
103104OSATOMIC_INTERCEPTORS_ARITHMETIC (OSAtomicIncrement, fetch_add,
@@ -111,25 +112,25 @@ OSATOMIC_INTERCEPTORS_BITWISE(OSAtomicAnd, fetch_and,
111112OSATOMIC_INTERCEPTORS_BITWISE (OSAtomicXor, fetch_xor,
112113 OSATOMIC_INTERCEPTOR_PLUS_X, OSATOMIC_INTERCEPTOR)
113114
114- #define OSATOMIC_INTERCEPTORS_CAS (f, tsan_atomic_f, tsan_t, t ) \
115- TSAN_INTERCEPTOR (bool , f, t old_value, t new_value, t volatile *ptr) { \
116- SCOPED_TSAN_INTERCEPTOR (f, old_value, new_value, ptr); \
117- return tsan_atomic_f##_compare_exchange_strong ( \
118- (volatile tsan_t *)ptr, (tsan_t *)&old_value, (tsan_t )new_value, \
119- kMacOrderNonBarrier , kMacFailureOrder ); \
120- } \
121- \
122- TSAN_INTERCEPTOR (bool , f##Barrier, t old_value, t new_value, \
123- t volatile *ptr) { \
124- SCOPED_TSAN_INTERCEPTOR (f##Barrier, old_value, new_value, ptr); \
125- return tsan_atomic_f##_compare_exchange_strong ( \
126- (volatile tsan_t *)ptr, (tsan_t *)&old_value, (tsan_t )new_value, \
127- kMacOrderBarrier , kMacFailureOrder ); \
128- }
115+ # define OSATOMIC_INTERCEPTORS_CAS (f, tsan_atomic_f, tsan_t, t ) \
116+ TSAN_INTERCEPTOR (bool , f, t old_value, t new_value, t volatile *ptr) { \
117+ SCOPED_TSAN_INTERCEPTOR (f, old_value, new_value, ptr); \
118+ return tsan_atomic_f##_compare_exchange_strong ( \
119+ (volatile tsan_t *)ptr, (tsan_t *)&old_value, (tsan_t )new_value, \
120+ kMacOrderNonBarrier , kMacFailureOrder ); \
121+ } \
122+ \
123+ TSAN_INTERCEPTOR (bool , f##Barrier, t old_value, t new_value, \
124+ t volatile *ptr) { \
125+ SCOPED_TSAN_INTERCEPTOR (f##Barrier, old_value, new_value, ptr); \
126+ return tsan_atomic_f##_compare_exchange_strong ( \
127+ (volatile tsan_t *)ptr, (tsan_t *)&old_value, (tsan_t )new_value, \
128+ kMacOrderBarrier , kMacFailureOrder ); \
129+ }
129130
130- #pragma clang diagnostic push
131+ # pragma clang diagnostic push
131132// OSAtomicCompareAndSwap* functions are deprecated.
132- #pragma clang diagnostic ignored "-Wdeprecated-declarations"
133+ # pragma clang diagnostic ignored "-Wdeprecated-declarations"
133134OSATOMIC_INTERCEPTORS_CAS (OSAtomicCompareAndSwapInt, __tsan_atomic32, a32, int )
134135OSATOMIC_INTERCEPTORS_CAS (OSAtomicCompareAndSwapLong, __tsan_atomic64, a64,
135136 long_t )
@@ -139,21 +140,21 @@ OSATOMIC_INTERCEPTORS_CAS(OSAtomicCompareAndSwap32, __tsan_atomic32, a32,
139140 int32_t )
140141OSATOMIC_INTERCEPTORS_CAS (OSAtomicCompareAndSwap64, __tsan_atomic64, a64,
141142 int64_t )
142- #pragma clang diagnostic pop
143-
144- #define OSATOMIC_INTERCEPTOR_BITOP (f, op, clear, mo ) \
145- TSAN_INTERCEPTOR (bool , f, uint32_t n, volatile void *ptr) { \
146- SCOPED_TSAN_INTERCEPTOR (f, n, ptr); \
147- volatile char *byte_ptr = ((volatile char *)ptr) + (n >> 3 ); \
148- char bit = 0x80u >> (n & 7 ); \
149- char mask = clear ? ~bit : bit; \
150- char orig_byte = op ((volatile a8 *)byte_ptr, mask, mo); \
151- return orig_byte & bit; \
152- }
143+ # pragma clang diagnostic pop
144+
145+ # define OSATOMIC_INTERCEPTOR_BITOP (f, op, clear, mo ) \
146+ TSAN_INTERCEPTOR (bool , f, uint32_t n, volatile void *ptr) { \
147+ SCOPED_TSAN_INTERCEPTOR (f, n, ptr); \
148+ volatile char *byte_ptr = ((volatile char *)ptr) + (n >> 3 ); \
149+ char bit = 0x80u >> (n & 7 ); \
150+ char mask = clear ? ~bit : bit; \
151+ char orig_byte = op ((volatile a8 *)byte_ptr, mask, mo); \
152+ return orig_byte & bit; \
153+ }
153154
154- #define OSATOMIC_INTERCEPTORS_BITOP (f, op, clear ) \
155- OSATOMIC_INTERCEPTOR_BITOP (f, op, clear, kMacOrderNonBarrier ) \
156- OSATOMIC_INTERCEPTOR_BITOP (f##Barrier, op, clear, kMacOrderBarrier )
155+ # define OSATOMIC_INTERCEPTORS_BITOP (f, op, clear ) \
156+ OSATOMIC_INTERCEPTOR_BITOP (f, op, clear, kMacOrderNonBarrier ) \
157+ OSATOMIC_INTERCEPTOR_BITOP (f##Barrier, op, clear, kMacOrderBarrier )
157158
158159OSATOMIC_INTERCEPTORS_BITOP (OSAtomicTestAndSet, __tsan_atomic8_fetch_or, false )
159160OSATOMIC_INTERCEPTORS_BITOP (OSAtomicTestAndClear, __tsan_atomic8_fetch_and,
@@ -169,12 +170,13 @@ TSAN_INTERCEPTOR(void, OSAtomicEnqueue, OSQueueHead *list, void *item,
169170TSAN_INTERCEPTOR (void *, OSAtomicDequeue, OSQueueHead *list, size_t offset) {
170171 SCOPED_TSAN_INTERCEPTOR (OSAtomicDequeue, list, offset);
171172 void *item = REAL (OSAtomicDequeue)(list, offset);
172- if (item) __tsan_acquire (item);
173+ if (item)
174+ __tsan_acquire (item);
173175 return item;
174176}
175177
176178// OSAtomicFifoEnqueue and OSAtomicFifoDequeue are only on OS X.
177- #if !SANITIZER_IOS
179+ # if !SANITIZER_IOS
178180
179181TSAN_INTERCEPTOR (void , OSAtomicFifoEnqueue, OSFifoQueueHead *list, void *item,
180182 size_t offset) {
@@ -187,11 +189,12 @@ TSAN_INTERCEPTOR(void *, OSAtomicFifoDequeue, OSFifoQueueHead *list,
187189 size_t offset) {
188190 SCOPED_TSAN_INTERCEPTOR (OSAtomicFifoDequeue, list, offset);
189191 void *item = REAL (OSAtomicFifoDequeue)(list, offset);
190- if (item) __tsan_acquire (item);
192+ if (item)
193+ __tsan_acquire (item);
191194 return item;
192195}
193196
194- #endif
197+ # endif
195198
196199TSAN_INTERCEPTOR (void , OSSpinLockLock, volatile OSSpinLock *lock) {
197200 CHECK (!cur_thread ()->is_dead );
@@ -296,7 +299,7 @@ TSAN_INTERCEPTOR(void, os_unfair_lock_unlock, os_unfair_lock_t lock) {
296299 REAL (os_unfair_lock_unlock)(lock);
297300}
298301
299- #if defined(__has_include) && __has_include(<xpc/xpc.h>)
302+ # if defined(__has_include) && __has_include(<xpc/xpc.h>)
300303
301304TSAN_INTERCEPTOR (void , xpc_connection_set_event_handler,
302305 xpc_connection_t connection, xpc_handler_t handler) {
@@ -350,7 +353,7 @@ TSAN_INTERCEPTOR(void, xpc_connection_cancel, xpc_connection_t connection) {
350353 REAL (xpc_connection_cancel)(connection);
351354}
352355
353- #endif // #if defined(__has_include) && __has_include(<xpc/xpc.h>)
356+ # endif // #if defined(__has_include) && __has_include(<xpc/xpc.h>)
354357
355358// Determines whether the Obj-C object pointer is a tagged pointer. Tagged
356359// pointers encode the object data directly in their pointer bits and do not
@@ -373,7 +376,7 @@ static uptr GetOrCreateSyncAddress(uptr addr, ThreadState *thr, uptr pc) {
373376 Map::Handle h (&Addresses, addr);
374377 if (h.created ()) {
375378 ThreadIgnoreBegin (thr, pc);
376- *h = (uptr) user_alloc (thr, pc, /* size=*/ 1 );
379+ *h = (uptr)user_alloc (thr, pc, /* size=*/ 1 );
377380 ThreadIgnoreEnd (thr);
378381 }
379382 return *h;
@@ -391,7 +394,8 @@ static uptr SyncAddressForObjCObject(id obj, ThreadState *thr, uptr pc) {
391394
392395TSAN_INTERCEPTOR (int , objc_sync_enter, id obj) {
393396 SCOPED_TSAN_INTERCEPTOR (objc_sync_enter, obj);
394- if (!obj) return REAL (objc_sync_enter)(obj);
397+ if (!obj)
398+ return REAL (objc_sync_enter)(obj);
395399 uptr addr = SyncAddressForObjCObject (obj, thr, pc);
396400 MutexPreLock (thr, pc, addr, MutexFlagWriteReentrant);
397401 int result = REAL (objc_sync_enter)(obj);
@@ -402,11 +406,13 @@ TSAN_INTERCEPTOR(int, objc_sync_enter, id obj) {
402406
403407TSAN_INTERCEPTOR (int , objc_sync_exit, id obj) {
404408 SCOPED_TSAN_INTERCEPTOR (objc_sync_exit, obj);
405- if (!obj) return REAL (objc_sync_exit)(obj);
409+ if (!obj)
410+ return REAL (objc_sync_exit)(obj);
406411 uptr addr = SyncAddressForObjCObject (obj, thr, pc);
407412 MutexUnlock (thr, pc, addr);
408413 int result = REAL (objc_sync_exit)(obj);
409- if (result != OBJC_SYNC_SUCCESS) MutexInvalidAccess (thr, pc, addr);
414+ if (result != OBJC_SYNC_SUCCESS)
415+ MutexInvalidAccess (thr, pc, addr);
410416 return result;
411417}
412418
@@ -437,7 +443,7 @@ TSAN_INTERCEPTOR(int, swapcontext, ucontext_t *oucp, const ucontext_t *ucp) {
437443
438444// On macOS, libc++ is always linked dynamically, so intercepting works the
439445// usual way.
440- #define STDCXX_INTERCEPTOR TSAN_INTERCEPTOR
446+ # define STDCXX_INTERCEPTOR TSAN_INTERCEPTOR
441447
442448namespace {
443449struct fake_shared_weak_count {
0 commit comments