1353944Sdim//===-- tsan_interceptors_mach_vm.cpp -------------------------------------===// 2353944Sdim// 3353944Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4353944Sdim// See https://llvm.org/LICENSE.txt for license information. 5353944Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6353944Sdim// 7353944Sdim//===----------------------------------------------------------------------===// 8353944Sdim// 9353944Sdim// This file is a part of ThreadSanitizer (TSan), a race detector. 10353944Sdim// 11353944Sdim// Interceptors for mach_vm_* user space memory routines on Darwin. 12353944Sdim//===----------------------------------------------------------------------===// 13353944Sdim 14353944Sdim#include "interception/interception.h" 15353944Sdim#include "tsan_interceptors.h" 16353944Sdim#include "tsan_platform.h" 17353944Sdim 18353944Sdim#include <mach/mach.h> 19353944Sdim 20353944Sdimnamespace __tsan { 21353944Sdim 22353944Sdimstatic bool intersects_with_shadow(mach_vm_address_t *address, 23353944Sdim mach_vm_size_t size, int flags) { 24353944Sdim // VM_FLAGS_FIXED is 0x0, so we have to test for VM_FLAGS_ANYWHERE. 25353944Sdim if (flags & VM_FLAGS_ANYWHERE) return false; 26353944Sdim uptr ptr = *address; 27353944Sdim return !IsAppMem(ptr) || !IsAppMem(ptr + size - 1); 28353944Sdim} 29353944Sdim 30353944SdimTSAN_INTERCEPTOR(kern_return_t, mach_vm_allocate, vm_map_t target, 31353944Sdim mach_vm_address_t *address, mach_vm_size_t size, int flags) { 32353944Sdim SCOPED_TSAN_INTERCEPTOR(mach_vm_allocate, target, address, size, flags); 33353944Sdim if (target != mach_task_self()) 34353944Sdim return REAL(mach_vm_allocate)(target, address, size, flags); 35353944Sdim if (intersects_with_shadow(address, size, flags)) 36353944Sdim return KERN_NO_SPACE; 37353944Sdim kern_return_t res = REAL(mach_vm_allocate)(target, address, size, flags); 38353944Sdim if (res == KERN_SUCCESS) 39353944Sdim MemoryRangeImitateWriteOrResetRange(thr, pc, *address, size); 40353944Sdim return res; 41353944Sdim} 42353944Sdim 43353944SdimTSAN_INTERCEPTOR(kern_return_t, mach_vm_deallocate, vm_map_t target, 44353944Sdim mach_vm_address_t address, mach_vm_size_t size) { 45353944Sdim SCOPED_TSAN_INTERCEPTOR(mach_vm_deallocate, target, address, size); 46353944Sdim if (target != mach_task_self()) 47353944Sdim return REAL(mach_vm_deallocate)(target, address, size); 48353944Sdim UnmapShadow(thr, address, size); 49353944Sdim return REAL(mach_vm_deallocate)(target, address, size); 50353944Sdim} 51353944Sdim 52353944Sdim} // namespace __tsan 53