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