1 //===-- allocator_config.h --------------------------------------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #ifndef SCUDO_ALLOCATOR_CONFIG_H_ 10 #define SCUDO_ALLOCATOR_CONFIG_H_ 11 12 #include "combined.h" 13 #include "common.h" 14 #include "condition_variable.h" 15 #include "flags.h" 16 #include "primary32.h" 17 #include "primary64.h" 18 #include "secondary.h" 19 #include "size_class_map.h" 20 #include "tsd_exclusive.h" 21 #include "tsd_shared.h" 22 23 // To import a custom configuration, define `SCUDO_USE_CUSTOM_CONFIG` and 24 // aliasing the `Config` like: 25 // 26 // namespace scudo { 27 // // The instance of Scudo will be initiated with `Config`. 28 // typedef CustomConfig Config; 29 // // Aliasing as default configuration to run the tests with this config. 30 // typedef CustomConfig DefaultConfig; 31 // } // namespace scudo 32 // 33 // Put them in the header `custom_scudo_config.h` then you will be using the 34 // custom configuration and able to run all the tests as well. 35 #ifdef SCUDO_USE_CUSTOM_CONFIG 36 #include "custom_scudo_config.h" 37 #endif 38 39 namespace scudo { 40 41 // The combined allocator uses a structure as a template argument that 42 // specifies the configuration options for the various subcomponents of the 43 // allocator. 44 // 45 // struct ExampleConfig { 46 // // Indicates possible support for Memory Tagging. 47 // static const bool MaySupportMemoryTagging = false; 48 // 49 // // Thread-Specific Data Registry used, shared or exclusive. 50 // template <class A> using TSDRegistryT = TSDRegistrySharedT<A, 8U, 4U>; 51 // 52 // struct Primary { 53 // // SizeClassMap to use with the Primary. 54 // using SizeClassMap = DefaultSizeClassMap; 55 // 56 // // Log2 of the size of a size class region, as used by the Primary. 57 // static const uptr RegionSizeLog = 30U; 58 // 59 // // Log2 of the size of block group, as used by the Primary. Each group 60 // // contains a range of memory addresses, blocks in the range will belong 61 // // to the same group. In general, single region may have 1 or 2MB group 62 // // size. Multiple regions will have the group size equal to the region 63 // // size because the region size is usually smaller than 1 MB. 64 // // Smaller value gives fine-grained control of memory usage but the 65 // // trade-off is that it may take longer time of deallocation. 66 // static const uptr GroupSizeLog = 20U; 67 // 68 // // Defines the type and scale of a compact pointer. A compact pointer can 69 // // be understood as the offset of a pointer within the region it belongs 70 // // to, in increments of a power-of-2 scale. 71 // // eg: Ptr = Base + (CompactPtr << Scale). 72 // typedef u32 CompactPtrT; 73 // static const uptr CompactPtrScale = SCUDO_MIN_ALIGNMENT_LOG; 74 // 75 // // Indicates support for offsetting the start of a region by 76 // // a random number of pages. Only used with primary64. 77 // static const bool EnableRandomOffset = true; 78 // 79 // // Call map for user memory with at least this size. Only used with 80 // // primary64. 81 // static const uptr MapSizeIncrement = 1UL << 18; 82 // 83 // // Defines the minimal & maximal release interval that can be set. 84 // static const s32 MinReleaseToOsIntervalMs = INT32_MIN; 85 // static const s32 MaxReleaseToOsIntervalMs = INT32_MAX; 86 // 87 // // Use condition variable to shorten the waiting time of refillment of 88 // // freelist. Note that this depends on the implementation of condition 89 // // variable on each platform and the performance may vary so that it 90 // // doesn't guarantee a performance benefit. 91 // // Note that both variables have to be defined to enable it. 92 // static const bool UseConditionVariable = true; 93 // using ConditionVariableT = ConditionVariableLinux; 94 // }; 95 // // Defines the type of Primary allocator to use. 96 // template <typename Config> using PrimaryT = SizeClassAllocator64<Config>; 97 // 98 // // Defines the type of cache used by the Secondary. Some additional 99 // // configuration entries can be necessary depending on the Cache. 100 // struct Secondary { 101 // struct Cache { 102 // static const u32 EntriesArraySize = 32U; 103 // static const u32 QuarantineSize = 0U; 104 // static const u32 DefaultMaxEntriesCount = 32U; 105 // static const uptr DefaultMaxEntrySize = 1UL << 19; 106 // static const s32 MinReleaseToOsIntervalMs = INT32_MIN; 107 // static const s32 MaxReleaseToOsIntervalMs = INT32_MAX; 108 // }; 109 // // Defines the type of Secondary Cache to use. 110 // template <typename Config> using CacheT = MapAllocatorCache<Config>; 111 // }; 112 // // Defines the type of Secondary allocator to use. 113 // template <typename Config> using SecondaryT = MapAllocator<Config>; 114 // }; 115 116 #ifndef SCUDO_USE_CUSTOM_CONFIG 117 118 // Default configurations for various platforms. Note this is only enabled when 119 // there's no custom configuration in the build system. 120 struct DefaultConfig { 121 static const bool MaySupportMemoryTagging = true; 122 template <class A> using TSDRegistryT = TSDRegistryExT<A>; // Exclusive 123 124 struct Primary { 125 using SizeClassMap = DefaultSizeClassMap; 126 #if SCUDO_CAN_USE_PRIMARY64 127 static const uptr RegionSizeLog = 32U; 128 static const uptr GroupSizeLog = 21U; 129 typedef uptr CompactPtrT; 130 static const uptr CompactPtrScale = 0; 131 static const bool EnableRandomOffset = true; 132 static const uptr MapSizeIncrement = 1UL << 18; 133 #else 134 static const uptr RegionSizeLog = 19U; 135 static const uptr GroupSizeLog = 19U; 136 typedef uptr CompactPtrT; 137 #endif 138 static const s32 MinReleaseToOsIntervalMs = INT32_MIN; 139 static const s32 MaxReleaseToOsIntervalMs = INT32_MAX; 140 }; 141 #if SCUDO_CAN_USE_PRIMARY64 142 template <typename Config> using PrimaryT = SizeClassAllocator64<Config>; 143 #else 144 template <typename Config> using PrimaryT = SizeClassAllocator32<Config>; 145 #endif 146 147 struct Secondary { 148 struct Cache { 149 static const u32 EntriesArraySize = 32U; 150 static const u32 QuarantineSize = 0U; 151 static const u32 DefaultMaxEntriesCount = 32U; 152 static const uptr DefaultMaxEntrySize = 1UL << 19; 153 static const s32 MinReleaseToOsIntervalMs = INT32_MIN; 154 static const s32 MaxReleaseToOsIntervalMs = INT32_MAX; 155 }; 156 template <typename Config> using CacheT = MapAllocatorCache<Config>; 157 }; 158 159 template <typename Config> using SecondaryT = MapAllocator<Config>; 160 }; 161 162 #endif // SCUDO_USE_CUSTOM_CONFIG 163 164 struct AndroidConfig { 165 static const bool MaySupportMemoryTagging = true; 166 template <class A> 167 using TSDRegistryT = TSDRegistrySharedT<A, 8U, 2U>; // Shared, max 8 TSDs. 168 169 struct Primary { 170 using SizeClassMap = AndroidSizeClassMap; 171 #if SCUDO_CAN_USE_PRIMARY64 172 static const uptr RegionSizeLog = 28U; 173 typedef u32 CompactPtrT; 174 static const uptr CompactPtrScale = SCUDO_MIN_ALIGNMENT_LOG; 175 static const uptr GroupSizeLog = 20U; 176 static const bool EnableRandomOffset = true; 177 static const uptr MapSizeIncrement = 1UL << 18; 178 #else 179 static const uptr RegionSizeLog = 18U; 180 static const uptr GroupSizeLog = 18U; 181 typedef uptr CompactPtrT; 182 #endif 183 static const s32 MinReleaseToOsIntervalMs = 1000; 184 static const s32 MaxReleaseToOsIntervalMs = 1000; 185 }; 186 #if SCUDO_CAN_USE_PRIMARY64 187 template <typename Config> using PrimaryT = SizeClassAllocator64<Config>; 188 #else 189 template <typename Config> using PrimaryT = SizeClassAllocator32<Config>; 190 #endif 191 192 struct Secondary { 193 struct Cache { 194 static const u32 EntriesArraySize = 256U; 195 static const u32 QuarantineSize = 32U; 196 static const u32 DefaultMaxEntriesCount = 32U; 197 static const uptr DefaultMaxEntrySize = 2UL << 20; 198 static const s32 MinReleaseToOsIntervalMs = 0; 199 static const s32 MaxReleaseToOsIntervalMs = 1000; 200 }; 201 template <typename Config> using CacheT = MapAllocatorCache<Config>; 202 }; 203 204 template <typename Config> using SecondaryT = MapAllocator<Config>; 205 }; 206 207 #if SCUDO_CAN_USE_PRIMARY64 208 struct FuchsiaConfig { 209 static const bool MaySupportMemoryTagging = false; 210 template <class A> 211 using TSDRegistryT = TSDRegistrySharedT<A, 8U, 4U>; // Shared, max 8 TSDs. 212 213 struct Primary { 214 using SizeClassMap = FuchsiaSizeClassMap; 215 #if SCUDO_RISCV64 216 // Support 39-bit VMA for riscv-64 217 static const uptr RegionSizeLog = 28U; 218 static const uptr GroupSizeLog = 19U; 219 #else 220 static const uptr RegionSizeLog = 30U; 221 static const uptr GroupSizeLog = 21U; 222 #endif 223 typedef u32 CompactPtrT; 224 static const bool EnableRandomOffset = true; 225 static const uptr MapSizeIncrement = 1UL << 18; 226 static const uptr CompactPtrScale = SCUDO_MIN_ALIGNMENT_LOG; 227 static const s32 MinReleaseToOsIntervalMs = INT32_MIN; 228 static const s32 MaxReleaseToOsIntervalMs = INT32_MAX; 229 }; 230 template <typename Config> using PrimaryT = SizeClassAllocator64<Config>; 231 232 struct Secondary { 233 template <typename Config> using CacheT = MapAllocatorNoCache<Config>; 234 }; 235 template <typename Config> using SecondaryT = MapAllocator<Config>; 236 }; 237 238 struct TrustyConfig { 239 static const bool MaySupportMemoryTagging = true; 240 template <class A> 241 using TSDRegistryT = TSDRegistrySharedT<A, 1U, 1U>; // Shared, max 1 TSD. 242 243 struct Primary { 244 using SizeClassMap = TrustySizeClassMap; 245 static const uptr RegionSizeLog = 28U; 246 static const uptr GroupSizeLog = 20U; 247 typedef u32 CompactPtrT; 248 static const bool EnableRandomOffset = false; 249 static const uptr MapSizeIncrement = 1UL << 12; 250 static const uptr CompactPtrScale = SCUDO_MIN_ALIGNMENT_LOG; 251 static const s32 MinReleaseToOsIntervalMs = INT32_MIN; 252 static const s32 MaxReleaseToOsIntervalMs = INT32_MAX; 253 }; 254 template <typename Config> using PrimaryT = SizeClassAllocator64<Config>; 255 256 struct Secondary { 257 template <typename Config> using CacheT = MapAllocatorNoCache<Config>; 258 }; 259 260 template <typename Config> using SecondaryT = MapAllocator<Config>; 261 }; 262 #endif 263 264 #ifndef SCUDO_USE_CUSTOM_CONFIG 265 266 #if SCUDO_ANDROID 267 typedef AndroidConfig Config; 268 #elif SCUDO_FUCHSIA 269 typedef FuchsiaConfig Config; 270 #elif SCUDO_TRUSTY 271 typedef TrustyConfig Config; 272 #else 273 typedef DefaultConfig Config; 274 #endif 275 276 #endif // SCUDO_USE_CUSTOM_CONFIG 277 278 } // namespace scudo 279 280 #endif // SCUDO_ALLOCATOR_CONFIG_H_ 281