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