1353944Sdim//===-- tsan_new_delete.cpp ---------------------------------------------===//
2353944Sdim//
3353944Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4353944Sdim// See https://llvm.org/LICENSE.txt for license information.
5353944Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6353944Sdim//
7353944Sdim//===----------------------------------------------------------------------===//
8353944Sdim//
9353944Sdim// This file is a part of ThreadSanitizer (TSan), a race detector.
10353944Sdim//
11353944Sdim// Interceptors for operators new and delete.
12353944Sdim//===----------------------------------------------------------------------===//
13353944Sdim#include "interception/interception.h"
14353944Sdim#include "sanitizer_common/sanitizer_allocator.h"
15353944Sdim#include "sanitizer_common/sanitizer_allocator_report.h"
16353944Sdim#include "sanitizer_common/sanitizer_internal_defs.h"
17353944Sdim#include "tsan_interceptors.h"
18353944Sdim#include "tsan_rtl.h"
19353944Sdim
20353944Sdimusing namespace __tsan;
21353944Sdim
22353944Sdimnamespace std {
23353944Sdimstruct nothrow_t {};
24353944Sdimenum class align_val_t: __sanitizer::uptr {};
25353944Sdim}  // namespace std
26353944Sdim
27353944SdimDECLARE_REAL(void *, malloc, uptr size)
28353944SdimDECLARE_REAL(void, free, void *ptr)
29353944Sdim
30353944Sdim// TODO(alekseys): throw std::bad_alloc instead of dying on OOM.
31353944Sdim#define OPERATOR_NEW_BODY(mangled_name, nothrow) \
32353944Sdim  if (in_symbolizer()) \
33353944Sdim    return InternalAlloc(size); \
34353944Sdim  void *p = 0; \
35353944Sdim  {  \
36353944Sdim    SCOPED_INTERCEPTOR_RAW(mangled_name, size); \
37353944Sdim    p = user_alloc(thr, pc, size); \
38353944Sdim    if (!nothrow && UNLIKELY(!p)) { \
39353944Sdim      GET_STACK_TRACE_FATAL(thr, pc); \
40353944Sdim      ReportOutOfMemory(size, &stack); \
41353944Sdim    } \
42353944Sdim  }  \
43353944Sdim  invoke_malloc_hook(p, size);  \
44353944Sdim  return p;
45353944Sdim
46353944Sdim#define OPERATOR_NEW_BODY_ALIGN(mangled_name, nothrow) \
47353944Sdim  if (in_symbolizer()) \
48353944Sdim    return InternalAlloc(size, nullptr, (uptr)align); \
49353944Sdim  void *p = 0; \
50353944Sdim  {  \
51353944Sdim    SCOPED_INTERCEPTOR_RAW(mangled_name, size); \
52353944Sdim    p = user_memalign(thr, pc, (uptr)align, size); \
53353944Sdim    if (!nothrow && UNLIKELY(!p)) { \
54353944Sdim      GET_STACK_TRACE_FATAL(thr, pc); \
55353944Sdim      ReportOutOfMemory(size, &stack); \
56353944Sdim    } \
57353944Sdim  }  \
58353944Sdim  invoke_malloc_hook(p, size);  \
59353944Sdim  return p;
60353944Sdim
61353944SdimSANITIZER_INTERFACE_ATTRIBUTE
62353944Sdimvoid *operator new(__sanitizer::uptr size);
63353944Sdimvoid *operator new(__sanitizer::uptr size) {
64353944Sdim  OPERATOR_NEW_BODY(_Znwm, false /*nothrow*/);
65353944Sdim}
66353944Sdim
67353944SdimSANITIZER_INTERFACE_ATTRIBUTE
68353944Sdimvoid *operator new[](__sanitizer::uptr size);
69353944Sdimvoid *operator new[](__sanitizer::uptr size) {
70353944Sdim  OPERATOR_NEW_BODY(_Znam, false /*nothrow*/);
71353944Sdim}
72353944Sdim
73353944SdimSANITIZER_INTERFACE_ATTRIBUTE
74353944Sdimvoid *operator new(__sanitizer::uptr size, std::nothrow_t const&);
75353944Sdimvoid *operator new(__sanitizer::uptr size, std::nothrow_t const&) {
76353944Sdim  OPERATOR_NEW_BODY(_ZnwmRKSt9nothrow_t, true /*nothrow*/);
77353944Sdim}
78353944Sdim
79353944SdimSANITIZER_INTERFACE_ATTRIBUTE
80353944Sdimvoid *operator new[](__sanitizer::uptr size, std::nothrow_t const&);
81353944Sdimvoid *operator new[](__sanitizer::uptr size, std::nothrow_t const&) {
82353944Sdim  OPERATOR_NEW_BODY(_ZnamRKSt9nothrow_t, true /*nothrow*/);
83353944Sdim}
84353944Sdim
85353944SdimSANITIZER_INTERFACE_ATTRIBUTE
86353944Sdimvoid *operator new(__sanitizer::uptr size, std::align_val_t align);
87353944Sdimvoid *operator new(__sanitizer::uptr size, std::align_val_t align) {
88353944Sdim  OPERATOR_NEW_BODY_ALIGN(_ZnwmSt11align_val_t, false /*nothrow*/);
89353944Sdim}
90353944Sdim
91353944SdimSANITIZER_INTERFACE_ATTRIBUTE
92353944Sdimvoid *operator new[](__sanitizer::uptr size, std::align_val_t align);
93353944Sdimvoid *operator new[](__sanitizer::uptr size, std::align_val_t align) {
94353944Sdim  OPERATOR_NEW_BODY_ALIGN(_ZnamSt11align_val_t, false /*nothrow*/);
95353944Sdim}
96353944Sdim
97353944SdimSANITIZER_INTERFACE_ATTRIBUTE
98353944Sdimvoid *operator new(__sanitizer::uptr size, std::align_val_t align,
99353944Sdim                   std::nothrow_t const&);
100353944Sdimvoid *operator new(__sanitizer::uptr size, std::align_val_t align,
101353944Sdim                   std::nothrow_t const&) {
102353944Sdim  OPERATOR_NEW_BODY_ALIGN(_ZnwmSt11align_val_tRKSt9nothrow_t,
103353944Sdim                          true /*nothrow*/);
104353944Sdim}
105353944Sdim
106353944SdimSANITIZER_INTERFACE_ATTRIBUTE
107353944Sdimvoid *operator new[](__sanitizer::uptr size, std::align_val_t align,
108353944Sdim                     std::nothrow_t const&);
109353944Sdimvoid *operator new[](__sanitizer::uptr size, std::align_val_t align,
110353944Sdim                     std::nothrow_t const&) {
111353944Sdim  OPERATOR_NEW_BODY_ALIGN(_ZnamSt11align_val_tRKSt9nothrow_t,
112353944Sdim                          true /*nothrow*/);
113353944Sdim}
114353944Sdim
115353944Sdim#define OPERATOR_DELETE_BODY(mangled_name) \
116353944Sdim  if (ptr == 0) return;  \
117353944Sdim  if (in_symbolizer()) \
118353944Sdim    return InternalFree(ptr); \
119353944Sdim  invoke_free_hook(ptr);  \
120353944Sdim  SCOPED_INTERCEPTOR_RAW(mangled_name, ptr);  \
121353944Sdim  user_free(thr, pc, ptr);
122353944Sdim
123353944SdimSANITIZER_INTERFACE_ATTRIBUTE
124353944Sdimvoid operator delete(void *ptr) NOEXCEPT;
125353944Sdimvoid operator delete(void *ptr) NOEXCEPT {
126353944Sdim  OPERATOR_DELETE_BODY(_ZdlPv);
127353944Sdim}
128353944Sdim
129353944SdimSANITIZER_INTERFACE_ATTRIBUTE
130353944Sdimvoid operator delete[](void *ptr) NOEXCEPT;
131353944Sdimvoid operator delete[](void *ptr) NOEXCEPT {
132353944Sdim  OPERATOR_DELETE_BODY(_ZdaPv);
133353944Sdim}
134353944Sdim
135353944SdimSANITIZER_INTERFACE_ATTRIBUTE
136353944Sdimvoid operator delete(void *ptr, std::nothrow_t const&);
137353944Sdimvoid operator delete(void *ptr, std::nothrow_t const&) {
138353944Sdim  OPERATOR_DELETE_BODY(_ZdlPvRKSt9nothrow_t);
139353944Sdim}
140353944Sdim
141353944SdimSANITIZER_INTERFACE_ATTRIBUTE
142353944Sdimvoid operator delete[](void *ptr, std::nothrow_t const&);
143353944Sdimvoid operator delete[](void *ptr, std::nothrow_t const&) {
144353944Sdim  OPERATOR_DELETE_BODY(_ZdaPvRKSt9nothrow_t);
145353944Sdim}
146353944Sdim
147353944SdimSANITIZER_INTERFACE_ATTRIBUTE
148353944Sdimvoid operator delete(void *ptr, __sanitizer::uptr size) NOEXCEPT;
149353944Sdimvoid operator delete(void *ptr, __sanitizer::uptr size) NOEXCEPT {
150353944Sdim  OPERATOR_DELETE_BODY(_ZdlPvm);
151353944Sdim}
152353944Sdim
153353944SdimSANITIZER_INTERFACE_ATTRIBUTE
154353944Sdimvoid operator delete[](void *ptr, __sanitizer::uptr size) NOEXCEPT;
155353944Sdimvoid operator delete[](void *ptr, __sanitizer::uptr size) NOEXCEPT {
156353944Sdim  OPERATOR_DELETE_BODY(_ZdaPvm);
157353944Sdim}
158353944Sdim
159353944SdimSANITIZER_INTERFACE_ATTRIBUTE
160353944Sdimvoid operator delete(void *ptr, std::align_val_t align) NOEXCEPT;
161353944Sdimvoid operator delete(void *ptr, std::align_val_t align) NOEXCEPT {
162353944Sdim  OPERATOR_DELETE_BODY(_ZdlPvSt11align_val_t);
163353944Sdim}
164353944Sdim
165353944SdimSANITIZER_INTERFACE_ATTRIBUTE
166353944Sdimvoid operator delete[](void *ptr, std::align_val_t align) NOEXCEPT;
167353944Sdimvoid operator delete[](void *ptr, std::align_val_t align) NOEXCEPT {
168353944Sdim  OPERATOR_DELETE_BODY(_ZdaPvSt11align_val_t);
169353944Sdim}
170353944Sdim
171353944SdimSANITIZER_INTERFACE_ATTRIBUTE
172353944Sdimvoid operator delete(void *ptr, std::align_val_t align, std::nothrow_t const&);
173353944Sdimvoid operator delete(void *ptr, std::align_val_t align, std::nothrow_t const&) {
174353944Sdim  OPERATOR_DELETE_BODY(_ZdlPvSt11align_val_tRKSt9nothrow_t);
175353944Sdim}
176353944Sdim
177353944SdimSANITIZER_INTERFACE_ATTRIBUTE
178353944Sdimvoid operator delete[](void *ptr, std::align_val_t align,
179353944Sdim                       std::nothrow_t const&);
180353944Sdimvoid operator delete[](void *ptr, std::align_val_t align,
181353944Sdim                       std::nothrow_t const&) {
182353944Sdim  OPERATOR_DELETE_BODY(_ZdaPvSt11align_val_tRKSt9nothrow_t);
183353944Sdim}
184353944Sdim
185353944SdimSANITIZER_INTERFACE_ATTRIBUTE
186353944Sdimvoid operator delete(void *ptr, __sanitizer::uptr size,
187353944Sdim                     std::align_val_t align) NOEXCEPT;
188353944Sdimvoid operator delete(void *ptr, __sanitizer::uptr size,
189353944Sdim                     std::align_val_t align) NOEXCEPT {
190353944Sdim  OPERATOR_DELETE_BODY(_ZdlPvmSt11align_val_t);
191353944Sdim}
192353944Sdim
193353944SdimSANITIZER_INTERFACE_ATTRIBUTE
194353944Sdimvoid operator delete[](void *ptr, __sanitizer::uptr size,
195353944Sdim                       std::align_val_t align) NOEXCEPT;
196353944Sdimvoid operator delete[](void *ptr, __sanitizer::uptr size,
197353944Sdim                       std::align_val_t align) NOEXCEPT {
198353944Sdim  OPERATOR_DELETE_BODY(_ZdaPvmSt11align_val_t);
199353944Sdim}
200