14
14
#include " sanitizer_common/sanitizer_platform.h"
15
15
#if SANITIZER_APPLE
16
16
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>)
33
33
34
34
typedef long long_t ;
35
35
@@ -49,55 +49,56 @@ static constexpr morder kMacOrderBarrier = mo_acq_rel;
49
49
static constexpr morder kMacOrderNonBarrier = mo_acq_rel;
50
50
static constexpr morder kMacFailureOrder = mo_relaxed;
51
51
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
+ }
57
57
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
+ }
63
64
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
+ }
69
71
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
+ }
76
78
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
99
100
// OSAtomic* functions are deprecated.
100
- #pragma clang diagnostic ignored "-Wdeprecated-declarations"
101
+ # pragma clang diagnostic ignored "-Wdeprecated-declarations"
101
102
OSATOMIC_INTERCEPTORS_ARITHMETIC (OSAtomicAdd, fetch_add,
102
103
OSATOMIC_INTERCEPTOR_PLUS_X)
103
104
OSATOMIC_INTERCEPTORS_ARITHMETIC (OSAtomicIncrement, fetch_add,
@@ -111,25 +112,25 @@ OSATOMIC_INTERCEPTORS_BITWISE(OSAtomicAnd, fetch_and,
111
112
OSATOMIC_INTERCEPTORS_BITWISE (OSAtomicXor, fetch_xor,
112
113
OSATOMIC_INTERCEPTOR_PLUS_X, OSATOMIC_INTERCEPTOR)
113
114
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
+ }
129
130
130
- #pragma clang diagnostic push
131
+ # pragma clang diagnostic push
131
132
// OSAtomicCompareAndSwap* functions are deprecated.
132
- #pragma clang diagnostic ignored "-Wdeprecated-declarations"
133
+ # pragma clang diagnostic ignored "-Wdeprecated-declarations"
133
134
OSATOMIC_INTERCEPTORS_CAS (OSAtomicCompareAndSwapInt, __tsan_atomic32, a32, int )
134
135
OSATOMIC_INTERCEPTORS_CAS (OSAtomicCompareAndSwapLong, __tsan_atomic64, a64,
135
136
long_t )
@@ -139,21 +140,21 @@ OSATOMIC_INTERCEPTORS_CAS(OSAtomicCompareAndSwap32, __tsan_atomic32, a32,
139
140
int32_t )
140
141
OSATOMIC_INTERCEPTORS_CAS (OSAtomicCompareAndSwap64, __tsan_atomic64, a64,
141
142
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
+ }
153
154
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 )
157
158
158
159
OSATOMIC_INTERCEPTORS_BITOP (OSAtomicTestAndSet, __tsan_atomic8_fetch_or, false )
159
160
OSATOMIC_INTERCEPTORS_BITOP (OSAtomicTestAndClear, __tsan_atomic8_fetch_and,
@@ -169,12 +170,13 @@ TSAN_INTERCEPTOR(void, OSAtomicEnqueue, OSQueueHead *list, void *item,
169
170
TSAN_INTERCEPTOR (void *, OSAtomicDequeue, OSQueueHead *list, size_t offset) {
170
171
SCOPED_TSAN_INTERCEPTOR (OSAtomicDequeue, list, offset);
171
172
void *item = REAL (OSAtomicDequeue)(list, offset);
172
- if (item) __tsan_acquire (item);
173
+ if (item)
174
+ __tsan_acquire (item);
173
175
return item;
174
176
}
175
177
176
178
// OSAtomicFifoEnqueue and OSAtomicFifoDequeue are only on OS X.
177
- #if !SANITIZER_IOS
179
+ # if !SANITIZER_IOS
178
180
179
181
TSAN_INTERCEPTOR (void , OSAtomicFifoEnqueue, OSFifoQueueHead *list, void *item,
180
182
size_t offset) {
@@ -187,11 +189,12 @@ TSAN_INTERCEPTOR(void *, OSAtomicFifoDequeue, OSFifoQueueHead *list,
187
189
size_t offset) {
188
190
SCOPED_TSAN_INTERCEPTOR (OSAtomicFifoDequeue, list, offset);
189
191
void *item = REAL (OSAtomicFifoDequeue)(list, offset);
190
- if (item) __tsan_acquire (item);
192
+ if (item)
193
+ __tsan_acquire (item);
191
194
return item;
192
195
}
193
196
194
- #endif
197
+ # endif
195
198
196
199
TSAN_INTERCEPTOR (void , OSSpinLockLock, volatile OSSpinLock *lock) {
197
200
CHECK (!cur_thread ()->is_dead );
@@ -296,7 +299,7 @@ TSAN_INTERCEPTOR(void, os_unfair_lock_unlock, os_unfair_lock_t lock) {
296
299
REAL (os_unfair_lock_unlock)(lock);
297
300
}
298
301
299
- #if defined(__has_include) && __has_include(<xpc/xpc.h>)
302
+ # if defined(__has_include) && __has_include(<xpc/xpc.h>)
300
303
301
304
TSAN_INTERCEPTOR (void , xpc_connection_set_event_handler,
302
305
xpc_connection_t connection, xpc_handler_t handler) {
@@ -350,7 +353,7 @@ TSAN_INTERCEPTOR(void, xpc_connection_cancel, xpc_connection_t connection) {
350
353
REAL (xpc_connection_cancel)(connection);
351
354
}
352
355
353
- #endif // #if defined(__has_include) && __has_include(<xpc/xpc.h>)
356
+ # endif // #if defined(__has_include) && __has_include(<xpc/xpc.h>)
354
357
355
358
// Determines whether the Obj-C object pointer is a tagged pointer. Tagged
356
359
// 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) {
373
376
Map::Handle h (&Addresses, addr);
374
377
if (h.created ()) {
375
378
ThreadIgnoreBegin (thr, pc);
376
- *h = (uptr) user_alloc (thr, pc, /* size=*/ 1 );
379
+ *h = (uptr)user_alloc (thr, pc, /* size=*/ 1 );
377
380
ThreadIgnoreEnd (thr);
378
381
}
379
382
return *h;
@@ -391,7 +394,8 @@ static uptr SyncAddressForObjCObject(id obj, ThreadState *thr, uptr pc) {
391
394
392
395
TSAN_INTERCEPTOR (int , objc_sync_enter, id obj) {
393
396
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);
395
399
uptr addr = SyncAddressForObjCObject (obj, thr, pc);
396
400
MutexPreLock (thr, pc, addr, MutexFlagWriteReentrant);
397
401
int result = REAL (objc_sync_enter)(obj);
@@ -402,11 +406,13 @@ TSAN_INTERCEPTOR(int, objc_sync_enter, id obj) {
402
406
403
407
TSAN_INTERCEPTOR (int , objc_sync_exit, id obj) {
404
408
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);
406
411
uptr addr = SyncAddressForObjCObject (obj, thr, pc);
407
412
MutexUnlock (thr, pc, addr);
408
413
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);
410
416
return result;
411
417
}
412
418
@@ -437,7 +443,7 @@ TSAN_INTERCEPTOR(int, swapcontext, ucontext_t *oucp, const ucontext_t *ucp) {
437
443
438
444
// On macOS, libc++ is always linked dynamically, so intercepting works the
439
445
// usual way.
440
- #define STDCXX_INTERCEPTOR TSAN_INTERCEPTOR
446
+ # define STDCXX_INTERCEPTOR TSAN_INTERCEPTOR
441
447
442
448
namespace {
443
449
struct fake_shared_weak_count {
0 commit comments