asan_new_delete.cc revision 296417
1272343Sngie//===-- asan_interceptors.cc ----------------------------------------------===// 2272343Sngie// 3272343Sngie// The LLVM Compiler Infrastructure 4272343Sngie// 5272343Sngie// This file is distributed under the University of Illinois Open Source 6272343Sngie// License. See LICENSE.TXT for details. 7272343Sngie// 8272343Sngie//===----------------------------------------------------------------------===// 9272343Sngie// 10272343Sngie// This file is a part of AddressSanitizer, an address sanity checker. 11272343Sngie// 12272343Sngie// Interceptors for operators new and delete. 13272343Sngie//===----------------------------------------------------------------------===// 14272343Sngie 15272343Sngie#include "asan_allocator.h" 16272343Sngie#include "asan_internal.h" 17272343Sngie#include "asan_stack.h" 18272343Sngie 19272343Sngie#include "interception/interception.h" 20272343Sngie 21272343Sngie#include <stddef.h> 22272343Sngie 23272343Sngie// C++ operators can't have visibility attributes on Windows. 24272343Sngie#if SANITIZER_WINDOWS 25272343Sngie# define CXX_OPERATOR_ATTRIBUTE 26272343Sngie#else 27272343Sngie# define CXX_OPERATOR_ATTRIBUTE INTERCEPTOR_ATTRIBUTE 28272343Sngie#endif 29272343Sngie 30272343Sngieusing namespace __asan; // NOLINT 31272343Sngie 32272343Sngie// This code has issues on OSX. 33272343Sngie// See https://github.com/google/sanitizers/issues/131. 34272343Sngie 35272343Sngie// Fake std::nothrow_t to avoid including <new>. 36272343Sngienamespace std { 37272343Sngiestruct nothrow_t {}; 38272343Sngie} // namespace std 39272343Sngie 40272343Sngie#define OPERATOR_NEW_BODY(type) \ 41272343Sngie GET_STACK_TRACE_MALLOC;\ 42272343Sngie return asan_memalign(0, size, &stack, type); 43272343Sngie 44272343Sngie// On OS X it's not enough to just provide our own 'operator new' and 45272343Sngie// 'operator delete' implementations, because they're going to be in the 46272343Sngie// runtime dylib, and the main executable will depend on both the runtime 47272343Sngie// dylib and libstdc++, each of those'll have its implementation of new and 48272343Sngie// delete. 49272343Sngie// To make sure that C++ allocation/deallocation operators are overridden on 50272343Sngie// OS X we need to intercept them using their mangled names. 51272343Sngie#if !SANITIZER_MAC 52272343Sngie// FreeBSD prior v9.2 have wrong definition of 'size_t'. 53272343Sngie// http://svnweb.freebsd.org/base?view=revision&revision=232261 54272343Sngie#if SANITIZER_FREEBSD && SANITIZER_WORDSIZE == 32 55272343Sngie#include <sys/param.h> 56272343Sngie#if __FreeBSD_version <= 902001 // v9.2 57272343Sngie#define size_t unsigned 58272343Sngie#endif // __FreeBSD_version 59272343Sngie#endif // SANITIZER_FREEBSD && SANITIZER_WORDSIZE == 32 60272343Sngie 61272343SngieCXX_OPERATOR_ATTRIBUTE 62272343Sngievoid *operator new(size_t size) { OPERATOR_NEW_BODY(FROM_NEW); } 63272343SngieCXX_OPERATOR_ATTRIBUTE 64272343Sngievoid *operator new[](size_t size) { OPERATOR_NEW_BODY(FROM_NEW_BR); } 65272343SngieCXX_OPERATOR_ATTRIBUTE 66272343Sngievoid *operator new(size_t size, std::nothrow_t const&) 67272343Sngie{ OPERATOR_NEW_BODY(FROM_NEW); } 68272343SngieCXX_OPERATOR_ATTRIBUTE 69272343Sngievoid *operator new[](size_t size, std::nothrow_t const&) 70272343Sngie{ OPERATOR_NEW_BODY(FROM_NEW_BR); } 71272343Sngie 72272343Sngie#else // SANITIZER_MAC 73272343SngieINTERCEPTOR(void *, _Znwm, size_t size) { 74272343Sngie OPERATOR_NEW_BODY(FROM_NEW); 75272343Sngie} 76272343SngieINTERCEPTOR(void *, _Znam, size_t size) { 77272343Sngie OPERATOR_NEW_BODY(FROM_NEW_BR); 78272343Sngie} 79272343SngieINTERCEPTOR(void *, _ZnwmRKSt9nothrow_t, size_t size, std::nothrow_t const&) { 80272343Sngie OPERATOR_NEW_BODY(FROM_NEW); 81272343Sngie} 82272343SngieINTERCEPTOR(void *, _ZnamRKSt9nothrow_t, size_t size, std::nothrow_t const&) { 83272343Sngie OPERATOR_NEW_BODY(FROM_NEW_BR); 84272343Sngie} 85272343Sngie#endif 86272343Sngie 87272343Sngie#define OPERATOR_DELETE_BODY(type) \ 88272343Sngie GET_STACK_TRACE_FREE;\ 89272343Sngie asan_free(ptr, &stack, type); 90272343Sngie 91272343Sngie#if !SANITIZER_MAC 92272343SngieCXX_OPERATOR_ATTRIBUTE 93272343Sngievoid operator delete(void *ptr) NOEXCEPT { 94272343Sngie OPERATOR_DELETE_BODY(FROM_NEW); 95272343Sngie} 96272343SngieCXX_OPERATOR_ATTRIBUTE 97272343Sngievoid operator delete[](void *ptr) NOEXCEPT { 98272343Sngie OPERATOR_DELETE_BODY(FROM_NEW_BR); 99272343Sngie} 100272343SngieCXX_OPERATOR_ATTRIBUTE 101272343Sngievoid operator delete(void *ptr, std::nothrow_t const&) { 102272343Sngie OPERATOR_DELETE_BODY(FROM_NEW); 103272343Sngie} 104272343SngieCXX_OPERATOR_ATTRIBUTE 105272343Sngievoid operator delete[](void *ptr, std::nothrow_t const&) { 106272343Sngie OPERATOR_DELETE_BODY(FROM_NEW_BR); 107272343Sngie} 108272343SngieCXX_OPERATOR_ATTRIBUTE 109272343Sngievoid operator delete(void *ptr, size_t size) NOEXCEPT { 110272343Sngie GET_STACK_TRACE_FREE; 111272343Sngie asan_sized_free(ptr, size, &stack, FROM_NEW); 112272343Sngie} 113272343SngieCXX_OPERATOR_ATTRIBUTE 114272343Sngievoid operator delete[](void *ptr, size_t size) NOEXCEPT { 115272343Sngie GET_STACK_TRACE_FREE; 116272343Sngie asan_sized_free(ptr, size, &stack, FROM_NEW_BR); 117272343Sngie} 118272343Sngie 119272343Sngie#else // SANITIZER_MAC 120272343SngieINTERCEPTOR(void, _ZdlPv, void *ptr) { 121272343Sngie OPERATOR_DELETE_BODY(FROM_NEW); 122272343Sngie} 123272343SngieINTERCEPTOR(void, _ZdaPv, void *ptr) { 124272343Sngie OPERATOR_DELETE_BODY(FROM_NEW_BR); 125272343Sngie} 126272343SngieINTERCEPTOR(void, _ZdlPvRKSt9nothrow_t, void *ptr, std::nothrow_t const&) { 127272343Sngie OPERATOR_DELETE_BODY(FROM_NEW); 128272343Sngie} 129272343SngieINTERCEPTOR(void, _ZdaPvRKSt9nothrow_t, void *ptr, std::nothrow_t const&) { 130272343Sngie OPERATOR_DELETE_BODY(FROM_NEW_BR); 131272343Sngie} 132272343Sngie#endif 133272343Sngie