]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/compiler-rt/lib/asan/asan_win_dll_thunk.cc
Merge clang 7.0.1 and several follow-up changes
[FreeBSD/FreeBSD.git] / contrib / compiler-rt / lib / asan / asan_win_dll_thunk.cc
1 //===-- asan_win_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://github.com/google/sanitizers/issues/209 for the details.
16 //===----------------------------------------------------------------------===//
17
18 #ifdef SANITIZER_DLL_THUNK
19 #include "asan_init_version.h"
20 #include "interception/interception.h"
21 #include "sanitizer_common/sanitizer_win_defs.h"
22 #include "sanitizer_common/sanitizer_win_dll_thunk.h"
23 #include "sanitizer_common/sanitizer_platform_interceptors.h"
24
25 // ASan own interface functions.
26 #define INTERFACE_FUNCTION(Name) INTERCEPT_SANITIZER_FUNCTION(Name)
27 #define INTERFACE_WEAK_FUNCTION(Name) INTERCEPT_SANITIZER_WEAK_FUNCTION(Name)
28 #include "asan_interface.inc"
29
30 // Memory allocation functions.
31 INTERCEPT_WRAP_V_W(free)
32 INTERCEPT_WRAP_V_W(_free_base)
33 INTERCEPT_WRAP_V_WW(_free_dbg)
34
35 INTERCEPT_WRAP_W_W(malloc)
36 INTERCEPT_WRAP_W_W(_malloc_base)
37 INTERCEPT_WRAP_W_WWWW(_malloc_dbg)
38
39 INTERCEPT_WRAP_W_WW(calloc)
40 INTERCEPT_WRAP_W_WW(_calloc_base)
41 INTERCEPT_WRAP_W_WWWWW(_calloc_dbg)
42 INTERCEPT_WRAP_W_WWW(_calloc_impl)
43
44 INTERCEPT_WRAP_W_WW(realloc)
45 INTERCEPT_WRAP_W_WW(_realloc_base)
46 INTERCEPT_WRAP_W_WWW(_realloc_dbg)
47 INTERCEPT_WRAP_W_WWW(_recalloc)
48 INTERCEPT_WRAP_W_WWW(_recalloc_base)
49
50 INTERCEPT_WRAP_W_W(_msize)
51 INTERCEPT_WRAP_W_W(_expand)
52 INTERCEPT_WRAP_W_W(_expand_dbg)
53
54 // TODO(timurrrr): Might want to add support for _aligned_* allocation
55 // functions to detect a bit more bugs.  Those functions seem to wrap malloc().
56
57 // TODO(timurrrr): Do we need to add _Crt* stuff here? (see asan_malloc_win.cc).
58
59 INTERCEPT_LIBRARY_FUNCTION(atoi);
60 INTERCEPT_LIBRARY_FUNCTION(atol);
61 INTERCEPT_LIBRARY_FUNCTION(frexp);
62 INTERCEPT_LIBRARY_FUNCTION(longjmp);
63 #if SANITIZER_INTERCEPT_MEMCHR
64 INTERCEPT_LIBRARY_FUNCTION(memchr);
65 #endif
66 INTERCEPT_LIBRARY_FUNCTION(memcmp);
67 INTERCEPT_LIBRARY_FUNCTION(memcpy);
68 INTERCEPT_LIBRARY_FUNCTION(memmove);
69 INTERCEPT_LIBRARY_FUNCTION(memset);
70 INTERCEPT_LIBRARY_FUNCTION(strcat);  // NOLINT
71 INTERCEPT_LIBRARY_FUNCTION(strchr);
72 INTERCEPT_LIBRARY_FUNCTION(strcmp);
73 INTERCEPT_LIBRARY_FUNCTION(strcpy);  // NOLINT
74 INTERCEPT_LIBRARY_FUNCTION(strcspn);
75 INTERCEPT_LIBRARY_FUNCTION(strdup);
76 INTERCEPT_LIBRARY_FUNCTION(strlen);
77 INTERCEPT_LIBRARY_FUNCTION(strncat);
78 INTERCEPT_LIBRARY_FUNCTION(strncmp);
79 INTERCEPT_LIBRARY_FUNCTION(strncpy);
80 INTERCEPT_LIBRARY_FUNCTION(strnlen);
81 INTERCEPT_LIBRARY_FUNCTION(strpbrk);
82 INTERCEPT_LIBRARY_FUNCTION(strrchr);
83 INTERCEPT_LIBRARY_FUNCTION(strspn);
84 INTERCEPT_LIBRARY_FUNCTION(strstr);
85 INTERCEPT_LIBRARY_FUNCTION(strtok);
86 INTERCEPT_LIBRARY_FUNCTION(strtol);
87 INTERCEPT_LIBRARY_FUNCTION(wcslen);
88 INTERCEPT_LIBRARY_FUNCTION(wcsnlen);
89
90 #ifdef _WIN64
91 INTERCEPT_LIBRARY_FUNCTION(__C_specific_handler);
92 #else
93 INTERCEPT_LIBRARY_FUNCTION(_except_handler3);
94 // _except_handler4 checks -GS cookie which is different for each module, so we
95 // can't use INTERCEPT_LIBRARY_FUNCTION(_except_handler4).
96 INTERCEPTOR(int, _except_handler4, void *a, void *b, void *c, void *d) {
97   __asan_handle_no_return();
98   return REAL(_except_handler4)(a, b, c, d);
99 }
100 #endif
101
102 // Windows specific functions not included in asan_interface.inc.
103 INTERCEPT_WRAP_W_V(__asan_should_detect_stack_use_after_return)
104 INTERCEPT_WRAP_W_V(__asan_get_shadow_memory_dynamic_address)
105 INTERCEPT_WRAP_W_W(__asan_unhandled_exception_filter)
106
107 using namespace __sanitizer;
108
109 extern "C" {
110 int __asan_option_detect_stack_use_after_return;
111 uptr __asan_shadow_memory_dynamic_address;
112 } // extern "C"
113
114 static int asan_dll_thunk_init() {
115   typedef void (*fntype)();
116   static fntype fn = 0;
117   // asan_dll_thunk_init is expected to be called by only one thread.
118   if (fn) return 0;
119
120   // Ensure all interception was executed.
121   __dll_thunk_init();
122
123   fn = (fntype) dllThunkGetRealAddrOrDie("__asan_init");
124   fn();
125   __asan_option_detect_stack_use_after_return =
126       (__asan_should_detect_stack_use_after_return() != 0);
127   __asan_shadow_memory_dynamic_address =
128       (uptr)__asan_get_shadow_memory_dynamic_address();
129
130 #ifndef _WIN64
131   INTERCEPT_FUNCTION(_except_handler4);
132 #endif
133   // In DLLs, the callbacks are expected to return 0,
134   // otherwise CRT initialization fails.
135   return 0;
136 }
137
138 #pragma section(".CRT$XIB", long, read)  // NOLINT
139 __declspec(allocate(".CRT$XIB")) int (*__asan_preinit)() = asan_dll_thunk_init;
140
141 static void WINAPI asan_thread_init(void *mod, unsigned long reason,
142                                     void *reserved) {
143   if (reason == /*DLL_PROCESS_ATTACH=*/1) asan_dll_thunk_init();
144 }
145
146 #pragma section(".CRT$XLAB", long, read)  // NOLINT
147 __declspec(allocate(".CRT$XLAB")) void (WINAPI *__asan_tls_init)(void *,
148     unsigned long, void *) = asan_thread_init;
149
150 WIN_FORCE_LINK(__asan_dso_reg_hook)
151
152 #endif // SANITIZER_DLL_THUNK