Timur Iskhodzhanov | 68cd60c | 2013-08-13 13:47:03 +0000 | [diff] [blame] | 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 |
Timur Iskhodzhanov | 68cd60c | 2013-08-13 13:47:03 +0000 | [diff] [blame] | 23 | |
Timur Iskhodzhanov | 43e62df | 2013-08-13 15:29:42 +0000 | [diff] [blame] | 24 | // ----------------- Helper functions and macros --------------------- {{{1 |
| 25 | extern "C" { |
| 26 | void *__stdcall GetModuleHandleA(const char *module_name); |
| 27 | void *__stdcall GetProcAddress(void *module, const char *proc_name); |
| 28 | void abort(); |
| 29 | } |
Timur Iskhodzhanov | 68cd60c | 2013-08-13 13:47:03 +0000 | [diff] [blame] | 30 | |
Timur Iskhodzhanov | 43e62df | 2013-08-13 15:29:42 +0000 | [diff] [blame] | 31 | static void *getRealProcAddressOrDie(const char *name) { |
| 32 | void *ret = GetProcAddress(GetModuleHandleA(0), name); |
Timur Iskhodzhanov | 68cd60c | 2013-08-13 13:47:03 +0000 | [diff] [blame] | 33 | if (!ret) |
| 34 | abort(); |
| 35 | return ret; |
| 36 | } |
| 37 | |
Timur Iskhodzhanov | 43e62df | 2013-08-13 15:29:42 +0000 | [diff] [blame] | 38 | #define WRAP_V_V(name) \ |
Timur Iskhodzhanov | 68cd60c | 2013-08-13 13:47:03 +0000 | [diff] [blame] | 39 | extern "C" void name() { \ |
| 40 | typedef void (*fntype)(); \ |
Timur Iskhodzhanov | a8b8e96 | 2013-09-23 11:40:58 +0000 | [diff] [blame] | 41 | static fntype fn = (fntype)getRealProcAddressOrDie(#name); \ |
Timur Iskhodzhanov | 68cd60c | 2013-08-13 13:47:03 +0000 | [diff] [blame] | 42 | fn(); \ |
| 43 | } |
| 44 | |
Timur Iskhodzhanov | 43e62df | 2013-08-13 15:29:42 +0000 | [diff] [blame] | 45 | #define WRAP_V_W(name) \ |
Timur Iskhodzhanov | 68cd60c | 2013-08-13 13:47:03 +0000 | [diff] [blame] | 46 | extern "C" void name(void *arg) { \ |
| 47 | typedef void (*fntype)(void *arg); \ |
Timur Iskhodzhanov | a8b8e96 | 2013-09-23 11:40:58 +0000 | [diff] [blame] | 48 | static fntype fn = (fntype)getRealProcAddressOrDie(#name); \ |
Timur Iskhodzhanov | 68cd60c | 2013-08-13 13:47:03 +0000 | [diff] [blame] | 49 | fn(arg); \ |
| 50 | } |
| 51 | |
Timur Iskhodzhanov | 43e62df | 2013-08-13 15:29:42 +0000 | [diff] [blame] | 52 | #define WRAP_V_WW(name) \ |
Timur Iskhodzhanov | 68cd60c | 2013-08-13 13:47:03 +0000 | [diff] [blame] | 53 | extern "C" void name(void *arg1, void *arg2) { \ |
| 54 | typedef void (*fntype)(void *, void *); \ |
Timur Iskhodzhanov | a8b8e96 | 2013-09-23 11:40:58 +0000 | [diff] [blame] | 55 | static fntype fn = (fntype)getRealProcAddressOrDie(#name); \ |
Timur Iskhodzhanov | 68cd60c | 2013-08-13 13:47:03 +0000 | [diff] [blame] | 56 | fn(arg1, arg2); \ |
| 57 | } |
Timur Iskhodzhanov | 43e62df | 2013-08-13 15:29:42 +0000 | [diff] [blame] | 58 | |
Timur Iskhodzhanov | c11fa09 | 2013-09-23 11:05:41 +0000 | [diff] [blame] | 59 | #define WRAP_V_WWW(name) \ |
| 60 | extern "C" void name(void *arg1, void *arg2, void *arg3) { \ |
| 61 | typedef void *(*fntype)(void *, void *, void *); \ |
Timur Iskhodzhanov | a8b8e96 | 2013-09-23 11:40:58 +0000 | [diff] [blame] | 62 | static fntype fn = (fntype)getRealProcAddressOrDie(#name); \ |
Timur Iskhodzhanov | c11fa09 | 2013-09-23 11:05:41 +0000 | [diff] [blame] | 63 | fn(arg1, arg2, arg3); \ |
| 64 | } |
| 65 | |
| 66 | #define WRAP_W_V(name) \ |
| 67 | extern "C" void *name() { \ |
| 68 | typedef void *(*fntype)(); \ |
Timur Iskhodzhanov | a8b8e96 | 2013-09-23 11:40:58 +0000 | [diff] [blame] | 69 | static fntype fn = (fntype)getRealProcAddressOrDie(#name); \ |
Timur Iskhodzhanov | c11fa09 | 2013-09-23 11:05:41 +0000 | [diff] [blame] | 70 | return fn(); \ |
| 71 | } |
| 72 | |
Timur Iskhodzhanov | 43e62df | 2013-08-13 15:29:42 +0000 | [diff] [blame] | 73 | #define WRAP_W_W(name) \ |
| 74 | extern "C" void *name(void *arg) { \ |
| 75 | typedef void *(*fntype)(void *arg); \ |
Timur Iskhodzhanov | a8b8e96 | 2013-09-23 11:40:58 +0000 | [diff] [blame] | 76 | static fntype fn = (fntype)getRealProcAddressOrDie(#name); \ |
Timur Iskhodzhanov | 43e62df | 2013-08-13 15:29:42 +0000 | [diff] [blame] | 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 *); \ |
Timur Iskhodzhanov | a8b8e96 | 2013-09-23 11:40:58 +0000 | [diff] [blame] | 83 | static fntype fn = (fntype)getRealProcAddressOrDie(#name); \ |
Timur Iskhodzhanov | 43e62df | 2013-08-13 15:29:42 +0000 | [diff] [blame] | 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 *); \ |
Timur Iskhodzhanov | a8b8e96 | 2013-09-23 11:40:58 +0000 | [diff] [blame] | 90 | static fntype fn = (fntype)getRealProcAddressOrDie(#name); \ |
Timur Iskhodzhanov | 43e62df | 2013-08-13 15:29:42 +0000 | [diff] [blame] | 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 *); \ |
Timur Iskhodzhanov | a8b8e96 | 2013-09-23 11:40:58 +0000 | [diff] [blame] | 97 | static fntype fn = (fntype)getRealProcAddressOrDie(#name); \ |
Timur Iskhodzhanov | 43e62df | 2013-08-13 15:29:42 +0000 | [diff] [blame] | 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 *); \ |
Timur Iskhodzhanov | a8b8e96 | 2013-09-23 11:40:58 +0000 | [diff] [blame] | 105 | static fntype fn = (fntype)getRealProcAddressOrDie(#name); \ |
Timur Iskhodzhanov | 43e62df | 2013-08-13 15:29:42 +0000 | [diff] [blame] | 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 *); \ |
Timur Iskhodzhanov | a8b8e96 | 2013-09-23 11:40:58 +0000 | [diff] [blame] | 113 | static fntype fn = (fntype)getRealProcAddressOrDie(#name); \ |
Timur Iskhodzhanov | 43e62df | 2013-08-13 15:29:42 +0000 | [diff] [blame] | 114 | return fn(arg1, arg2, arg3, arg4, arg5, arg6); \ |
| 115 | } |
Timur Iskhodzhanov | 68cd60c | 2013-08-13 13:47:03 +0000 | [diff] [blame] | 116 | // }}} |
| 117 | |
Timur Iskhodzhanov | 43e62df | 2013-08-13 15:29:42 +0000 | [diff] [blame] | 118 | // ----------------- ASan own interface functions -------------------- |
Timur Iskhodzhanov | c11fa09 | 2013-09-23 11:05:41 +0000 | [diff] [blame] | 119 | WRAP_W_V(__asan_should_detect_stack_use_after_return) |
| 120 | |
| 121 | extern "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 = |
Timur Iskhodzhanov | def895b | 2013-09-23 11:19:43 +0000 | [diff] [blame] | 131 | (__asan_should_detect_stack_use_after_return() != 0); |
Timur Iskhodzhanov | c11fa09 | 2013-09-23 11:05:41 +0000 | [diff] [blame] | 132 | } |
| 133 | } |
Timur Iskhodzhanov | 68cd60c | 2013-08-13 13:47:03 +0000 | [diff] [blame] | 134 | |
Timur Iskhodzhanov | 43e62df | 2013-08-13 15:29:42 +0000 | [diff] [blame] | 135 | WRAP_V_W(__asan_report_store1) |
| 136 | WRAP_V_W(__asan_report_store2) |
| 137 | WRAP_V_W(__asan_report_store4) |
| 138 | WRAP_V_W(__asan_report_store8) |
| 139 | WRAP_V_W(__asan_report_store16) |
| 140 | WRAP_V_WW(__asan_report_store_n) |
Timur Iskhodzhanov | 68cd60c | 2013-08-13 13:47:03 +0000 | [diff] [blame] | 141 | |
Timur Iskhodzhanov | 43e62df | 2013-08-13 15:29:42 +0000 | [diff] [blame] | 142 | WRAP_V_W(__asan_report_load1) |
| 143 | WRAP_V_W(__asan_report_load2) |
| 144 | WRAP_V_W(__asan_report_load4) |
| 145 | WRAP_V_W(__asan_report_load8) |
| 146 | WRAP_V_W(__asan_report_load16) |
| 147 | WRAP_V_WW(__asan_report_load_n) |
Timur Iskhodzhanov | 68cd60c | 2013-08-13 13:47:03 +0000 | [diff] [blame] | 148 | |
Timur Iskhodzhanov | 43e62df | 2013-08-13 15:29:42 +0000 | [diff] [blame] | 149 | WRAP_V_WW(__asan_register_globals) |
| 150 | WRAP_V_WW(__asan_unregister_globals) |
Timur Iskhodzhanov | 68cd60c | 2013-08-13 13:47:03 +0000 | [diff] [blame] | 151 | |
Timur Iskhodzhanov | c11fa09 | 2013-09-23 11:05:41 +0000 | [diff] [blame] | 152 | WRAP_W_WW(__asan_stack_malloc_0) |
| 153 | WRAP_W_WW(__asan_stack_malloc_1) |
| 154 | WRAP_W_WW(__asan_stack_malloc_2) |
| 155 | WRAP_W_WW(__asan_stack_malloc_3) |
| 156 | WRAP_W_WW(__asan_stack_malloc_4) |
| 157 | WRAP_W_WW(__asan_stack_malloc_5) |
| 158 | WRAP_W_WW(__asan_stack_malloc_6) |
| 159 | WRAP_W_WW(__asan_stack_malloc_7) |
| 160 | WRAP_W_WW(__asan_stack_malloc_8) |
| 161 | WRAP_W_WW(__asan_stack_malloc_9) |
| 162 | WRAP_W_WW(__asan_stack_malloc_10) |
| 163 | |
| 164 | WRAP_V_WWW(__asan_stack_free_0) |
| 165 | WRAP_V_WWW(__asan_stack_free_1) |
| 166 | WRAP_V_WWW(__asan_stack_free_2) |
| 167 | WRAP_V_WWW(__asan_stack_free_4) |
| 168 | WRAP_V_WWW(__asan_stack_free_5) |
| 169 | WRAP_V_WWW(__asan_stack_free_6) |
| 170 | WRAP_V_WWW(__asan_stack_free_7) |
| 171 | WRAP_V_WWW(__asan_stack_free_8) |
| 172 | WRAP_V_WWW(__asan_stack_free_9) |
| 173 | WRAP_V_WWW(__asan_stack_free_10) |
| 174 | |
Timur Iskhodzhanov | 68cd60c | 2013-08-13 13:47:03 +0000 | [diff] [blame] | 175 | // TODO(timurrrr): Add more interface functions on the as-needed basis. |
| 176 | |
Timur Iskhodzhanov | 43e62df | 2013-08-13 15:29:42 +0000 | [diff] [blame] | 177 | // ----------------- Memory allocation functions --------------------- |
| 178 | WRAP_V_W(free) |
| 179 | WRAP_V_WW(_free_dbg) |
| 180 | |
| 181 | WRAP_W_W(malloc) |
| 182 | WRAP_W_WWWW(_malloc_dbg) |
| 183 | |
| 184 | WRAP_W_WW(calloc) |
| 185 | WRAP_W_WWWWW(_calloc_dbg) |
| 186 | WRAP_W_WWW(_calloc_impl) |
| 187 | |
| 188 | WRAP_W_WW(realloc) |
| 189 | WRAP_W_WWW(_realloc_dbg) |
| 190 | WRAP_W_WWW(_recalloc) |
| 191 | |
| 192 | WRAP_W_W(_msize) |
| 193 | |
| 194 | // TODO(timurrrr): Do we need to add _Crt* stuff here? (see asan_malloc_win.cc). |
Timur Iskhodzhanov | 68cd60c | 2013-08-13 13:47:03 +0000 | [diff] [blame] | 195 | |
| 196 | #endif // ASAN_DLL_THUNK |