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