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
25extern "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
41STATIC_MALLOC_INTERFACE size_t _msize(void *ptr) { return __asan_msize(ptr); }
42
43STATIC_MALLOC_INTERFACE size_t _msize_base(void *ptr) {
44 return __asan_msize(ptr);
45}
46
47STATIC_MALLOC_INTERFACE size_t _msize_dbg(void *ptr) {
48 return __asan_msize(ptr);
49}
50
51// free
52STATIC_MALLOC_INTERFACE void free(void *const ptr) { return __asan_free(ptr); }
53
54STATIC_MALLOC_INTERFACE void _free_base(void *const ptr) {
55 return __asan_free(ptr);
56}
57
58STATIC_MALLOC_INTERFACE void _free_dbg(void *const ptr) {
59 return __asan_free(ptr);
60}
61
62// malloc
63STATIC_MALLOC_INTERFACE void *malloc(const size_t size) {
64 return __asan_malloc(size);
65}
66
67STATIC_MALLOC_INTERFACE void *_malloc_base(const size_t size) {
68 return __asan_malloc(size);
69}
70
71STATIC_MALLOC_INTERFACE void *_malloc_dbg(const size_t size) {
72 return __asan_malloc(size);
73}
74
75// calloc
76STATIC_MALLOC_INTERFACE void *calloc(const size_t nmemb, const size_t size) {
77 return __asan_calloc(nmemb, size);
78}
79
80STATIC_MALLOC_INTERFACE void *_calloc_base(const size_t nmemb,
81 const size_t size) {
82 return __asan_calloc(nmemb, size);
83}
84
85STATIC_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
94STATIC_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
100STATIC_MALLOC_INTERFACE void *realloc(void *const ptr, const size_t size) {
101 return __asan_realloc(ptr, size);
102}
103
104STATIC_MALLOC_INTERFACE void *_realloc_base(void *const ptr,
105 const size_t size) {
106 return __asan_realloc(ptr, size);
107}
108
109STATIC_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
115STATIC_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
120STATIC_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
126STATIC_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
133STATIC_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
139STATIC_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.
147long _CrtSetBreakAlloc(long const) { return ~0; }
148
149void _CrtSetDbgBlockType(void *const, int const) { return; }
150
151typedef int(__cdecl *CRT_ALLOC_HOOK)(int, void *, size_t, int, long,
152 const unsigned char *, int);
153
154CRT_ALLOC_HOOK _CrtGetAllocHook() { return nullptr; }
155
156CRT_ALLOC_HOOK _CrtSetAllocHook(CRT_ALLOC_HOOK const hook) { return hook; }
157
158int _CrtCheckMemory() { return 1; }
159
160int _CrtSetDbgFlag(int const new_bits) { return new_bits; }
161
162typedef void (*CrtDoForAllClientObjectsCallback)(void *, void *);
163
164void _CrtDoForAllClientObjects(CrtDoForAllClientObjectsCallback const,
165 void *const) {
166 return;
167}
168
169int _CrtIsValidPointer(void const *const p, unsigned int const, int const) {
170 return p != nullptr;
171}
172
173int _CrtIsValidHeapPointer(void const *const block) {
174 if (!block) {
175 return 0;
176 }
177
178 return __sanitizer_get_ownership(block);
179}
180
181int _CrtIsMemoryBlock(void const *const, unsigned const, long *const,
182 char **const, int *const) {
183 return 0;
184}
185
186int _CrtReportBlockType(void const *const) { return -1; }
187
188typedef void(__cdecl *CRT_DUMP_CLIENT)(void *, size_t);
189
190CRT_DUMP_CLIENT _CrtGetDumpClient() { return nullptr; }
191
192CRT_DUMP_CLIENT _CrtSetDumpClient(CRT_DUMP_CLIENT new_client) {
193 return new_client;
194}
195
196void _CrtMemCheckpoint(void *const) { return; }
197
198int _CrtMemDifference(void *const, void const *const, void const *const) {
199 return 0;
200}
201
202void _CrtMemDumpAllObjectsSince(void const *const) { return; }
203
204int _CrtDumpMemoryLeaks() { return 0; }
205
206void _CrtMemDumpStatistics(void const *const) { return; }
207
208int _crtDbgFlag{0};
209long _crtBreakAlloc{-1};
210CRT_DUMP_CLIENT _pfnDumpClient{nullptr};
211
212int *__p__crtDbgFlag() { return &_crtDbgFlag; }
213
214long *__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

source code of compiler-rt/lib/asan/asan_malloc_win_thunk.cpp