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 21 namespace __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. 25 void ReplaceOperatorsNewAndDelete() { } 26 } 27 28 using 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>. 35 namespace std { 36 struct 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 51 INTERCEPTOR_ATTRIBUTE 52 void *operator new(size_t size) { OPERATOR_NEW_BODY(FROM_NEW); } 53 INTERCEPTOR_ATTRIBUTE 54 void *operator new[](size_t size) { OPERATOR_NEW_BODY(FROM_NEW_BR); } 55 INTERCEPTOR_ATTRIBUTE 56 void *operator new(size_t size, std::nothrow_t const&) 57 { OPERATOR_NEW_BODY(FROM_NEW); } 58 INTERCEPTOR_ATTRIBUTE 59 void *operator new[](size_t size, std::nothrow_t const&) 60 { OPERATOR_NEW_BODY(FROM_NEW_BR); } 61 62 #else // SANITIZER_MAC 63 INTERCEPTOR(void *, _Znwm, size_t size) { 64 OPERATOR_NEW_BODY(FROM_NEW); 65 } 66 INTERCEPTOR(void *, _Znam, size_t size) { 67 OPERATOR_NEW_BODY(FROM_NEW_BR); 68 } 69 INTERCEPTOR(void *, _ZnwmRKSt9nothrow_t, size_t size, std::nothrow_t const&) { 70 OPERATOR_NEW_BODY(FROM_NEW); 71 } 72 INTERCEPTOR(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 82 INTERCEPTOR_ATTRIBUTE 83 void operator delete(void *ptr) { OPERATOR_DELETE_BODY(FROM_NEW); } 84 INTERCEPTOR_ATTRIBUTE 85 void operator delete[](void *ptr) { OPERATOR_DELETE_BODY(FROM_NEW_BR); } 86 INTERCEPTOR_ATTRIBUTE 87 void operator delete(void *ptr, std::nothrow_t const&) 88 { OPERATOR_DELETE_BODY(FROM_NEW); } 89 INTERCEPTOR_ATTRIBUTE 90 void operator delete[](void *ptr, std::nothrow_t const&) 91 { OPERATOR_DELETE_BODY(FROM_NEW_BR); } 92 93 #else // SANITIZER_MAC 94 INTERCEPTOR(void, _ZdlPv, void *ptr) { 95 OPERATOR_DELETE_BODY(FROM_NEW); 96 } 97 INTERCEPTOR(void, _ZdaPv, void *ptr) { 98 OPERATOR_DELETE_BODY(FROM_NEW_BR); 99 } 100 INTERCEPTOR(void, _ZdlPvRKSt9nothrow_t, void *ptr, std::nothrow_t const&) { 101 OPERATOR_DELETE_BODY(FROM_NEW); 102 } 103 INTERCEPTOR(void, _ZdaPvRKSt9nothrow_t, void *ptr, std::nothrow_t const&) { 104 OPERATOR_DELETE_BODY(FROM_NEW_BR); 105 } 106 #endif 107 108 #endif 109