1 // Copyright 2016 The Chromium Authors 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef PARTITION_ALLOC_SHIM_ALLOCATOR_SHIM_H_ 6 #define PARTITION_ALLOC_SHIM_ALLOCATOR_SHIM_H_ 7 8 #include <cstddef> 9 #include <cstdint> 10 11 #include "partition_alloc/partition_alloc_buildflags.h" 12 13 #if BUILDFLAG(USE_ALLOCATOR_SHIM) 14 #include "build/build_config.h" 15 #include "partition_alloc/partition_alloc_base/component_export.h" 16 #include "partition_alloc/partition_alloc_base/types/strong_alias.h" 17 #include "partition_alloc/shim/allocator_dispatch.h" 18 #include "partition_alloc/tagging.h" 19 20 #if BUILDFLAG(USE_PARTITION_ALLOC_AS_MALLOC) && BUILDFLAG(USE_STARSCAN) 21 #include "partition_alloc/starscan/pcscan.h" 22 #endif 23 24 namespace allocator_shim { 25 26 // Allocator Shim API. Allows to: 27 // - Configure the behavior of the allocator (what to do on OOM failures). 28 // - Install new hooks (AllocatorDispatch) in the allocator chain. 29 30 // When this shim layer is enabled, the route of an allocation is as-follows: 31 // 32 // [allocator_shim_override_*.h] Intercept malloc() / operator new calls: 33 // The override_* headers define the symbols required to intercept calls to 34 // malloc() and operator new (if not overridden by specific C++ classes). 35 // 36 // [allocator_shim.cc] Routing allocation calls to the shim: 37 // The headers above route the calls to the internal ShimMalloc(), ShimFree(), 38 // ShimCppNew() etc. methods defined in allocator_shim.cc. 39 // These methods will: (1) forward the allocation call to the front of the 40 // AllocatorDispatch chain. (2) perform security hardenings (e.g., might 41 // call std::new_handler on OOM failure). 42 // 43 // [allocator_shim_default_dispatch_to_*.cc] The AllocatorDispatch chain: 44 // It is a singly linked list where each element is a struct with function 45 // pointers (|malloc_function|, |free_function|, etc). Normally the chain 46 // consists of a single AllocatorDispatch element, herein called 47 // the "default dispatch", which is statically defined at build time and 48 // ultimately routes the calls to the actual allocator defined by the build 49 // config (glibc, ...). 50 // 51 // It is possible to dynamically insert further AllocatorDispatch stages 52 // to the front of the chain, for debugging / profiling purposes. 53 // 54 // All the functions must be thread safe. The shim does not enforce any 55 // serialization. This is to route to thread-aware allocators without 56 // introducing unnecessary perf hits. 57 58 // When true makes malloc behave like new, w.r.t calling the new_handler if 59 // the allocation fails (see set_new_mode() in Windows). 60 PA_COMPONENT_EXPORT(ALLOCATOR_SHIM) 61 void SetCallNewHandlerOnMallocFailure(bool value); 62 63 // Allocates |size| bytes or returns nullptr. It does NOT call the new_handler, 64 // regardless of SetCallNewHandlerOnMallocFailure(). 65 PA_COMPONENT_EXPORT(ALLOCATOR_SHIM) void* UncheckedAlloc(size_t size); 66 67 // Frees memory allocated with UncheckedAlloc(). 68 PA_COMPONENT_EXPORT(ALLOCATOR_SHIM) void UncheckedFree(void* ptr); 69 70 // Inserts |dispatch| in front of the allocator chain. This method is 71 // thread-safe w.r.t concurrent invocations of InsertAllocatorDispatch(). 72 // The callers have responsibility for inserting a single dispatch no more 73 // than once. 74 PA_COMPONENT_EXPORT(ALLOCATOR_SHIM) 75 void InsertAllocatorDispatch(AllocatorDispatch* dispatch); 76 77 // Test-only. Rationale: (1) lack of use cases; (2) dealing safely with a 78 // removal of arbitrary elements from a singly linked list would require a lock 79 // in malloc(), which we really don't want. 80 PA_COMPONENT_EXPORT(ALLOCATOR_SHIM) 81 void RemoveAllocatorDispatchForTesting(AllocatorDispatch* dispatch); 82 83 #if BUILDFLAG(IS_APPLE) 84 // The fallback function to be called when try_free_default_function receives a 85 // pointer which doesn't belong to the allocator. 86 PA_COMPONENT_EXPORT(ALLOCATOR_SHIM) 87 void TryFreeDefaultFallbackToFindZoneAndFree(void* ptr); 88 #endif // BUILDFLAG(IS_APPLE) 89 90 #if BUILDFLAG(IS_APPLE) 91 #if BUILDFLAG(USE_PARTITION_ALLOC_AS_MALLOC) 92 PA_COMPONENT_EXPORT(ALLOCATOR_SHIM) 93 void InitializeDefaultAllocatorPartitionRoot(); 94 bool IsDefaultAllocatorPartitionRootInitialized(); 95 #endif // BUILDFLAG(USE_PARTITION_ALLOC_AS_MALLOC) 96 // On macOS, the allocator shim needs to be turned on during runtime. 97 PA_COMPONENT_EXPORT(ALLOCATOR_SHIM) void InitializeAllocatorShim(); 98 #endif // BUILDFLAG(IS_APPLE) 99 100 #if BUILDFLAG(USE_PARTITION_ALLOC_AS_MALLOC) 101 PA_COMPONENT_EXPORT(ALLOCATOR_SHIM) void EnablePartitionAllocMemoryReclaimer(); 102 103 using EnableBrp = 104 partition_alloc::internal::base::StrongAlias<class EnableBrpTag, bool>; 105 using EnableMemoryTagging = 106 partition_alloc::internal::base::StrongAlias<class EnableMemoryTaggingTag, 107 bool>; 108 enum class BucketDistribution : uint8_t { kNeutral, kDenser }; 109 using SchedulerLoopQuarantine = partition_alloc::internal::base:: 110 StrongAlias<class SchedulerLoopQuarantineTag, bool>; 111 using ZappingByFreeFlags = 112 partition_alloc::internal::base::StrongAlias<class ZappingByFreeFlagsTag, 113 bool>; 114 115 using UsePoolOffsetFreelists = partition_alloc::internal::base:: 116 StrongAlias<class UsePoolOffsetFreelistsTag, bool>; 117 118 // If |thread_cache_on_non_quarantinable_partition| is specified, the 119 // thread-cache will be enabled on the non-quarantinable partition. The 120 // thread-cache on the main (malloc) partition will be disabled. 121 PA_COMPONENT_EXPORT(ALLOCATOR_SHIM) 122 void ConfigurePartitions( 123 EnableBrp enable_brp, 124 EnableMemoryTagging enable_memory_tagging, 125 partition_alloc::TagViolationReportingMode memory_tagging_reporting_mode, 126 BucketDistribution distribution, 127 SchedulerLoopQuarantine scheduler_loop_quarantine, 128 size_t scheduler_loop_quarantine_capacity_in_bytes, 129 ZappingByFreeFlags zapping_by_free_flags, 130 UsePoolOffsetFreelists use_pool_offset_freelists); 131 132 PA_COMPONENT_EXPORT(ALLOCATOR_SHIM) uint32_t GetMainPartitionRootExtrasSize(); 133 134 PA_COMPONENT_EXPORT(ALLOCATOR_SHIM) void AdjustDefaultAllocatorForForeground(); 135 PA_COMPONENT_EXPORT(ALLOCATOR_SHIM) void AdjustDefaultAllocatorForBackground(); 136 137 #if BUILDFLAG(USE_STARSCAN) 138 PA_COMPONENT_EXPORT(ALLOCATOR_SHIM) 139 void EnablePCScan(partition_alloc::internal::PCScan::InitConfig); 140 #endif 141 #endif // BUILDFLAG(USE_PARTITION_ALLOC_AS_MALLOC) 142 143 } // namespace allocator_shim 144 145 #endif // BUILDFLAG(USE_ALLOCATOR_SHIM) 146 147 #endif // PARTITION_ALLOC_SHIM_ALLOCATOR_SHIM_H_ 148