summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/asan/asan_interceptors.cc165
-rw-r--r--lib/asan/asan_interceptors.h97
-rw-r--r--lib/asan/asan_mac.cc47
-rw-r--r--lib/asan/asan_mac.h67
-rw-r--r--lib/asan/asan_malloc_linux.cc40
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__