diff options
author | wmi <wmi@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-10-30 06:45:44 +0000 |
---|---|---|
committer | wmi <wmi@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-10-30 06:45:44 +0000 |
commit | 362cbc2d5f18c9f00dc3b945fb01c43bb0d36aae (patch) | |
tree | 589f7a9c3f1e4f86404119e62b9aa4ab35641d4c /libasan/asan_malloc_win.cc | |
parent | d10645e53e4367f33c05406abb17357bbc339844 (diff) | |
download | gcc-362cbc2d5f18c9f00dc3b945fb01c43bb0d36aae.tar.gz |
2012-10-29 Wei Mi <wmi@google.com>
* configure.ac: Add libasan to target_libraries
* Makefile.def: Ditto
* configure: Regenerate
* Makefile.in: Regenerate
* libasan: New directory for asan runtime
gcc:
2012-10-29 Wei Mi <wmi@google.com>
* gcc.c (LINK_COMMAND_SPEC): Add -lasan to link command
if -fasan is on.
libasan:
2012-10-29 Wei Mi <wmi@google.com>
Initial checkin: migrate asan runtime from llvm.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/asan@192977 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libasan/asan_malloc_win.cc')
-rw-r--r-- | libasan/asan_malloc_win.cc | 140 |
1 files changed, 140 insertions, 0 deletions
diff --git a/libasan/asan_malloc_win.cc b/libasan/asan_malloc_win.cc new file mode 100644 index 00000000000..7389a257248 --- /dev/null +++ b/libasan/asan_malloc_win.cc @@ -0,0 +1,140 @@ +//===-- asan_malloc_win.cc ------------------------------------------------===// +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file is a part of AddressSanitizer, an address sanity checker. +// +// Windows-specific malloc interception. +//===----------------------------------------------------------------------===// +#ifdef _WIN32 + +#include "asan_allocator.h" +#include "asan_interceptors.h" +#include "asan_internal.h" +#include "asan_stack.h" +#include "interception/interception.h" + +#include <stddef.h> + +// ---------------------- Replacement functions ---------------- {{{1 +using namespace __asan; // NOLINT + +// FIXME: Simply defining functions with the same signature in *.obj +// files overrides the standard functions in *.lib +// This works well for simple helloworld-like tests but might need to be +// revisited in the future. + +extern "C" { +void free(void *ptr) { + GET_STACK_TRACE_HERE_FOR_FREE(ptr); + return asan_free(ptr, &stack); +} + +void _free_dbg(void* ptr, int) { + free(ptr); +} + +void cfree(void *ptr) { + CHECK(!"cfree() should not be used on Windows?"); +} + +void *malloc(size_t size) { + GET_STACK_TRACE_HERE_FOR_MALLOC; + return asan_malloc(size, &stack); +} + +void* _malloc_dbg(size_t size, int , const char*, int) { + return malloc(size); +} + +void *calloc(size_t nmemb, size_t size) { + GET_STACK_TRACE_HERE_FOR_MALLOC; + return asan_calloc(nmemb, size, &stack); +} + +void* _calloc_dbg(size_t n, size_t size, int, const char*, int) { + return calloc(n, size); +} + +void *_calloc_impl(size_t nmemb, size_t size, int *errno_tmp) { + return calloc(nmemb, size); +} + +void *realloc(void *ptr, size_t size) { + GET_STACK_TRACE_HERE_FOR_MALLOC; + return asan_realloc(ptr, size, &stack); +} + +void *_realloc_dbg(void *ptr, size_t size, int) { + CHECK(!"_realloc_dbg should not exist!"); + return 0; +} + +void* _recalloc(void* p, size_t n, size_t elem_size) { + if (!p) + return calloc(n, elem_size); + const size_t size = n * elem_size; + if (elem_size != 0 && size / elem_size != n) + return 0; + return realloc(p, size); +} + +size_t _msize(void *ptr) { + GET_STACK_TRACE_HERE_FOR_MALLOC; + return asan_malloc_usable_size(ptr, &stack); +} + +int _CrtDbgReport(int, const char*, int, + const char*, const char*, ...) { + ShowStatsAndAbort(); +} + +int _CrtDbgReportW(int reportType, const wchar_t*, int, + const wchar_t*, const wchar_t*, ...) { + ShowStatsAndAbort(); +} + +int _CrtSetReportMode(int, int) { + return 0; +} +} // extern "C" + +using __interception::GetRealFunctionAddress; + +// We don't want to include "windows.h" in this file to avoid extra attributes +// set on malloc/free etc (e.g. dllimport), so declare a few things manually: +extern "C" int __stdcall VirtualProtect(void* addr, size_t size, + DWORD prot, DWORD *old_prot); +const int PAGE_EXECUTE_READWRITE = 0x40; + +namespace __asan { +void ReplaceSystemMalloc() { +#if defined(_DLL) +# ifdef _WIN64 +# error ReplaceSystemMalloc was not tested on x64 +# endif + char *crt_malloc; + if (GetRealFunctionAddress("malloc", (void**)&crt_malloc)) { + // Replace malloc in the CRT dll with a jump to our malloc. + DWORD old_prot, unused; + CHECK(VirtualProtect(crt_malloc, 16, PAGE_EXECUTE_READWRITE, &old_prot)); + REAL(memset)(crt_malloc, 0xCC /* int 3 */, 16); // just in case. + + ptrdiff_t jmp_offset = (char*)malloc - (char*)crt_malloc - 5; + crt_malloc[0] = 0xE9; // jmp, should be followed by an offset. + REAL(memcpy)(crt_malloc + 1, &jmp_offset, sizeof(jmp_offset)); + + CHECK(VirtualProtect(crt_malloc, 16, old_prot, &unused)); + + // FYI: FlushInstructionCache is needed on Itanium etc but not on x86/x64. + } + + // FIXME: investigate whether anything else is needed. +#endif +} +} // namespace __asan + +#endif // _WIN32 |