1238901Sandrew//===-- asan_interceptors.cc ----------------------------------------------===// 2238901Sandrew// 3238901Sandrew// The LLVM Compiler Infrastructure 4238901Sandrew// 5238901Sandrew// This file is distributed under the University of Illinois Open Source 6238901Sandrew// License. See LICENSE.TXT for details. 7238901Sandrew// 8238901Sandrew//===----------------------------------------------------------------------===// 9238901Sandrew// 10238901Sandrew// This file is a part of AddressSanitizer, an address sanity checker. 11238901Sandrew// 12238901Sandrew// Interceptors for operators new and delete. 13238901Sandrew//===----------------------------------------------------------------------===// 14238901Sandrew 15238901Sandrew#include "asan_allocator.h" 16238901Sandrew#include "asan_internal.h" 17238901Sandrew#include "asan_stack.h" 18238901Sandrew 19276789Sdim#include "interception/interception.h" 20276789Sdim 21238901Sandrew#include <stddef.h> 22238901Sandrew 23276789Sdim// C++ operators can't have visibility attributes on Windows. 24276789Sdim#if SANITIZER_WINDOWS 25276789Sdim# define CXX_OPERATOR_ATTRIBUTE 26276789Sdim#else 27276789Sdim# define CXX_OPERATOR_ATTRIBUTE INTERCEPTOR_ATTRIBUTE 28276789Sdim#endif 29238901Sandrew 30238901Sandrewusing namespace __asan; // NOLINT 31238901Sandrew 32276789Sdim// This code has issues on OSX. 33296417Sdim// See https://github.com/google/sanitizers/issues/131. 34238901Sandrew 35245614Sandrew// Fake std::nothrow_t to avoid including <new>. 36245614Sandrewnamespace std { 37245614Sandrewstruct nothrow_t {}; 38245614Sandrew} // namespace std 39238901Sandrew 40245614Sandrew#define OPERATOR_NEW_BODY(type) \ 41245614Sandrew GET_STACK_TRACE_MALLOC;\ 42245614Sandrew return asan_memalign(0, size, &stack, type); 43238901Sandrew 44251034Sed// On OS X it's not enough to just provide our own 'operator new' and 45251034Sed// 'operator delete' implementations, because they're going to be in the 46251034Sed// runtime dylib, and the main executable will depend on both the runtime 47251034Sed// dylib and libstdc++, each of those'll have its implementation of new and 48251034Sed// delete. 49251034Sed// To make sure that C++ allocation/deallocation operators are overridden on 50251034Sed// OS X we need to intercept them using their mangled names. 51251034Sed#if !SANITIZER_MAC 52276789Sdim// FreeBSD prior v9.2 have wrong definition of 'size_t'. 53276789Sdim// http://svnweb.freebsd.org/base?view=revision&revision=232261 54276789Sdim#if SANITIZER_FREEBSD && SANITIZER_WORDSIZE == 32 55276789Sdim#include <sys/param.h> 56276789Sdim#if __FreeBSD_version <= 902001 // v9.2 57276789Sdim#define size_t unsigned 58276789Sdim#endif // __FreeBSD_version 59276789Sdim#endif // SANITIZER_FREEBSD && SANITIZER_WORDSIZE == 32 60276789Sdim 61276789SdimCXX_OPERATOR_ATTRIBUTE 62245614Sandrewvoid *operator new(size_t size) { OPERATOR_NEW_BODY(FROM_NEW); } 63276789SdimCXX_OPERATOR_ATTRIBUTE 64245614Sandrewvoid *operator new[](size_t size) { OPERATOR_NEW_BODY(FROM_NEW_BR); } 65276789SdimCXX_OPERATOR_ATTRIBUTE 66245614Sandrewvoid *operator new(size_t size, std::nothrow_t const&) 67245614Sandrew{ OPERATOR_NEW_BODY(FROM_NEW); } 68276789SdimCXX_OPERATOR_ATTRIBUTE 69245614Sandrewvoid *operator new[](size_t size, std::nothrow_t const&) 70245614Sandrew{ OPERATOR_NEW_BODY(FROM_NEW_BR); } 71245614Sandrew 72251034Sed#else // SANITIZER_MAC 73251034SedINTERCEPTOR(void *, _Znwm, size_t size) { 74251034Sed OPERATOR_NEW_BODY(FROM_NEW); 75251034Sed} 76251034SedINTERCEPTOR(void *, _Znam, size_t size) { 77251034Sed OPERATOR_NEW_BODY(FROM_NEW_BR); 78251034Sed} 79251034SedINTERCEPTOR(void *, _ZnwmRKSt9nothrow_t, size_t size, std::nothrow_t const&) { 80251034Sed OPERATOR_NEW_BODY(FROM_NEW); 81251034Sed} 82251034SedINTERCEPTOR(void *, _ZnamRKSt9nothrow_t, size_t size, std::nothrow_t const&) { 83251034Sed OPERATOR_NEW_BODY(FROM_NEW_BR); 84251034Sed} 85251034Sed#endif 86251034Sed 87245614Sandrew#define OPERATOR_DELETE_BODY(type) \ 88245614Sandrew GET_STACK_TRACE_FREE;\ 89245614Sandrew asan_free(ptr, &stack, type); 90245614Sandrew 91251034Sed#if !SANITIZER_MAC 92276789SdimCXX_OPERATOR_ATTRIBUTE 93296417Sdimvoid operator delete(void *ptr) NOEXCEPT { 94276789Sdim OPERATOR_DELETE_BODY(FROM_NEW); 95276789Sdim} 96276789SdimCXX_OPERATOR_ATTRIBUTE 97296417Sdimvoid operator delete[](void *ptr) NOEXCEPT { 98276789Sdim OPERATOR_DELETE_BODY(FROM_NEW_BR); 99276789Sdim} 100276789SdimCXX_OPERATOR_ATTRIBUTE 101276789Sdimvoid operator delete(void *ptr, std::nothrow_t const&) { 102276789Sdim OPERATOR_DELETE_BODY(FROM_NEW); 103276789Sdim} 104276789SdimCXX_OPERATOR_ATTRIBUTE 105276789Sdimvoid operator delete[](void *ptr, std::nothrow_t const&) { 106276789Sdim OPERATOR_DELETE_BODY(FROM_NEW_BR); 107276789Sdim} 108276789SdimCXX_OPERATOR_ATTRIBUTE 109296417Sdimvoid operator delete(void *ptr, size_t size) NOEXCEPT { 110276789Sdim GET_STACK_TRACE_FREE; 111276789Sdim asan_sized_free(ptr, size, &stack, FROM_NEW); 112276789Sdim} 113276789SdimCXX_OPERATOR_ATTRIBUTE 114296417Sdimvoid operator delete[](void *ptr, size_t size) NOEXCEPT { 115276789Sdim GET_STACK_TRACE_FREE; 116276789Sdim asan_sized_free(ptr, size, &stack, FROM_NEW_BR); 117276789Sdim} 118245614Sandrew 119251034Sed#else // SANITIZER_MAC 120251034SedINTERCEPTOR(void, _ZdlPv, void *ptr) { 121251034Sed OPERATOR_DELETE_BODY(FROM_NEW); 122251034Sed} 123251034SedINTERCEPTOR(void, _ZdaPv, void *ptr) { 124251034Sed OPERATOR_DELETE_BODY(FROM_NEW_BR); 125251034Sed} 126251034SedINTERCEPTOR(void, _ZdlPvRKSt9nothrow_t, void *ptr, std::nothrow_t const&) { 127251034Sed OPERATOR_DELETE_BODY(FROM_NEW); 128251034Sed} 129251034SedINTERCEPTOR(void, _ZdaPvRKSt9nothrow_t, void *ptr, std::nothrow_t const&) { 130251034Sed OPERATOR_DELETE_BODY(FROM_NEW_BR); 131251034Sed} 132245614Sandrew#endif 133