1 //===-- tsan_interceptors_mach_vm.cpp -------------------------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 // This file is a part of ThreadSanitizer (TSan), a race detector.
11 // Interceptors for mach_vm_* user space memory routines on Darwin.
12 //===----------------------------------------------------------------------===//
14 #include "interception/interception.h"
15 #include "tsan_interceptors.h"
16 #include "tsan_platform.h"
18 #include <mach/mach.h>
22 static bool intersects_with_shadow(mach_vm_address_t address
,
23 mach_vm_size_t size
, int flags
) {
24 // VM_FLAGS_FIXED is 0x0, so we have to test for VM_FLAGS_ANYWHERE.
25 if (flags
& VM_FLAGS_ANYWHERE
) return false;
26 return !IsAppMem(address
) || !IsAppMem(address
+ size
- 1);
29 TSAN_INTERCEPTOR(kern_return_t
, mach_vm_allocate
, vm_map_t target
,
30 mach_vm_address_t
*address
, mach_vm_size_t size
, int flags
) {
31 SCOPED_TSAN_INTERCEPTOR(mach_vm_allocate
, target
, address
, size
, flags
);
32 if (target
!= mach_task_self())
33 return REAL(mach_vm_allocate
)(target
, address
, size
, flags
);
34 if (address
&& intersects_with_shadow(*address
, size
, flags
))
36 kern_return_t kr
= REAL(mach_vm_allocate
)(target
, address
, size
, flags
);
37 if (kr
== KERN_SUCCESS
)
38 MemoryRangeImitateWriteOrResetRange(thr
, pc
, *address
, size
);
42 TSAN_INTERCEPTOR(kern_return_t
, mach_vm_deallocate
, vm_map_t target
,
43 mach_vm_address_t address
, mach_vm_size_t size
) {
44 SCOPED_TSAN_INTERCEPTOR(mach_vm_deallocate
, target
, address
, size
);
45 if (target
!= mach_task_self())
46 return REAL(mach_vm_deallocate
)(target
, address
, size
);
47 kern_return_t kr
= REAL(mach_vm_deallocate
)(target
, address
, size
);
48 if (kr
== KERN_SUCCESS
&& address
)
49 UnmapShadow(thr
, address
, size
);