-
Notifications
You must be signed in to change notification settings - Fork 81
/
new.cpp
161 lines (146 loc) · 4.44 KB
/
new.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
// Copyright 2016 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <new>
// Placement new operators are inlined in the <new> header.
// No linkage definitions are required.
#include <stdlib.h>
#include <zircon/assert.h>
// In ASan builds, the ASan runtime supplies the operator new/delete functions.
// Those versions check for mismatches between allocation entry path and
// deallocation entry path, so we don't want to override them. Also, in
// certain complex static linking situations, it's difficult to avoid sometimes
// getting the definition of one from this library and another from libc++.
#if !__has_feature(address_sanitizer)
#if !_KERNEL
// The kernel does not want non-AllocCheckered non-placement new
// overloads, but userspace can have them.
void* operator new(size_t s) {
if (s == 0u) {
s = 1u;
}
auto mem = ::malloc(s);
if (!mem) {
ZX_PANIC("Out of memory (new)\n");
}
return mem;
}
void* operator new(size_t s, std::align_val_t align) {
if (s == 0u) {
s = 1u;
}
auto mem = aligned_alloc(static_cast<size_t>(align), s);
if (!mem) {
ZX_PANIC("Out of memory (new)\n");
}
return mem;
}
void* operator new[](size_t s) {
if (s == 0u) {
s = 1u;
}
auto mem = ::malloc(s);
if (!mem) {
ZX_PANIC("Out of memory (new[])\n");
}
return mem;
}
void* operator new[](size_t s, std::align_val_t align) {
if (s == 0u) {
s = 1u;
}
auto mem = aligned_alloc(static_cast<size_t>(align), s);
if (!mem) {
ZX_PANIC("Out of memory (new[])\n");
}
return mem;
}
void* operator new(size_t s, const std::nothrow_t&) noexcept {
if (s == 0u) {
s = 1u;
}
return ::malloc(s);
}
void* operator new(size_t s, std::align_val_t align, const std::nothrow_t&) noexcept {
if (s == 0u) {
s = 1u;
}
return aligned_alloc(static_cast<size_t>(align), s);
}
void* operator new[](size_t s, const std::nothrow_t&) noexcept {
if (s == 0u) {
s = 1u;
}
return ::malloc(s);
}
void* operator new[](size_t s, std::align_val_t align, const std::nothrow_t&) noexcept {
if (s == 0u) {
s = 1u;
}
return aligned_alloc(static_cast<size_t>(align), s);
}
#else // _KERNEL
// kernel versions may pass through the call site to the underlying allocator
void* operator new(size_t s, void* caller, const std::nothrow_t&) noexcept {
if (s == 0u) {
s = 1u;
}
return ::malloc_debug_caller(s, caller);
}
void* operator new(size_t s, std::align_val_t align, void* caller, const std::nothrow_t&) noexcept {
if (s == 0u) {
s = 1u;
}
return ::memalign_debug_caller(s, static_cast<size_t>(align), caller);
}
void* operator new[](size_t s, void* caller, const std::nothrow_t&) noexcept {
if (s == 0u) {
s = 1u;
}
return ::malloc_debug_caller(s, caller);
}
void* operator new[](size_t s, std::align_val_t align, void* caller, const std::nothrow_t&) noexcept {
if (s == 0u) {
s = 1u;
}
return ::memalign_debug_caller(s, static_cast<size_t>(align), caller);
}
#endif // _KERNEL
void operator delete(void* p) {
return ::free(p);
}
void operator delete[](void* p) {
return ::free(p);
}
void operator delete(void* p, size_t s) {
return ::free(p);
}
void operator delete[](void* p, size_t s) {
return ::free(p);
}
void operator delete(void* p, std::align_val_t align) {
return ::free(p);
}
void operator delete(void* p, std::size_t s, std::align_val_t align) {
return ::free(p);
}
#endif // !__has_feature(address_sanitizer)
// These are the mangled names of all the functions above. Because these
// functions are magical in the language, the compiler insists on making
// default-visibility definitions regardless of all the ways to tell it to use
// hidden visibility. So there is nothing left but to go around the compiler's
// back and force them to .hidden via assembler directives. These declarations
// have no effect and do no harm when not all of these functions are defined
// here (kernel, ASan).
asm(".hidden _ZdaPv");
asm(".hidden _ZdaPvm");
asm(".hidden _ZdlPv");
asm(".hidden _ZdlPvm");
asm(".hidden _ZdlPvSt11align_val_t");
asm(".hidden _ZdlPvmSt11align_val_t");
asm(".hidden _Znam");
asm(".hidden _ZnamPv");
asm(".hidden _ZnamRKSt9nothrow_t");
asm(".hidden _Znwm");
asm(".hidden _ZnwmPv");
asm(".hidden _ZnwmRKSt9nothrow_t");