github.com/moontrade/nogc@v0.1.7/alloc/rpmalloc/src/malloc.c (about) 1 /* malloc.c - Memory allocator - Public Domain - 2016 Mattias Jansson 2 * 3 * This library provides a cross-platform lock free thread caching malloc implementation in C11. 4 * The latest source code is always available at 5 * 6 * https://github.com/mjansson/rpmalloc 7 * 8 * This library is put in the public domain; you can redistribute it and/or modify it without any restrictions. 9 * 10 */ 11 12 // 13 // This file provides overrides for the standard library malloc entry points for C and new/delete operators for C++ 14 // It also provides automatic initialization/finalization of process and threads 15 // 16 17 #ifndef ARCH_64BIT 18 # if defined(__LLP64__) || defined(__LP64__) || defined(_WIN64) 19 # define ARCH_64BIT 1 20 _Static_assert(sizeof(size_t) == 8, "Data type size mismatch"); 21 _Static_assert(sizeof(void*) == 8, "Data type size mismatch"); 22 # else 23 # define ARCH_64BIT 0 24 _Static_assert(sizeof(size_t) == 4, "Data type size mismatch"); 25 _Static_assert(sizeof(void*) == 4, "Data type size mismatch"); 26 # endif 27 #endif 28 29 #if (defined(__GNUC__) || defined(__clang__)) && !defined(__MACH__) 30 #pragma GCC visibility push(default) 31 #endif 32 33 #define USE_IMPLEMENT 1 34 #define USE_INTERPOSE 0 35 #define USE_ALIAS 0 36 37 #if defined(__APPLE__) && ENABLE_PRELOAD 38 #undef USE_INTERPOSE 39 #define USE_INTERPOSE 1 40 41 typedef struct interpose_t { 42 void* new_func; 43 void* orig_func; 44 } interpose_t; 45 46 #define MAC_INTERPOSE_PAIR(newf, oldf) { (void*)newf, (void*)oldf } 47 #define MAC_INTERPOSE_SINGLE(newf, oldf) \ 48 __attribute__((used)) static const interpose_t macinterpose##newf##oldf \ 49 __attribute__ ((section("__DATA, __interpose"))) = MAC_INTERPOSE_PAIR(newf, oldf) 50 51 #endif 52 53 #if !defined(_WIN32) && !USE_INTERPOSE 54 #undef USE_IMPLEMENT 55 #undef USE_ALIAS 56 #define USE_IMPLEMENT 0 57 #define USE_ALIAS 1 58 #endif 59 60 #ifdef _MSC_VER 61 #pragma warning (disable : 4100) 62 #undef malloc 63 #undef free 64 #undef calloc 65 #define RPMALLOC_RESTRICT __declspec(restrict) 66 #else 67 #define RPMALLOC_RESTRICT 68 #endif 69 70 #if ENABLE_OVERRIDE 71 72 typedef struct rp_nothrow_t { int __dummy; } rp_nothrow_t; 73 74 #if USE_IMPLEMENT 75 76 extern inline RPMALLOC_RESTRICT void* RPMALLOC_CDECL malloc(size_t size) { return rpmalloc(size); } 77 extern inline RPMALLOC_RESTRICT void* RPMALLOC_CDECL calloc(size_t count, size_t size) { return rpcalloc(count, size); } 78 extern inline RPMALLOC_RESTRICT void* RPMALLOC_CDECL realloc(void* ptr, size_t size) { return rprealloc(ptr, size); } 79 extern inline void* RPMALLOC_CDECL reallocf(void* ptr, size_t size) { return rprealloc(ptr, size); } 80 extern inline void* RPMALLOC_CDECL aligned_alloc(size_t alignment, size_t size) { return rpaligned_alloc(alignment, size); } 81 extern inline void* RPMALLOC_CDECL memalign(size_t alignment, size_t size) { return rpmemalign(alignment, size); } 82 extern inline int RPMALLOC_CDECL posix_memalign(void** memptr, size_t alignment, size_t size) { return rpposix_memalign(memptr, alignment, size); } 83 extern inline void RPMALLOC_CDECL free(void* ptr) { rpfree(ptr); } 84 extern inline void RPMALLOC_CDECL cfree(void* ptr) { rpfree(ptr); } 85 extern inline size_t RPMALLOC_CDECL malloc_usable_size(void* ptr) { return rpmalloc_usable_size(ptr); } 86 extern inline size_t RPMALLOC_CDECL malloc_size(void* ptr) { return rpmalloc_usable_size(ptr); } 87 88 #ifdef _WIN32 89 // For Windows, #include <rpnew.h> in one source file to get the C++ operator overrides implemented in your module 90 #else 91 // Overload the C++ operators using the mangled names (https://itanium-cxx-abi.github.io/cxx-abi/abi.html#mangling) 92 // operators delete and delete[] 93 extern void _ZdlPv(void* p); void _ZdlPv(void* p) { rpfree(p); } 94 extern void _ZdaPv(void* p); void _ZdaPv(void* p) { rpfree(p); } 95 #if ARCH_64BIT 96 // 64-bit operators new and new[], normal and aligned 97 extern void* _Znwm(uint64_t size); void* _Znwm(uint64_t size) { return rpmalloc(size); } 98 extern void* _Znam(uint64_t size); void* _Znam(uint64_t size) { return rpmalloc(size); } 99 extern void* _Znwmm(uint64_t size, uint64_t align); void* _Znwmm(uint64_t size, uint64_t align) { return rpaligned_alloc(align, size); } 100 extern void* _Znamm(uint64_t size, uint64_t align); void* _Znamm(uint64_t size, uint64_t align) { return rpaligned_alloc(align, size); } 101 extern void* _ZnwmSt11align_val_t(uint64_t size, uint64_t align); void* _ZnwmSt11align_val_t(uint64_t size, uint64_t align) { return rpaligned_alloc(align, size); } 102 extern void* _ZnamSt11align_val_t(uint64_t size, uint64_t align); void* _ZnamSt11align_val_t(uint64_t size, uint64_t align) { return rpaligned_alloc(align, size); } 103 extern void* _ZnwmRKSt9nothrow_t(uint64_t size, rp_nothrow_t t); void* _ZnwmRKSt9nothrow_t(uint64_t size, rp_nothrow_t t) { (void)sizeof(t); return rpmalloc(size); } 104 extern void* _ZnamRKSt9nothrow_t(uint64_t size, rp_nothrow_t t); void* _ZnamRKSt9nothrow_t(uint64_t size, rp_nothrow_t t) { (void)sizeof(t); return rpmalloc(size); } 105 extern void* _ZnwmSt11align_val_tRKSt9nothrow_t(uint64_t size, uint64_t align, rp_nothrow_t t); void* _ZnwmSt11align_val_tRKSt9nothrow_t(uint64_t size, uint64_t align, rp_nothrow_t t) { (void)sizeof(t); return rpaligned_alloc(align, size); } 106 extern void* _ZnamSt11align_val_tRKSt9nothrow_t(uint64_t size, uint64_t align, rp_nothrow_t t); void* _ZnamSt11align_val_tRKSt9nothrow_t(uint64_t size, uint64_t align, rp_nothrow_t t) { (void)sizeof(t); return rpaligned_alloc(align, size); } 107 // 64-bit operators sized delete and delete[], normal and aligned 108 extern void _ZdlPvm(void* p, uint64_t size); void _ZdlPvm(void* p, uint64_t size) { rpfree(p); (void)sizeof(size); } 109 extern void _ZdaPvm(void* p, uint64_t size); void _ZdaPvm(void* p, uint64_t size) { rpfree(p); (void)sizeof(size); } 110 extern void _ZdlPvSt11align_val_t(void* p, uint64_t align); void _ZdlPvSt11align_val_t(void* p, uint64_t align) { rpfree(p); (void)sizeof(align); } 111 extern void _ZdaPvSt11align_val_t(void* p, uint64_t align); void _ZdaPvSt11align_val_t(void* p, uint64_t align) { rpfree(p); (void)sizeof(align); } 112 extern void _ZdlPvmSt11align_val_t(void* p, uint64_t size, uint64_t align); void _ZdlPvmSt11align_val_t(void* p, uint64_t size, uint64_t align) { rpfree(p); (void)sizeof(size); (void)sizeof(align); } 113 extern void _ZdaPvmSt11align_val_t(void* p, uint64_t size, uint64_t align); void _ZdaPvmSt11align_val_t(void* p, uint64_t size, uint64_t align) { rpfree(p); (void)sizeof(size); (void)sizeof(align); } 114 #else 115 // 32-bit operators new and new[], normal and aligned 116 extern void* _Znwj(uint32_t size); void* _Znwj(uint32_t size) { return rpmalloc(size); } 117 extern void* _Znaj(uint32_t size); void* _Znaj(uint32_t size) { return rpmalloc(size); } 118 extern void* _Znwjj(uint32_t size, uint32_t align); void* _Znwjj(uint32_t size, uint32_t align) { return rpaligned_alloc(align, size); } 119 extern void* _Znajj(uint32_t size, uint32_t align); void* _Znajj(uint32_t size, uint32_t align) { return rpaligned_alloc(align, size); } 120 extern void* _ZnwjSt11align_val_t(size_t size, size_t align); void* _ZnwjSt11align_val_t(size_t size, size_t align) { return rpaligned_alloc(align, size); } 121 extern void* _ZnajSt11align_val_t(size_t size, size_t align); void* _ZnajSt11align_val_t(size_t size, size_t align) { return rpaligned_alloc(align, size); } 122 extern void* _ZnwjRKSt9nothrow_t(size_t size, rp_nothrow_t t); void* _ZnwjRKSt9nothrow_t(size_t size, rp_nothrow_t t) { (void)sizeof(t); return rpmalloc(size); } 123 extern void* _ZnajRKSt9nothrow_t(size_t size, rp_nothrow_t t); void* _ZnajRKSt9nothrow_t(size_t size, rp_nothrow_t t) { (void)sizeof(t); return rpmalloc(size); } 124 extern void* _ZnwjSt11align_val_tRKSt9nothrow_t(size_t size, size_t align, rp_nothrow_t t); void* _ZnwjSt11align_val_tRKSt9nothrow_t(size_t size, size_t align, rp_nothrow_t t) { (void)sizeof(t); return rpaligned_alloc(align, size); } 125 extern void* _ZnajSt11align_val_tRKSt9nothrow_t(size_t size, size_t align, rp_nothrow_t t); void* _ZnajSt11align_val_tRKSt9nothrow_t(size_t size, size_t align, rp_nothrow_t t) { (void)sizeof(t); return rpaligned_alloc(align, size); } 126 // 32-bit operators sized delete and delete[], normal and aligned 127 extern void _ZdlPvj(void* p, uint64_t size); void _ZdlPvj(void* p, uint64_t size) { rpfree(p); (void)sizeof(size); } 128 extern void _ZdaPvj(void* p, uint64_t size); void _ZdaPvj(void* p, uint64_t size) { rpfree(p); (void)sizeof(size); } 129 extern void _ZdlPvSt11align_val_t(void* p, uint32_t align); void _ZdlPvSt11align_val_t(void* p, uint64_t a) { rpfree(p); (void)sizeof(align); } 130 extern void _ZdaPvSt11align_val_t(void* p, uint32_t align); void _ZdaPvSt11align_val_t(void* p, uint64_t a) { rpfree(p); (void)sizeof(align); } 131 extern void _ZdlPvjSt11align_val_t(void* p, uint32_t size, uint32_t align); void _ZdlPvjSt11align_val_t(void* p, uint64_t size, uint64_t align) { rpfree(p); (void)sizeof(size); (void)sizeof(a); } 132 extern void _ZdaPvjSt11align_val_t(void* p, uint32_t size, uint32_t align); void _ZdaPvjSt11align_val_t(void* p, uint64_t size, uint64_t align) { rpfree(p); (void)sizeof(size); (void)sizeof(a); } 133 #endif 134 #endif 135 136 #endif 137 138 #if USE_INTERPOSE 139 140 __attribute__((used)) static const interpose_t macinterpose_malloc[] 141 __attribute__ ((section("__DATA, __interpose"))) = { 142 //new and new[] 143 MAC_INTERPOSE_PAIR(rpmalloc, _Znwm), 144 MAC_INTERPOSE_PAIR(rpmalloc, _Znam), 145 //delete and delete[] 146 MAC_INTERPOSE_PAIR(rpfree, _ZdlPv), 147 MAC_INTERPOSE_PAIR(rpfree, _ZdaPv), 148 MAC_INTERPOSE_PAIR(rpmalloc, malloc), 149 MAC_INTERPOSE_PAIR(rpmalloc, calloc), 150 MAC_INTERPOSE_PAIR(rprealloc, realloc), 151 MAC_INTERPOSE_PAIR(rprealloc, reallocf), 152 #if defined(__MAC_10_15) && __MAC_OS_X_VERSION_MIN_REQUIRED >= __MAC_10_15 153 MAC_INTERPOSE_PAIR(rpaligned_alloc, aligned_alloc), 154 #endif 155 MAC_INTERPOSE_PAIR(rpmemalign, memalign), 156 MAC_INTERPOSE_PAIR(rpposix_memalign, posix_memalign), 157 MAC_INTERPOSE_PAIR(rpfree, free), 158 MAC_INTERPOSE_PAIR(rpfree, cfree), 159 MAC_INTERPOSE_PAIR(rpmalloc_usable_size, malloc_usable_size), 160 MAC_INTERPOSE_PAIR(rpmalloc_usable_size, malloc_size) 161 }; 162 163 #endif 164 165 #if USE_ALIAS 166 167 #define RPALIAS(fn) __attribute__((alias(#fn), used, visibility("default"))); 168 169 // Alias the C++ operators using the mangled names (https://itanium-cxx-abi.github.io/cxx-abi/abi.html#mangling) 170 171 // operators delete and delete[] 172 void _ZdlPv(void* p) RPALIAS(rpfree) 173 void _ZdaPv(void* p) RPALIAS(rpfree) 174 extern inline void _ZdlPvm(void* p, size_t n) { rpfree(p); (void)sizeof(n); } 175 extern inline void _ZdaPvm(void* p, size_t n) { rpfree(p); (void)sizeof(n); } 176 extern inline void _ZdlPvSt11align_val_t(void* p, size_t a) { rpfree(p); (void)sizeof(a); } 177 extern inline void _ZdaPvSt11align_val_t(void* p, size_t a) { rpfree(p); (void)sizeof(a); } 178 extern inline void _ZdlPvmSt11align_val_t(void* p, size_t n, size_t a) { rpfree(p); (void)sizeof(n); (void)sizeof(a); } 179 extern inline void _ZdaPvmSt11align_val_t(void* p, size_t n, size_t a) { rpfree(p); (void)sizeof(n); (void)sizeof(a); } 180 181 #if ARCH_64BIT 182 // 64-bit operators new and new[], normal and aligned 183 void* _Znwm(uint64_t size) RPALIAS(rpmalloc) 184 void* _Znam(uint64_t size) RPALIAS(rpmalloc) 185 extern inline void* _Znwmm(uint64_t size, uint64_t align) { return rpaligned_alloc(align, size); } 186 extern inline void* _Znamm(uint64_t size, uint64_t align) { return rpaligned_alloc(align, size); } 187 extern inline void* _ZnwmSt11align_val_t(size_t size, size_t align) { return rpaligned_alloc(align, size); } 188 extern inline void* _ZnamSt11align_val_t(size_t size, size_t align) { return rpaligned_alloc(align, size); } 189 extern inline void* _ZnwmRKSt9nothrow_t(size_t size, rp_nothrow_t t) { (void)sizeof(t); return rpmalloc(size); } 190 extern inline void* _ZnamRKSt9nothrow_t(size_t size, rp_nothrow_t t) { (void)sizeof(t); return rpmalloc(size); } 191 extern inline void* _ZnwmSt11align_val_tRKSt9nothrow_t(size_t size, size_t align, rp_nothrow_t t) { (void)sizeof(t); return rpaligned_alloc(align, size); } 192 extern inline void* _ZnamSt11align_val_tRKSt9nothrow_t(size_t size, size_t align, rp_nothrow_t t) { (void)sizeof(t); return rpaligned_alloc(align, size); } 193 #else 194 // 32-bit operators new and new[], normal and aligned 195 void* _Znwj(uint32_t size) RPALIAS(rpmalloc) 196 void* _Znaj(uint32_t size) RPALIAS(rpmalloc) 197 extern inline void* _Znwjj(uint32_t size, uint32_t align) { return rpaligned_alloc(align, size); } 198 extern inline void* _Znajj(uint32_t size, uint32_t align) { return rpaligned_alloc(align, size); } 199 extern inline void* _ZnwjSt11align_val_t(size_t size, size_t align) { return rpaligned_alloc(align, size); } 200 extern inline void* _ZnajSt11align_val_t(size_t size, size_t align) { return rpaligned_alloc(align, size); } 201 extern inline void* _ZnwjRKSt9nothrow_t(size_t size, rp_nothrow_t t) { (void)sizeof(t); return rpmalloc(size); } 202 extern inline void* _ZnajRKSt9nothrow_t(size_t size, rp_nothrow_t t) { (void)sizeof(t); return rpmalloc(size); } 203 extern inline void* _ZnwjSt11align_val_tRKSt9nothrow_t(size_t size, size_t align, rp_nothrow_t t) { (void)sizeof(t); return rpaligned_alloc(align, size); } 204 extern inline void* _ZnajSt11align_val_tRKSt9nothrow_t(size_t size, size_t align, rp_nothrow_t t) { (void)sizeof(t); return rpaligned_alloc(align, size); } 205 #endif 206 207 void* malloc(size_t size) RPALIAS(rpmalloc) 208 void* calloc(size_t count, size_t size) RPALIAS(rpcalloc) 209 void* realloc(void* ptr, size_t size) RPALIAS(rprealloc) 210 void* reallocf(void* ptr, size_t size) RPALIAS(rprealloc) 211 void* aligned_alloc(size_t alignment, size_t size) RPALIAS(rpaligned_alloc) 212 void* memalign(size_t alignment, size_t size) RPALIAS(rpmemalign) 213 int posix_memalign(void** memptr, size_t alignment, size_t size) RPALIAS(rpposix_memalign) 214 void free(void* ptr) RPALIAS(rpfree) 215 void cfree(void* ptr) RPALIAS(rpfree) 216 #if defined(__ANDROID__) 217 size_t malloc_usable_size(const void* ptr) RPALIAS(rpmalloc_usable_size) 218 #else 219 size_t malloc_usable_size(void* ptr) RPALIAS(rpmalloc_usable_size) 220 #endif 221 size_t malloc_size(void* ptr) RPALIAS(rpmalloc_usable_size) 222 223 #endif 224 225 static inline size_t 226 _rpmalloc_page_size(void) { 227 return _memory_page_size; 228 } 229 230 extern inline void* RPMALLOC_CDECL 231 reallocarray(void* ptr, size_t count, size_t size) { 232 size_t total; 233 #if ENABLE_VALIDATE_ARGS 234 #ifdef _MSC_VER 235 int err = SizeTMult(count, size, &total); 236 if ((err != S_OK) || (total >= MAX_ALLOC_SIZE)) { 237 errno = EINVAL; 238 return 0; 239 } 240 #else 241 int err = __builtin_umull_overflow(count, size, &total); 242 if (err || (total >= MAX_ALLOC_SIZE)) { 243 errno = EINVAL; 244 return 0; 245 } 246 #endif 247 #else 248 total = count * size; 249 #endif 250 return realloc(ptr, total); 251 } 252 253 extern inline void* RPMALLOC_CDECL 254 valloc(size_t size) { 255 get_thread_heap(); 256 return rpaligned_alloc(_rpmalloc_page_size(), size); 257 } 258 259 extern inline void* RPMALLOC_CDECL 260 pvalloc(size_t size) { 261 get_thread_heap(); 262 const size_t page_size = _rpmalloc_page_size(); 263 const size_t aligned_size = ((size + page_size - 1) / page_size) * page_size; 264 #if ENABLE_VALIDATE_ARGS 265 if (aligned_size < size) { 266 errno = EINVAL; 267 return 0; 268 } 269 #endif 270 return rpaligned_alloc(_rpmalloc_page_size(), aligned_size); 271 } 272 273 #endif // ENABLE_OVERRIDE 274 275 #if ENABLE_PRELOAD 276 277 #ifdef _WIN32 278 279 #if defined(BUILD_DYNAMIC_LINK) && BUILD_DYNAMIC_LINK 280 281 extern __declspec(dllexport) BOOL WINAPI 282 DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved); 283 284 extern __declspec(dllexport) BOOL WINAPI 285 DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved) { 286 (void)sizeof(reserved); 287 (void)sizeof(instance); 288 if (reason == DLL_PROCESS_ATTACH) 289 rpmalloc_initialize(); 290 else if (reason == DLL_PROCESS_DETACH) 291 rpmalloc_finalize(); 292 else if (reason == DLL_THREAD_ATTACH) 293 rpmalloc_thread_initialize(); 294 else if (reason == DLL_THREAD_DETACH) 295 rpmalloc_thread_finalize(1); 296 return TRUE; 297 } 298 299 //end BUILD_DYNAMIC_LINK 300 #else 301 302 extern void 303 _global_rpmalloc_init(void) { 304 rpmalloc_set_main_thread(); 305 rpmalloc_initialize(); 306 } 307 308 #if defined(__clang__) || defined(__GNUC__) 309 310 static void __attribute__((constructor)) 311 initializer(void) { 312 _global_rpmalloc_init(); 313 } 314 315 #elif defined(_MSC_VER) 316 317 #pragma section(".CRT$XIB",read) 318 __declspec(allocate(".CRT$XIB")) void (*_rpmalloc_module_init)(void) = _global_rpmalloc_init; 319 #pragma comment(linker, "/include:_rpmalloc_module_init") 320 321 #endif 322 323 //end !BUILD_DYNAMIC_LINK 324 #endif 325 326 #else 327 328 #include <pthread.h> 329 #include <stdlib.h> 330 #include <stdint.h> 331 #include <unistd.h> 332 333 extern void 334 rpmalloc_set_main_thread(void); 335 336 static pthread_key_t destructor_key; 337 338 static void 339 thread_destructor(void*); 340 341 static void __attribute__((constructor)) 342 initializer(void) { 343 rpmalloc_set_main_thread(); 344 rpmalloc_initialize(); 345 pthread_key_create(&destructor_key, thread_destructor); 346 } 347 348 static void __attribute__((destructor)) 349 finalizer(void) { 350 rpmalloc_finalize(); 351 } 352 353 typedef struct { 354 void* (*real_start)(void*); 355 void* real_arg; 356 } thread_starter_arg; 357 358 static void* 359 thread_starter(void* argptr) { 360 thread_starter_arg* arg = argptr; 361 void* (*real_start)(void*) = arg->real_start; 362 void* real_arg = arg->real_arg; 363 rpmalloc_thread_initialize(); 364 rpfree(argptr); 365 pthread_setspecific(destructor_key, (void*)1); 366 return (*real_start)(real_arg); 367 } 368 369 static void 370 thread_destructor(void* value) { 371 (void)sizeof(value); 372 rpmalloc_thread_finalize(1); 373 } 374 375 #ifdef __APPLE__ 376 377 static int 378 pthread_create_proxy(pthread_t* thread, 379 const pthread_attr_t* attr, 380 void* (*start_routine)(void*), 381 void* arg) { 382 rpmalloc_initialize(); 383 // fprintf(stderr, "pthread_create_proxy\n"); 384 thread_starter_arg* starter_arg = rpmalloc(sizeof(thread_starter_arg)); 385 starter_arg->real_start = start_routine; 386 starter_arg->real_arg = arg; 387 return pthread_create(thread, attr, thread_starter, starter_arg); 388 } 389 390 MAC_INTERPOSE_SINGLE(pthread_create_proxy, pthread_create); 391 392 #else 393 394 #include <dlfcn.h> 395 396 int 397 pthread_create(pthread_t* thread, 398 const pthread_attr_t* attr, 399 void* (*start_routine)(void*), 400 void* arg) { 401 #if defined(__linux__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__DragonFly__) || \ 402 defined(__APPLE__) || defined(__HAIKU__) 403 char fname[] = "pthread_create"; 404 #else 405 char fname[] = "_pthread_create"; 406 #endif 407 void* real_pthread_create = dlsym(RTLD_NEXT, fname); 408 rpmalloc_thread_initialize(); 409 thread_starter_arg* starter_arg = rpmalloc(sizeof(thread_starter_arg)); 410 starter_arg->real_start = start_routine; 411 starter_arg->real_arg = arg; 412 return (*(int (*)(pthread_t*, const pthread_attr_t*, void* (*)(void*), void*))real_pthread_create)(thread, attr, thread_starter, starter_arg); 413 } 414 415 #endif 416 417 #endif 418 419 #endif 420 421 #if ENABLE_OVERRIDE 422 423 #if defined(__GLIBC__) && defined(__linux__) 424 425 void* __libc_malloc(size_t size) RPALIAS(rpmalloc) 426 void* __libc_calloc(size_t count, size_t size) RPALIAS(rpcalloc) 427 void* __libc_realloc(void* p, size_t size) RPALIAS(rprealloc) 428 void __libc_free(void* p) RPALIAS(rpfree) 429 void __libc_cfree(void* p) RPALIAS(rpfree) 430 void* __libc_memalign(size_t align, size_t size) RPALIAS(rpmemalign) 431 int __posix_memalign(void** p, size_t align, size_t size) RPALIAS(rpposix_memalign) 432 433 extern void* __libc_valloc(size_t size); 434 extern void* __libc_pvalloc(size_t size); 435 436 void* 437 __libc_valloc(size_t size) { 438 return valloc(size); 439 } 440 441 void* 442 __libc_pvalloc(size_t size) { 443 return pvalloc(size); 444 } 445 446 #endif 447 448 #endif 449 450 #if (defined(__GNUC__) || defined(__clang__)) && !defined(__MACH__) 451 #pragma GCC visibility pop 452 #endif