asan_dll_thunk.cc revision c11fa095b344c1423ba76822d5bde122b1676223
1//===-- asan_dll_thunk.cc -------------------------------------------------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file is a part of AddressSanitizer, an address sanity checker. 11// 12// This file defines a family of thunks that should be statically linked into 13// the DLLs that have ASan instrumentation in order to delegate the calls to the 14// shared runtime that lives in the main binary. 15// See https://code.google.com/p/address-sanitizer/issues/detail?id=209 for the 16// details. 17//===----------------------------------------------------------------------===// 18 19// Only compile this code when buidling asan_dll_thunk.lib 20// Using #ifdef rather than relying on Makefiles etc. 21// simplifies the build procedure. 22#ifdef ASAN_DLL_THUNK 23 24// ----------------- Helper functions and macros --------------------- {{{1 25extern "C" { 26void *__stdcall GetModuleHandleA(const char *module_name); 27void *__stdcall GetProcAddress(void *module, const char *proc_name); 28void abort(); 29} 30 31static void *getRealProcAddressOrDie(const char *name) { 32 void *ret = GetProcAddress(GetModuleHandleA(0), name); 33 if (!ret) 34 abort(); 35 return ret; 36} 37 38#define WRAP_V_V(name) \ 39 extern "C" void name() { \ 40 typedef void (*fntype)(); \ 41 fntype fn = (fntype)getRealProcAddressOrDie(#name); \ 42 fn(); \ 43 } 44 45#define WRAP_V_W(name) \ 46 extern "C" void name(void *arg) { \ 47 typedef void (*fntype)(void *arg); \ 48 fntype fn = (fntype)getRealProcAddressOrDie(#name); \ 49 fn(arg); \ 50 } 51 52#define WRAP_V_WW(name) \ 53 extern "C" void name(void *arg1, void *arg2) { \ 54 typedef void (*fntype)(void *, void *); \ 55 fntype fn = (fntype)getRealProcAddressOrDie(#name); \ 56 fn(arg1, arg2); \ 57 } 58 59#define WRAP_V_WWW(name) \ 60 extern "C" void name(void *arg1, void *arg2, void *arg3) { \ 61 typedef void *(*fntype)(void *, void *, void *); \ 62 fntype fn = (fntype)getRealProcAddressOrDie(#name); \ 63 fn(arg1, arg2, arg3); \ 64 } 65 66#define WRAP_W_V(name) \ 67 extern "C" void *name() { \ 68 typedef void *(*fntype)(); \ 69 fntype fn = (fntype)getRealProcAddressOrDie(#name); \ 70 return fn(); \ 71 } 72 73#define WRAP_W_W(name) \ 74 extern "C" void *name(void *arg) { \ 75 typedef void *(*fntype)(void *arg); \ 76 fntype fn = (fntype)getRealProcAddressOrDie(#name); \ 77 return fn(arg); \ 78 } 79 80#define WRAP_W_WW(name) \ 81 extern "C" void *name(void *arg1, void *arg2) { \ 82 typedef void *(*fntype)(void *, void *); \ 83 fntype fn = (fntype)getRealProcAddressOrDie(#name); \ 84 return fn(arg1, arg2); \ 85 } 86 87#define WRAP_W_WWW(name) \ 88 extern "C" void *name(void *arg1, void *arg2, void *arg3) { \ 89 typedef void *(*fntype)(void *, void *, void *); \ 90 fntype fn = (fntype)getRealProcAddressOrDie(#name); \ 91 return fn(arg1, arg2, arg3); \ 92 } 93 94#define WRAP_W_WWWW(name) \ 95 extern "C" void *name(void *arg1, void *arg2, void *arg3, void *arg4) { \ 96 typedef void *(*fntype)(void *, void *, void *, void *); \ 97 fntype fn = (fntype)getRealProcAddressOrDie(#name); \ 98 return fn(arg1, arg2, arg3, arg4); \ 99 } 100 101#define WRAP_W_WWWWW(name) \ 102 extern "C" void *name(void *arg1, void *arg2, void *arg3, void *arg4, \ 103 void *arg5) { \ 104 typedef void *(*fntype)(void *, void *, void *, void *, void *); \ 105 fntype fn = (fntype)getRealProcAddressOrDie(#name); \ 106 return fn(arg1, arg2, arg3, arg4, arg5); \ 107 } 108 109#define WRAP_W_WWWWWW(name) \ 110 extern "C" void *name(void *arg1, void *arg2, void *arg3, void *arg4, \ 111 void *arg5, void *arg6) { \ 112 typedef void *(*fntype)(void *, void *, void *, void *, void *, void *); \ 113 fntype fn = (fntype)getRealProcAddressOrDie(#name); \ 114 return fn(arg1, arg2, arg3, arg4, arg5, arg6); \ 115 } 116// }}} 117 118// ----------------- ASan own interface functions -------------------- 119WRAP_W_V(__asan_should_detect_stack_use_after_return) 120 121extern "C" { 122 int __asan_option_detect_stack_use_after_return; 123 124 // Manually wrap __asan_init as we need to initialize 125 // __asan_option_detect_stack_use_after_return afterwards. 126 void __asan_init_v3() { 127 typedef void (*fntype)(); 128 static fntype fn = (fntype)getRealProcAddressOrDie("__asan_init_v3"); 129 fn(); 130 __asan_option_detect_stack_use_after_return = 131 (bool)__asan_should_detect_stack_use_after_return(); 132 } 133} 134 135WRAP_V_W(__asan_report_store1) 136WRAP_V_W(__asan_report_store2) 137WRAP_V_W(__asan_report_store4) 138WRAP_V_W(__asan_report_store8) 139WRAP_V_W(__asan_report_store16) 140WRAP_V_WW(__asan_report_store_n) 141 142WRAP_V_W(__asan_report_load1) 143WRAP_V_W(__asan_report_load2) 144WRAP_V_W(__asan_report_load4) 145WRAP_V_W(__asan_report_load8) 146WRAP_V_W(__asan_report_load16) 147WRAP_V_WW(__asan_report_load_n) 148 149WRAP_V_WW(__asan_register_globals) 150WRAP_V_WW(__asan_unregister_globals) 151 152WRAP_W_WW(__asan_stack_malloc_0) 153WRAP_W_WW(__asan_stack_malloc_1) 154WRAP_W_WW(__asan_stack_malloc_2) 155WRAP_W_WW(__asan_stack_malloc_3) 156WRAP_W_WW(__asan_stack_malloc_4) 157WRAP_W_WW(__asan_stack_malloc_5) 158WRAP_W_WW(__asan_stack_malloc_6) 159WRAP_W_WW(__asan_stack_malloc_7) 160WRAP_W_WW(__asan_stack_malloc_8) 161WRAP_W_WW(__asan_stack_malloc_9) 162WRAP_W_WW(__asan_stack_malloc_10) 163 164WRAP_V_WWW(__asan_stack_free_0) 165WRAP_V_WWW(__asan_stack_free_1) 166WRAP_V_WWW(__asan_stack_free_2) 167WRAP_V_WWW(__asan_stack_free_4) 168WRAP_V_WWW(__asan_stack_free_5) 169WRAP_V_WWW(__asan_stack_free_6) 170WRAP_V_WWW(__asan_stack_free_7) 171WRAP_V_WWW(__asan_stack_free_8) 172WRAP_V_WWW(__asan_stack_free_9) 173WRAP_V_WWW(__asan_stack_free_10) 174 175// TODO(timurrrr): Add more interface functions on the as-needed basis. 176 177// ----------------- Memory allocation functions --------------------- 178WRAP_V_W(free) 179WRAP_V_WW(_free_dbg) 180 181WRAP_W_W(malloc) 182WRAP_W_WWWW(_malloc_dbg) 183 184WRAP_W_WW(calloc) 185WRAP_W_WWWWW(_calloc_dbg) 186WRAP_W_WWW(_calloc_impl) 187 188WRAP_W_WW(realloc) 189WRAP_W_WWW(_realloc_dbg) 190WRAP_W_WWW(_recalloc) 191 192WRAP_W_W(_msize) 193 194// TODO(timurrrr): Do we need to add _Crt* stuff here? (see asan_malloc_win.cc). 195 196#endif // ASAN_DLL_THUNK 197