blob: cedd60d342f6c3add2e3ec2a8b04b12e7b30b79d [file] [log] [blame]
Timur Iskhodzhanov68cd60c2013-08-13 13:47:03 +00001//===-- 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 Iskhodzhanov68cd60c2013-08-13 13:47:03 +000023
Timur Iskhodzhanov43e62df2013-08-13 15:29:42 +000024// ----------------- 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}
Timur Iskhodzhanov68cd60c2013-08-13 13:47:03 +000030
Timur Iskhodzhanov43e62df2013-08-13 15:29:42 +000031static void *getRealProcAddressOrDie(const char *name) {
32 void *ret = GetProcAddress(GetModuleHandleA(0), name);
Timur Iskhodzhanov68cd60c2013-08-13 13:47:03 +000033 if (!ret)
34 abort();
35 return ret;
36}
37
Timur Iskhodzhanov43e62df2013-08-13 15:29:42 +000038#define WRAP_V_V(name) \
Timur Iskhodzhanov68cd60c2013-08-13 13:47:03 +000039 extern "C" void name() { \
40 typedef void (*fntype)(); \
Timur Iskhodzhanova8b8e962013-09-23 11:40:58 +000041 static fntype fn = (fntype)getRealProcAddressOrDie(#name); \
Timur Iskhodzhanov68cd60c2013-08-13 13:47:03 +000042 fn(); \
43 }
44
Timur Iskhodzhanov43e62df2013-08-13 15:29:42 +000045#define WRAP_V_W(name) \
Timur Iskhodzhanov68cd60c2013-08-13 13:47:03 +000046 extern "C" void name(void *arg) { \
47 typedef void (*fntype)(void *arg); \
Timur Iskhodzhanova8b8e962013-09-23 11:40:58 +000048 static fntype fn = (fntype)getRealProcAddressOrDie(#name); \
Timur Iskhodzhanov68cd60c2013-08-13 13:47:03 +000049 fn(arg); \
50 }
51
Timur Iskhodzhanov43e62df2013-08-13 15:29:42 +000052#define WRAP_V_WW(name) \
Timur Iskhodzhanov68cd60c2013-08-13 13:47:03 +000053 extern "C" void name(void *arg1, void *arg2) { \
54 typedef void (*fntype)(void *, void *); \
Timur Iskhodzhanova8b8e962013-09-23 11:40:58 +000055 static fntype fn = (fntype)getRealProcAddressOrDie(#name); \
Timur Iskhodzhanov68cd60c2013-08-13 13:47:03 +000056 fn(arg1, arg2); \
57 }
Timur Iskhodzhanov43e62df2013-08-13 15:29:42 +000058
Timur Iskhodzhanovc11fa092013-09-23 11:05:41 +000059#define WRAP_V_WWW(name) \
60 extern "C" void name(void *arg1, void *arg2, void *arg3) { \
61 typedef void *(*fntype)(void *, void *, void *); \
Timur Iskhodzhanova8b8e962013-09-23 11:40:58 +000062 static fntype fn = (fntype)getRealProcAddressOrDie(#name); \
Timur Iskhodzhanovc11fa092013-09-23 11:05:41 +000063 fn(arg1, arg2, arg3); \
64 }
65
66#define WRAP_W_V(name) \
67 extern "C" void *name() { \
68 typedef void *(*fntype)(); \
Timur Iskhodzhanova8b8e962013-09-23 11:40:58 +000069 static fntype fn = (fntype)getRealProcAddressOrDie(#name); \
Timur Iskhodzhanovc11fa092013-09-23 11:05:41 +000070 return fn(); \
71 }
72
Timur Iskhodzhanov43e62df2013-08-13 15:29:42 +000073#define WRAP_W_W(name) \
74 extern "C" void *name(void *arg) { \
75 typedef void *(*fntype)(void *arg); \
Timur Iskhodzhanova8b8e962013-09-23 11:40:58 +000076 static fntype fn = (fntype)getRealProcAddressOrDie(#name); \
Timur Iskhodzhanov43e62df2013-08-13 15:29:42 +000077 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 Iskhodzhanova8b8e962013-09-23 11:40:58 +000083 static fntype fn = (fntype)getRealProcAddressOrDie(#name); \
Timur Iskhodzhanov43e62df2013-08-13 15:29:42 +000084 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 Iskhodzhanova8b8e962013-09-23 11:40:58 +000090 static fntype fn = (fntype)getRealProcAddressOrDie(#name); \
Timur Iskhodzhanov43e62df2013-08-13 15:29:42 +000091 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 Iskhodzhanova8b8e962013-09-23 11:40:58 +000097 static fntype fn = (fntype)getRealProcAddressOrDie(#name); \
Timur Iskhodzhanov43e62df2013-08-13 15:29:42 +000098 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 Iskhodzhanova8b8e962013-09-23 11:40:58 +0000105 static fntype fn = (fntype)getRealProcAddressOrDie(#name); \
Timur Iskhodzhanov43e62df2013-08-13 15:29:42 +0000106 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 Iskhodzhanova8b8e962013-09-23 11:40:58 +0000113 static fntype fn = (fntype)getRealProcAddressOrDie(#name); \
Timur Iskhodzhanov43e62df2013-08-13 15:29:42 +0000114 return fn(arg1, arg2, arg3, arg4, arg5, arg6); \
115 }
Timur Iskhodzhanov68cd60c2013-08-13 13:47:03 +0000116// }}}
117
Timur Iskhodzhanov43e62df2013-08-13 15:29:42 +0000118// ----------------- ASan own interface functions --------------------
Timur Iskhodzhanovc11fa092013-09-23 11:05:41 +0000119WRAP_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 =
Timur Iskhodzhanovdef895b2013-09-23 11:19:43 +0000131 (__asan_should_detect_stack_use_after_return() != 0);
Timur Iskhodzhanovc11fa092013-09-23 11:05:41 +0000132 }
133}
Timur Iskhodzhanov68cd60c2013-08-13 13:47:03 +0000134
Timur Iskhodzhanov43e62df2013-08-13 15:29:42 +0000135WRAP_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)
Timur Iskhodzhanov68cd60c2013-08-13 13:47:03 +0000141
Timur Iskhodzhanov43e62df2013-08-13 15:29:42 +0000142WRAP_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)
Timur Iskhodzhanov68cd60c2013-08-13 13:47:03 +0000148
Timur Iskhodzhanov43e62df2013-08-13 15:29:42 +0000149WRAP_V_WW(__asan_register_globals)
150WRAP_V_WW(__asan_unregister_globals)
Timur Iskhodzhanov68cd60c2013-08-13 13:47:03 +0000151
Timur Iskhodzhanovc11fa092013-09-23 11:05:41 +0000152WRAP_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
Timur Iskhodzhanov68cd60c2013-08-13 13:47:03 +0000175// TODO(timurrrr): Add more interface functions on the as-needed basis.
176
Timur Iskhodzhanov43e62df2013-08-13 15:29:42 +0000177// ----------------- 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).
Timur Iskhodzhanov68cd60c2013-08-13 13:47:03 +0000195
196#endif // ASAN_DLL_THUNK