1//===-- asan_interceptors.cc ----------------------------------------------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file is a part of AddressSanitizer, an address sanity checker. 11// 12// Interceptors for operators new and delete. 13//===----------------------------------------------------------------------===// 14 15#include "asan_allocator.h" 16#include "asan_internal.h" 17#include "asan_stack.h" 18 19#include <stddef.h> 20 21namespace __asan { 22// This function is a no-op. We need it to make sure that object file 23// with our replacements will actually be loaded from static ASan 24// run-time library at link-time. 25void ReplaceOperatorsNewAndDelete() { } 26} 27 28using namespace __asan; // NOLINT 29 30// On Android new() goes through malloc interceptors. 31// See also https://code.google.com/p/address-sanitizer/issues/detail?id=131. 32#if !SANITIZER_ANDROID 33 34// Fake std::nothrow_t to avoid including <new>. 35namespace std { 36struct nothrow_t {}; 37} // namespace std 38 39#define OPERATOR_NEW_BODY(type) \ 40 GET_STACK_TRACE_MALLOC;\ 41 return asan_memalign(0, size, &stack, type); 42 43// On OS X it's not enough to just provide our own 'operator new' and 44// 'operator delete' implementations, because they're going to be in the 45// runtime dylib, and the main executable will depend on both the runtime 46// dylib and libstdc++, each of those'll have its implementation of new and 47// delete. 48// To make sure that C++ allocation/deallocation operators are overridden on 49// OS X we need to intercept them using their mangled names. 50#if !SANITIZER_MAC 51INTERCEPTOR_ATTRIBUTE 52void *operator new(size_t size) { OPERATOR_NEW_BODY(FROM_NEW); } 53INTERCEPTOR_ATTRIBUTE 54void *operator new[](size_t size) { OPERATOR_NEW_BODY(FROM_NEW_BR); } 55INTERCEPTOR_ATTRIBUTE 56void *operator new(size_t size, std::nothrow_t const&) 57{ OPERATOR_NEW_BODY(FROM_NEW); } 58INTERCEPTOR_ATTRIBUTE 59void *operator new[](size_t size, std::nothrow_t const&) 60{ OPERATOR_NEW_BODY(FROM_NEW_BR); } 61 62#else // SANITIZER_MAC 63INTERCEPTOR(void *, _Znwm, size_t size) { 64 OPERATOR_NEW_BODY(FROM_NEW); 65} 66INTERCEPTOR(void *, _Znam, size_t size) { 67 OPERATOR_NEW_BODY(FROM_NEW_BR); 68} 69INTERCEPTOR(void *, _ZnwmRKSt9nothrow_t, size_t size, std::nothrow_t const&) { 70 OPERATOR_NEW_BODY(FROM_NEW); 71} 72INTERCEPTOR(void *, _ZnamRKSt9nothrow_t, size_t size, std::nothrow_t const&) { 73 OPERATOR_NEW_BODY(FROM_NEW_BR); 74} 75#endif 76 77#define OPERATOR_DELETE_BODY(type) \ 78 GET_STACK_TRACE_FREE;\ 79 asan_free(ptr, &stack, type); 80 81#if !SANITIZER_MAC 82INTERCEPTOR_ATTRIBUTE 83void operator delete(void *ptr) { OPERATOR_DELETE_BODY(FROM_NEW); } 84INTERCEPTOR_ATTRIBUTE 85void operator delete[](void *ptr) { OPERATOR_DELETE_BODY(FROM_NEW_BR); } 86INTERCEPTOR_ATTRIBUTE 87void operator delete(void *ptr, std::nothrow_t const&) 88{ OPERATOR_DELETE_BODY(FROM_NEW); } 89INTERCEPTOR_ATTRIBUTE 90void operator delete[](void *ptr, std::nothrow_t const&) 91{ OPERATOR_DELETE_BODY(FROM_NEW_BR); } 92 93#else // SANITIZER_MAC 94INTERCEPTOR(void, _ZdlPv, void *ptr) { 95 OPERATOR_DELETE_BODY(FROM_NEW); 96} 97INTERCEPTOR(void, _ZdaPv, void *ptr) { 98 OPERATOR_DELETE_BODY(FROM_NEW_BR); 99} 100INTERCEPTOR(void, _ZdlPvRKSt9nothrow_t, void *ptr, std::nothrow_t const&) { 101 OPERATOR_DELETE_BODY(FROM_NEW); 102} 103INTERCEPTOR(void, _ZdaPvRKSt9nothrow_t, void *ptr, std::nothrow_t const&) { 104 OPERATOR_DELETE_BODY(FROM_NEW_BR); 105} 106#endif 107 108#endif 109