diff options
-rw-r--r-- | lib/asan/asan_interceptors.cc | 165 | ||||
-rw-r--r-- | lib/asan/asan_interceptors.h | 97 | ||||
-rw-r--r-- | lib/asan/asan_mac.cc | 47 | ||||
-rw-r--r-- | lib/asan/asan_mac.h | 67 | ||||
-rw-r--r-- | lib/asan/asan_malloc_linux.cc | 40 |
5 files changed, 152 insertions, 264 deletions
diff --git a/lib/asan/asan_interceptors.cc b/lib/asan/asan_interceptors.cc index 00c33e5bd..d5476b598 100644 --- a/lib/asan/asan_interceptors.cc +++ b/lib/asan/asan_interceptors.cc @@ -50,7 +50,6 @@ #include <strings.h> #include "mach_override/mach_override.h" -#define WRAPPER_NAME(x) "wrap_"#x #define OVERRIDE_FUNCTION(oldfunc, newfunc) \ do {CHECK(0 == __asan_mach_override_ptr_custom((void*)(oldfunc), \ @@ -77,8 +76,6 @@ #elif defined(_WIN32) // TODO(timurrrr): change these macros once we decide how to intercept // functions on Windows. -#define WRAPPER_NAME(x) #x - #define INTERCEPT_FUNCTION(func) \ do { } while (0) @@ -86,8 +83,6 @@ do { } while (0) #else // __linux__ -#define WRAPPER_NAME(x) #x - #define INTERCEPT_FUNCTION(func) \ CHECK((real_##func = (func##_f)dlsym(RTLD_NEXT, #func))); @@ -97,47 +92,6 @@ namespace __asan { -typedef void (*longjmp_f)(void *env, int val); -typedef longjmp_f _longjmp_f; -typedef longjmp_f siglongjmp_f; -typedef void (*__cxa_throw_f)(void *, void *, void *); -typedef int (*pthread_create_f)(void *thread, const void *attr, - void *(*start_routine) (void *), void *arg); -#ifdef __APPLE__ -dispatch_async_f_f real_dispatch_async_f; -dispatch_sync_f_f real_dispatch_sync_f; -dispatch_after_f_f real_dispatch_after_f; -dispatch_barrier_async_f_f real_dispatch_barrier_async_f; -dispatch_group_async_f_f real_dispatch_group_async_f; -pthread_workqueue_additem_np_f real_pthread_workqueue_additem_np; -CFStringCreateCopy_f real_CFStringCreateCopy; -#endif - -sigaction_f real_sigaction; -signal_f real_signal; -longjmp_f real_longjmp; -_longjmp_f real__longjmp; -siglongjmp_f real_siglongjmp; -__cxa_throw_f real___cxa_throw; -pthread_create_f real_pthread_create; - -index_f real_index; -memcmp_f real_memcmp; -memcpy_f real_memcpy; -memmove_f real_memmove; -memset_f real_memset; -strcasecmp_f real_strcasecmp; -strcat_f real_strcat; -strchr_f real_strchr; -strcmp_f real_strcmp; -strcpy_f real_strcpy; -strdup_f real_strdup; -strlen_f real_strlen; -strncasecmp_f real_strncasecmp; -strncmp_f real_strncmp; -strncpy_f real_strncpy; -strnlen_f real_strnlen; - // Instruments read/write access to a single byte in memory. // On error calls __asan_report_error, which aborts the program. __attribute__((noinline)) @@ -205,9 +159,11 @@ size_t internal_strlen(const char *s) { } size_t internal_strnlen(const char *s, size_t maxlen) { +#ifndef __APPLE__ if (real_strnlen != NULL) { return real_strnlen(s, maxlen); } +#endif size_t i = 0; while (i < maxlen && s[i]) i++; return i; @@ -302,10 +258,9 @@ static void *asan_thread_start(void *arg) { } #ifndef _WIN32 -extern "C" -INTERCEPTOR_ATTRIBUTE -int WRAP(pthread_create)(pthread_t *thread, const pthread_attr_t *attr, - void *(*start_routine) (void *), void *arg) { +INTERCEPTOR(int, pthread_create, pthread_t *thread, + const pthread_attr_t *attr, + void *(*start_routine)(void*), void *arg) { GET_STACK_TRACE_HERE(kStackTraceMax); int current_tid = asanThreadRegistry().GetCurrentTidOrMinusOne(); AsanThread *t = AsanThread::Create(current_tid, start_routine, arg, &stack); @@ -313,19 +268,15 @@ int WRAP(pthread_create)(pthread_t *thread, const pthread_attr_t *attr, return real_pthread_create(thread, attr, asan_thread_start, t); } -extern "C" -INTERCEPTOR_ATTRIBUTE -void *WRAP(signal)(int signum, void *handler) { +INTERCEPTOR(void*, signal, int signum, void *handler) { if (!AsanInterceptsSignal(signum)) { return real_signal(signum, handler); } return NULL; } -extern "C" -INTERCEPTOR_ATTRIBUTE -int WRAP(sigaction)(int signum, const struct sigaction *act, - struct sigaction *oldact) { +INTERCEPTOR(int, sigaction, int signum, const struct sigaction *act, + struct sigaction *oldact) { if (!AsanInterceptsSignal(signum)) { return real_sigaction(signum, act, oldact); } @@ -343,23 +294,17 @@ static void UnpoisonStackFromHereToTop() { PoisonShadow(bottom, top - bottom, 0); } -extern "C" -INTERCEPTOR_ATTRIBUTE -void WRAP(longjmp)(void *env, int val) { +INTERCEPTOR(void, longjmp, void *env, int val) { UnpoisonStackFromHereToTop(); real_longjmp(env, val); } -extern "C" -INTERCEPTOR_ATTRIBUTE -void WRAP(_longjmp)(void *env, int val) { +INTERCEPTOR(void, _longjmp, void *env, int val) { UnpoisonStackFromHereToTop(); real__longjmp(env, val); } -extern "C" -INTERCEPTOR_ATTRIBUTE -void WRAP(siglongjmp)(void *env, int val) { +INTERCEPTOR(void, siglongjmp, void *env, int val) { UnpoisonStackFromHereToTop(); real_siglongjmp(env, val); } @@ -369,16 +314,13 @@ void WRAP(siglongjmp)(void *env, int val) { extern "C" void __cxa_throw(void *a, void *b, void *c); #endif // __APPLE__ -extern "C" -INTERCEPTOR_ATTRIBUTE -void WRAP(__cxa_throw)(void *a, void *b, void *c) { +INTERCEPTOR(void, __cxa_throw, void *a, void *b, void *c) { CHECK(&real___cxa_throw); UnpoisonStackFromHereToTop(); real___cxa_throw(a, b, c); } #endif -extern "C" { // intercept mlock and friends. // Since asan maps 16T of RAM, mlock is completely unfriendly to asan. // All functions return 0 (success). @@ -389,6 +331,7 @@ static void MlockIsUnsupported() { Printf("INFO: AddressSanitizer ignores mlock/mlockall/munlock/munlockall\n"); } +extern "C" { INTERCEPTOR_ATTRIBUTE int mlock(const void *addr, size_t len) { MlockIsUnsupported(); @@ -414,8 +357,6 @@ int munlockall(void) { } } // extern "C" - - static inline int CharCmp(unsigned char c1, unsigned char c2) { return (c1 == c2) ? 0 : (c1 < c2) ? -1 : 1; } @@ -426,9 +367,7 @@ static inline int CharCaseCmp(unsigned char c1, unsigned char c2) { return c1_low - c2_low; } -extern "C" -INTERCEPTOR_ATTRIBUTE -int WRAP(memcmp)(const void *a1, const void *a2, size_t size) { +INTERCEPTOR(int, memcmp, const void *a1, const void *a2, size_t size) { ENSURE_ASAN_INITED(); unsigned char c1 = 0, c2 = 0; const unsigned char *s1 = (const unsigned char*)a1; @@ -444,9 +383,7 @@ int WRAP(memcmp)(const void *a1, const void *a2, size_t size) { return CharCmp(c1, c2); } -extern "C" -INTERCEPTOR_ATTRIBUTE -void *WRAP(memcpy)(void *to, const void *from, size_t size) { +INTERCEPTOR(void*, memcpy, void *to, const void *from, size_t size) { // memcpy is called during __asan_init() from the internals // of printf(...). if (asan_init_is_running) { @@ -465,9 +402,7 @@ void *WRAP(memcpy)(void *to, const void *from, size_t size) { return real_memcpy(to, from, size); } -extern "C" -INTERCEPTOR_ATTRIBUTE -void *WRAP(memmove)(void *to, const void *from, size_t size) { +INTERCEPTOR(void*, memmove, void *to, const void *from, size_t size) { ENSURE_ASAN_INITED(); if (FLAG_replace_intrin) { ASAN_WRITE_RANGE(from, size); @@ -476,9 +411,7 @@ void *WRAP(memmove)(void *to, const void *from, size_t size) { return real_memmove(to, from, size); } -extern "C" -INTERCEPTOR_ATTRIBUTE -void *WRAP(memset)(void *block, int c, size_t size) { +INTERCEPTOR(void*, memset, void *block, int c, size_t size) { // memset is called inside INTERCEPT_FUNCTION on Mac. if (asan_init_is_running) { return real_memset(block, c, size); @@ -490,16 +423,7 @@ void *WRAP(memset)(void *block, int c, size_t size) { return real_memset(block, c, size); } -#ifndef __APPLE__ -extern "C" -INTERCEPTOR_ATTRIBUTE -char *WRAP(index)(const char *str, int c) - __attribute__((alias(WRAPPER_NAME(strchr)))); -#endif - -extern "C" -INTERCEPTOR_ATTRIBUTE -char *WRAP(strchr)(const char *str, int c) { +INTERCEPTOR(char*, strchr, const char *str, int c) { ENSURE_ASAN_INITED(); char *result = real_strchr(str, c); if (FLAG_replace_str) { @@ -509,9 +433,14 @@ char *WRAP(strchr)(const char *str, int c) { return result; } -extern "C" -INTERCEPTOR_ATTRIBUTE -int WRAP(strcasecmp)(const char *s1, const char *s2) { +#ifndef __APPLE__ +INTERCEPTOR(void*, index, const char *string, int c) + __attribute__((alias(WRAPPER_NAME(strchr)))); +#else +DEFINE_REAL(void*, index, const char *string, int c); +#endif + +INTERCEPTOR(int, strcasecmp, const char *s1, const char *s2) { ENSURE_ASAN_INITED(); unsigned char c1, c2; size_t i; @@ -525,9 +454,7 @@ int WRAP(strcasecmp)(const char *s1, const char *s2) { return CharCaseCmp(c1, c2); } -extern "C" -INTERCEPTOR_ATTRIBUTE -char *WRAP(strcat)(char *to, const char *from) { // NOLINT +INTERCEPTOR(char*, strcat, char *to, const char *from) { // NOLINT ENSURE_ASAN_INITED(); if (FLAG_replace_str) { size_t from_length = real_strlen(from); @@ -542,9 +469,7 @@ char *WRAP(strcat)(char *to, const char *from) { // NOLINT return real_strcat(to, from); } -extern "C" -INTERCEPTOR_ATTRIBUTE -int WRAP(strcmp)(const char *s1, const char *s2) { +INTERCEPTOR(int, strcmp, const char *s1, const char *s2) { if (!asan_inited) { return internal_strcmp(s1, s2); } @@ -560,9 +485,7 @@ int WRAP(strcmp)(const char *s1, const char *s2) { return CharCmp(c1, c2); } -extern "C" -INTERCEPTOR_ATTRIBUTE -char *WRAP(strcpy)(char *to, const char *from) { // NOLINT +INTERCEPTOR(char*, strcpy, char *to, const char *from) { // NOLINT // strcpy is called from malloc_default_purgeable_zone() // in __asan::ReplaceSystemAlloc() on Mac. if (asan_init_is_running) { @@ -578,9 +501,7 @@ char *WRAP(strcpy)(char *to, const char *from) { // NOLINT return real_strcpy(to, from); } -extern "C" -INTERCEPTOR_ATTRIBUTE -char *WRAP(strdup)(const char *s) { +INTERCEPTOR(char*, strdup, const char *s) { ENSURE_ASAN_INITED(); if (FLAG_replace_str) { size_t length = real_strlen(s); @@ -589,9 +510,7 @@ char *WRAP(strdup)(const char *s) { return real_strdup(s); } -extern "C" -INTERCEPTOR_ATTRIBUTE -size_t WRAP(strlen)(const char *s) { +INTERCEPTOR(size_t, strlen, const char *s) { // strlen is called from malloc_default_purgeable_zone() // in __asan::ReplaceSystemAlloc() on Mac. if (asan_init_is_running) { @@ -605,25 +524,21 @@ size_t WRAP(strlen)(const char *s) { return length; } -extern "C" -INTERCEPTOR_ATTRIBUTE -int WRAP(strncasecmp)(const char *s1, const char *s2, size_t size) { +INTERCEPTOR(int, strncasecmp, const char *s1, const char *s2, size_t n) { ENSURE_ASAN_INITED(); unsigned char c1 = 0, c2 = 0; size_t i; - for (i = 0; i < size; i++) { + for (i = 0; i < n; i++) { c1 = (unsigned char)s1[i]; c2 = (unsigned char)s2[i]; if (CharCaseCmp(c1, c2) != 0 || c1 == '\0') break; } - ASAN_READ_RANGE(s1, Min(i + 1, size)); - ASAN_READ_RANGE(s2, Min(i + 1, size)); + ASAN_READ_RANGE(s1, Min(i + 1, n)); + ASAN_READ_RANGE(s2, Min(i + 1, n)); return CharCaseCmp(c1, c2); } -extern "C" -INTERCEPTOR_ATTRIBUTE -int WRAP(strncmp)(const char *s1, const char *s2, size_t size) { +INTERCEPTOR(int, strncmp, const char *s1, const char *s2, size_t size) { // strncmp is called from malloc_default_purgeable_zone() // in __asan::ReplaceSystemAlloc() on Mac. if (asan_init_is_running) { @@ -641,9 +556,7 @@ int WRAP(strncmp)(const char *s1, const char *s2, size_t size) { return CharCmp(c1, c2); } -extern "C" -INTERCEPTOR_ATTRIBUTE -char *WRAP(strncpy)(char *to, const char *from, size_t size) { +INTERCEPTOR(char*, strncpy, char *to, const char *from, size_t size) { ENSURE_ASAN_INITED(); if (FLAG_replace_str) { size_t from_size = Min(size, internal_strnlen(from, size) + 1); @@ -655,9 +568,7 @@ char *WRAP(strncpy)(char *to, const char *from, size_t size) { } #ifndef __APPLE__ -extern "C" -INTERCEPTOR_ATTRIBUTE -size_t WRAP(strnlen)(const char *s, size_t maxlen) { +INTERCEPTOR(size_t, strnlen, const char *s, size_t maxlen) { ENSURE_ASAN_INITED(); size_t length = real_strnlen(s, maxlen); if (FLAG_replace_str) { diff --git a/lib/asan/asan_interceptors.h b/lib/asan/asan_interceptors.h index 08dc25aba..665339aba 100644 --- a/lib/asan/asan_interceptors.h +++ b/lib/asan/asan_interceptors.h @@ -16,61 +16,78 @@ #include "asan_internal.h" +// Suppose you need to wrap/replace system function (generally, from libc): +// int foo(const char *bar, double baz); +// You'll need to: +// 1) define INTERCEPT(int, foo, const char *bar, double baz) { ... } +// 2) add a line "INTERCEPT_FUNCTION(foo)" to InitializeAsanInterceptors() +// You can access original function by calling __asan::real_foo(bar, baz). +// By defualt, real_foo will be visible only inside your interceptor, and if +// you want to use it in other parts of RTL, you'll need to: +// 3a) add DECLARE_REAL(int, foo, const char*, double); to a +// header file. +// However, if you want to implement your interceptor somewhere outside +// asan_interceptors.cc, you'll instead need to: +// 3b) add DECLARE_REAL_AND_INTERCEPTOR(int, foo, const char*, double); +// to a header. + #if defined(__APPLE__) # define WRAP(x) wrap_##x +# define WRAPPER_NAME(x) "wrap_"#x # define INTERCEPTOR_ATTRIBUTE #elif defined(_WIN32) // TODO(timurrrr): we're likely to use something else later on Windows. # define WRAP(x) wrap_##x +# define WRAPPER_NAME(x) #x # define INTERCEPTOR_ATTRIBUTE #else # define WRAP(x) x +# define WRAPPER_NAME(x) #x # define INTERCEPTOR_ATTRIBUTE __attribute__((visibility("default"))) #endif -struct sigaction; +#define REAL(x) real_##x +#define FUNC_TYPE(x) x##_f -namespace __asan { +#define DECLARE_REAL(ret_type, func, ...); \ + typedef ret_type (*FUNC_TYPE(func))(__VA_ARGS__); \ + namespace __asan { \ + extern FUNC_TYPE(func) REAL(func); \ + } + +#define DECLARE_REAL_AND_INTERCEPTOR(ret_type, func, ...); \ + DECLARE_REAL(ret_type, func, ##__VA_ARGS__); \ + extern "C" \ + ret_type WRAP(func)(__VA_ARGS__); -typedef void* (*index_f)(const char *string, int c); -typedef int (*memcmp_f)(const void *a1, const void *a2, size_t size); -typedef void* (*memcpy_f)(void *to, const void *from, size_t size); -typedef void* (*memmove_f)(void *to, const void *from, size_t size); -typedef void* (*memset_f)(void *block, int c, size_t size); -typedef int (*strcasecmp_f)(const char *s1, const char *s2); -typedef char* (*strcat_f)(char *to, const char *from); -typedef char* (*strchr_f)(const char *str, int c); -typedef int (*strcmp_f)(const char *s1, const char *s2); -typedef char* (*strcpy_f)(char *to, const char *from); -typedef char* (*strdup_f)(const char *s); -typedef size_t (*strlen_f)(const char *s); -typedef int (*strncasecmp_f)(const char *s1, const char *s2, size_t n); -typedef int (*strncmp_f)(const char *s1, const char *s2, size_t size); -typedef char* (*strncpy_f)(char *to, const char *from, size_t size); -typedef size_t (*strnlen_f)(const char *s, size_t maxlen); -typedef void *(*signal_f)(int signum, void *handler); -typedef int (*sigaction_f)(int signum, const struct sigaction *act, - struct sigaction *oldact); +// Generally, you don't need to use DEFINE_REAL by itself, as INTERCEPTOR +// macros does its job. In exceptional cases you may need to call REAL(foo) +// without defining INTERCEPTOR(..., foo, ...). For example, if you override +// foo with interceptor for other function. +#define DEFINE_REAL(ret_type, func, ...); \ + typedef ret_type (*FUNC_TYPE(func))(__VA_ARGS__); \ + namespace __asan { \ + FUNC_TYPE(func) REAL(func); \ + } -// __asan::real_X() holds pointer to library implementation of X(). -extern index_f real_index; -extern memcmp_f real_memcmp; -extern memcpy_f real_memcpy; -extern memmove_f real_memmove; -extern memset_f real_memset; -extern strcasecmp_f real_strcasecmp; -extern strcat_f real_strcat; -extern strchr_f real_strchr; -extern strcmp_f real_strcmp; -extern strcpy_f real_strcpy; -extern strdup_f real_strdup; -extern strlen_f real_strlen; -extern strncasecmp_f real_strncasecmp; -extern strncmp_f real_strncmp; -extern strncpy_f real_strncpy; -extern strnlen_f real_strnlen; -extern signal_f real_signal; -extern sigaction_f real_sigaction; +#define INTERCEPTOR(ret_type, func, ...); \ + DEFINE_REAL(ret_type, func, __VA_ARGS__); \ + extern "C" \ + INTERCEPTOR_ATTRIBUTE \ + ret_type WRAP(func)(__VA_ARGS__) + +DECLARE_REAL(int, memcmp, const void *a1, const void *a2, size_t size); +DECLARE_REAL(void*, memcpy, void *to, const void *from, size_t size); +DECLARE_REAL(void*, memset, void *block, int c, size_t size); +DECLARE_REAL(char*, strchr, const char *str, int c); +DECLARE_REAL(size_t, strlen, const char *s); +DECLARE_REAL(char*, strncpy, char *to, const char *from, size_t size); +DECLARE_REAL(size_t, strnlen, const char *s, size_t maxlen); +struct sigaction; +DECLARE_REAL(int, sigaction, int signum, const struct sigaction *act, + struct sigaction *oldact); + +namespace __asan { // __asan::internal_X() is the implementation of X() for use in RTL. size_t internal_strlen(const char *s); diff --git a/lib/asan/asan_mac.cc b/lib/asan/asan_mac.cc index 9abe4c381..112aebf8d 100644 --- a/lib/asan/asan_mac.cc +++ b/lib/asan/asan_mac.cc @@ -38,14 +38,6 @@ namespace __asan { void *island_allocator_pos = NULL; -extern dispatch_async_f_f real_dispatch_async_f; -extern dispatch_sync_f_f real_dispatch_sync_f; -extern dispatch_after_f_f real_dispatch_after_f; -extern dispatch_barrier_async_f_f real_dispatch_barrier_async_f; -extern dispatch_group_async_f_f real_dispatch_group_async_f; -extern pthread_workqueue_additem_np_f real_pthread_workqueue_additem_np; -extern CFStringCreateCopy_f real_CFStringCreateCopy; - void GetPcSpBp(void *context, uintptr_t *pc, uintptr_t *sp, uintptr_t *bp) { ucontext_t *ucontext = (ucontext_t*)context; # if __WORDSIZE == 64 @@ -431,10 +423,8 @@ asan_block_context_t *alloc_asan_context(void *ctxt, dispatch_function_t func, } // TODO(glider): can we reduce code duplication by introducing a macro? -extern "C" -int WRAP(dispatch_async_f)(dispatch_queue_t dq, - void *ctxt, - dispatch_function_t func) { +INTERCEPTOR(void, dispatch_async_f, dispatch_queue_t dq, void *ctxt, + dispatch_function_t func) { GET_STACK_TRACE_HERE(kStackTraceMax); asan_block_context_t *asan_ctxt = alloc_asan_context(ctxt, func, &stack); if (FLAG_v >= 2) { @@ -446,10 +436,8 @@ int WRAP(dispatch_async_f)(dispatch_queue_t dq, asan_dispatch_call_block_and_release); } -extern "C" -int WRAP(dispatch_sync_f)(dispatch_queue_t dq, - void *ctxt, - dispatch_function_t func) { +INTERCEPTOR(void, dispatch_sync_f, dispatch_queue_t dq, void *ctxt, + dispatch_function_t func) { GET_STACK_TRACE_HERE(kStackTraceMax); asan_block_context_t *asan_ctxt = alloc_asan_context(ctxt, func, &stack); if (FLAG_v >= 2) { @@ -461,11 +449,9 @@ int WRAP(dispatch_sync_f)(dispatch_queue_t dq, asan_dispatch_call_block_and_release); } -extern "C" -int WRAP(dispatch_after_f)(dispatch_time_t when, - dispatch_queue_t dq, - void *ctxt, - dispatch_function_t func) { +INTERCEPTOR(void, dispatch_after_f, dispatch_time_t when, + dispatch_queue_t dq, void *ctxt, + dispatch_function_t func) { GET_STACK_TRACE_HERE(kStackTraceMax); asan_block_context_t *asan_ctxt = alloc_asan_context(ctxt, func, &stack); if (FLAG_v >= 2) { @@ -476,9 +462,8 @@ int WRAP(dispatch_after_f)(dispatch_time_t when, asan_dispatch_call_block_and_release); } -extern "C" -void WRAP(dispatch_barrier_async_f)(dispatch_queue_t dq, - void *ctxt, dispatch_function_t func) { +INTERCEPTOR(void, dispatch_barrier_async_f, dispatch_queue_t dq, void *ctxt, + dispatch_function_t func) { GET_STACK_TRACE_HERE(kStackTraceMax); asan_block_context_t *asan_ctxt = alloc_asan_context(ctxt, func, &stack); if (FLAG_v >= 2) { @@ -490,10 +475,9 @@ void WRAP(dispatch_barrier_async_f)(dispatch_queue_t dq, asan_dispatch_call_block_and_release); } -extern "C" -void WRAP(dispatch_group_async_f)(dispatch_group_t group, - dispatch_queue_t dq, - void *ctxt, dispatch_function_t func) { +INTERCEPTOR(void, dispatch_group_async_f, dispatch_group_t group, + dispatch_queue_t dq, void *ctxt, + dispatch_function_t func) { GET_STACK_TRACE_HERE(kStackTraceMax); asan_block_context_t *asan_ctxt = alloc_asan_context(ctxt, func, &stack); if (FLAG_v >= 2) { @@ -524,8 +508,7 @@ void *wrap_workitem_func(void *arg) { return result; } -extern "C" -int WRAP(pthread_workqueue_additem_np)(pthread_workqueue_t workq, +INTERCEPTOR(int, pthread_workqueue_additem_np, pthread_workqueue_t workq, void *(*workitem_func)(void *), void * workitem_arg, pthread_workitem_handle_t * itemhandlep, unsigned int *gencountp) { GET_STACK_TRACE_HERE(kStackTraceMax); @@ -574,8 +557,8 @@ int __CFStrIsConstant(CFStringRef str) { #endif } -extern "C" -CFStringRef WRAP(CFStringCreateCopy)(CFAllocatorRef alloc, CFStringRef str) { +INTERCEPTOR(CFStringRef, CFStringCreateCopy, CFAllocatorRef alloc, + CFStringRef str) { if (__CFStrIsConstant(str)) { return str; } else { diff --git a/lib/asan/asan_mac.h b/lib/asan/asan_mac.h index e0ac5f6b7..506cf87bd 100644 --- a/lib/asan/asan_mac.h +++ b/lib/asan/asan_mac.h @@ -40,24 +40,35 @@ typedef void* pthread_workitem_handle_t; typedef void (*dispatch_function_t)(void *block); typedef void* (*worker_t)(void *block); -typedef int (*dispatch_async_f_f)(dispatch_queue_t dq, void *ctxt, - dispatch_function_t func); -typedef int (*dispatch_sync_f_f)(dispatch_queue_t dq, void *ctxt, - dispatch_function_t func); -typedef int (*dispatch_after_f_f)(dispatch_time_t when, - dispatch_queue_t dq, void *ctxt, - dispatch_function_t func); -typedef void (*dispatch_barrier_async_f_f)(dispatch_queue_t dq, - void *ctxt, - dispatch_function_t func); -typedef void (*dispatch_group_async_f_f)(dispatch_group_t group, - dispatch_queue_t dq, - void *ctxt, dispatch_function_t func); -typedef int (*pthread_workqueue_additem_np_f)(pthread_workqueue_t workq, - void *(*workitem_func)(void *), void * workitem_arg, - pthread_workitem_handle_t * itemhandlep, unsigned int *gencountp); -typedef CFStringRef (*CFStringCreateCopy_f)(CFAllocatorRef alloc, - CFStringRef str); + +DECLARE_REAL_AND_INTERCEPTOR(void, dispatch_async_f, dispatch_queue_t dq, + void *ctxt, + dispatch_function_t func); +DECLARE_REAL_AND_INTERCEPTOR(void, dispatch_sync_f, dispatch_queue_t dq, + void *ctxt, + dispatch_function_t func); +DECLARE_REAL_AND_INTERCEPTOR(void, dispatch_after_f, dispatch_time_t when, + dispatch_queue_t dq, + void *ctxt, + dispatch_function_t func); +DECLARE_REAL_AND_INTERCEPTOR(void, dispatch_barrier_async_f, + dispatch_queue_t dq, + void *ctxt, + dispatch_function_t func); +DECLARE_REAL_AND_INTERCEPTOR(void, dispatch_group_async_f, + dispatch_group_t group, + dispatch_queue_t dq, + void *ctxt, + dispatch_function_t func); +DECLARE_REAL_AND_INTERCEPTOR(int, pthread_workqueue_additem_np, + pthread_workqueue_t workq, + void *(*workitem_func)(void *), + void * workitem_arg, + pthread_workitem_handle_t * itemhandlep, + unsigned int *gencountp); +DECLARE_REAL_AND_INTERCEPTOR(CFStringRef, CFStringCreateCopy, + CFAllocatorRef alloc, + CFStringRef str); // A wrapper for the ObjC blocks used to support libdispatch. typedef struct { @@ -84,26 +95,6 @@ void dispatch_barrier_async_f(dispatch_queue_t dq, int pthread_workqueue_additem_np(pthread_workqueue_t workq, void *(*workitem_func)(void *), void * workitem_arg, pthread_workitem_handle_t * itemhandlep, unsigned int *gencountp); - -int WRAP(dispatch_async_f)(dispatch_queue_t dq, - void *ctxt, - dispatch_function_t func); -int WRAP(dispatch_sync_f)(dispatch_queue_t dq, - void *ctxt, - dispatch_function_t func); -int WRAP(dispatch_after_f)(dispatch_time_t when, - dispatch_queue_t dq, - void *ctxt, - dispatch_function_t func); -void WRAP(dispatch_barrier_async_f)(dispatch_queue_t dq, - void *ctxt, dispatch_function_t func); -void WRAP(dispatch_group_async_f)(dispatch_group_t group, - dispatch_queue_t dq, - void *ctxt, dispatch_function_t func); -int WRAP(pthread_workqueue_additem_np)(pthread_workqueue_t workq, - void *(*workitem_func)(void *), void * workitem_arg, - pthread_workitem_handle_t * itemhandlep, unsigned int *gencountp); -CFStringRef WRAP(CFStringCreateCopy)(CFAllocatorRef alloc, CFStringRef str); } #endif // ASAN_MAC_H diff --git a/lib/asan/asan_malloc_linux.cc b/lib/asan/asan_malloc_linux.cc index acad5742a..4547041fd 100644 --- a/lib/asan/asan_malloc_linux.cc +++ b/lib/asan/asan_malloc_linux.cc @@ -54,27 +54,22 @@ void ReplaceSystemMalloc() { // ---------------------- Replacement functions ---------------- {{{1 using namespace __asan; // NOLINT -extern "C" { -INTERCEPTOR_ATTRIBUTE -void free(void *ptr) { +INTERCEPTOR(void, free, void *ptr) { GET_STACK_TRACE_HERE_FOR_FREE(ptr); asan_free(ptr, &stack); } -INTERCEPTOR_ATTRIBUTE -void cfree(void *ptr) { +INTERCEPTOR(void, cfree, void *ptr) { GET_STACK_TRACE_HERE_FOR_FREE(ptr); asan_free(ptr, &stack); } -INTERCEPTOR_ATTRIBUTE -void *malloc(size_t size) { +INTERCEPTOR(void*, malloc, size_t size) { GET_STACK_TRACE_HERE_FOR_MALLOC; return asan_malloc(size, &stack); } -INTERCEPTOR_ATTRIBUTE -void *calloc(size_t nmemb, size_t size) { +INTERCEPTOR(void*, calloc, size_t nmemb, size_t size) { if (!asan_inited) { // Hack: dlsym calls calloc before real_calloc is retrieved from dlsym. const size_t kCallocPoolSize = 1024; @@ -90,57 +85,48 @@ void *calloc(size_t nmemb, size_t size) { return asan_calloc(nmemb, size, &stack); } -INTERCEPTOR_ATTRIBUTE -void *realloc(void *ptr, size_t size) { +INTERCEPTOR(void*, realloc, void *ptr, size_t size) { GET_STACK_TRACE_HERE_FOR_MALLOC; return asan_realloc(ptr, size, &stack); } -INTERCEPTOR_ATTRIBUTE -void *memalign(size_t boundary, size_t size) { +INTERCEPTOR(void*, memalign, size_t boundary, size_t size) { GET_STACK_TRACE_HERE_FOR_MALLOC; return asan_memalign(boundary, size, &stack); } -void* __libc_memalign(size_t align, size_t s) +INTERCEPTOR(void*, __libc_memalign, size_t align, size_t s) __attribute__((alias("memalign"))); -INTERCEPTOR_ATTRIBUTE -size_t malloc_usable_size(void *ptr) { +INTERCEPTOR(size_t, malloc_usable_size, void *ptr) { GET_STACK_TRACE_HERE_FOR_MALLOC; return asan_malloc_usable_size(ptr, &stack); } -INTERCEPTOR_ATTRIBUTE -struct mallinfo mallinfo() { +INTERCEPTOR(struct mallinfo, mallinfo) { struct mallinfo res; real_memset(&res, 0, sizeof(res)); return res; } -INTERCEPTOR_ATTRIBUTE -int mallopt(int cmd, int value) { +INTERCEPTOR(int, mallopt, int cmd, int value) { return -1; } -INTERCEPTOR_ATTRIBUTE -int posix_memalign(void **memptr, size_t alignment, size_t size) { +INTERCEPTOR(int, posix_memalign, void **memptr, size_t alignment, size_t size) { GET_STACK_TRACE_HERE_FOR_MALLOC; // Printf("posix_memalign: %lx %ld\n", alignment, size); return asan_posix_memalign(memptr, alignment, size, &stack); } -INTERCEPTOR_ATTRIBUTE -void *valloc(size_t size) { +INTERCEPTOR(void*, valloc, size_t size) { GET_STACK_TRACE_HERE_FOR_MALLOC; return asan_valloc(size, &stack); } -INTERCEPTOR_ATTRIBUTE -void *pvalloc(size_t size) { +INTERCEPTOR(void*, pvalloc, size_t size) { GET_STACK_TRACE_HERE_FOR_MALLOC; return asan_pvalloc(size, &stack); } -} // extern "C" #endif // __linux__ |