11e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany//===-- asan_mac.cc -------------------------------------------------------===// 21e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// 31e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// The LLVM Compiler Infrastructure 41e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// 51e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// This file is distributed under the University of Illinois Open Source 61e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// License. See LICENSE.TXT for details. 71e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// 81e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany//===----------------------------------------------------------------------===// 91e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// 101e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// This file is a part of AddressSanitizer, an address sanity checker. 111e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// 121e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// Mac-specific details. 131e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany//===----------------------------------------------------------------------===// 141e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 1524e13723f8477d8c42ab8b2a7f4f69fc089842f1Evgeniy Stepanov#include "sanitizer_common/sanitizer_platform.h" 1630e110edf92303237d471f1cb8e3ad07954fb145Evgeniy Stepanov#if SANITIZER_MAC 171e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 1864ce2db7c838cd95315f7a4428e8a628eaa3e2fcAlexey Samsonov#include "asan_interceptors.h" 191e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#include "asan_internal.h" 20895b3872acb5bcccb1769ea69d37dd33c722f99dAlexander Potapenko#include "asan_mapping.h" 211e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#include "asan_stack.h" 221e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#include "asan_thread.h" 2331f78fda9c511f9ab4afc3494f54cb24450e28e6Alexander Potapenko#include "sanitizer_common/sanitizer_atomic.h" 24ae4d9caa4f47fa6abcd641719e9f520622940c17Alexey Samsonov#include "sanitizer_common/sanitizer_libc.h" 252d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#include "sanitizer_common/sanitizer_mac.h" 261e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 27c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#include <dlfcn.h> 28799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar#include <fcntl.h> 29799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar#include <libkern/OSAtomic.h> 308a34d384255f9bf4c2a9b03a4df81b9af57124d8Alexander Potapenko#include <mach-o/dyld.h> 31c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#include <mach-o/getsect.h> 329b993e8cd0f8964782ee93524603d0c53adc2249Kostya Serebryany#include <mach-o/loader.h> 33799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar#include <pthread.h> 34799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar#include <stdlib.h> // for free() 351e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#include <sys/mman.h> 36ef14ff6512d7b2e20aa3206dff820b5f90285420Kostya Serebryany#include <sys/resource.h> 3759dc578df0de177b44c8c78f69d73735e38e5c14Alexander Potapenko#include <sys/sysctl.h> 389107c26bd88fc9cf44a2cd7d6967eb830ac63be3Kostya Serebryany#include <sys/ucontext.h> 391e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#include <unistd.h> 401e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 41c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar// from <crt_externs.h>, but we don't have that file on iOS 42c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainarextern "C" { 43c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar extern char ***_NSGetArgv(void); 44c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar extern char ***_NSGetEnviron(void); 45c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar} 46c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar 471e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanynamespace __asan { 481e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 497c9150579ed0278492f51cc8434b1d63a44b9bd1Pirama Arumuga Nainarvoid InitializePlatformInterceptors() {} 50c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainarvoid InitializePlatformExceptionHandlers() {} 5131f78fda9c511f9ab4afc3494f54cb24450e28e6Alexander Potapenko 5238dd4ed885e714c376466f6fe0d69f5f22d37014Alexey Samsonovbool PlatformHasDifferentMemcpyAndMemmove() { 5338dd4ed885e714c376466f6fe0d69f5f22d37014Alexey Samsonov // On OS X 10.7 memcpy() and memmove() are both resolved 5438dd4ed885e714c376466f6fe0d69f5f22d37014Alexey Samsonov // into memmove$VARIANT$sse42. 55799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar // See also https://github.com/google/sanitizers/issues/34. 5638dd4ed885e714c376466f6fe0d69f5f22d37014Alexey Samsonov // TODO(glider): need to check dynamically that memcpy() and memmove() are 5738dd4ed885e714c376466f6fe0d69f5f22d37014Alexey Samsonov // actually the same function. 5838dd4ed885e714c376466f6fe0d69f5f22d37014Alexey Samsonov return GetMacosVersion() == MACOS_VERSION_SNOW_LEOPARD; 5938dd4ed885e714c376466f6fe0d69f5f22d37014Alexey Samsonov} 6038dd4ed885e714c376466f6fe0d69f5f22d37014Alexey Samsonov 611e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// No-op. Mac does not support static linkage anyway. 621e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyvoid *AsanDoesNotSupportStaticLinkage() { 633f4c3875c42078e22c7e5356c5746fd18756d958Kostya Serebryany return 0; 641e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany} 651e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 662d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// No-op. Mac does not support static linkage anyway. 672d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesvoid AsanCheckDynamicRTPrereqs() {} 682d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 692d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// No-op. Mac does not support static linkage anyway. 702d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesvoid AsanCheckIncompatibleRT() {} 712d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 72c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainarvoid AsanApplyToGlobals(globals_op_fptr op, const void *needle) { 73c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar // Find the Mach-O header for the image containing the needle 74c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar Dl_info info; 75c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar int err = dladdr(needle, &info); 76c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar if (err == 0) return; 77c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar 78c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#if __LP64__ 79c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar const struct mach_header_64 *mh = (struct mach_header_64 *)info.dli_fbase; 80c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#else 81c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar const struct mach_header *mh = (struct mach_header *)info.dli_fbase; 82c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#endif 83c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar 84c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar // Look up the __asan_globals section in that image and register its globals 85c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar unsigned long size = 0; 86c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar __asan_global *globals = (__asan_global *)getsectiondata( 87c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar mh, 88c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar "__DATA", "__asan_globals", 89c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar &size); 90c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar 91c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar if (!globals) return; 92c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar if (size % sizeof(__asan_global) != 0) return; 93c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar op(globals, size / sizeof(__asan_global)); 94c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar} 95c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar 9657db4bae483e7268dd7fc5bc42b0e55564014048Alexey Samsonovvoid ReadContextStack(void *context, uptr *stack, uptr *ssize) { 97f3950c6d6acf53fe60735f6d38715c1ea6df814bAlexey Samsonov UNIMPLEMENTED(); 98f3950c6d6acf53fe60735f6d38715c1ea6df814bAlexey Samsonov} 99f3950c6d6acf53fe60735f6d38715c1ea6df814bAlexey Samsonov 1001e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// Support for the following functions from libdispatch on Mac OS: 1011e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// dispatch_async_f() 1021e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// dispatch_async() 1031e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// dispatch_sync_f() 1041e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// dispatch_sync() 1051e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// dispatch_after_f() 1061e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// dispatch_after() 1071e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// dispatch_group_async_f() 1081e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// dispatch_group_async() 1091e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// TODO(glider): libdispatch API contains other functions that we don't support 1101e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// yet. 1111e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// 1121e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// dispatch_sync() and dispatch_sync_f() are synchronous, although chances are 1131e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// they can cause jobs to run on a thread different from the current one. 1141e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// TODO(glider): if so, we need a test for this (otherwise we should remove 1151e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// them). 1161e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// 1171e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// The following functions use dispatch_barrier_async_f() (which isn't a library 1181e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// function but is exported) and are thus supported: 1191e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// dispatch_source_set_cancel_handler_f() 1201e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// dispatch_source_set_cancel_handler() 1211e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// dispatch_source_set_event_handler_f() 1221e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// dispatch_source_set_event_handler() 1231e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// 1241e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// The reference manual for Grand Central Dispatch is available at 1251e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// http://developer.apple.com/library/mac/#documentation/Performance/Reference/GCD_libdispatch_Ref/Reference/reference.html 1261e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// The implementation details are at 1271e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// http://libdispatch.macosforge.org/trac/browser/trunk/src/queue.c 1281e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 129f7ceaad2919d2e26e9edea29232bc9dd8f145c42Alexey Samsonovtypedef void* dispatch_group_t; 130f7ceaad2919d2e26e9edea29232bc9dd8f145c42Alexey Samsonovtypedef void* dispatch_queue_t; 131af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenkotypedef void* dispatch_source_t; 132ee3925515e4c7966f3ef489f687aa7e5692806a9Kostya Serebryanytypedef u64 dispatch_time_t; 133f7ceaad2919d2e26e9edea29232bc9dd8f145c42Alexey Samsonovtypedef void (*dispatch_function_t)(void *block); 1345cf832dc0a6566ae4bb8d48b1f41da623d2c2c1aAlexey Samsonovtypedef void* (*worker_t)(void *block); 1355cf832dc0a6566ae4bb8d48b1f41da623d2c2c1aAlexey Samsonov 1365cf832dc0a6566ae4bb8d48b1f41da623d2c2c1aAlexey Samsonov// A wrapper for the ObjC blocks used to support libdispatch. 1375cf832dc0a6566ae4bb8d48b1f41da623d2c2c1aAlexey Samsonovtypedef struct { 1385cf832dc0a6566ae4bb8d48b1f41da623d2c2c1aAlexey Samsonov void *block; 1395cf832dc0a6566ae4bb8d48b1f41da623d2c2c1aAlexey Samsonov dispatch_function_t func; 140e0cff0bc20ae51790c8edfbceb817e18ebf5355eKostya Serebryany u32 parent_tid; 1415cf832dc0a6566ae4bb8d48b1f41da623d2c2c1aAlexey Samsonov} asan_block_context_t; 1425cf832dc0a6566ae4bb8d48b1f41da623d2c2c1aAlexey Samsonov 143b157c67e17c3fc8805c8b7cb590668885680608fTimur IskhodzhanovALWAYS_INLINE 144c3390df6670cb166119b961eb27a033fb9073496Kostya Serebryanyvoid asan_register_worker_thread(int parent_tid, StackTrace *stack) { 145c25e62b0cdbca855e7611583b0ff7013c31db21dAlexey Samsonov AsanThread *t = GetCurrentThread(); 146af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenko if (!t) { 14786277eb844c4983c81de62d7c050e92fe7155788Stephen Hines t = AsanThread::Create(/* start_routine */ nullptr, /* arg */ nullptr, 14886277eb844c4983c81de62d7c050e92fe7155788Stephen Hines parent_tid, stack, /* detached */ true); 149af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenko t->Init(); 150def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov asanThreadRegistry().StartThread(t->tid(), 0, 0); 151c25e62b0cdbca855e7611583b0ff7013c31db21dAlexey Samsonov SetCurrentThread(t); 152af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenko } 153af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenko} 154af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenko 1552483ce3e635515d907c0cd8c97db315142fb28dbAlexander Potapenko// For use by only those functions that allocated the context via 1562483ce3e635515d907c0cd8c97db315142fb28dbAlexander Potapenko// alloc_asan_context(). 1571e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyextern "C" 1581e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyvoid asan_dispatch_call_block_and_release(void *block) { 159a30c8f9eac981dcf137e84226810b760e35c7be1Kostya Serebryany GET_STACK_TRACE_THREAD; 1601e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany asan_block_context_t *context = (asan_block_context_t*)block; 1612d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines VReport(2, 1622d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines "asan_dispatch_call_block_and_release(): " 1632d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines "context: %p, pthread_self: %p\n", 1642d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines block, pthread_self()); 165af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenko asan_register_worker_thread(context->parent_tid, &stack); 1661e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany // Call the original dispatcher for the block. 1671e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany context->func(context->block); 168fe6d91684bcda766593800f6307233f1a33d31f6Kostya Serebryany asan_free(context, &stack, FROM_MALLOC); 1691e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany} 1701e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 1711e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany} // namespace __asan 1721e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 1731e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyusing namespace __asan; // NOLINT 1741e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 1751e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// Wrap |ctxt| and |func| into an asan_block_context_t. 1761e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// The caller retains control of the allocated context. 1771e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyextern "C" 1781e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyasan_block_context_t *alloc_asan_context(void *ctxt, dispatch_function_t func, 1796d1862363c88c183b0ed7740fca876342cf0474bStephen Hines BufferedStackTrace *stack) { 1801e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany asan_block_context_t *asan_ctxt = 1811e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany (asan_block_context_t*) asan_malloc(sizeof(asan_block_context_t), stack); 1821e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany asan_ctxt->block = ctxt; 1831e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany asan_ctxt->func = func; 184c25e62b0cdbca855e7611583b0ff7013c31db21dAlexey Samsonov asan_ctxt->parent_tid = GetCurrentTidOrInvalid(); 1851e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany return asan_ctxt; 1861e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany} 1871e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 188b09dd34786713a150fed5c5ab1529f01de0e2bc0Alexander Potapenko// Define interceptor for dispatch_*_f function with the three most common 189b09dd34786713a150fed5c5ab1529f01de0e2bc0Alexander Potapenko// parameters: dispatch_queue_t, context, dispatch_function_t. 190b09dd34786713a150fed5c5ab1529f01de0e2bc0Alexander Potapenko#define INTERCEPT_DISPATCH_X_F_3(dispatch_x_f) \ 191b09dd34786713a150fed5c5ab1529f01de0e2bc0Alexander Potapenko INTERCEPTOR(void, dispatch_x_f, dispatch_queue_t dq, void *ctxt, \ 192b09dd34786713a150fed5c5ab1529f01de0e2bc0Alexander Potapenko dispatch_function_t func) { \ 193a30c8f9eac981dcf137e84226810b760e35c7be1Kostya Serebryany GET_STACK_TRACE_THREAD; \ 194b09dd34786713a150fed5c5ab1529f01de0e2bc0Alexander Potapenko asan_block_context_t *asan_ctxt = alloc_asan_context(ctxt, func, &stack); \ 19586277eb844c4983c81de62d7c050e92fe7155788Stephen Hines if (Verbosity() >= 2) { \ 196b09dd34786713a150fed5c5ab1529f01de0e2bc0Alexander Potapenko Report(#dispatch_x_f "(): context: %p, pthread_self: %p\n", \ 197b09dd34786713a150fed5c5ab1529f01de0e2bc0Alexander Potapenko asan_ctxt, pthread_self()); \ 1982d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines PRINT_CURRENT_STACK(); \ 1992d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines } \ 2002d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines return REAL(dispatch_x_f)(dq, (void*)asan_ctxt, \ 2012d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines asan_dispatch_call_block_and_release); \ 2020ffc227f91b068c78908f735a4846f92e339a337Kostya Serebryany } 203b09dd34786713a150fed5c5ab1529f01de0e2bc0Alexander Potapenko 204b09dd34786713a150fed5c5ab1529f01de0e2bc0Alexander PotapenkoINTERCEPT_DISPATCH_X_F_3(dispatch_async_f) 205b09dd34786713a150fed5c5ab1529f01de0e2bc0Alexander PotapenkoINTERCEPT_DISPATCH_X_F_3(dispatch_sync_f) 206b09dd34786713a150fed5c5ab1529f01de0e2bc0Alexander PotapenkoINTERCEPT_DISPATCH_X_F_3(dispatch_barrier_async_f) 2071e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 208f2598fc21bf651d23feab396a7581d48c01c3be5Alexey SamsonovINTERCEPTOR(void, dispatch_after_f, dispatch_time_t when, 209f2598fc21bf651d23feab396a7581d48c01c3be5Alexey Samsonov dispatch_queue_t dq, void *ctxt, 210f2598fc21bf651d23feab396a7581d48c01c3be5Alexey Samsonov dispatch_function_t func) { 211a30c8f9eac981dcf137e84226810b760e35c7be1Kostya Serebryany GET_STACK_TRACE_THREAD; 2121e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany asan_block_context_t *asan_ctxt = alloc_asan_context(ctxt, func, &stack); 21386277eb844c4983c81de62d7c050e92fe7155788Stephen Hines if (Verbosity() >= 2) { 2141e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany Report("dispatch_after_f: %p\n", asan_ctxt); 2151e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany PRINT_CURRENT_STACK(); 2161e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany } 21709672caefb5694f1981a1712fdefa44840a95e67Alexey Samsonov return REAL(dispatch_after_f)(when, dq, (void*)asan_ctxt, 21809672caefb5694f1981a1712fdefa44840a95e67Alexey Samsonov asan_dispatch_call_block_and_release); 2191e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany} 2201e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 221af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander PotapenkoINTERCEPTOR(void, dispatch_group_async_f, dispatch_group_t group, 222af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenko dispatch_queue_t dq, void *ctxt, 223af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenko dispatch_function_t func) { 224a30c8f9eac981dcf137e84226810b760e35c7be1Kostya Serebryany GET_STACK_TRACE_THREAD; 225af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenko asan_block_context_t *asan_ctxt = alloc_asan_context(ctxt, func, &stack); 22686277eb844c4983c81de62d7c050e92fe7155788Stephen Hines if (Verbosity() >= 2) { 227af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenko Report("dispatch_group_async_f(): context: %p, pthread_self: %p\n", 228af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenko asan_ctxt, pthread_self()); 229af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenko PRINT_CURRENT_STACK(); 230af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenko } 231af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenko REAL(dispatch_group_async_f)(group, dq, (void*)asan_ctxt, 232af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenko asan_dispatch_call_block_and_release); 233af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenko} 234af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenko 23569563986ca570ce750111a82264d51ddbf4107baAlexander Potapenko#if !defined(MISSING_BLOCKS_SUPPORT) 236af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenkoextern "C" { 237af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenkovoid dispatch_async(dispatch_queue_t dq, void(^work)(void)); 238af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenkovoid dispatch_group_async(dispatch_group_t dg, dispatch_queue_t dq, 239af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenko void(^work)(void)); 240af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenkovoid dispatch_after(dispatch_time_t when, dispatch_queue_t queue, 241af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenko void(^work)(void)); 242af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenkovoid dispatch_source_set_cancel_handler(dispatch_source_t ds, 243af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenko void(^work)(void)); 244af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenkovoid dispatch_source_set_event_handler(dispatch_source_t ds, void(^work)(void)); 2452483ce3e635515d907c0cd8c97db315142fb28dbAlexander Potapenko} 2462483ce3e635515d907c0cd8c97db315142fb28dbAlexander Potapenko 247af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenko#define GET_ASAN_BLOCK(work) \ 248af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenko void (^asan_block)(void); \ 249c25e62b0cdbca855e7611583b0ff7013c31db21dAlexey Samsonov int parent_tid = GetCurrentTidOrInvalid(); \ 250af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenko asan_block = ^(void) { \ 251a30c8f9eac981dcf137e84226810b760e35c7be1Kostya Serebryany GET_STACK_TRACE_THREAD; \ 252af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenko asan_register_worker_thread(parent_tid, &stack); \ 253af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenko work(); \ 2542483ce3e635515d907c0cd8c97db315142fb28dbAlexander Potapenko } 2552483ce3e635515d907c0cd8c97db315142fb28dbAlexander Potapenko 2562483ce3e635515d907c0cd8c97db315142fb28dbAlexander PotapenkoINTERCEPTOR(void, dispatch_async, 257af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenko dispatch_queue_t dq, void(^work)(void)) { 2586a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines ENABLE_FRAME_POINTER; 259af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenko GET_ASAN_BLOCK(work); 260af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenko REAL(dispatch_async)(dq, asan_block); 261af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenko} 262af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenko 263af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander PotapenkoINTERCEPTOR(void, dispatch_group_async, 264af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenko dispatch_group_t dg, dispatch_queue_t dq, void(^work)(void)) { 2656a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines ENABLE_FRAME_POINTER; 266af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenko GET_ASAN_BLOCK(work); 267af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenko REAL(dispatch_group_async)(dg, dq, asan_block); 2682483ce3e635515d907c0cd8c97db315142fb28dbAlexander Potapenko} 2692483ce3e635515d907c0cd8c97db315142fb28dbAlexander Potapenko 2702483ce3e635515d907c0cd8c97db315142fb28dbAlexander PotapenkoINTERCEPTOR(void, dispatch_after, 271af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenko dispatch_time_t when, dispatch_queue_t queue, void(^work)(void)) { 2726a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines ENABLE_FRAME_POINTER; 273af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenko GET_ASAN_BLOCK(work); 274af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenko REAL(dispatch_after)(when, queue, asan_block); 2752483ce3e635515d907c0cd8c97db315142fb28dbAlexander Potapenko} 2762483ce3e635515d907c0cd8c97db315142fb28dbAlexander Potapenko 277af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander PotapenkoINTERCEPTOR(void, dispatch_source_set_cancel_handler, 278af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenko dispatch_source_t ds, void(^work)(void)) { 27986277eb844c4983c81de62d7c050e92fe7155788Stephen Hines if (!work) { 28086277eb844c4983c81de62d7c050e92fe7155788Stephen Hines REAL(dispatch_source_set_cancel_handler)(ds, work); 28186277eb844c4983c81de62d7c050e92fe7155788Stephen Hines return; 28286277eb844c4983c81de62d7c050e92fe7155788Stephen Hines } 2836a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines ENABLE_FRAME_POINTER; 284af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenko GET_ASAN_BLOCK(work); 285af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenko REAL(dispatch_source_set_cancel_handler)(ds, asan_block); 2861e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany} 2871e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 288af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander PotapenkoINTERCEPTOR(void, dispatch_source_set_event_handler, 289af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenko dispatch_source_t ds, void(^work)(void)) { 2906a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines ENABLE_FRAME_POINTER; 291af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenko GET_ASAN_BLOCK(work); 292af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenko REAL(dispatch_source_set_event_handler)(ds, asan_block); 293af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenko} 294af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenko#endif 295af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenko 296649a270f5341efe9c57f473dbb78706b0b2ed523Alexey Samsonov#endif // SANITIZER_MAC 297