// -*- C++ -*- /** * @file gnuwrapper.cpp * @brief Replaces malloc family on GNU/Linux with custom versions. * @author Emery Berger * @note Copyright (C) 2010-2020 by Emery Berger. Heap Layers is distributed under the terms of the Apache 2.0 license. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 */ #ifndef __GNUC__ #error "This file requires the GNU compiler." #endif #include #include #include #include #include #include #include #include "heaplayers.h" /* To use this library, you only need to define the following allocation functions: - xxmalloc - xxfree - xxmalloc_usable_size - xxmalloc_lock - xxmalloc_unlock See the extern "C" block below for function prototypes and more details. YOU SHOULD NOT NEED TO MODIFY ANY OF THE CODE HERE TO SUPPORT ANY ALLOCATOR. LIMITATIONS: - This wrapper assumes that the underlying allocator will do "the right thing" when xxfree() is called with a pointer internal to an allocated object. Header-based allocators, for example, need not apply. */ #ifndef __THROW #define __THROW #endif static bool initialized = false; //#include "wrapper.cpp" extern "C" { void * xxmalloc(size_t); void xxfree(void *); size_t xxmalloc_usable_size(void *); void xxmalloc_lock(); void xxmalloc_unlock(); static void my_init_hook(); // New hooks for allocation functions. static void * my_malloc_hook (size_t, const void *); static void my_free_hook (void *, const void *); static void * my_realloc_hook (void *, size_t, const void *); static void * my_memalign_hook (size_t, size_t, const void *); // Store the old hooks just in case. static void * (*old_malloc_hook) (size_t, const void *); static void (*old_free_hook) (void *, const void *); static void * (*old_realloc_hook)(void *ptr, size_t size, const void *caller); static void * (*old_memalign_hook)(size_t alignment, size_t size, const void *caller); // From GNU libc 2.14 this macro is defined, to declare // hook variables as volatile. Define it as empty for // older glibc versions #ifndef __MALLOC_HOOK_VOLATILE #define __MALLOC_HOOK_VOLATILE #endif void (*__MALLOC_HOOK_VOLATILE __malloc_initialize_hook)() = my_init_hook; #pragma GCC diagnostic ignored "-Wdeprecated-declarations" static void my_init_hook() { if (!initialized) { // Store the old hooks. old_malloc_hook = __malloc_hook; old_free_hook = __free_hook; old_realloc_hook = __realloc_hook; old_memalign_hook = __memalign_hook; // Point the hooks to the replacement functions. __malloc_hook = my_malloc_hook; __free_hook = my_free_hook; __realloc_hook = my_realloc_hook; __memalign_hook = my_memalign_hook; // Set up everything so that fork behaves properly. pthread_atfork(xxmalloc_lock, xxmalloc_unlock, xxmalloc_unlock); initialized = true; } } static void * my_malloc_hook (size_t size, const void *) { return xxmalloc(size); } static void my_free_hook (void * ptr, const void *) { xxfree(ptr); } static void * my_realloc_hook (void * ptr, size_t sz, const void *) { return CUSTOM_PREFIX(realloc)(ptr, sz); } static void * my_memalign_hook (size_t size, size_t alignment, const void *) { return CUSTOM_PREFIX(memalign)(size, alignment); } }