1*67226badSAlexandre Ganea //===------------------------ malloc.c ------------------*- C -*-=============//
2*67226badSAlexandre Ganea //
3*67226badSAlexandre Ganea // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*67226badSAlexandre Ganea // See https://llvm.org/LICENSE.txt for license information.
5*67226badSAlexandre Ganea // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*67226badSAlexandre Ganea //
7*67226badSAlexandre Ganea //===----------------------------------------------------------------------===//
8*67226badSAlexandre Ganea //
9*67226badSAlexandre Ganea // This library provides a cross-platform lock free thread caching malloc
10*67226badSAlexandre Ganea // implementation in C11.
11*67226badSAlexandre Ganea //
12*67226badSAlexandre Ganea //
13*67226badSAlexandre Ganea // This file provides overrides for the standard library malloc entry points for
14*67226badSAlexandre Ganea // C and new/delete operators for C++ It also provides automatic
15*67226badSAlexandre Ganea // initialization/finalization of process and threads
16*67226badSAlexandre Ganea //
17*67226badSAlexandre Ganea //===----------------------------------------------------------------------===//
18*67226badSAlexandre Ganea
19*67226badSAlexandre Ganea #if defined(__TINYC__)
20*67226badSAlexandre Ganea #include <sys/types.h>
21*67226badSAlexandre Ganea #endif
22*67226badSAlexandre Ganea
23*67226badSAlexandre Ganea #ifndef ARCH_64BIT
24*67226badSAlexandre Ganea #if defined(__LLP64__) || defined(__LP64__) || defined(_WIN64)
25*67226badSAlexandre Ganea #define ARCH_64BIT 1
26*67226badSAlexandre Ganea _Static_assert(sizeof(size_t) == 8, "Data type size mismatch");
27*67226badSAlexandre Ganea _Static_assert(sizeof(void *) == 8, "Data type size mismatch");
28*67226badSAlexandre Ganea #else
29*67226badSAlexandre Ganea #define ARCH_64BIT 0
30*67226badSAlexandre Ganea _Static_assert(sizeof(size_t) == 4, "Data type size mismatch");
31*67226badSAlexandre Ganea _Static_assert(sizeof(void *) == 4, "Data type size mismatch");
32*67226badSAlexandre Ganea #endif
33*67226badSAlexandre Ganea #endif
34*67226badSAlexandre Ganea
35*67226badSAlexandre Ganea #if (defined(__GNUC__) || defined(__clang__))
36*67226badSAlexandre Ganea #pragma GCC visibility push(default)
37*67226badSAlexandre Ganea #endif
38*67226badSAlexandre Ganea
39*67226badSAlexandre Ganea #define USE_IMPLEMENT 1
40*67226badSAlexandre Ganea #define USE_INTERPOSE 0
41*67226badSAlexandre Ganea #define USE_ALIAS 0
42*67226badSAlexandre Ganea
43*67226badSAlexandre Ganea #if defined(__APPLE__)
44*67226badSAlexandre Ganea #undef USE_INTERPOSE
45*67226badSAlexandre Ganea #define USE_INTERPOSE 1
46*67226badSAlexandre Ganea
47*67226badSAlexandre Ganea typedef struct interpose_t {
48*67226badSAlexandre Ganea void *new_func;
49*67226badSAlexandre Ganea void *orig_func;
50*67226badSAlexandre Ganea } interpose_t;
51*67226badSAlexandre Ganea
52*67226badSAlexandre Ganea #define MAC_INTERPOSE_PAIR(newf, oldf) {(void *)newf, (void *)oldf}
53*67226badSAlexandre Ganea #define MAC_INTERPOSE_SINGLE(newf, oldf) \
54*67226badSAlexandre Ganea __attribute__((used)) static const interpose_t macinterpose##newf##oldf \
55*67226badSAlexandre Ganea __attribute__((section("__DATA, __interpose"))) = \
56*67226badSAlexandre Ganea MAC_INTERPOSE_PAIR(newf, oldf)
57*67226badSAlexandre Ganea
58*67226badSAlexandre Ganea #endif
59*67226badSAlexandre Ganea
60*67226badSAlexandre Ganea #if !defined(_WIN32) && !defined(__APPLE__)
61*67226badSAlexandre Ganea #undef USE_IMPLEMENT
62*67226badSAlexandre Ganea #undef USE_ALIAS
63*67226badSAlexandre Ganea #define USE_IMPLEMENT 0
64*67226badSAlexandre Ganea #define USE_ALIAS 1
65*67226badSAlexandre Ganea #endif
66*67226badSAlexandre Ganea
67*67226badSAlexandre Ganea #ifdef _MSC_VER
68*67226badSAlexandre Ganea #pragma warning(disable : 4100)
69*67226badSAlexandre Ganea #undef malloc
70*67226badSAlexandre Ganea #undef free
71*67226badSAlexandre Ganea #undef calloc
72*67226badSAlexandre Ganea #define RPMALLOC_RESTRICT __declspec(restrict)
73*67226badSAlexandre Ganea #else
74*67226badSAlexandre Ganea #define RPMALLOC_RESTRICT
75*67226badSAlexandre Ganea #endif
76*67226badSAlexandre Ganea
77*67226badSAlexandre Ganea #if ENABLE_OVERRIDE
78*67226badSAlexandre Ganea
79*67226badSAlexandre Ganea typedef struct rp_nothrow_t {
80*67226badSAlexandre Ganea int __dummy;
81*67226badSAlexandre Ganea } rp_nothrow_t;
82*67226badSAlexandre Ganea
83*67226badSAlexandre Ganea #if USE_IMPLEMENT
84*67226badSAlexandre Ganea
malloc(size_t size)85*67226badSAlexandre Ganea extern inline RPMALLOC_RESTRICT void *RPMALLOC_CDECL malloc(size_t size) {
86*67226badSAlexandre Ganea return rpmalloc(size);
87*67226badSAlexandre Ganea }
calloc(size_t count,size_t size)88*67226badSAlexandre Ganea extern inline RPMALLOC_RESTRICT void *RPMALLOC_CDECL calloc(size_t count,
89*67226badSAlexandre Ganea size_t size) {
90*67226badSAlexandre Ganea return rpcalloc(count, size);
91*67226badSAlexandre Ganea }
realloc(void * ptr,size_t size)92*67226badSAlexandre Ganea extern inline RPMALLOC_RESTRICT void *RPMALLOC_CDECL realloc(void *ptr,
93*67226badSAlexandre Ganea size_t size) {
94*67226badSAlexandre Ganea return rprealloc(ptr, size);
95*67226badSAlexandre Ganea }
reallocf(void * ptr,size_t size)96*67226badSAlexandre Ganea extern inline void *RPMALLOC_CDECL reallocf(void *ptr, size_t size) {
97*67226badSAlexandre Ganea return rprealloc(ptr, size);
98*67226badSAlexandre Ganea }
aligned_alloc(size_t alignment,size_t size)99*67226badSAlexandre Ganea extern inline void *RPMALLOC_CDECL aligned_alloc(size_t alignment,
100*67226badSAlexandre Ganea size_t size) {
101*67226badSAlexandre Ganea return rpaligned_alloc(alignment, size);
102*67226badSAlexandre Ganea }
memalign(size_t alignment,size_t size)103*67226badSAlexandre Ganea extern inline void *RPMALLOC_CDECL memalign(size_t alignment, size_t size) {
104*67226badSAlexandre Ganea return rpmemalign(alignment, size);
105*67226badSAlexandre Ganea }
posix_memalign(void ** memptr,size_t alignment,size_t size)106*67226badSAlexandre Ganea extern inline int RPMALLOC_CDECL posix_memalign(void **memptr, size_t alignment,
107*67226badSAlexandre Ganea size_t size) {
108*67226badSAlexandre Ganea return rpposix_memalign(memptr, alignment, size);
109*67226badSAlexandre Ganea }
free(void * ptr)110*67226badSAlexandre Ganea extern inline void RPMALLOC_CDECL free(void *ptr) { rpfree(ptr); }
cfree(void * ptr)111*67226badSAlexandre Ganea extern inline void RPMALLOC_CDECL cfree(void *ptr) { rpfree(ptr); }
malloc_usable_size(void * ptr)112*67226badSAlexandre Ganea extern inline size_t RPMALLOC_CDECL malloc_usable_size(void *ptr) {
113*67226badSAlexandre Ganea return rpmalloc_usable_size(ptr);
114*67226badSAlexandre Ganea }
malloc_size(void * ptr)115*67226badSAlexandre Ganea extern inline size_t RPMALLOC_CDECL malloc_size(void *ptr) {
116*67226badSAlexandre Ganea return rpmalloc_usable_size(ptr);
117*67226badSAlexandre Ganea }
118*67226badSAlexandre Ganea
119*67226badSAlexandre Ganea #ifdef _WIN32
_malloc_base(size_t size)120*67226badSAlexandre Ganea extern inline RPMALLOC_RESTRICT void *RPMALLOC_CDECL _malloc_base(size_t size) {
121*67226badSAlexandre Ganea return rpmalloc(size);
122*67226badSAlexandre Ganea }
_free_base(void * ptr)123*67226badSAlexandre Ganea extern inline void RPMALLOC_CDECL _free_base(void *ptr) { rpfree(ptr); }
_calloc_base(size_t count,size_t size)124*67226badSAlexandre Ganea extern inline RPMALLOC_RESTRICT void *RPMALLOC_CDECL _calloc_base(size_t count,
125*67226badSAlexandre Ganea size_t size) {
126*67226badSAlexandre Ganea return rpcalloc(count, size);
127*67226badSAlexandre Ganea }
_msize(void * ptr)128*67226badSAlexandre Ganea extern inline size_t RPMALLOC_CDECL _msize(void *ptr) {
129*67226badSAlexandre Ganea return rpmalloc_usable_size(ptr);
130*67226badSAlexandre Ganea }
_msize_base(void * ptr)131*67226badSAlexandre Ganea extern inline size_t RPMALLOC_CDECL _msize_base(void *ptr) {
132*67226badSAlexandre Ganea return rpmalloc_usable_size(ptr);
133*67226badSAlexandre Ganea }
134*67226badSAlexandre Ganea extern inline RPMALLOC_RESTRICT void *RPMALLOC_CDECL
_realloc_base(void * ptr,size_t size)135*67226badSAlexandre Ganea _realloc_base(void *ptr, size_t size) {
136*67226badSAlexandre Ganea return rprealloc(ptr, size);
137*67226badSAlexandre Ganea }
138*67226badSAlexandre Ganea #endif
139*67226badSAlexandre Ganea
140*67226badSAlexandre Ganea #ifdef _WIN32
141*67226badSAlexandre Ganea // For Windows, #include <rpnew.h> in one source file to get the C++ operator
142*67226badSAlexandre Ganea // overrides implemented in your module
143*67226badSAlexandre Ganea #else
144*67226badSAlexandre Ganea // Overload the C++ operators using the mangled names
145*67226badSAlexandre Ganea // (https://itanium-cxx-abi.github.io/cxx-abi/abi.html#mangling) operators
146*67226badSAlexandre Ganea // delete and delete[]
147*67226badSAlexandre Ganea #define RPDEFVIS __attribute__((visibility("default")))
148*67226badSAlexandre Ganea extern void _ZdlPv(void *p);
_ZdlPv(void * p)149*67226badSAlexandre Ganea void RPDEFVIS _ZdlPv(void *p) { rpfree(p); }
150*67226badSAlexandre Ganea extern void _ZdaPv(void *p);
_ZdaPv(void * p)151*67226badSAlexandre Ganea void RPDEFVIS _ZdaPv(void *p) { rpfree(p); }
152*67226badSAlexandre Ganea #if ARCH_64BIT
153*67226badSAlexandre Ganea // 64-bit operators new and new[], normal and aligned
154*67226badSAlexandre Ganea extern void *_Znwm(uint64_t size);
_Znwm(uint64_t size)155*67226badSAlexandre Ganea void *RPDEFVIS _Znwm(uint64_t size) { return rpmalloc(size); }
156*67226badSAlexandre Ganea extern void *_Znam(uint64_t size);
_Znam(uint64_t size)157*67226badSAlexandre Ganea void *RPDEFVIS _Znam(uint64_t size) { return rpmalloc(size); }
158*67226badSAlexandre Ganea extern void *_Znwmm(uint64_t size, uint64_t align);
_Znwmm(uint64_t size,uint64_t align)159*67226badSAlexandre Ganea void *RPDEFVIS _Znwmm(uint64_t size, uint64_t align) {
160*67226badSAlexandre Ganea return rpaligned_alloc(align, size);
161*67226badSAlexandre Ganea }
162*67226badSAlexandre Ganea extern void *_Znamm(uint64_t size, uint64_t align);
_Znamm(uint64_t size,uint64_t align)163*67226badSAlexandre Ganea void *RPDEFVIS _Znamm(uint64_t size, uint64_t align) {
164*67226badSAlexandre Ganea return rpaligned_alloc(align, size);
165*67226badSAlexandre Ganea }
166*67226badSAlexandre Ganea extern void *_ZnwmSt11align_val_t(uint64_t size, uint64_t align);
_ZnwmSt11align_val_t(uint64_t size,uint64_t align)167*67226badSAlexandre Ganea void *RPDEFVIS _ZnwmSt11align_val_t(uint64_t size, uint64_t align) {
168*67226badSAlexandre Ganea return rpaligned_alloc(align, size);
169*67226badSAlexandre Ganea }
170*67226badSAlexandre Ganea extern void *_ZnamSt11align_val_t(uint64_t size, uint64_t align);
_ZnamSt11align_val_t(uint64_t size,uint64_t align)171*67226badSAlexandre Ganea void *RPDEFVIS _ZnamSt11align_val_t(uint64_t size, uint64_t align) {
172*67226badSAlexandre Ganea return rpaligned_alloc(align, size);
173*67226badSAlexandre Ganea }
174*67226badSAlexandre Ganea extern void *_ZnwmRKSt9nothrow_t(uint64_t size, rp_nothrow_t t);
_ZnwmRKSt9nothrow_t(uint64_t size,rp_nothrow_t t)175*67226badSAlexandre Ganea void *RPDEFVIS _ZnwmRKSt9nothrow_t(uint64_t size, rp_nothrow_t t) {
176*67226badSAlexandre Ganea (void)sizeof(t);
177*67226badSAlexandre Ganea return rpmalloc(size);
178*67226badSAlexandre Ganea }
179*67226badSAlexandre Ganea extern void *_ZnamRKSt9nothrow_t(uint64_t size, rp_nothrow_t t);
_ZnamRKSt9nothrow_t(uint64_t size,rp_nothrow_t t)180*67226badSAlexandre Ganea void *RPDEFVIS _ZnamRKSt9nothrow_t(uint64_t size, rp_nothrow_t t) {
181*67226badSAlexandre Ganea (void)sizeof(t);
182*67226badSAlexandre Ganea return rpmalloc(size);
183*67226badSAlexandre Ganea }
184*67226badSAlexandre Ganea extern void *_ZnwmSt11align_val_tRKSt9nothrow_t(uint64_t size, uint64_t align,
185*67226badSAlexandre Ganea rp_nothrow_t t);
_ZnwmSt11align_val_tRKSt9nothrow_t(uint64_t size,uint64_t align,rp_nothrow_t t)186*67226badSAlexandre Ganea void *RPDEFVIS _ZnwmSt11align_val_tRKSt9nothrow_t(uint64_t size, uint64_t align,
187*67226badSAlexandre Ganea rp_nothrow_t t) {
188*67226badSAlexandre Ganea (void)sizeof(t);
189*67226badSAlexandre Ganea return rpaligned_alloc(align, size);
190*67226badSAlexandre Ganea }
191*67226badSAlexandre Ganea extern void *_ZnamSt11align_val_tRKSt9nothrow_t(uint64_t size, uint64_t align,
192*67226badSAlexandre Ganea rp_nothrow_t t);
_ZnamSt11align_val_tRKSt9nothrow_t(uint64_t size,uint64_t align,rp_nothrow_t t)193*67226badSAlexandre Ganea void *RPDEFVIS _ZnamSt11align_val_tRKSt9nothrow_t(uint64_t size, uint64_t align,
194*67226badSAlexandre Ganea rp_nothrow_t t) {
195*67226badSAlexandre Ganea (void)sizeof(t);
196*67226badSAlexandre Ganea return rpaligned_alloc(align, size);
197*67226badSAlexandre Ganea }
198*67226badSAlexandre Ganea // 64-bit operators sized delete and delete[], normal and aligned
199*67226badSAlexandre Ganea extern void _ZdlPvm(void *p, uint64_t size);
_ZdlPvm(void * p,uint64_t size)200*67226badSAlexandre Ganea void RPDEFVIS _ZdlPvm(void *p, uint64_t size) {
201*67226badSAlexandre Ganea rpfree(p);
202*67226badSAlexandre Ganea (void)sizeof(size);
203*67226badSAlexandre Ganea }
204*67226badSAlexandre Ganea extern void _ZdaPvm(void *p, uint64_t size);
_ZdaPvm(void * p,uint64_t size)205*67226badSAlexandre Ganea void RPDEFVIS _ZdaPvm(void *p, uint64_t size) {
206*67226badSAlexandre Ganea rpfree(p);
207*67226badSAlexandre Ganea (void)sizeof(size);
208*67226badSAlexandre Ganea }
209*67226badSAlexandre Ganea extern void _ZdlPvSt11align_val_t(void *p, uint64_t align);
_ZdlPvSt11align_val_t(void * p,uint64_t align)210*67226badSAlexandre Ganea void RPDEFVIS _ZdlPvSt11align_val_t(void *p, uint64_t align) {
211*67226badSAlexandre Ganea rpfree(p);
212*67226badSAlexandre Ganea (void)sizeof(align);
213*67226badSAlexandre Ganea }
214*67226badSAlexandre Ganea extern void _ZdaPvSt11align_val_t(void *p, uint64_t align);
_ZdaPvSt11align_val_t(void * p,uint64_t align)215*67226badSAlexandre Ganea void RPDEFVIS _ZdaPvSt11align_val_t(void *p, uint64_t align) {
216*67226badSAlexandre Ganea rpfree(p);
217*67226badSAlexandre Ganea (void)sizeof(align);
218*67226badSAlexandre Ganea }
219*67226badSAlexandre Ganea extern void _ZdlPvmSt11align_val_t(void *p, uint64_t size, uint64_t align);
_ZdlPvmSt11align_val_t(void * p,uint64_t size,uint64_t align)220*67226badSAlexandre Ganea void RPDEFVIS _ZdlPvmSt11align_val_t(void *p, uint64_t size, uint64_t align) {
221*67226badSAlexandre Ganea rpfree(p);
222*67226badSAlexandre Ganea (void)sizeof(size);
223*67226badSAlexandre Ganea (void)sizeof(align);
224*67226badSAlexandre Ganea }
225*67226badSAlexandre Ganea extern void _ZdaPvmSt11align_val_t(void *p, uint64_t size, uint64_t align);
_ZdaPvmSt11align_val_t(void * p,uint64_t size,uint64_t align)226*67226badSAlexandre Ganea void RPDEFVIS _ZdaPvmSt11align_val_t(void *p, uint64_t size, uint64_t align) {
227*67226badSAlexandre Ganea rpfree(p);
228*67226badSAlexandre Ganea (void)sizeof(size);
229*67226badSAlexandre Ganea (void)sizeof(align);
230*67226badSAlexandre Ganea }
231*67226badSAlexandre Ganea #else
232*67226badSAlexandre Ganea // 32-bit operators new and new[], normal and aligned
233*67226badSAlexandre Ganea extern void *_Znwj(uint32_t size);
_Znwj(uint32_t size)234*67226badSAlexandre Ganea void *RPDEFVIS _Znwj(uint32_t size) { return rpmalloc(size); }
235*67226badSAlexandre Ganea extern void *_Znaj(uint32_t size);
_Znaj(uint32_t size)236*67226badSAlexandre Ganea void *RPDEFVIS _Znaj(uint32_t size) { return rpmalloc(size); }
237*67226badSAlexandre Ganea extern void *_Znwjj(uint32_t size, uint32_t align);
_Znwjj(uint32_t size,uint32_t align)238*67226badSAlexandre Ganea void *RPDEFVIS _Znwjj(uint32_t size, uint32_t align) {
239*67226badSAlexandre Ganea return rpaligned_alloc(align, size);
240*67226badSAlexandre Ganea }
241*67226badSAlexandre Ganea extern void *_Znajj(uint32_t size, uint32_t align);
_Znajj(uint32_t size,uint32_t align)242*67226badSAlexandre Ganea void *RPDEFVIS _Znajj(uint32_t size, uint32_t align) {
243*67226badSAlexandre Ganea return rpaligned_alloc(align, size);
244*67226badSAlexandre Ganea }
245*67226badSAlexandre Ganea extern void *_ZnwjSt11align_val_t(size_t size, size_t align);
_ZnwjSt11align_val_t(size_t size,size_t align)246*67226badSAlexandre Ganea void *RPDEFVIS _ZnwjSt11align_val_t(size_t size, size_t align) {
247*67226badSAlexandre Ganea return rpaligned_alloc(align, size);
248*67226badSAlexandre Ganea }
249*67226badSAlexandre Ganea extern void *_ZnajSt11align_val_t(size_t size, size_t align);
_ZnajSt11align_val_t(size_t size,size_t align)250*67226badSAlexandre Ganea void *RPDEFVIS _ZnajSt11align_val_t(size_t size, size_t align) {
251*67226badSAlexandre Ganea return rpaligned_alloc(align, size);
252*67226badSAlexandre Ganea }
253*67226badSAlexandre Ganea extern void *_ZnwjRKSt9nothrow_t(size_t size, rp_nothrow_t t);
_ZnwjRKSt9nothrow_t(size_t size,rp_nothrow_t t)254*67226badSAlexandre Ganea void *RPDEFVIS _ZnwjRKSt9nothrow_t(size_t size, rp_nothrow_t t) {
255*67226badSAlexandre Ganea (void)sizeof(t);
256*67226badSAlexandre Ganea return rpmalloc(size);
257*67226badSAlexandre Ganea }
258*67226badSAlexandre Ganea extern void *_ZnajRKSt9nothrow_t(size_t size, rp_nothrow_t t);
_ZnajRKSt9nothrow_t(size_t size,rp_nothrow_t t)259*67226badSAlexandre Ganea void *RPDEFVIS _ZnajRKSt9nothrow_t(size_t size, rp_nothrow_t t) {
260*67226badSAlexandre Ganea (void)sizeof(t);
261*67226badSAlexandre Ganea return rpmalloc(size);
262*67226badSAlexandre Ganea }
263*67226badSAlexandre Ganea extern void *_ZnwjSt11align_val_tRKSt9nothrow_t(size_t size, size_t align,
264*67226badSAlexandre Ganea rp_nothrow_t t);
_ZnwjSt11align_val_tRKSt9nothrow_t(size_t size,size_t align,rp_nothrow_t t)265*67226badSAlexandre Ganea void *RPDEFVIS _ZnwjSt11align_val_tRKSt9nothrow_t(size_t size, size_t align,
266*67226badSAlexandre Ganea rp_nothrow_t t) {
267*67226badSAlexandre Ganea (void)sizeof(t);
268*67226badSAlexandre Ganea return rpaligned_alloc(align, size);
269*67226badSAlexandre Ganea }
270*67226badSAlexandre Ganea extern void *_ZnajSt11align_val_tRKSt9nothrow_t(size_t size, size_t align,
271*67226badSAlexandre Ganea rp_nothrow_t t);
_ZnajSt11align_val_tRKSt9nothrow_t(size_t size,size_t align,rp_nothrow_t t)272*67226badSAlexandre Ganea void *RPDEFVIS _ZnajSt11align_val_tRKSt9nothrow_t(size_t size, size_t align,
273*67226badSAlexandre Ganea rp_nothrow_t t) {
274*67226badSAlexandre Ganea (void)sizeof(t);
275*67226badSAlexandre Ganea return rpaligned_alloc(align, size);
276*67226badSAlexandre Ganea }
277*67226badSAlexandre Ganea // 32-bit operators sized delete and delete[], normal and aligned
278*67226badSAlexandre Ganea extern void _ZdlPvj(void *p, uint64_t size);
_ZdlPvj(void * p,uint64_t size)279*67226badSAlexandre Ganea void RPDEFVIS _ZdlPvj(void *p, uint64_t size) {
280*67226badSAlexandre Ganea rpfree(p);
281*67226badSAlexandre Ganea (void)sizeof(size);
282*67226badSAlexandre Ganea }
283*67226badSAlexandre Ganea extern void _ZdaPvj(void *p, uint64_t size);
_ZdaPvj(void * p,uint64_t size)284*67226badSAlexandre Ganea void RPDEFVIS _ZdaPvj(void *p, uint64_t size) {
285*67226badSAlexandre Ganea rpfree(p);
286*67226badSAlexandre Ganea (void)sizeof(size);
287*67226badSAlexandre Ganea }
288*67226badSAlexandre Ganea extern void _ZdlPvSt11align_val_t(void *p, uint32_t align);
_ZdlPvSt11align_val_t(void * p,uint64_t a)289*67226badSAlexandre Ganea void RPDEFVIS _ZdlPvSt11align_val_t(void *p, uint64_t a) {
290*67226badSAlexandre Ganea rpfree(p);
291*67226badSAlexandre Ganea (void)sizeof(align);
292*67226badSAlexandre Ganea }
293*67226badSAlexandre Ganea extern void _ZdaPvSt11align_val_t(void *p, uint32_t align);
_ZdaPvSt11align_val_t(void * p,uint64_t a)294*67226badSAlexandre Ganea void RPDEFVIS _ZdaPvSt11align_val_t(void *p, uint64_t a) {
295*67226badSAlexandre Ganea rpfree(p);
296*67226badSAlexandre Ganea (void)sizeof(align);
297*67226badSAlexandre Ganea }
298*67226badSAlexandre Ganea extern void _ZdlPvjSt11align_val_t(void *p, uint32_t size, uint32_t align);
_ZdlPvjSt11align_val_t(void * p,uint64_t size,uint64_t align)299*67226badSAlexandre Ganea void RPDEFVIS _ZdlPvjSt11align_val_t(void *p, uint64_t size, uint64_t align) {
300*67226badSAlexandre Ganea rpfree(p);
301*67226badSAlexandre Ganea (void)sizeof(size);
302*67226badSAlexandre Ganea (void)sizeof(a);
303*67226badSAlexandre Ganea }
304*67226badSAlexandre Ganea extern void _ZdaPvjSt11align_val_t(void *p, uint32_t size, uint32_t align);
_ZdaPvjSt11align_val_t(void * p,uint64_t size,uint64_t align)305*67226badSAlexandre Ganea void RPDEFVIS _ZdaPvjSt11align_val_t(void *p, uint64_t size, uint64_t align) {
306*67226badSAlexandre Ganea rpfree(p);
307*67226badSAlexandre Ganea (void)sizeof(size);
308*67226badSAlexandre Ganea (void)sizeof(a);
309*67226badSAlexandre Ganea }
310*67226badSAlexandre Ganea #endif
311*67226badSAlexandre Ganea #endif
312*67226badSAlexandre Ganea #endif
313*67226badSAlexandre Ganea
314*67226badSAlexandre Ganea #if USE_INTERPOSE || USE_ALIAS
315*67226badSAlexandre Ganea
rpmalloc_nothrow(size_t size,rp_nothrow_t t)316*67226badSAlexandre Ganea static void *rpmalloc_nothrow(size_t size, rp_nothrow_t t) {
317*67226badSAlexandre Ganea (void)sizeof(t);
318*67226badSAlexandre Ganea return rpmalloc(size);
319*67226badSAlexandre Ganea }
rpaligned_alloc_reverse(size_t size,size_t align)320*67226badSAlexandre Ganea static void *rpaligned_alloc_reverse(size_t size, size_t align) {
321*67226badSAlexandre Ganea return rpaligned_alloc(align, size);
322*67226badSAlexandre Ganea }
rpaligned_alloc_reverse_nothrow(size_t size,size_t align,rp_nothrow_t t)323*67226badSAlexandre Ganea static void *rpaligned_alloc_reverse_nothrow(size_t size, size_t align,
324*67226badSAlexandre Ganea rp_nothrow_t t) {
325*67226badSAlexandre Ganea (void)sizeof(t);
326*67226badSAlexandre Ganea return rpaligned_alloc(align, size);
327*67226badSAlexandre Ganea }
rpfree_size(void * p,size_t size)328*67226badSAlexandre Ganea static void rpfree_size(void *p, size_t size) {
329*67226badSAlexandre Ganea (void)sizeof(size);
330*67226badSAlexandre Ganea rpfree(p);
331*67226badSAlexandre Ganea }
rpfree_aligned(void * p,size_t align)332*67226badSAlexandre Ganea static void rpfree_aligned(void *p, size_t align) {
333*67226badSAlexandre Ganea (void)sizeof(align);
334*67226badSAlexandre Ganea rpfree(p);
335*67226badSAlexandre Ganea }
rpfree_size_aligned(void * p,size_t size,size_t align)336*67226badSAlexandre Ganea static void rpfree_size_aligned(void *p, size_t size, size_t align) {
337*67226badSAlexandre Ganea (void)sizeof(size);
338*67226badSAlexandre Ganea (void)sizeof(align);
339*67226badSAlexandre Ganea rpfree(p);
340*67226badSAlexandre Ganea }
341*67226badSAlexandre Ganea
342*67226badSAlexandre Ganea #endif
343*67226badSAlexandre Ganea
344*67226badSAlexandre Ganea #if USE_INTERPOSE
345*67226badSAlexandre Ganea
346*67226badSAlexandre Ganea __attribute__((used)) static const interpose_t macinterpose_malloc[]
347*67226badSAlexandre Ganea __attribute__((section("__DATA, __interpose"))) = {
348*67226badSAlexandre Ganea // new and new[]
349*67226badSAlexandre Ganea MAC_INTERPOSE_PAIR(rpmalloc, _Znwm),
350*67226badSAlexandre Ganea MAC_INTERPOSE_PAIR(rpmalloc, _Znam),
351*67226badSAlexandre Ganea MAC_INTERPOSE_PAIR(rpaligned_alloc_reverse, _Znwmm),
352*67226badSAlexandre Ganea MAC_INTERPOSE_PAIR(rpaligned_alloc_reverse, _Znamm),
353*67226badSAlexandre Ganea MAC_INTERPOSE_PAIR(rpmalloc_nothrow, _ZnwmRKSt9nothrow_t),
354*67226badSAlexandre Ganea MAC_INTERPOSE_PAIR(rpmalloc_nothrow, _ZnamRKSt9nothrow_t),
355*67226badSAlexandre Ganea MAC_INTERPOSE_PAIR(rpaligned_alloc_reverse, _ZnwmSt11align_val_t),
356*67226badSAlexandre Ganea MAC_INTERPOSE_PAIR(rpaligned_alloc_reverse, _ZnamSt11align_val_t),
357*67226badSAlexandre Ganea MAC_INTERPOSE_PAIR(rpaligned_alloc_reverse_nothrow,
358*67226badSAlexandre Ganea _ZnwmSt11align_val_tRKSt9nothrow_t),
359*67226badSAlexandre Ganea MAC_INTERPOSE_PAIR(rpaligned_alloc_reverse_nothrow,
360*67226badSAlexandre Ganea _ZnamSt11align_val_tRKSt9nothrow_t),
361*67226badSAlexandre Ganea // delete and delete[]
362*67226badSAlexandre Ganea MAC_INTERPOSE_PAIR(rpfree, _ZdlPv), MAC_INTERPOSE_PAIR(rpfree, _ZdaPv),
363*67226badSAlexandre Ganea MAC_INTERPOSE_PAIR(rpfree_size, _ZdlPvm),
364*67226badSAlexandre Ganea MAC_INTERPOSE_PAIR(rpfree_size, _ZdaPvm),
365*67226badSAlexandre Ganea MAC_INTERPOSE_PAIR(rpfree_aligned, _ZdlPvSt11align_val_t),
366*67226badSAlexandre Ganea MAC_INTERPOSE_PAIR(rpfree_aligned, _ZdaPvSt11align_val_t),
367*67226badSAlexandre Ganea MAC_INTERPOSE_PAIR(rpfree_size_aligned, _ZdlPvmSt11align_val_t),
368*67226badSAlexandre Ganea MAC_INTERPOSE_PAIR(rpfree_size_aligned, _ZdaPvmSt11align_val_t),
369*67226badSAlexandre Ganea // libc entry points
370*67226badSAlexandre Ganea MAC_INTERPOSE_PAIR(rpmalloc, malloc),
371*67226badSAlexandre Ganea MAC_INTERPOSE_PAIR(rpmalloc, calloc),
372*67226badSAlexandre Ganea MAC_INTERPOSE_PAIR(rprealloc, realloc),
373*67226badSAlexandre Ganea MAC_INTERPOSE_PAIR(rprealloc, reallocf),
374*67226badSAlexandre Ganea #if defined(__MAC_10_15) && __MAC_OS_X_VERSION_MIN_REQUIRED >= __MAC_10_15
375*67226badSAlexandre Ganea MAC_INTERPOSE_PAIR(rpaligned_alloc, aligned_alloc),
376*67226badSAlexandre Ganea #endif
377*67226badSAlexandre Ganea MAC_INTERPOSE_PAIR(rpmemalign, memalign),
378*67226badSAlexandre Ganea MAC_INTERPOSE_PAIR(rpposix_memalign, posix_memalign),
379*67226badSAlexandre Ganea MAC_INTERPOSE_PAIR(rpfree, free), MAC_INTERPOSE_PAIR(rpfree, cfree),
380*67226badSAlexandre Ganea MAC_INTERPOSE_PAIR(rpmalloc_usable_size, malloc_usable_size),
381*67226badSAlexandre Ganea MAC_INTERPOSE_PAIR(rpmalloc_usable_size, malloc_size)};
382*67226badSAlexandre Ganea
383*67226badSAlexandre Ganea #endif
384*67226badSAlexandre Ganea
385*67226badSAlexandre Ganea #if USE_ALIAS
386*67226badSAlexandre Ganea
387*67226badSAlexandre Ganea #define RPALIAS(fn) __attribute__((alias(#fn), used, visibility("default")));
388*67226badSAlexandre Ganea
389*67226badSAlexandre Ganea // Alias the C++ operators using the mangled names
390*67226badSAlexandre Ganea // (https://itanium-cxx-abi.github.io/cxx-abi/abi.html#mangling)
391*67226badSAlexandre Ganea
392*67226badSAlexandre Ganea // operators delete and delete[]
_ZdlPv(void * p)393*67226badSAlexandre Ganea void _ZdlPv(void *p) RPALIAS(rpfree) void _ZdaPv(void *p) RPALIAS(rpfree)
394*67226badSAlexandre Ganea
395*67226badSAlexandre Ganea #if ARCH_64BIT
396*67226badSAlexandre Ganea // 64-bit operators new and new[], normal and aligned
397*67226badSAlexandre Ganea void *_Znwm(uint64_t size) RPMALLOC_ATTRIB_MALLOC
398*67226badSAlexandre Ganea RPMALLOC_ATTRIB_ALLOC_SIZE(1)
399*67226badSAlexandre Ganea RPALIAS(rpmalloc) void *_Znam(uint64_t size) RPMALLOC_ATTRIB_MALLOC
400*67226badSAlexandre Ganea RPMALLOC_ATTRIB_ALLOC_SIZE(1) RPALIAS(rpmalloc) void *_Znwmm(uint64_t size,
401*67226badSAlexandre Ganea uint64_t align)
402*67226badSAlexandre Ganea RPALIAS(rpaligned_alloc_reverse) void *_Znamm(uint64_t size,
403*67226badSAlexandre Ganea uint64_t align)
404*67226badSAlexandre Ganea RPALIAS(rpaligned_alloc_reverse) void *_ZnwmSt11align_val_t(
405*67226badSAlexandre Ganea size_t size, size_t align)
406*67226badSAlexandre Ganea RPALIAS(rpaligned_alloc_reverse) void *_ZnamSt11align_val_t(
407*67226badSAlexandre Ganea size_t size, size_t align)
408*67226badSAlexandre Ganea RPALIAS(rpaligned_alloc_reverse) void *_ZnwmRKSt9nothrow_t(
409*67226badSAlexandre Ganea size_t size, rp_nothrow_t t)
410*67226badSAlexandre Ganea RPALIAS(rpmalloc_nothrow) void *_ZnamRKSt9nothrow_t(
411*67226badSAlexandre Ganea size_t size,
412*67226badSAlexandre Ganea rp_nothrow_t t) RPALIAS(rpmalloc_nothrow) void
413*67226badSAlexandre Ganea *_ZnwmSt11align_val_tRKSt9nothrow_t(size_t size,
414*67226badSAlexandre Ganea size_t align,
415*67226badSAlexandre Ganea rp_nothrow_t t)
416*67226badSAlexandre Ganea RPALIAS(rpaligned_alloc_reverse_nothrow) void
417*67226badSAlexandre Ganea *_ZnamSt11align_val_tRKSt9nothrow_t(
418*67226badSAlexandre Ganea size_t size, size_t align,
419*67226badSAlexandre Ganea rp_nothrow_t t)
420*67226badSAlexandre Ganea RPALIAS(rpaligned_alloc_reverse_nothrow)
421*67226badSAlexandre Ganea // 64-bit operators delete and delete[], sized and aligned
422*67226badSAlexandre Ganea void _ZdlPvm(void *p, size_t n) RPALIAS(rpfree_size) void _ZdaPvm(void *p,
423*67226badSAlexandre Ganea size_t n)
424*67226badSAlexandre Ganea RPALIAS(rpfree_size) void _ZdlPvSt11align_val_t(void *p, size_t a)
425*67226badSAlexandre Ganea RPALIAS(rpfree_aligned) void _ZdaPvSt11align_val_t(void *p,
426*67226badSAlexandre Ganea size_t a)
427*67226badSAlexandre Ganea RPALIAS(rpfree_aligned) void _ZdlPvmSt11align_val_t(void *p,
428*67226badSAlexandre Ganea size_t n,
429*67226badSAlexandre Ganea size_t a)
430*67226badSAlexandre Ganea RPALIAS(rpfree_size_aligned) void _ZdaPvmSt11align_val_t(
431*67226badSAlexandre Ganea void *p, size_t n, size_t a)
432*67226badSAlexandre Ganea RPALIAS(rpfree_size_aligned)
433*67226badSAlexandre Ganea #else
434*67226badSAlexandre Ganea // 32-bit operators new and new[], normal and aligned
435*67226badSAlexandre Ganea void *_Znwj(uint32_t size) RPMALLOC_ATTRIB_MALLOC
436*67226badSAlexandre Ganea RPMALLOC_ATTRIB_ALLOC_SIZE(1)
437*67226badSAlexandre Ganea RPALIAS(rpmalloc) void *_Znaj(uint32_t size) RPMALLOC_ATTRIB_MALLOC
438*67226badSAlexandre Ganea RPMALLOC_ATTRIB_ALLOC_SIZE(1) RPALIAS(rpmalloc) void *_Znwjj(uint32_t size,
439*67226badSAlexandre Ganea uint32_t align)
440*67226badSAlexandre Ganea RPALIAS(rpaligned_alloc_reverse) void *_Znajj(uint32_t size,
441*67226badSAlexandre Ganea uint32_t align)
442*67226badSAlexandre Ganea RPALIAS(rpaligned_alloc_reverse) void *_ZnwjSt11align_val_t(
443*67226badSAlexandre Ganea size_t size, size_t align)
444*67226badSAlexandre Ganea RPALIAS(rpaligned_alloc_reverse) void *_ZnajSt11align_val_t(
445*67226badSAlexandre Ganea size_t size, size_t align)
446*67226badSAlexandre Ganea RPALIAS(rpaligned_alloc_reverse) void *_ZnwjRKSt9nothrow_t(
447*67226badSAlexandre Ganea size_t size, rp_nothrow_t t)
448*67226badSAlexandre Ganea RPALIAS(rpmalloc_nothrow) void *_ZnajRKSt9nothrow_t(
449*67226badSAlexandre Ganea size_t size,
450*67226badSAlexandre Ganea rp_nothrow_t t) RPALIAS(rpmalloc_nothrow) void
451*67226badSAlexandre Ganea *_ZnwjSt11align_val_tRKSt9nothrow_t(size_t size,
452*67226badSAlexandre Ganea size_t align,
453*67226badSAlexandre Ganea rp_nothrow_t t)
454*67226badSAlexandre Ganea RPALIAS(rpaligned_alloc_reverse_nothrow) void
455*67226badSAlexandre Ganea *_ZnajSt11align_val_tRKSt9nothrow_t(
456*67226badSAlexandre Ganea size_t size, size_t align,
457*67226badSAlexandre Ganea rp_nothrow_t t)
458*67226badSAlexandre Ganea RPALIAS(rpaligned_alloc_reverse_nothrow)
459*67226badSAlexandre Ganea // 32-bit operators delete and delete[], sized and aligned
460*67226badSAlexandre Ganea void _ZdlPvj(void *p, size_t n) RPALIAS(rpfree_size) void _ZdaPvj(void *p,
461*67226badSAlexandre Ganea size_t n)
462*67226badSAlexandre Ganea RPALIAS(rpfree_size) void _ZdlPvSt11align_val_t(void *p, size_t a)
463*67226badSAlexandre Ganea RPALIAS(rpfree_aligned) void _ZdaPvSt11align_val_t(void *p,
464*67226badSAlexandre Ganea size_t a)
465*67226badSAlexandre Ganea RPALIAS(rpfree_aligned) void _ZdlPvjSt11align_val_t(void *p,
466*67226badSAlexandre Ganea size_t n,
467*67226badSAlexandre Ganea size_t a)
468*67226badSAlexandre Ganea RPALIAS(rpfree_size_aligned) void _ZdaPvjSt11align_val_t(
469*67226badSAlexandre Ganea void *p, size_t n, size_t a)
470*67226badSAlexandre Ganea RPALIAS(rpfree_size_aligned)
471*67226badSAlexandre Ganea #endif
472*67226badSAlexandre Ganea
473*67226badSAlexandre Ganea void *malloc(size_t size) RPMALLOC_ATTRIB_MALLOC
474*67226badSAlexandre Ganea RPMALLOC_ATTRIB_ALLOC_SIZE(1)
475*67226badSAlexandre Ganea RPALIAS(rpmalloc) void *calloc(size_t count, size_t size)
476*67226badSAlexandre Ganea RPALIAS(rpcalloc) void *realloc(void *ptr, size_t size)
477*67226badSAlexandre Ganea RPALIAS(rprealloc) void *reallocf(void *ptr, size_t size)
478*67226badSAlexandre Ganea RPMALLOC_ATTRIB_MALLOC
479*67226badSAlexandre Ganea RPMALLOC_ATTRIB_ALLOC_SIZE(2)
480*67226badSAlexandre Ganea RPALIAS(rprealloc) void *aligned_alloc(size_t alignment, size_t size)
481*67226badSAlexandre Ganea RPALIAS(rpaligned_alloc) void *memalign(
482*67226badSAlexandre Ganea size_t alignment, size_t size) RPMALLOC_ATTRIB_MALLOC
483*67226badSAlexandre Ganea RPMALLOC_ATTRIB_ALLOC_SIZE(2)
484*67226badSAlexandre Ganea RPALIAS(rpmemalign) int posix_memalign(void **memptr, size_t alignment,
485*67226badSAlexandre Ganea size_t size)
486*67226badSAlexandre Ganea RPALIAS(rpposix_memalign) void free(void *ptr)
487*67226badSAlexandre Ganea RPALIAS(rpfree) void cfree(void *ptr) RPALIAS(rpfree)
488*67226badSAlexandre Ganea #if defined(__ANDROID__) || defined(__FreeBSD__)
489*67226badSAlexandre Ganea size_t
490*67226badSAlexandre Ganea malloc_usable_size(const void *ptr) RPALIAS(rpmalloc_usable_size)
491*67226badSAlexandre Ganea #else
492*67226badSAlexandre Ganea size_t
493*67226badSAlexandre Ganea malloc_usable_size(void *ptr) RPALIAS(rpmalloc_usable_size)
494*67226badSAlexandre Ganea #endif
495*67226badSAlexandre Ganea size_t malloc_size(void *ptr) RPALIAS(rpmalloc_usable_size)
496*67226badSAlexandre Ganea
497*67226badSAlexandre Ganea #endif
498*67226badSAlexandre Ganea
499*67226badSAlexandre Ganea static inline size_t _rpmalloc_page_size(void) {
500*67226badSAlexandre Ganea return _memory_page_size;
501*67226badSAlexandre Ganea }
502*67226badSAlexandre Ganea
503*67226badSAlexandre Ganea extern void *RPMALLOC_CDECL reallocarray(void *ptr, size_t count, size_t size);
504*67226badSAlexandre Ganea
reallocarray(void * ptr,size_t count,size_t size)505*67226badSAlexandre Ganea extern void *RPMALLOC_CDECL reallocarray(void *ptr, size_t count, size_t size) {
506*67226badSAlexandre Ganea size_t total;
507*67226badSAlexandre Ganea #if ENABLE_VALIDATE_ARGS
508*67226badSAlexandre Ganea #ifdef _MSC_VER
509*67226badSAlexandre Ganea int err = SizeTMult(count, size, &total);
510*67226badSAlexandre Ganea if ((err != S_OK) || (total >= MAX_ALLOC_SIZE)) {
511*67226badSAlexandre Ganea errno = EINVAL;
512*67226badSAlexandre Ganea return 0;
513*67226badSAlexandre Ganea }
514*67226badSAlexandre Ganea #else
515*67226badSAlexandre Ganea int err = __builtin_umull_overflow(count, size, &total);
516*67226badSAlexandre Ganea if (err || (total >= MAX_ALLOC_SIZE)) {
517*67226badSAlexandre Ganea errno = EINVAL;
518*67226badSAlexandre Ganea return 0;
519*67226badSAlexandre Ganea }
520*67226badSAlexandre Ganea #endif
521*67226badSAlexandre Ganea #else
522*67226badSAlexandre Ganea total = count * size;
523*67226badSAlexandre Ganea #endif
524*67226badSAlexandre Ganea return realloc(ptr, total);
525*67226badSAlexandre Ganea }
526*67226badSAlexandre Ganea
valloc(size_t size)527*67226badSAlexandre Ganea extern inline void *RPMALLOC_CDECL valloc(size_t size) {
528*67226badSAlexandre Ganea get_thread_heap();
529*67226badSAlexandre Ganea return rpaligned_alloc(_rpmalloc_page_size(), size);
530*67226badSAlexandre Ganea }
531*67226badSAlexandre Ganea
pvalloc(size_t size)532*67226badSAlexandre Ganea extern inline void *RPMALLOC_CDECL pvalloc(size_t size) {
533*67226badSAlexandre Ganea get_thread_heap();
534*67226badSAlexandre Ganea const size_t page_size = _rpmalloc_page_size();
535*67226badSAlexandre Ganea const size_t aligned_size = ((size + page_size - 1) / page_size) * page_size;
536*67226badSAlexandre Ganea #if ENABLE_VALIDATE_ARGS
537*67226badSAlexandre Ganea if (aligned_size < size) {
538*67226badSAlexandre Ganea errno = EINVAL;
539*67226badSAlexandre Ganea return 0;
540*67226badSAlexandre Ganea }
541*67226badSAlexandre Ganea #endif
542*67226badSAlexandre Ganea return rpaligned_alloc(_rpmalloc_page_size(), aligned_size);
543*67226badSAlexandre Ganea }
544*67226badSAlexandre Ganea
545*67226badSAlexandre Ganea #endif // ENABLE_OVERRIDE
546*67226badSAlexandre Ganea
547*67226badSAlexandre Ganea #if ENABLE_PRELOAD
548*67226badSAlexandre Ganea
549*67226badSAlexandre Ganea #ifdef _WIN32
550*67226badSAlexandre Ganea
551*67226badSAlexandre Ganea #if defined(BUILD_DYNAMIC_LINK) && BUILD_DYNAMIC_LINK
552*67226badSAlexandre Ganea
553*67226badSAlexandre Ganea extern __declspec(dllexport) BOOL WINAPI DllMain(HINSTANCE instance,
554*67226badSAlexandre Ganea DWORD reason, LPVOID reserved);
555*67226badSAlexandre Ganea
DllMain(HINSTANCE instance,DWORD reason,LPVOID reserved)556*67226badSAlexandre Ganea extern __declspec(dllexport) BOOL WINAPI DllMain(HINSTANCE instance,
557*67226badSAlexandre Ganea DWORD reason,
558*67226badSAlexandre Ganea LPVOID reserved) {
559*67226badSAlexandre Ganea (void)sizeof(reserved);
560*67226badSAlexandre Ganea (void)sizeof(instance);
561*67226badSAlexandre Ganea if (reason == DLL_PROCESS_ATTACH)
562*67226badSAlexandre Ganea rpmalloc_initialize();
563*67226badSAlexandre Ganea else if (reason == DLL_PROCESS_DETACH)
564*67226badSAlexandre Ganea rpmalloc_finalize();
565*67226badSAlexandre Ganea else if (reason == DLL_THREAD_ATTACH)
566*67226badSAlexandre Ganea rpmalloc_thread_initialize();
567*67226badSAlexandre Ganea else if (reason == DLL_THREAD_DETACH)
568*67226badSAlexandre Ganea rpmalloc_thread_finalize(1);
569*67226badSAlexandre Ganea return TRUE;
570*67226badSAlexandre Ganea }
571*67226badSAlexandre Ganea
572*67226badSAlexandre Ganea // end BUILD_DYNAMIC_LINK
573*67226badSAlexandre Ganea #else
574*67226badSAlexandre Ganea
_global_rpmalloc_init(void)575*67226badSAlexandre Ganea extern void _global_rpmalloc_init(void) {
576*67226badSAlexandre Ganea rpmalloc_set_main_thread();
577*67226badSAlexandre Ganea rpmalloc_initialize();
578*67226badSAlexandre Ganea }
579*67226badSAlexandre Ganea
580*67226badSAlexandre Ganea #if defined(__clang__) || defined(__GNUC__)
581*67226badSAlexandre Ganea
initializer(void)582*67226badSAlexandre Ganea static void __attribute__((constructor)) initializer(void) {
583*67226badSAlexandre Ganea _global_rpmalloc_init();
584*67226badSAlexandre Ganea }
585*67226badSAlexandre Ganea
586*67226badSAlexandre Ganea #elif defined(_MSC_VER)
587*67226badSAlexandre Ganea
_global_rpmalloc_xib(void)588*67226badSAlexandre Ganea static int _global_rpmalloc_xib(void) {
589*67226badSAlexandre Ganea _global_rpmalloc_init();
590*67226badSAlexandre Ganea return 0;
591*67226badSAlexandre Ganea }
592*67226badSAlexandre Ganea
593*67226badSAlexandre Ganea #pragma section(".CRT$XIB", read)
594*67226badSAlexandre Ganea __declspec(allocate(".CRT$XIB")) void (*_rpmalloc_module_init)(void) =
595*67226badSAlexandre Ganea _global_rpmalloc_xib;
596*67226badSAlexandre Ganea #if defined(_M_IX86) || defined(__i386__)
597*67226badSAlexandre Ganea #pragma comment(linker, "/include:" \
598*67226badSAlexandre Ganea "__rpmalloc_module_init")
599*67226badSAlexandre Ganea #else
600*67226badSAlexandre Ganea #pragma comment(linker, "/include:" \
601*67226badSAlexandre Ganea "_rpmalloc_module_init")
602*67226badSAlexandre Ganea #endif
603*67226badSAlexandre Ganea
604*67226badSAlexandre Ganea #endif
605*67226badSAlexandre Ganea
606*67226badSAlexandre Ganea // end !BUILD_DYNAMIC_LINK
607*67226badSAlexandre Ganea #endif
608*67226badSAlexandre Ganea
609*67226badSAlexandre Ganea #else
610*67226badSAlexandre Ganea
611*67226badSAlexandre Ganea #include <pthread.h>
612*67226badSAlexandre Ganea #include <stdint.h>
613*67226badSAlexandre Ganea #include <stdlib.h>
614*67226badSAlexandre Ganea #include <unistd.h>
615*67226badSAlexandre Ganea
616*67226badSAlexandre Ganea extern void rpmalloc_set_main_thread(void);
617*67226badSAlexandre Ganea
618*67226badSAlexandre Ganea static pthread_key_t destructor_key;
619*67226badSAlexandre Ganea
620*67226badSAlexandre Ganea static void thread_destructor(void *);
621*67226badSAlexandre Ganea
initializer(void)622*67226badSAlexandre Ganea static void __attribute__((constructor)) initializer(void) {
623*67226badSAlexandre Ganea rpmalloc_set_main_thread();
624*67226badSAlexandre Ganea rpmalloc_initialize();
625*67226badSAlexandre Ganea pthread_key_create(&destructor_key, thread_destructor);
626*67226badSAlexandre Ganea }
627*67226badSAlexandre Ganea
finalizer(void)628*67226badSAlexandre Ganea static void __attribute__((destructor)) finalizer(void) { rpmalloc_finalize(); }
629*67226badSAlexandre Ganea
630*67226badSAlexandre Ganea typedef struct {
631*67226badSAlexandre Ganea void *(*real_start)(void *);
632*67226badSAlexandre Ganea void *real_arg;
633*67226badSAlexandre Ganea } thread_starter_arg;
634*67226badSAlexandre Ganea
thread_starter(void * argptr)635*67226badSAlexandre Ganea static void *thread_starter(void *argptr) {
636*67226badSAlexandre Ganea thread_starter_arg *arg = argptr;
637*67226badSAlexandre Ganea void *(*real_start)(void *) = arg->real_start;
638*67226badSAlexandre Ganea void *real_arg = arg->real_arg;
639*67226badSAlexandre Ganea rpmalloc_thread_initialize();
640*67226badSAlexandre Ganea rpfree(argptr);
641*67226badSAlexandre Ganea pthread_setspecific(destructor_key, (void *)1);
642*67226badSAlexandre Ganea return (*real_start)(real_arg);
643*67226badSAlexandre Ganea }
644*67226badSAlexandre Ganea
thread_destructor(void * value)645*67226badSAlexandre Ganea static void thread_destructor(void *value) {
646*67226badSAlexandre Ganea (void)sizeof(value);
647*67226badSAlexandre Ganea rpmalloc_thread_finalize(1);
648*67226badSAlexandre Ganea }
649*67226badSAlexandre Ganea
650*67226badSAlexandre Ganea #ifdef __APPLE__
651*67226badSAlexandre Ganea
pthread_create_proxy(pthread_t * thread,const pthread_attr_t * attr,void * (* start_routine)(void *),void * arg)652*67226badSAlexandre Ganea static int pthread_create_proxy(pthread_t *thread, const pthread_attr_t *attr,
653*67226badSAlexandre Ganea void *(*start_routine)(void *), void *arg) {
654*67226badSAlexandre Ganea rpmalloc_initialize();
655*67226badSAlexandre Ganea thread_starter_arg *starter_arg = rpmalloc(sizeof(thread_starter_arg));
656*67226badSAlexandre Ganea starter_arg->real_start = start_routine;
657*67226badSAlexandre Ganea starter_arg->real_arg = arg;
658*67226badSAlexandre Ganea return pthread_create(thread, attr, thread_starter, starter_arg);
659*67226badSAlexandre Ganea }
660*67226badSAlexandre Ganea
661*67226badSAlexandre Ganea MAC_INTERPOSE_SINGLE(pthread_create_proxy, pthread_create);
662*67226badSAlexandre Ganea
663*67226badSAlexandre Ganea #else
664*67226badSAlexandre Ganea
665*67226badSAlexandre Ganea #include <dlfcn.h>
666*67226badSAlexandre Ganea
pthread_create(pthread_t * thread,const pthread_attr_t * attr,void * (* start_routine)(void *),void * arg)667*67226badSAlexandre Ganea int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
668*67226badSAlexandre Ganea void *(*start_routine)(void *), void *arg) {
669*67226badSAlexandre Ganea #if defined(__linux__) || defined(__FreeBSD__) || defined(__OpenBSD__) || \
670*67226badSAlexandre Ganea defined(__NetBSD__) || defined(__DragonFly__) || defined(__APPLE__) || \
671*67226badSAlexandre Ganea defined(__HAIKU__)
672*67226badSAlexandre Ganea char fname[] = "pthread_create";
673*67226badSAlexandre Ganea #else
674*67226badSAlexandre Ganea char fname[] = "_pthread_create";
675*67226badSAlexandre Ganea #endif
676*67226badSAlexandre Ganea void *real_pthread_create = dlsym(RTLD_NEXT, fname);
677*67226badSAlexandre Ganea rpmalloc_thread_initialize();
678*67226badSAlexandre Ganea thread_starter_arg *starter_arg = rpmalloc(sizeof(thread_starter_arg));
679*67226badSAlexandre Ganea starter_arg->real_start = start_routine;
680*67226badSAlexandre Ganea starter_arg->real_arg = arg;
681*67226badSAlexandre Ganea return (*(int (*)(pthread_t *, const pthread_attr_t *, void *(*)(void *),
682*67226badSAlexandre Ganea void *))real_pthread_create)(thread, attr, thread_starter,
683*67226badSAlexandre Ganea starter_arg);
684*67226badSAlexandre Ganea }
685*67226badSAlexandre Ganea
686*67226badSAlexandre Ganea #endif
687*67226badSAlexandre Ganea
688*67226badSAlexandre Ganea #endif
689*67226badSAlexandre Ganea
690*67226badSAlexandre Ganea #endif
691*67226badSAlexandre Ganea
692*67226badSAlexandre Ganea #if ENABLE_OVERRIDE
693*67226badSAlexandre Ganea
694*67226badSAlexandre Ganea #if defined(__GLIBC__) && defined(__linux__)
695*67226badSAlexandre Ganea
696*67226badSAlexandre Ganea void *__libc_malloc(size_t size) RPMALLOC_ATTRIB_MALLOC
697*67226badSAlexandre Ganea RPMALLOC_ATTRIB_ALLOC_SIZE(1)
698*67226badSAlexandre Ganea RPALIAS(rpmalloc) void *__libc_calloc(size_t count, size_t size)
699*67226badSAlexandre Ganea RPMALLOC_ATTRIB_MALLOC RPMALLOC_ATTRIB_ALLOC_SIZE2(1, 2)
700*67226badSAlexandre Ganea RPALIAS(rpcalloc) void *__libc_realloc(void *p, size_t size)
701*67226badSAlexandre Ganea RPMALLOC_ATTRIB_MALLOC
702*67226badSAlexandre Ganea RPMALLOC_ATTRIB_ALLOC_SIZE(2) RPALIAS(rprealloc) void __libc_free(void *p)
703*67226badSAlexandre Ganea RPALIAS(rpfree) void __libc_cfree(void *p)
704*67226badSAlexandre Ganea RPALIAS(rpfree) void *__libc_memalign(size_t align, size_t size)
705*67226badSAlexandre Ganea RPMALLOC_ATTRIB_MALLOC
706*67226badSAlexandre Ganea RPMALLOC_ATTRIB_ALLOC_SIZE(2)
707*67226badSAlexandre Ganea RPALIAS(rpmemalign) int __posix_memalign(void **p, size_t align,
708*67226badSAlexandre Ganea size_t size)
709*67226badSAlexandre Ganea RPALIAS(rpposix_memalign)
710*67226badSAlexandre Ganea
711*67226badSAlexandre Ganea extern void *__libc_valloc(size_t size);
712*67226badSAlexandre Ganea extern void *__libc_pvalloc(size_t size);
713*67226badSAlexandre Ganea
__libc_valloc(size_t size)714*67226badSAlexandre Ganea void *__libc_valloc(size_t size) { return valloc(size); }
715*67226badSAlexandre Ganea
__libc_pvalloc(size_t size)716*67226badSAlexandre Ganea void *__libc_pvalloc(size_t size) { return pvalloc(size); }
717*67226badSAlexandre Ganea
718*67226badSAlexandre Ganea #endif
719*67226badSAlexandre Ganea
720*67226badSAlexandre Ganea #endif
721*67226badSAlexandre Ganea
722*67226badSAlexandre Ganea #if (defined(__GNUC__) || defined(__clang__))
723*67226badSAlexandre Ganea #pragma GCC visibility pop
724*67226badSAlexandre Ganea #endif
725