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