230 lines · cpp
1//===-- asan_malloc_win_thunk.cpp2//-----------------------------------------------===//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-exception7//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 linking14// with the C Runtime (/MT, /MTd) in order to provide ASAN-aware15// versions of the C allocation functions.16//===----------------------------------------------------------------------===//17 18#ifdef SANITIZER_STATIC_RUNTIME_THUNK19# 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// _msize41STATIC_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// free52STATIC_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// malloc63STATIC_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// calloc76STATIC_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// realloc100STATIC_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// recalloc115STATIC_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// expand133STATIC_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 to145// provide any. Most of these functions make no sense under ASan and so we146// 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_THUNK230