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