Chromium Code Reviews| Index: base/allocator/allocator_shim_override_mac_symbols.h |
| diff --git a/base/allocator/allocator_shim_override_mac_symbols.h b/base/allocator/allocator_shim_override_mac_symbols.h |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..ea47f20e9ecf3045e9be1c7d111360a829608a45 |
| --- /dev/null |
| +++ b/base/allocator/allocator_shim_override_mac_symbols.h |
| @@ -0,0 +1,181 @@ |
| +// Copyright 2016 The Chromium Authors. All rights reserved. |
|
Primiano Tucci (use gerrit)
2017/01/17 17:09:59
s/2016/2017/ happy new year :)
also I think this f
|
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +// This header defines symbols to override the same functions in the Visual C++ |
| +// CRT implementation. |
| + |
| +#ifdef BASE_ALLOCATOR_ALLOCATOR_SHIM_OVERRIDE_MAC_SYMBOLS_H_ |
| +#error This header is meant to be included only once by allocator_shim.cc |
| +#endif |
| +#define BASE_ALLOCATOR_ALLOCATOR_SHIM_OVERRIDE_MAC_SYMBOLS_H_ |
| + |
| +#include <pthread.h> |
| +#include <mach/mach.h> |
| +#include <mach/mach_vm.h> |
| +#include <malloc/malloc.h> |
| + |
| +#include "base/logging.h" |
| +#include "base/mac/mach_logging.h" |
| +#include "base/process/memory.h" |
| +#include "third_party/apple_apsl/malloc.h" |
| + |
| +namespace { |
| + |
| +using base::allocator::AllocatorDispatch; |
| + |
| +ChromeMallocZone g_unshimmed_zone; |
| + |
| +template <class F, class... Args> |
| +auto CallUnshimmed(F ChromeMallocZone::*m, Args... args) |
| + -> decltype(std::declval<F>()(nullptr, args...)) { |
| + F f = g_unshimmed_zone.*m |
| + ? g_unshimmed_zone.*m |
| + : reinterpret_cast<ChromeMallocZone*>(malloc_default_zone())->*m; |
| + return f(malloc_default_zone(), args...); |
| +} |
| + |
| +void* MallocImpl(const AllocatorDispatch*, size_t size) { |
| + return CallUnshimmed(&ChromeMallocZone::malloc, size); |
| +} |
| + |
| +void* CallocImpl(const AllocatorDispatch*, size_t n, size_t size) { |
| + return CallUnshimmed(&ChromeMallocZone::calloc, n, size); |
| +} |
| + |
| +void* MemalignImpl(const AllocatorDispatch*, size_t alignment, size_t size) { |
| + ChromeMallocZone* defaul_zone = |
| + reinterpret_cast<ChromeMallocZone*>(malloc_default_zone()); |
| + if (defaul_zone->version >= 5) { |
| + return CallUnshimmed(&ChromeMallocZone::memalign, alignment, size); |
| + } else if (alignment == GetCachedPageSize()) { |
| + return CallUnshimmed(&ChromeMallocZone::valloc, size); |
| + } else { |
| + CHECK(false) << "memalign() is not implemented."; |
| + return nullptr; |
| + } |
| +} |
| + |
| +void* ReallocImpl(const AllocatorDispatch*, void* ptr, size_t size) { |
| + return CallUnshimmed(&ChromeMallocZone::realloc, ptr, size); |
| +} |
| + |
| +void FreeImpl(const AllocatorDispatch*, void* ptr) { |
| + CallUnshimmed(&ChromeMallocZone::free, ptr); |
| +} |
| + |
| +size_t GetSizeEstimateImpl(const AllocatorDispatch*, void* ptr) { |
| + return CallUnshimmed(&ChromeMallocZone::size, ptr); |
| +} |
| + |
| +unsigned BatchMallocImpl(const AllocatorDispatch* self, |
| + size_t size, |
| + void** results, |
| + unsigned num_requested) { |
| + return CallUnshimmed(&ChromeMallocZone::batch_malloc, size, results, |
| + num_requested); |
| +} |
| + |
| +void BatchFreeImpl(const AllocatorDispatch* self, |
| + void** to_be_freed, |
| + unsigned num_to_be_freed) { |
| + CallUnshimmed(&ChromeMallocZone::batch_free, to_be_freed, num_to_be_freed); |
| +} |
| + |
| +void ShimZoneCallbacks(ChromeMallocZone* zone) { |
|
Primiano Tucci (use gerrit)
2017/01/17 17:09:59
just for clarify I think should be called Initiali
|
| + zone->size = [](malloc_zone_t* zone, const void* ptr) -> size_t { |
| + return ShimGetSizeEstimate(ptr); |
| + }; |
| + zone->malloc = [](malloc_zone_t* zone, size_t size) -> void* { |
| + return ShimMalloc(size); |
| + }; |
| + zone->calloc = [](malloc_zone_t* zone, size_t n, size_t size) -> void* { |
| + return ShimCalloc(n, size); |
| + }; |
| + zone->valloc = [](malloc_zone_t* zone, size_t size) -> void* { |
| + return ShimValloc(size); |
| + }; |
| + zone->free = [](malloc_zone_t* zone, void* ptr) { ShimFree(ptr); }; |
| + zone->realloc = [](malloc_zone_t* zone, void* ptr, size_t size) -> void* { |
| + return ShimRealloc(ptr, size); |
| + }; |
| + zone->batch_malloc = [](struct _malloc_zone_t* zone, size_t size, |
| + void** results, unsigned num_requested) -> unsigned { |
| + return ShimBatchMalloc(size, results, num_requested); |
| + }; |
| + zone->batch_free = [](struct _malloc_zone_t* zone, void** to_be_freed, |
| + unsigned num_to_be_freed) -> void { |
| + ShimBatchFree(to_be_freed, num_to_be_freed); |
| + }; |
| + |
| + if (zone->version >= 5) { |
| + zone->memalign = [](malloc_zone_t* zone, size_t alignment, |
| + size_t size) -> void* { |
| + return ShimMemalign(alignment, size); |
| + }; |
| + } |
| + if (zone->version >= 6) { |
| + zone->free_definite_size = [](malloc_zone_t* zone, void* ptr, size_t size) { |
| + ShimFree(ptr); |
| + }; |
| + } |
| +} |
| + |
| +void InitializeAllocatorShim() { |
| + ChromeMallocZone* default_zone = |
| + reinterpret_cast<ChromeMallocZone*>(malloc_default_zone()); |
| + |
| + mach_vm_address_t default_reprotection_start = 0; |
| + mach_vm_size_t default_reprotection_length = 0; |
| + vm_prot_t default_reprotection_value = VM_PROT_NONE; |
| + base::DeprotectMallocZone(default_zone, &default_reprotection_start, |
| + &default_reprotection_length, |
| + &default_reprotection_value); |
| + |
| + CHECK(default_zone->size && default_zone->malloc && default_zone->calloc && |
| + default_zone->valloc && default_zone->free && default_zone->realloc) |
| + << "Failed to get system allocation functions."; |
| + g_unshimmed_zone.size = default_zone->size; |
| + g_unshimmed_zone.malloc = default_zone->malloc; |
| + g_unshimmed_zone.calloc = default_zone->calloc; |
| + g_unshimmed_zone.valloc = default_zone->valloc; |
| + g_unshimmed_zone.free = default_zone->free; |
| + g_unshimmed_zone.realloc = default_zone->realloc; |
| + g_unshimmed_zone.batch_malloc = default_zone->batch_malloc; |
| + g_unshimmed_zone.batch_free = default_zone->batch_free; |
| + |
| + g_unshimmed_zone.version = default_zone->version; |
| + if (default_zone->version >= 5) { |
| + g_unshimmed_zone.memalign = default_zone->memalign; |
| + } |
| + if (default_zone->version >= 6) { |
| + g_unshimmed_zone.free_definite_size = default_zone->free_definite_size; |
| + } |
| + |
| + ShimZoneCallbacks(default_zone); |
| + |
| + if (default_reprotection_start) { |
| + kern_return_t result = mach_vm_protect( |
| + mach_task_self(), default_reprotection_start, |
| + default_reprotection_length, false, default_reprotection_value); |
| + MACH_CHECK(result == KERN_SUCCESS, result) << "mach_vm_protect"; |
| + } |
| +} |
| + |
| +__attribute__((constructor)) void InitializeAllocatorShimAtDlOpen() { |
| + InitializeAllocatorShim(); |
|
Primiano Tucci (use gerrit)
2017/01/17 17:09:59
Hmm this:
- will cause the static initializers che
|
| +} |
| + |
| +} // namespace |
| + |
| +const AllocatorDispatch AllocatorDispatch::default_dispatch = { |
| + &MallocImpl, /* alloc_function */ |
| + &CallocImpl, /* alloc_zero_initialized_function */ |
| + &MemalignImpl, /* alloc_aligned_function */ |
| + &ReallocImpl, /* realloc_function */ |
| + &FreeImpl, /* free_function */ |
| + &GetSizeEstimateImpl, /* get_size_estimate_function */ |
| + &BatchMallocImpl, /* batch_malloc_function */ |
| + &BatchFreeImpl, /* batch_free_function */ |
| + nullptr, /* next */ |
| +}; |