1 // Copyright 2016 The Chromium 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 <malloc.h> 6 7 #include "base/allocator/allocator_shim.h" 8 #include "build/build_config.h" 9 10 #if defined(OS_ANDROID) && __ANDROID_API__ < 17 11 #include <dlfcn.h> 12 #endif 13 14 // This translation unit defines a default dispatch for the allocator shim which 15 // routes allocations to the original libc functions when using the link-time 16 // -Wl,-wrap,malloc approach (see README.md). 17 // The __real_X functions here are special symbols that the linker will relocate 18 // against the real "X" undefined symbol, so that __real_malloc becomes the 19 // equivalent of what an undefined malloc symbol reference would have been. 20 // This is the counterpart of allocator_shim_override_linker_wrapped_symbols.h, 21 // which routes the __wrap_X functions into the shim. 22 23 extern "C" { 24 void* __real_malloc(size_t); 25 void* __real_calloc(size_t, size_t); 26 void* __real_realloc(void*, size_t); 27 void* __real_memalign(size_t, size_t); 28 void* __real_free(void*); 29 } // extern "C" 30 31 namespace { 32 33 using base::allocator::AllocatorDispatch; 34 35 void* RealMalloc(const AllocatorDispatch*, size_t size, void* context) { 36 return __real_malloc(size); 37 } 38 39 void* RealCalloc(const AllocatorDispatch*, 40 size_t n, 41 size_t size, 42 void* context) { 43 return __real_calloc(n, size); 44 } 45 46 void* RealRealloc(const AllocatorDispatch*, 47 void* address, 48 size_t size, 49 void* context) { 50 return __real_realloc(address, size); 51 } 52 53 void* RealMemalign(const AllocatorDispatch*, 54 size_t alignment, 55 size_t size, 56 void* context) { 57 return __real_memalign(alignment, size); 58 } 59 60 void RealFree(const AllocatorDispatch*, void* address, void* context) { 61 __real_free(address); 62 } 63 64 #if defined(OS_ANDROID) && __ANDROID_API__ < 17 65 size_t DummyMallocUsableSize(const void*) { return 0; } 66 #endif 67 68 size_t RealSizeEstimate(const AllocatorDispatch*, 69 void* address, 70 void* context) { 71 #if defined(OS_ANDROID) 72 #if __ANDROID_API__ < 17 73 // malloc_usable_size() is available only starting from API 17. 74 // TODO(dskiba): remove once we start building against 17+. 75 using MallocUsableSizeFunction = decltype(malloc_usable_size)*; 76 static MallocUsableSizeFunction usable_size_function = nullptr; 77 if (!usable_size_function) { 78 void* function_ptr = dlsym(RTLD_DEFAULT, "malloc_usable_size"); 79 if (function_ptr) { 80 usable_size_function = reinterpret_cast<MallocUsableSizeFunction>( 81 function_ptr); 82 } else { 83 usable_size_function = &DummyMallocUsableSize; 84 } 85 } 86 return usable_size_function(address); 87 #else 88 return malloc_usable_size(address); 89 #endif 90 #endif // OS_ANDROID 91 92 // TODO(primiano): This should be redirected to malloc_usable_size or 93 // the like. 94 return 0; 95 } 96 97 } // namespace 98 99 const AllocatorDispatch AllocatorDispatch::default_dispatch = { 100 &RealMalloc, /* alloc_function */ 101 &RealCalloc, /* alloc_zero_initialized_function */ 102 &RealMemalign, /* alloc_aligned_function */ 103 &RealRealloc, /* realloc_function */ 104 &RealFree, /* free_function */ 105 &RealSizeEstimate, /* get_size_estimate_function */ 106 nullptr, /* batch_malloc_function */ 107 nullptr, /* batch_free_function */ 108 nullptr, /* free_definite_size_function */ 109 nullptr, /* next */ 110 }; 111