Home | History | Annotate | Download | only in allocator
      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