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 namespace scudo {
23 
24 // The combined allocator uses a structure as a template argument that
25 // specifies the configuration options for the various subcomponents of the
26 // allocator.
27 //
28 // struct ExampleConfig {
29 //   // SizeClasMmap to use with the Primary.
30 //   using SizeClassMap = DefaultSizeClassMap;
31 //   // Indicates possible support for Memory Tagging.
32 //   static const bool MaySupportMemoryTagging = false;
33 //   // Defines the Primary allocator to use.
34 //   typedef SizeClassAllocator64<ExampleConfig> Primary;
35 //   // Log2 of the size of a size class region, as used by the Primary.
36 //   static const uptr PrimaryRegionSizeLog = 30U;
37 //   // Defines the type and scale of a compact pointer. A compact pointer can
38 //   // be understood as the offset of a pointer within the region it belongs
39 //   // to, in increments of a power-of-2 scale.
40 //   // eg: Ptr = Base + (CompactPtr << Scale).
41 //   typedef u32 PrimaryCompactPtrT;
42 //   static const uptr PrimaryCompactPtrScale = SCUDO_MIN_ALIGNMENT_LOG;
43 //   // Indicates support for offsetting the start of a region by
44 //   // a random number of pages. Only used with primary64.
45 //   static const bool PrimaryEnableRandomOffset = true;
46 //   // Call map for user memory with at least this size. Only used with
47 //   // primary64.
48 //   static const uptr PrimaryMapSizeIncrement = 1UL << 18;
49 //   // Defines the minimal & maximal release interval that can be set.
50 //   static const s32 PrimaryMinReleaseToOsIntervalMs = INT32_MIN;
51 //   static const s32 PrimaryMaxReleaseToOsIntervalMs = INT32_MAX;
52 //   // Defines the type of cache used by the Secondary. Some additional
53 //   // configuration entries can be necessary depending on the Cache.
54 //   typedef MapAllocatorNoCache SecondaryCache;
55 //   // Thread-Specific Data Registry used, shared or exclusive.
56 //   template <class A> using TSDRegistryT = TSDRegistrySharedT<A, 8U, 4U>;
57 // };
58 
59 // Default configurations for various platforms.
60 
61 struct DefaultConfig {
62   using SizeClassMap = DefaultSizeClassMap;
63   static const bool MaySupportMemoryTagging = true;
64 
65 #if SCUDO_CAN_USE_PRIMARY64
66   typedef SizeClassAllocator64<DefaultConfig> Primary;
67   static const uptr PrimaryRegionSizeLog = 32U;
68   typedef uptr PrimaryCompactPtrT;
69   static const uptr PrimaryCompactPtrScale = 0;
70   static const bool PrimaryEnableRandomOffset = true;
71   static const uptr PrimaryMapSizeIncrement = 1UL << 18;
72 #else
73   typedef SizeClassAllocator32<DefaultConfig> Primary;
74   static const uptr PrimaryRegionSizeLog = 19U;
75   typedef uptr PrimaryCompactPtrT;
76 #endif
77   static const s32 PrimaryMinReleaseToOsIntervalMs = INT32_MIN;
78   static const s32 PrimaryMaxReleaseToOsIntervalMs = INT32_MAX;
79 
80   typedef MapAllocatorCache<DefaultConfig> SecondaryCache;
81   static const u32 SecondaryCacheEntriesArraySize = 32U;
82   static const u32 SecondaryCacheQuarantineSize = 0U;
83   static const u32 SecondaryCacheDefaultMaxEntriesCount = 32U;
84   static const uptr SecondaryCacheDefaultMaxEntrySize = 1UL << 19;
85   static const s32 SecondaryCacheMinReleaseToOsIntervalMs = INT32_MIN;
86   static const s32 SecondaryCacheMaxReleaseToOsIntervalMs = INT32_MAX;
87 
88   template <class A> using TSDRegistryT = TSDRegistryExT<A>; // Exclusive
89 };
90 struct AndroidConfig {
91   using SizeClassMap = AndroidSizeClassMap;
92   static const bool MaySupportMemoryTagging = true;
93 
94 #if SCUDO_CAN_USE_PRIMARY64
95   typedef SizeClassAllocator64<AndroidConfig> Primary;
96   static const uptr PrimaryRegionSizeLog = 28U;
97   typedef u32 PrimaryCompactPtrT;
98   static const uptr PrimaryCompactPtrScale = SCUDO_MIN_ALIGNMENT_LOG;
99   static const bool PrimaryEnableRandomOffset = true;
100   static const uptr PrimaryMapSizeIncrement = 1UL << 18;
101 #else
102   typedef SizeClassAllocator32<AndroidConfig> Primary;
103   static const uptr PrimaryRegionSizeLog = 18U;
104   typedef uptr PrimaryCompactPtrT;
105 #endif
106   static const s32 PrimaryMinReleaseToOsIntervalMs = 1000;
107   static const s32 PrimaryMaxReleaseToOsIntervalMs = 1000;
108 
109   typedef MapAllocatorCache<AndroidConfig> SecondaryCache;
110   static const u32 SecondaryCacheEntriesArraySize = 256U;
111   static const u32 SecondaryCacheQuarantineSize = 32U;
112   static const u32 SecondaryCacheDefaultMaxEntriesCount = 32U;
113   static const uptr SecondaryCacheDefaultMaxEntrySize = 2UL << 20;
114   static const s32 SecondaryCacheMinReleaseToOsIntervalMs = 0;
115   static const s32 SecondaryCacheMaxReleaseToOsIntervalMs = 1000;
116 
117   template <class A>
118   using TSDRegistryT = TSDRegistrySharedT<A, 8U, 2U>; // Shared, max 8 TSDs.
119 };
120 
121 struct AndroidSvelteConfig {
122   using SizeClassMap = SvelteSizeClassMap;
123   static const bool MaySupportMemoryTagging = false;
124 
125 #if SCUDO_CAN_USE_PRIMARY64
126   typedef SizeClassAllocator64<AndroidSvelteConfig> Primary;
127   static const uptr PrimaryRegionSizeLog = 27U;
128   typedef u32 PrimaryCompactPtrT;
129   static const uptr PrimaryCompactPtrScale = SCUDO_MIN_ALIGNMENT_LOG;
130   static const bool PrimaryEnableRandomOffset = true;
131   static const uptr PrimaryMapSizeIncrement = 1UL << 18;
132 #else
133   typedef SizeClassAllocator32<AndroidSvelteConfig> Primary;
134   static const uptr PrimaryRegionSizeLog = 16U;
135   typedef uptr PrimaryCompactPtrT;
136 #endif
137   static const s32 PrimaryMinReleaseToOsIntervalMs = 1000;
138   static const s32 PrimaryMaxReleaseToOsIntervalMs = 1000;
139 
140   typedef MapAllocatorCache<AndroidSvelteConfig> SecondaryCache;
141   static const u32 SecondaryCacheEntriesArraySize = 16U;
142   static const u32 SecondaryCacheQuarantineSize = 32U;
143   static const u32 SecondaryCacheDefaultMaxEntriesCount = 4U;
144   static const uptr SecondaryCacheDefaultMaxEntrySize = 1UL << 18;
145   static const s32 SecondaryCacheMinReleaseToOsIntervalMs = 0;
146   static const s32 SecondaryCacheMaxReleaseToOsIntervalMs = 0;
147 
148   template <class A>
149   using TSDRegistryT = TSDRegistrySharedT<A, 2U, 1U>; // Shared, max 2 TSDs.
150 };
151 
152 #if SCUDO_CAN_USE_PRIMARY64
153 struct FuchsiaConfig {
154   using SizeClassMap = FuchsiaSizeClassMap;
155   static const bool MaySupportMemoryTagging = false;
156 
157   typedef SizeClassAllocator64<FuchsiaConfig> Primary;
158   static const uptr PrimaryRegionSizeLog = 30U;
159   typedef u32 PrimaryCompactPtrT;
160   static const bool PrimaryEnableRandomOffset = true;
161   static const uptr PrimaryMapSizeIncrement = 1UL << 18;
162   static const uptr PrimaryCompactPtrScale = SCUDO_MIN_ALIGNMENT_LOG;
163   static const s32 PrimaryMinReleaseToOsIntervalMs = INT32_MIN;
164   static const s32 PrimaryMaxReleaseToOsIntervalMs = INT32_MAX;
165 
166   typedef MapAllocatorNoCache SecondaryCache;
167   template <class A>
168   using TSDRegistryT = TSDRegistrySharedT<A, 8U, 4U>; // Shared, max 8 TSDs.
169 };
170 
171 struct TrustyConfig {
172   using SizeClassMap = TrustySizeClassMap;
173   static const bool MaySupportMemoryTagging = false;
174 
175   typedef SizeClassAllocator64<TrustyConfig> Primary;
176   // Some apps have 1 page of heap total so small regions are necessary.
177   static const uptr PrimaryRegionSizeLog = 10U;
178   typedef u32 PrimaryCompactPtrT;
179   static const bool PrimaryEnableRandomOffset = false;
180   // Trusty is extremely memory-constrained so minimally round up map calls.
181   static const uptr PrimaryMapSizeIncrement = 1UL << 4;
182   static const uptr PrimaryCompactPtrScale = SCUDO_MIN_ALIGNMENT_LOG;
183   static const s32 PrimaryMinReleaseToOsIntervalMs = INT32_MIN;
184   static const s32 PrimaryMaxReleaseToOsIntervalMs = INT32_MAX;
185 
186   typedef MapAllocatorNoCache SecondaryCache;
187   template <class A>
188   using TSDRegistryT = TSDRegistrySharedT<A, 1U, 1U>; // Shared, max 1 TSD.
189 };
190 #endif
191 
192 #if SCUDO_ANDROID
193 typedef AndroidConfig Config;
194 #elif SCUDO_FUCHSIA
195 typedef FuchsiaConfig Config;
196 #elif SCUDO_TRUSTY
197 typedef TrustyConfig Config;
198 #else
199 typedef DefaultConfig Config;
200 #endif
201 
202 } // namespace scudo
203 
204 #endif // SCUDO_ALLOCATOR_CONFIG_H_
205