PR sanitizer/77567
[official-gcc.git] / libsanitizer / asan / asan_new_delete.cc
blobbf7a34ac87b4d9011631d25e57821ec3b607eb42
1 //===-- asan_interceptors.cc ----------------------------------------------===//
2 //
3 // This file is distributed under the University of Illinois Open Source
4 // License. See LICENSE.TXT for details.
5 //
6 //===----------------------------------------------------------------------===//
7 //
8 // This file is a part of AddressSanitizer, an address sanity checker.
9 //
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"
19 #include <stddef.h>
21 // C++ operators can't have visibility attributes on Windows.
22 #if SANITIZER_WINDOWS
23 # define CXX_OPERATOR_ATTRIBUTE
24 #else
25 # define CXX_OPERATOR_ATTRIBUTE INTERCEPTOR_ATTRIBUTE
26 #endif
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>.
43 namespace std {
44 struct nothrow_t {};
45 enum class align_val_t: size_t {};
46 } // namespace std
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
59 // delete.
60 // To make sure that C++ allocation/deallocation operators are overridden on
61 // OS X we need to intercept them using their mangled names.
62 #if !SANITIZER_MAC
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);
99 #endif
101 #define OPERATOR_DELETE_BODY(type) \
102 GET_STACK_TRACE_FREE;\
103 asan_free(ptr, &stack, type);
105 #if !SANITIZER_MAC
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);
172 #endif