1 //===-- asan_interceptors.cc ----------------------------------------------===//
3 // This file is distributed under the University of Illinois Open Source
4 // License. See LICENSE.TXT for details.
6 //===----------------------------------------------------------------------===//
8 // This file is a part of AddressSanitizer, an address sanity checker.
10 // Interceptors for operators new and delete.
11 //===----------------------------------------------------------------------===//
13 #include "asan_allocator.h"
14 #include "asan_internal.h"
15 #include "asan_stack.h"
17 #include "interception/interception.h"
21 // C++ operators can't have visibility attributes on Windows.
23 # define CXX_OPERATOR_ATTRIBUTE
25 # define CXX_OPERATOR_ATTRIBUTE INTERCEPTOR_ATTRIBUTE
28 using namespace __asan
; // NOLINT
30 // FreeBSD prior v9.2 have wrong definition of 'size_t'.
31 // http://svnweb.freebsd.org/base?view=revision&revision=232261
32 #if SANITIZER_FREEBSD && SANITIZER_WORDSIZE == 32
33 #include <sys/param.h>
34 #if __FreeBSD_version <= 902001 // v9.2
35 #define size_t unsigned
36 #endif // __FreeBSD_version
37 #endif // SANITIZER_FREEBSD && SANITIZER_WORDSIZE == 32
39 // This code has issues on OSX.
40 // See https://code.google.com/p/address-sanitizer/issues/detail?id=131.
42 // Fake std::nothrow_t and std::align_val_t to avoid including <new>.
45 enum class align_val_t
: size_t {};
48 #define OPERATOR_NEW_BODY(type) \
49 GET_STACK_TRACE_MALLOC;\
50 return asan_memalign(0, size, &stack, type);
51 #define OPERATOR_NEW_BODY_ALIGN(type) \
52 GET_STACK_TRACE_MALLOC;\
53 return asan_memalign((uptr)align, size, &stack, type);
55 // On OS X it's not enough to just provide our own 'operator new' and
56 // 'operator delete' implementations, because they're going to be in the
57 // runtime dylib, and the main executable will depend on both the runtime
58 // dylib and libstdc++, each of those'll have its implementation of new and
60 // To make sure that C++ allocation/deallocation operators are overridden on
61 // OS X we need to intercept them using their mangled names.
63 CXX_OPERATOR_ATTRIBUTE
64 void *operator new(size_t size
) { OPERATOR_NEW_BODY(FROM_NEW
); }
65 CXX_OPERATOR_ATTRIBUTE
66 void *operator new[](size_t size
) { OPERATOR_NEW_BODY(FROM_NEW_BR
); }
67 CXX_OPERATOR_ATTRIBUTE
68 void *operator new(size_t size
, std::nothrow_t
const&)
69 { OPERATOR_NEW_BODY(FROM_NEW
); }
70 CXX_OPERATOR_ATTRIBUTE
71 void *operator new[](size_t size
, std::nothrow_t
const&)
72 { OPERATOR_NEW_BODY(FROM_NEW_BR
); }
73 CXX_OPERATOR_ATTRIBUTE
74 void *operator new(size_t size
, std::align_val_t align
)
75 { OPERATOR_NEW_BODY_ALIGN(FROM_NEW
); }
76 CXX_OPERATOR_ATTRIBUTE
77 void *operator new[](size_t size
, std::align_val_t align
)
78 { OPERATOR_NEW_BODY_ALIGN(FROM_NEW_BR
); }
79 CXX_OPERATOR_ATTRIBUTE
80 void *operator new(size_t size
, std::align_val_t align
, std::nothrow_t
const&)
81 { OPERATOR_NEW_BODY_ALIGN(FROM_NEW
); }
82 CXX_OPERATOR_ATTRIBUTE
83 void *operator new[](size_t size
, std::align_val_t align
, std::nothrow_t
const&)
84 { OPERATOR_NEW_BODY_ALIGN(FROM_NEW_BR
); }
86 #else // SANITIZER_MAC
87 INTERCEPTOR(void *, _Znwm
, size_t size
) {
88 OPERATOR_NEW_BODY(FROM_NEW
);
90 INTERCEPTOR(void *, _Znam
, size_t size
) {
91 OPERATOR_NEW_BODY(FROM_NEW_BR
);
93 INTERCEPTOR(void *, _ZnwmRKSt9nothrow_t
, size_t size
, std::nothrow_t
const&) {
94 OPERATOR_NEW_BODY(FROM_NEW
);
96 INTERCEPTOR(void *, _ZnamRKSt9nothrow_t
, size_t size
, std::nothrow_t
const&) {
97 OPERATOR_NEW_BODY(FROM_NEW_BR
);
101 #define OPERATOR_DELETE_BODY(type) \
102 GET_STACK_TRACE_FREE;\
103 asan_free(ptr, &stack, type);
106 CXX_OPERATOR_ATTRIBUTE
107 void operator delete(void *ptr
) NOEXCEPT
{
108 OPERATOR_DELETE_BODY(FROM_NEW
);
110 CXX_OPERATOR_ATTRIBUTE
111 void operator delete[](void *ptr
) NOEXCEPT
{
112 OPERATOR_DELETE_BODY(FROM_NEW_BR
);
114 CXX_OPERATOR_ATTRIBUTE
115 void operator delete(void *ptr
, std::nothrow_t
const&) {
116 OPERATOR_DELETE_BODY(FROM_NEW
);
118 CXX_OPERATOR_ATTRIBUTE
119 void operator delete[](void *ptr
, std::nothrow_t
const&) {
120 OPERATOR_DELETE_BODY(FROM_NEW_BR
);
122 CXX_OPERATOR_ATTRIBUTE
123 void operator delete(void *ptr
, size_t size
) NOEXCEPT
{
124 GET_STACK_TRACE_FREE
;
125 asan_sized_free(ptr
, size
, &stack
, FROM_NEW
);
127 CXX_OPERATOR_ATTRIBUTE
128 void operator delete[](void *ptr
, size_t size
) NOEXCEPT
{
129 GET_STACK_TRACE_FREE
;
130 asan_sized_free(ptr
, size
, &stack
, FROM_NEW_BR
);
132 CXX_OPERATOR_ATTRIBUTE
133 void operator delete(void *ptr
, std::align_val_t
) NOEXCEPT
{
134 OPERATOR_DELETE_BODY(FROM_NEW
);
136 CXX_OPERATOR_ATTRIBUTE
137 void operator delete[](void *ptr
, std::align_val_t
) NOEXCEPT
{
138 OPERATOR_DELETE_BODY(FROM_NEW_BR
);
140 CXX_OPERATOR_ATTRIBUTE
141 void operator delete(void *ptr
, std::align_val_t
, std::nothrow_t
const&) {
142 OPERATOR_DELETE_BODY(FROM_NEW
);
144 CXX_OPERATOR_ATTRIBUTE
145 void operator delete[](void *ptr
, std::align_val_t
, std::nothrow_t
const&) {
146 OPERATOR_DELETE_BODY(FROM_NEW_BR
);
148 CXX_OPERATOR_ATTRIBUTE
149 void operator delete(void *ptr
, size_t size
, std::align_val_t
) NOEXCEPT
{
150 GET_STACK_TRACE_FREE
;
151 asan_sized_free(ptr
, size
, &stack
, FROM_NEW
);
153 CXX_OPERATOR_ATTRIBUTE
154 void operator delete[](void *ptr
, size_t size
, std::align_val_t
) NOEXCEPT
{
155 GET_STACK_TRACE_FREE
;
156 asan_sized_free(ptr
, size
, &stack
, FROM_NEW_BR
);
159 #else // SANITIZER_MAC
160 INTERCEPTOR(void, _ZdlPv
, void *ptr
) {
161 OPERATOR_DELETE_BODY(FROM_NEW
);
163 INTERCEPTOR(void, _ZdaPv
, void *ptr
) {
164 OPERATOR_DELETE_BODY(FROM_NEW_BR
);
166 INTERCEPTOR(void, _ZdlPvRKSt9nothrow_t
, void *ptr
, std::nothrow_t
const&) {
167 OPERATOR_DELETE_BODY(FROM_NEW
);
169 INTERCEPTOR(void, _ZdaPvRKSt9nothrow_t
, void *ptr
, std::nothrow_t
const&) {
170 OPERATOR_DELETE_BODY(FROM_NEW_BR
);