1 //===-- asan_malloc_win_thunk.cpp 2 //-----------------------------------------------===// 3 // 4 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 5 // See https://llvm.org/LICENSE.txt for license information. 6 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file is a part of AddressSanitizer, an address sanity checker. 11 // 12 // Windows-specific malloc interception. 13 // This is included statically for projects statically linking 14 // with the C Runtime (/MT, /MTd) in order to provide ASAN-aware 15 // versions of the C allocation functions. 16 //===----------------------------------------------------------------------===// 17 18 #ifdef SANITIZER_STATIC_RUNTIME_THUNK 19 # include "..\sanitizer_common\sanitizer_allocator_interface.h" 20 // #include "asan_win_thunk_common.h" 21 22 // Preserve stack traces with noinline. 23 # define STATIC_MALLOC_INTERFACE __declspec(noinline) 24 25 extern "C" { 26 __declspec(dllimport) size_t __cdecl __asan_msize(void *ptr); 27 __declspec(dllimport) void __cdecl __asan_free(void *const ptr); 28 __declspec(dllimport) void *__cdecl __asan_malloc(const size_t size); 29 __declspec(dllimport) void *__cdecl __asan_calloc(const size_t nmemb, 30 const size_t size); 31 __declspec(dllimport) void *__cdecl __asan_realloc(void *const ptr, 32 const size_t size); 33 __declspec(dllimport) void *__cdecl __asan_recalloc(void *const ptr, 34 const size_t nmemb, 35 const size_t size); 36 37 // Avoid tailcall optimization to preserve stack frames. 38 # pragma optimize("", off) 39 40 // _msize 41 STATIC_MALLOC_INTERFACE size_t _msize(void *ptr) { return __asan_msize(ptr); } 42 43 STATIC_MALLOC_INTERFACE size_t _msize_base(void *ptr) { 44 return __asan_msize(ptr); 45 } 46 47 STATIC_MALLOC_INTERFACE size_t _msize_dbg(void *ptr) { 48 return __asan_msize(ptr); 49 } 50 51 // free 52 STATIC_MALLOC_INTERFACE void free(void *const ptr) { return __asan_free(ptr); } 53 54 STATIC_MALLOC_INTERFACE void _free_base(void *const ptr) { 55 return __asan_free(ptr); 56 } 57 58 STATIC_MALLOC_INTERFACE void _free_dbg(void *const ptr) { 59 return __asan_free(ptr); 60 } 61 62 // malloc 63 STATIC_MALLOC_INTERFACE void *malloc(const size_t size) { 64 return __asan_malloc(size); 65 } 66 67 STATIC_MALLOC_INTERFACE void *_malloc_base(const size_t size) { 68 return __asan_malloc(size); 69 } 70 71 STATIC_MALLOC_INTERFACE void *_malloc_dbg(const size_t size) { 72 return __asan_malloc(size); 73 } 74 75 // calloc 76 STATIC_MALLOC_INTERFACE void *calloc(const size_t nmemb, const size_t size) { 77 return __asan_calloc(nmemb, size); 78 } 79 80 STATIC_MALLOC_INTERFACE void *_calloc_base(const size_t nmemb, 81 const size_t size) { 82 return __asan_calloc(nmemb, size); 83 } 84 85 STATIC_MALLOC_INTERFACE void *_calloc_impl(const size_t nmemb, 86 const size_t size, 87 int *const errno_tmp) { 88 // Provided by legacy msvcrt. 89 (void)errno_tmp; 90 91 return __asan_calloc(nmemb, size); 92 } 93 94 STATIC_MALLOC_INTERFACE void *_calloc_dbg(const size_t nmemb, const size_t size, 95 int, const char *, int) { 96 return __asan_calloc(nmemb, size); 97 } 98 99 // realloc 100 STATIC_MALLOC_INTERFACE void *realloc(void *const ptr, const size_t size) { 101 return __asan_realloc(ptr, size); 102 } 103 104 STATIC_MALLOC_INTERFACE void *_realloc_base(void *const ptr, 105 const size_t size) { 106 return __asan_realloc(ptr, size); 107 } 108 109 STATIC_MALLOC_INTERFACE void *_realloc_dbg(void *const ptr, const size_t size, 110 int, const char *, int) { 111 return __asan_realloc(ptr, size); 112 } 113 114 // recalloc 115 STATIC_MALLOC_INTERFACE void *_recalloc(void *const ptr, const size_t nmemb, 116 const size_t size) { 117 return __asan_recalloc(ptr, nmemb, size); 118 } 119 120 STATIC_MALLOC_INTERFACE void *_recalloc_base(void *const ptr, 121 const size_t nmemb, 122 const size_t size) { 123 return __asan_recalloc(ptr, nmemb, size); 124 } 125 126 STATIC_MALLOC_INTERFACE void *_recalloc_dbg(void *const ptr, const size_t nmemb, 127 const size_t size, int, 128 const char *, int) { 129 return __asan_recalloc(ptr, nmemb, size); 130 } 131 132 // expand 133 STATIC_MALLOC_INTERFACE void *_expand(void *, size_t) { 134 // _expand is used in realloc-like functions to resize the buffer if possible. 135 // We don't want memory to stand still while resizing buffers, so return 0. 136 return nullptr; 137 } 138 139 STATIC_MALLOC_INTERFACE void *_expand_dbg(void *, size_t, int, const char *, 140 int) { 141 return nullptr; 142 } 143 144 // We need to provide symbols for all the debug CRT functions if we decide to 145 // provide any. Most of these functions make no sense under ASan and so we 146 // make them no-ops. 147 long _CrtSetBreakAlloc(long const) { return ~0; } 148 149 void _CrtSetDbgBlockType(void *const, int const) { return; } 150 151 typedef int(__cdecl *CRT_ALLOC_HOOK)(int, void *, size_t, int, long, 152 const unsigned char *, int); 153 154 CRT_ALLOC_HOOK _CrtGetAllocHook() { return nullptr; } 155 156 CRT_ALLOC_HOOK _CrtSetAllocHook(CRT_ALLOC_HOOK const hook) { return hook; } 157 158 int _CrtCheckMemory() { return 1; } 159 160 int _CrtSetDbgFlag(int const new_bits) { return new_bits; } 161 162 typedef void (*CrtDoForAllClientObjectsCallback)(void *, void *); 163 164 void _CrtDoForAllClientObjects(CrtDoForAllClientObjectsCallback const, 165 void *const) { 166 return; 167 } 168 169 int _CrtIsValidPointer(void const *const p, unsigned int const, int const) { 170 return p != nullptr; 171 } 172 173 int _CrtIsValidHeapPointer(void const *const block) { 174 if (!block) { 175 return 0; 176 } 177 178 return __sanitizer_get_ownership(block); 179 } 180 181 int _CrtIsMemoryBlock(void const *const, unsigned const, long *const, 182 char **const, int *const) { 183 return 0; 184 } 185 186 int _CrtReportBlockType(void const *const) { return -1; } 187 188 typedef void(__cdecl *CRT_DUMP_CLIENT)(void *, size_t); 189 190 CRT_DUMP_CLIENT _CrtGetDumpClient() { return nullptr; } 191 192 CRT_DUMP_CLIENT _CrtSetDumpClient(CRT_DUMP_CLIENT new_client) { 193 return new_client; 194 } 195 196 void _CrtMemCheckpoint(void *const) { return; } 197 198 int _CrtMemDifference(void *const, void const *const, void const *const) { 199 return 0; 200 } 201 202 void _CrtMemDumpAllObjectsSince(void const *const) { return; } 203 204 int _CrtDumpMemoryLeaks() { return 0; } 205 206 void _CrtMemDumpStatistics(void const *const) { return; } 207 208 int _crtDbgFlag{0}; 209 long _crtBreakAlloc{-1}; 210 CRT_DUMP_CLIENT _pfnDumpClient{nullptr}; 211 212 int *__p__crtDbgFlag() { return &_crtDbgFlag; } 213 214 long *__p__crtBreakAlloc() { return &_crtBreakAlloc; } 215 216 // TODO: These were added upstream but conflict with definitions in ucrtbased. 217 // int _CrtDbgReport(int, const char *, int, const char *, const char *, ...) { 218 // ShowStatsAndAbort(); 219 // } 220 // 221 // int _CrtDbgReportW(int reportType, const wchar_t *, int, const wchar_t *, 222 // const wchar_t *, ...) { 223 // ShowStatsAndAbort(); 224 // } 225 // 226 // int _CrtSetReportMode(int, int) { return 0; } 227 228 } // extern "C" 229 #endif // SANITIZER_STATIC_RUNTIME_THUNK 230