xref: /netbsd-src/external/gpl3/gcc/dist/libsanitizer/tsan/tsan_new_delete.cpp (revision ff6d591ca308ed13e9c5ae142cf113a246c2cdc6)
1*ff6d591cSmrg //===-- tsan_new_delete.cpp ---------------------------------------------===//
2*ff6d591cSmrg //
3*ff6d591cSmrg // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*ff6d591cSmrg // See https://llvm.org/LICENSE.txt for license information.
5*ff6d591cSmrg // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*ff6d591cSmrg //
7*ff6d591cSmrg //===----------------------------------------------------------------------===//
8*ff6d591cSmrg //
9*ff6d591cSmrg // This file is a part of ThreadSanitizer (TSan), a race detector.
10*ff6d591cSmrg //
11*ff6d591cSmrg // Interceptors for operators new and delete.
12*ff6d591cSmrg //===----------------------------------------------------------------------===//
13*ff6d591cSmrg #include "interception/interception.h"
14*ff6d591cSmrg #include "sanitizer_common/sanitizer_allocator.h"
15*ff6d591cSmrg #include "sanitizer_common/sanitizer_allocator_report.h"
16*ff6d591cSmrg #include "sanitizer_common/sanitizer_internal_defs.h"
17*ff6d591cSmrg #include "tsan_interceptors.h"
18*ff6d591cSmrg #include "tsan_rtl.h"
19*ff6d591cSmrg 
20*ff6d591cSmrg using namespace __tsan;
21*ff6d591cSmrg 
22*ff6d591cSmrg namespace std {
23*ff6d591cSmrg struct nothrow_t {};
24*ff6d591cSmrg enum class align_val_t: __sanitizer::uptr {};
25*ff6d591cSmrg }  // namespace std
26*ff6d591cSmrg 
27*ff6d591cSmrg DECLARE_REAL(void *, malloc, uptr size)
28*ff6d591cSmrg DECLARE_REAL(void, free, void *ptr)
29*ff6d591cSmrg 
30*ff6d591cSmrg // TODO(alekseys): throw std::bad_alloc instead of dying on OOM.
31*ff6d591cSmrg #define OPERATOR_NEW_BODY(mangled_name, nothrow) \
32*ff6d591cSmrg   if (in_symbolizer()) \
33*ff6d591cSmrg     return InternalAlloc(size); \
34*ff6d591cSmrg   void *p = 0; \
35*ff6d591cSmrg   {  \
36*ff6d591cSmrg     SCOPED_INTERCEPTOR_RAW(mangled_name, size); \
37*ff6d591cSmrg     p = user_alloc(thr, pc, size); \
38*ff6d591cSmrg     if (!nothrow && UNLIKELY(!p)) { \
39*ff6d591cSmrg       GET_STACK_TRACE_FATAL(thr, pc); \
40*ff6d591cSmrg       ReportOutOfMemory(size, &stack); \
41*ff6d591cSmrg     } \
42*ff6d591cSmrg   }  \
43*ff6d591cSmrg   invoke_malloc_hook(p, size);  \
44*ff6d591cSmrg   return p;
45*ff6d591cSmrg 
46*ff6d591cSmrg #define OPERATOR_NEW_BODY_ALIGN(mangled_name, nothrow) \
47*ff6d591cSmrg   if (in_symbolizer()) \
48*ff6d591cSmrg     return InternalAlloc(size, nullptr, (uptr)align); \
49*ff6d591cSmrg   void *p = 0; \
50*ff6d591cSmrg   {  \
51*ff6d591cSmrg     SCOPED_INTERCEPTOR_RAW(mangled_name, size); \
52*ff6d591cSmrg     p = user_memalign(thr, pc, (uptr)align, size); \
53*ff6d591cSmrg     if (!nothrow && UNLIKELY(!p)) { \
54*ff6d591cSmrg       GET_STACK_TRACE_FATAL(thr, pc); \
55*ff6d591cSmrg       ReportOutOfMemory(size, &stack); \
56*ff6d591cSmrg     } \
57*ff6d591cSmrg   }  \
58*ff6d591cSmrg   invoke_malloc_hook(p, size);  \
59*ff6d591cSmrg   return p;
60*ff6d591cSmrg 
61*ff6d591cSmrg SANITIZER_INTERFACE_ATTRIBUTE
62*ff6d591cSmrg void *operator new(__sanitizer::uptr size);
operator new(__sanitizer::uptr size)63*ff6d591cSmrg void *operator new(__sanitizer::uptr size) {
64*ff6d591cSmrg   OPERATOR_NEW_BODY(_Znwm, false /*nothrow*/);
65*ff6d591cSmrg }
66*ff6d591cSmrg 
67*ff6d591cSmrg SANITIZER_INTERFACE_ATTRIBUTE
68*ff6d591cSmrg void *operator new[](__sanitizer::uptr size);
operator new[](__sanitizer::uptr size)69*ff6d591cSmrg void *operator new[](__sanitizer::uptr size) {
70*ff6d591cSmrg   OPERATOR_NEW_BODY(_Znam, false /*nothrow*/);
71*ff6d591cSmrg }
72*ff6d591cSmrg 
73*ff6d591cSmrg SANITIZER_INTERFACE_ATTRIBUTE
74*ff6d591cSmrg void *operator new(__sanitizer::uptr size, std::nothrow_t const&);
operator new(__sanitizer::uptr size,std::nothrow_t const &)75*ff6d591cSmrg void *operator new(__sanitizer::uptr size, std::nothrow_t const&) {
76*ff6d591cSmrg   OPERATOR_NEW_BODY(_ZnwmRKSt9nothrow_t, true /*nothrow*/);
77*ff6d591cSmrg }
78*ff6d591cSmrg 
79*ff6d591cSmrg SANITIZER_INTERFACE_ATTRIBUTE
80*ff6d591cSmrg void *operator new[](__sanitizer::uptr size, std::nothrow_t const&);
operator new[](__sanitizer::uptr size,std::nothrow_t const &)81*ff6d591cSmrg void *operator new[](__sanitizer::uptr size, std::nothrow_t const&) {
82*ff6d591cSmrg   OPERATOR_NEW_BODY(_ZnamRKSt9nothrow_t, true /*nothrow*/);
83*ff6d591cSmrg }
84*ff6d591cSmrg 
85*ff6d591cSmrg SANITIZER_INTERFACE_ATTRIBUTE
86*ff6d591cSmrg void *operator new(__sanitizer::uptr size, std::align_val_t align);
operator new(__sanitizer::uptr size,std::align_val_t align)87*ff6d591cSmrg void *operator new(__sanitizer::uptr size, std::align_val_t align) {
88*ff6d591cSmrg   OPERATOR_NEW_BODY_ALIGN(_ZnwmSt11align_val_t, false /*nothrow*/);
89*ff6d591cSmrg }
90*ff6d591cSmrg 
91*ff6d591cSmrg SANITIZER_INTERFACE_ATTRIBUTE
92*ff6d591cSmrg void *operator new[](__sanitizer::uptr size, std::align_val_t align);
operator new[](__sanitizer::uptr size,std::align_val_t align)93*ff6d591cSmrg void *operator new[](__sanitizer::uptr size, std::align_val_t align) {
94*ff6d591cSmrg   OPERATOR_NEW_BODY_ALIGN(_ZnamSt11align_val_t, false /*nothrow*/);
95*ff6d591cSmrg }
96*ff6d591cSmrg 
97*ff6d591cSmrg SANITIZER_INTERFACE_ATTRIBUTE
98*ff6d591cSmrg void *operator new(__sanitizer::uptr size, std::align_val_t align,
99*ff6d591cSmrg                    std::nothrow_t const&);
operator new(__sanitizer::uptr size,std::align_val_t align,std::nothrow_t const &)100*ff6d591cSmrg void *operator new(__sanitizer::uptr size, std::align_val_t align,
101*ff6d591cSmrg                    std::nothrow_t const&) {
102*ff6d591cSmrg   OPERATOR_NEW_BODY_ALIGN(_ZnwmSt11align_val_tRKSt9nothrow_t,
103*ff6d591cSmrg                           true /*nothrow*/);
104*ff6d591cSmrg }
105*ff6d591cSmrg 
106*ff6d591cSmrg SANITIZER_INTERFACE_ATTRIBUTE
107*ff6d591cSmrg void *operator new[](__sanitizer::uptr size, std::align_val_t align,
108*ff6d591cSmrg                      std::nothrow_t const&);
operator new[](__sanitizer::uptr size,std::align_val_t align,std::nothrow_t const &)109*ff6d591cSmrg void *operator new[](__sanitizer::uptr size, std::align_val_t align,
110*ff6d591cSmrg                      std::nothrow_t const&) {
111*ff6d591cSmrg   OPERATOR_NEW_BODY_ALIGN(_ZnamSt11align_val_tRKSt9nothrow_t,
112*ff6d591cSmrg                           true /*nothrow*/);
113*ff6d591cSmrg }
114*ff6d591cSmrg 
115*ff6d591cSmrg #define OPERATOR_DELETE_BODY(mangled_name) \
116*ff6d591cSmrg   if (ptr == 0) return;  \
117*ff6d591cSmrg   if (in_symbolizer()) \
118*ff6d591cSmrg     return InternalFree(ptr); \
119*ff6d591cSmrg   invoke_free_hook(ptr);  \
120*ff6d591cSmrg   SCOPED_INTERCEPTOR_RAW(mangled_name, ptr);  \
121*ff6d591cSmrg   user_free(thr, pc, ptr);
122*ff6d591cSmrg 
123*ff6d591cSmrg SANITIZER_INTERFACE_ATTRIBUTE
124*ff6d591cSmrg void operator delete(void *ptr) NOEXCEPT;
operator delete(void * ptr)125*ff6d591cSmrg void operator delete(void *ptr) NOEXCEPT {
126*ff6d591cSmrg   OPERATOR_DELETE_BODY(_ZdlPv);
127*ff6d591cSmrg }
128*ff6d591cSmrg 
129*ff6d591cSmrg SANITIZER_INTERFACE_ATTRIBUTE
130*ff6d591cSmrg void operator delete[](void *ptr) NOEXCEPT;
operator delete[](void * ptr)131*ff6d591cSmrg void operator delete[](void *ptr) NOEXCEPT {
132*ff6d591cSmrg   OPERATOR_DELETE_BODY(_ZdaPv);
133*ff6d591cSmrg }
134*ff6d591cSmrg 
135*ff6d591cSmrg SANITIZER_INTERFACE_ATTRIBUTE
136*ff6d591cSmrg void operator delete(void *ptr, std::nothrow_t const&);
operator delete(void * ptr,std::nothrow_t const &)137*ff6d591cSmrg void operator delete(void *ptr, std::nothrow_t const&) {
138*ff6d591cSmrg   OPERATOR_DELETE_BODY(_ZdlPvRKSt9nothrow_t);
139*ff6d591cSmrg }
140*ff6d591cSmrg 
141*ff6d591cSmrg SANITIZER_INTERFACE_ATTRIBUTE
142*ff6d591cSmrg void operator delete[](void *ptr, std::nothrow_t const&);
operator delete[](void * ptr,std::nothrow_t const &)143*ff6d591cSmrg void operator delete[](void *ptr, std::nothrow_t const&) {
144*ff6d591cSmrg   OPERATOR_DELETE_BODY(_ZdaPvRKSt9nothrow_t);
145*ff6d591cSmrg }
146*ff6d591cSmrg 
147*ff6d591cSmrg SANITIZER_INTERFACE_ATTRIBUTE
148*ff6d591cSmrg void operator delete(void *ptr, __sanitizer::uptr size) NOEXCEPT;
operator delete(void * ptr,__sanitizer::uptr size)149*ff6d591cSmrg void operator delete(void *ptr, __sanitizer::uptr size) NOEXCEPT {
150*ff6d591cSmrg   OPERATOR_DELETE_BODY(_ZdlPvm);
151*ff6d591cSmrg }
152*ff6d591cSmrg 
153*ff6d591cSmrg SANITIZER_INTERFACE_ATTRIBUTE
154*ff6d591cSmrg void operator delete[](void *ptr, __sanitizer::uptr size) NOEXCEPT;
operator delete[](void * ptr,__sanitizer::uptr size)155*ff6d591cSmrg void operator delete[](void *ptr, __sanitizer::uptr size) NOEXCEPT {
156*ff6d591cSmrg   OPERATOR_DELETE_BODY(_ZdaPvm);
157*ff6d591cSmrg }
158*ff6d591cSmrg 
159*ff6d591cSmrg SANITIZER_INTERFACE_ATTRIBUTE
160*ff6d591cSmrg void operator delete(void *ptr, std::align_val_t align) NOEXCEPT;
operator delete(void * ptr,std::align_val_t align)161*ff6d591cSmrg void operator delete(void *ptr, std::align_val_t align) NOEXCEPT {
162*ff6d591cSmrg   OPERATOR_DELETE_BODY(_ZdlPvSt11align_val_t);
163*ff6d591cSmrg }
164*ff6d591cSmrg 
165*ff6d591cSmrg SANITIZER_INTERFACE_ATTRIBUTE
166*ff6d591cSmrg void operator delete[](void *ptr, std::align_val_t align) NOEXCEPT;
operator delete[](void * ptr,std::align_val_t align)167*ff6d591cSmrg void operator delete[](void *ptr, std::align_val_t align) NOEXCEPT {
168*ff6d591cSmrg   OPERATOR_DELETE_BODY(_ZdaPvSt11align_val_t);
169*ff6d591cSmrg }
170*ff6d591cSmrg 
171*ff6d591cSmrg SANITIZER_INTERFACE_ATTRIBUTE
172*ff6d591cSmrg void operator delete(void *ptr, std::align_val_t align, std::nothrow_t const&);
operator delete(void * ptr,std::align_val_t align,std::nothrow_t const &)173*ff6d591cSmrg void operator delete(void *ptr, std::align_val_t align, std::nothrow_t const&) {
174*ff6d591cSmrg   OPERATOR_DELETE_BODY(_ZdlPvSt11align_val_tRKSt9nothrow_t);
175*ff6d591cSmrg }
176*ff6d591cSmrg 
177*ff6d591cSmrg SANITIZER_INTERFACE_ATTRIBUTE
178*ff6d591cSmrg void operator delete[](void *ptr, std::align_val_t align,
179*ff6d591cSmrg                        std::nothrow_t const&);
operator delete[](void * ptr,std::align_val_t align,std::nothrow_t const &)180*ff6d591cSmrg void operator delete[](void *ptr, std::align_val_t align,
181*ff6d591cSmrg                        std::nothrow_t const&) {
182*ff6d591cSmrg   OPERATOR_DELETE_BODY(_ZdaPvSt11align_val_tRKSt9nothrow_t);
183*ff6d591cSmrg }
184*ff6d591cSmrg 
185*ff6d591cSmrg SANITIZER_INTERFACE_ATTRIBUTE
186*ff6d591cSmrg void operator delete(void *ptr, __sanitizer::uptr size,
187*ff6d591cSmrg                      std::align_val_t align) NOEXCEPT;
operator delete(void * ptr,__sanitizer::uptr size,std::align_val_t align)188*ff6d591cSmrg void operator delete(void *ptr, __sanitizer::uptr size,
189*ff6d591cSmrg                      std::align_val_t align) NOEXCEPT {
190*ff6d591cSmrg   OPERATOR_DELETE_BODY(_ZdlPvmSt11align_val_t);
191*ff6d591cSmrg }
192*ff6d591cSmrg 
193*ff6d591cSmrg SANITIZER_INTERFACE_ATTRIBUTE
194*ff6d591cSmrg void operator delete[](void *ptr, __sanitizer::uptr size,
195*ff6d591cSmrg                        std::align_val_t align) NOEXCEPT;
operator delete[](void * ptr,__sanitizer::uptr size,std::align_val_t align)196*ff6d591cSmrg void operator delete[](void *ptr, __sanitizer::uptr size,
197*ff6d591cSmrg                        std::align_val_t align) NOEXCEPT {
198*ff6d591cSmrg   OPERATOR_DELETE_BODY(_ZdaPvmSt11align_val_t);
199*ff6d591cSmrg }
200