1*d4514f0bSApple OSS Distributions #ifndef VM_PARAMETER_VALIDATION_H
2*d4514f0bSApple OSS Distributions #define VM_PARAMETER_VALIDATION_H
3*d4514f0bSApple OSS Distributions
4*d4514f0bSApple OSS Distributions
5*d4514f0bSApple OSS Distributions /*
6*d4514f0bSApple OSS Distributions * Common Naming Conventions:
7*d4514f0bSApple OSS Distributions * call_* functions are harnesses used to call a single function under test.
8*d4514f0bSApple OSS Distributions * They take all arguments needed to call the function and avoid calling functions with PANICing values.
9*d4514f0bSApple OSS Distributions * test_* functions are used to call the call_ functions. They iterate through possibilities of interesting parameters
10*d4514f0bSApple OSS Distributions * and provide those as arguments to the call_ functions.
11*d4514f0bSApple OSS Distributions *
12*d4514f0bSApple OSS Distributions * test_* functions are named in the following way:
13*d4514f0bSApple OSS Distributions * Arguments under test are put at the end of the name. e.g. (test_mach_vm_prot) tests a vm_prot_t
14*d4514f0bSApple OSS Distributions * test_mach_... functions test a function with the first argument being a MAP_T.
15*d4514f0bSApple OSS Distributions * test_unix_... functions test a unix-y function. This means it doesn't take a MAP_T.
16*d4514f0bSApple OSS Distributions * In kernel context, it means it operates on current_map instead of an arbitrary vm_map_t
17*d4514f0bSApple OSS Distributions * test_..._with_allocated_... means an allocation has already been created, and some parameters referring to that allocation are passed in.
18*d4514f0bSApple OSS Distributions *
19*d4514f0bSApple OSS Distributions * Common Abbreviations:
20*d4514f0bSApple OSS Distributions * ssz: Start + Start + Size
21*d4514f0bSApple OSS Distributions * ssoo: Start + Size + Offset + Object
22*d4514f0bSApple OSS Distributions * sso: Start + Start + Offset
23*d4514f0bSApple OSS Distributions */
24*d4514f0bSApple OSS Distributions
25*d4514f0bSApple OSS Distributions #include <sys/mman.h>
26*d4514f0bSApple OSS Distributions #if KERNEL
27*d4514f0bSApple OSS Distributions
28*d4514f0bSApple OSS Distributions #include <mach/vm_map.h>
29*d4514f0bSApple OSS Distributions #include <mach/mach_vm.h>
30*d4514f0bSApple OSS Distributions #include <mach/vm_reclaim.h>
31*d4514f0bSApple OSS Distributions #include <mach/mach_types.h>
32*d4514f0bSApple OSS Distributions #include <mach/mach_host.h>
33*d4514f0bSApple OSS Distributions #include <mach/memory_object.h>
34*d4514f0bSApple OSS Distributions #include <mach/memory_entry.h>
35*d4514f0bSApple OSS Distributions #include <mach/mach_vm_server.h>
36*d4514f0bSApple OSS Distributions
37*d4514f0bSApple OSS Distributions #include <device/device_port.h>
38*d4514f0bSApple OSS Distributions #include <sys/mman.h>
39*d4514f0bSApple OSS Distributions #include <sys/errno.h>
40*d4514f0bSApple OSS Distributions #include <vm/memory_object.h>
41*d4514f0bSApple OSS Distributions #include <vm/vm_fault.h>
42*d4514f0bSApple OSS Distributions #include <vm/vm_map_internal.h>
43*d4514f0bSApple OSS Distributions #include <vm/vm_kern_internal.h>
44*d4514f0bSApple OSS Distributions #include <vm/vm_pageout.h>
45*d4514f0bSApple OSS Distributions #include <vm/vm_protos.h>
46*d4514f0bSApple OSS Distributions #include <vm/vm_memtag.h>
47*d4514f0bSApple OSS Distributions #include <vm/vm_memory_entry.h>
48*d4514f0bSApple OSS Distributions #include <vm/vm_memory_entry_xnu.h>
49*d4514f0bSApple OSS Distributions #include <vm/vm_object_internal.h>
50*d4514f0bSApple OSS Distributions #include <vm/vm_iokit.h>
51*d4514f0bSApple OSS Distributions #include <kern/ledger.h>
52*d4514f0bSApple OSS Distributions extern ledger_template_t task_ledger_template;
53*d4514f0bSApple OSS Distributions
54*d4514f0bSApple OSS Distributions #define FLAGS_AND_TAG(f, t) ({ \
55*d4514f0bSApple OSS Distributions vm_map_kernel_flags_t vmk_flags; \
56*d4514f0bSApple OSS Distributions vm_map_kernel_flags_set_vmflags(&vmk_flags, f, t); \
57*d4514f0bSApple OSS Distributions vmk_flags; \
58*d4514f0bSApple OSS Distributions })
59*d4514f0bSApple OSS Distributions
60*d4514f0bSApple OSS Distributions #else // KERNEL
61*d4514f0bSApple OSS Distributions
62*d4514f0bSApple OSS Distributions #include <TargetConditionals.h>
63*d4514f0bSApple OSS Distributions
64*d4514f0bSApple OSS Distributions #endif // KERNEL
65*d4514f0bSApple OSS Distributions
66*d4514f0bSApple OSS Distributions
67*d4514f0bSApple OSS Distributions // ignore some warnings inside this file
68*d4514f0bSApple OSS Distributions #pragma clang diagnostic push
69*d4514f0bSApple OSS Distributions #pragma clang diagnostic ignored "-Wdeclaration-after-statement"
70*d4514f0bSApple OSS Distributions #pragma clang diagnostic ignored "-Wincompatible-function-pointer-types"
71*d4514f0bSApple OSS Distributions #pragma clang diagnostic ignored "-Wmissing-prototypes"
72*d4514f0bSApple OSS Distributions #pragma clang diagnostic ignored "-Wpedantic"
73*d4514f0bSApple OSS Distributions #pragma clang diagnostic ignored "-Wgcc-compat"
74*d4514f0bSApple OSS Distributions
75*d4514f0bSApple OSS Distributions /*
76*d4514f0bSApple OSS Distributions * Invalid values for various types. These are used by the outparameter tests.
77*d4514f0bSApple OSS Distributions * UNLIKELY_ means the value is not 100% guaranteed to be invalid for that type,
78*d4514f0bSApple OSS Distributions * and is just a very unlikely value for it. Tests should not rely on them to compare against UNLIKELY_
79*d4514f0bSApple OSS Distributions * values without explicit reason it cannot be possible.
80*d4514f0bSApple OSS Distributions *
81*d4514f0bSApple OSS Distributions * INVALID_* means the value is 100% guaranteed to be invalid. They can be relied on to be compared against.
82*d4514f0bSApple OSS Distributions */
83*d4514f0bSApple OSS Distributions
84*d4514f0bSApple OSS Distributions #define UNLIKELY_INITIAL_ADDRESS 0xabababab
85*d4514f0bSApple OSS Distributions /*
86*d4514f0bSApple OSS Distributions * It's important for us to never have a test with a size like
87*d4514f0bSApple OSS Distributions * UNLIKELY_INITIAL_SIZE, and for this to stay non page aligned.
88*d4514f0bSApple OSS Distributions * See comment in call_mach_memory_entry_map_size__start_size for more info
89*d4514f0bSApple OSS Distributions */
90*d4514f0bSApple OSS Distributions #define UNLIKELY_INITIAL_SIZE 0xabababab
91*d4514f0bSApple OSS Distributions #define UNLIKELY_INITIAL_PPNUM 0xabababab
92*d4514f0bSApple OSS Distributions #define UNLIKELY_INITIAL_MACH_PORT ((mach_port_t) 0xbabababa)
93*d4514f0bSApple OSS Distributions #define UNLIKELY_INITIAL_VID 0xbabababa
94*d4514f0bSApple OSS Distributions // This cannot possibly be a valid vnode pointer as they are pointers
95*d4514f0bSApple OSS Distributions #define INVALID_VNODE_PTR ((void *) -1)
96*d4514f0bSApple OSS Distributions // This cannot possibly be a valid vm_map_copy_t as they are pointers
97*d4514f0bSApple OSS Distributions #define INVALID_VM_MAP_COPY ((vm_map_copy_t) (void *) -1)
98*d4514f0bSApple OSS Distributions // This cannot be a purgable state (see vm_purgable.h) It's way above the last valid state
99*d4514f0bSApple OSS Distributions #define INVALID_PURGABLE_STATE 0xababab
100*d4514f0bSApple OSS Distributions static_assert(INVALID_PURGABLE_STATE > VM_PURGABLE_STATE_MAX, "This test requires a purgable state above the max");
101*d4514f0bSApple OSS Distributions // Disposition values are generated via the VM_PAGE_QUERY_ values being ored.
102*d4514f0bSApple OSS Distributions // This cannot be a valid one as it's above the greatest possible or
103*d4514f0bSApple OSS Distributions #define INVALID_DISPOSITION_VALUE 0xffffff0
104*d4514f0bSApple OSS Distributions #define INVALID_INHERIT 0xbaba
105*d4514f0bSApple OSS Distributions static_assert(INVALID_INHERIT > VM_INHERIT_LAST_VALID, "This test requires an inheritance above the max");
106*d4514f0bSApple OSS Distributions
107*d4514f0bSApple OSS Distributions #define INVALID_INITIAL_VID 0xbabababa
108*d4514f0bSApple OSS Distributions // output buffer size for kext/xnu sysctl tests
109*d4514f0bSApple OSS Distributions // note: 1 GB is too big for watchOS
110*d4514f0bSApple OSS Distributions static const int64_t SYSCTL_OUTPUT_BUFFER_SIZE = 512 * 1024 * 1024; // 512 MB
111*d4514f0bSApple OSS Distributions
112*d4514f0bSApple OSS Distributions // caller name (kernel/kext/userspace), used to label the output
113*d4514f0bSApple OSS Distributions #if KERNEL
114*d4514f0bSApple OSS Distributions # define CALLER_NAME "kernel"
115*d4514f0bSApple OSS Distributions #else
116*d4514f0bSApple OSS Distributions # define CALLER_NAME "userspace"
117*d4514f0bSApple OSS Distributions #endif
118*d4514f0bSApple OSS Distributions
119*d4514f0bSApple OSS Distributions // os name, used to label the output
120*d4514f0bSApple OSS Distributions #if KERNEL
121*d4514f0bSApple OSS Distributions # if XNU_TARGET_OS_OSX
122*d4514f0bSApple OSS Distributions # define OS_NAME "macos"
123*d4514f0bSApple OSS Distributions # elif XNU_TARGET_OS_IOS
124*d4514f0bSApple OSS Distributions # define OS_NAME "ios"
125*d4514f0bSApple OSS Distributions # elif XNU_TARGET_OS_TV
126*d4514f0bSApple OSS Distributions # define OS_NAME "tvos"
127*d4514f0bSApple OSS Distributions # elif XNU_TARGET_OS_WATCH
128*d4514f0bSApple OSS Distributions # define OS_NAME "watchos"
129*d4514f0bSApple OSS Distributions # elif XNU_TARGET_OS_BRIDGE
130*d4514f0bSApple OSS Distributions # define OS_NAME "bridgeos"
131*d4514f0bSApple OSS Distributions # else
132*d4514f0bSApple OSS Distributions # define OS_NAME "unknown-os"
133*d4514f0bSApple OSS Distributions # endif
134*d4514f0bSApple OSS Distributions #else
135*d4514f0bSApple OSS Distributions # if TARGET_OS_OSX
136*d4514f0bSApple OSS Distributions # define OS_NAME "macos"
137*d4514f0bSApple OSS Distributions # elif TARGET_OS_MACCATALYST
138*d4514f0bSApple OSS Distributions # define OS_NAME "catalyst"
139*d4514f0bSApple OSS Distributions # elif TARGET_OS_IOS
140*d4514f0bSApple OSS Distributions # define OS_NAME "ios"
141*d4514f0bSApple OSS Distributions # elif TARGET_OS_TV
142*d4514f0bSApple OSS Distributions # define OS_NAME "tvos"
143*d4514f0bSApple OSS Distributions # elif TARGET_OS_WATCH
144*d4514f0bSApple OSS Distributions # define OS_NAME "watchos"
145*d4514f0bSApple OSS Distributions # elif TARGET_OS_BRIDGE
146*d4514f0bSApple OSS Distributions # define OS_NAME "bridgeos"
147*d4514f0bSApple OSS Distributions # else
148*d4514f0bSApple OSS Distributions # define OS_NAME "unknown-os"
149*d4514f0bSApple OSS Distributions # endif
150*d4514f0bSApple OSS Distributions #endif
151*d4514f0bSApple OSS Distributions
152*d4514f0bSApple OSS Distributions // architecture name, used to label the output
153*d4514f0bSApple OSS Distributions #if KERNEL
154*d4514f0bSApple OSS Distributions # if __i386__
155*d4514f0bSApple OSS Distributions # define ARCH_NAME "i386"
156*d4514f0bSApple OSS Distributions # elif __x86_64__
157*d4514f0bSApple OSS Distributions # define ARCH_NAME "x86_64"
158*d4514f0bSApple OSS Distributions # elif __arm64__ && __LP64__
159*d4514f0bSApple OSS Distributions # define ARCH_NAME "arm64"
160*d4514f0bSApple OSS Distributions # elif __arm64__ && !__LP64__
161*d4514f0bSApple OSS Distributions # define ARCH_NAME "arm64_32"
162*d4514f0bSApple OSS Distributions # elif __arm__
163*d4514f0bSApple OSS Distributions # define ARCH_NAME "arm"
164*d4514f0bSApple OSS Distributions # else
165*d4514f0bSApple OSS Distributions # define ARCH_NAME "unknown-arch"
166*d4514f0bSApple OSS Distributions # endif
167*d4514f0bSApple OSS Distributions #else
168*d4514f0bSApple OSS Distributions # if TARGET_CPU_X86
169*d4514f0bSApple OSS Distributions # define ARCH_NAME "i386"
170*d4514f0bSApple OSS Distributions # elif TARGET_CPU_X86_64
171*d4514f0bSApple OSS Distributions # define ARCH_NAME "x86_64"
172*d4514f0bSApple OSS Distributions # elif TARGET_CPU_ARM64 && __LP64__
173*d4514f0bSApple OSS Distributions # define ARCH_NAME "arm64"
174*d4514f0bSApple OSS Distributions # elif TARGET_CPU_ARM64 && !__LP64__
175*d4514f0bSApple OSS Distributions # define ARCH_NAME "arm64_32"
176*d4514f0bSApple OSS Distributions # elif TARGET_CPU_ARM
177*d4514f0bSApple OSS Distributions # define ARCH_NAME "arm"
178*d4514f0bSApple OSS Distributions # else
179*d4514f0bSApple OSS Distributions # define ARCH_NAME "unknown-arch"
180*d4514f0bSApple OSS Distributions # endif
181*d4514f0bSApple OSS Distributions #endif
182*d4514f0bSApple OSS Distributions
183*d4514f0bSApple OSS Distributions #if KERNEL
184*d4514f0bSApple OSS Distributions # define MAP_T vm_map_t
185*d4514f0bSApple OSS Distributions #else
186*d4514f0bSApple OSS Distributions # define MAP_T mach_port_t
187*d4514f0bSApple OSS Distributions #endif
188*d4514f0bSApple OSS Distributions
189*d4514f0bSApple OSS Distributions // Mach has new-style functions with 64-bit address and size
190*d4514f0bSApple OSS Distributions // and old-style functions with pointer-size address and size.
191*d4514f0bSApple OSS Distributions // On U64 platforms both names send the same MIG message
192*d4514f0bSApple OSS Distributions // and run the same kernel code so we need not test both.
193*d4514f0bSApple OSS Distributions // On U32 platforms they are different inside the kernel.
194*d4514f0bSApple OSS Distributions // fixme for kext/kernel, verify that vm32 entrypoints are not used and not exported
195*d4514f0bSApple OSS Distributions #if KERNEL || __LP64__
196*d4514f0bSApple OSS Distributions # define TEST_OLD_STYLE_MACH 0
197*d4514f0bSApple OSS Distributions #else
198*d4514f0bSApple OSS Distributions # define TEST_OLD_STYLE_MACH 1
199*d4514f0bSApple OSS Distributions #endif
200*d4514f0bSApple OSS Distributions
201*d4514f0bSApple OSS Distributions // always 64-bit: addr_t, mach_vm_address/size_t, memory_object_size/offset_t
202*d4514f0bSApple OSS Distributions // always 32-bit: mach_msg_type_number_t, natural_t
203*d4514f0bSApple OSS Distributions // pointer-size: void*, vm_address_t, vm_size_t
204*d4514f0bSApple OSS Distributions typedef uint64_t addr_t;
205*d4514f0bSApple OSS Distributions
206*d4514f0bSApple OSS Distributions // We often use 4KB or 16KB instead of PAGE_SIZE
207*d4514f0bSApple OSS Distributions // (for example using 16KB instead of PAGE_SIZE to avoid Rosetta complications)
208*d4514f0bSApple OSS Distributions #define KB4 ((addr_t)4*1024)
209*d4514f0bSApple OSS Distributions #define KB16 ((addr_t)16*1024)
210*d4514f0bSApple OSS Distributions
211*d4514f0bSApple OSS Distributions // Allocation size commonly used in tests.
212*d4514f0bSApple OSS Distributions // This size is big enough that our trials of small
213*d4514f0bSApple OSS Distributions // address offsets and sizes will still fit inside it.
214*d4514f0bSApple OSS Distributions #define TEST_ALLOC_SIZE (4 * KB16)
215*d4514f0bSApple OSS Distributions
216*d4514f0bSApple OSS Distributions // Magic return codes used for in-band signalling.
217*d4514f0bSApple OSS Distributions // These must avoid kern_return_t and errno values.
218*d4514f0bSApple OSS Distributions #define BUSTED -99 // trial is broken
219*d4514f0bSApple OSS Distributions #define IGNORED -98 // trial not performed for acceptable reasons
220*d4514f0bSApple OSS Distributions #define ZEROSIZE -97 // trial succeeded because size==0 (FAKE tests only)
221*d4514f0bSApple OSS Distributions #define PANIC -96 // trial not performed because it would provoke a panic
222*d4514f0bSApple OSS Distributions #define GUARD -95 // trial not performed because it would provoke EXC_GUARD
223*d4514f0bSApple OSS Distributions #define ACCEPTABLE -94 // trial should be considered successful no matter what the golden result is
224*d4514f0bSApple OSS Distributions #define OUT_PARAM_BAD -93 // trial has incorrect setting of out parameter values
225*d4514f0bSApple OSS Distributions
226*d4514f0bSApple OSS Distributions static inline bool
is_fake_error(int err)227*d4514f0bSApple OSS Distributions is_fake_error(int err)
228*d4514f0bSApple OSS Distributions {
229*d4514f0bSApple OSS Distributions return err == BUSTED || err == IGNORED || err == ZEROSIZE ||
230*d4514f0bSApple OSS Distributions err == PANIC || err == GUARD || err == OUT_PARAM_BAD;
231*d4514f0bSApple OSS Distributions }
232*d4514f0bSApple OSS Distributions
233*d4514f0bSApple OSS Distributions // Return the count of a (non-decayed!) array.
234*d4514f0bSApple OSS Distributions #define countof(array) (sizeof(array) / sizeof((array)[0]))
235*d4514f0bSApple OSS Distributions
236*d4514f0bSApple OSS Distributions #if !KERNEL
237*d4514f0bSApple OSS Distributions static inline uint64_t
VM_MAP_PAGE_SIZE(MAP_T map __unused)238*d4514f0bSApple OSS Distributions VM_MAP_PAGE_SIZE(MAP_T map __unused)
239*d4514f0bSApple OSS Distributions {
240*d4514f0bSApple OSS Distributions // fixme wrong for out-of-process maps
241*d4514f0bSApple OSS Distributions // on platforms that support processes with two different page sizes
242*d4514f0bSApple OSS Distributions return PAGE_SIZE;
243*d4514f0bSApple OSS Distributions }
244*d4514f0bSApple OSS Distributions
245*d4514f0bSApple OSS Distributions static inline uint64_t
VM_MAP_PAGE_MASK(MAP_T map __unused)246*d4514f0bSApple OSS Distributions VM_MAP_PAGE_MASK(MAP_T map __unused)
247*d4514f0bSApple OSS Distributions {
248*d4514f0bSApple OSS Distributions // fixme wrong for out-of-process maps
249*d4514f0bSApple OSS Distributions // on platforms that support processes with two different page sizes
250*d4514f0bSApple OSS Distributions return PAGE_MASK;
251*d4514f0bSApple OSS Distributions }
252*d4514f0bSApple OSS Distributions #endif
253*d4514f0bSApple OSS Distributions
254*d4514f0bSApple OSS Distributions
255*d4514f0bSApple OSS Distributions #define IMPL(T) \
256*d4514f0bSApple OSS Distributions /* Round up to the given page mask. */ \
257*d4514f0bSApple OSS Distributions __attribute__((overloadable, used)) \
258*d4514f0bSApple OSS Distributions static inline T \
259*d4514f0bSApple OSS Distributions vm_sanitize_map_round_page_mask(T addr, uint64_t pagemask) { \
260*d4514f0bSApple OSS Distributions return (addr + (T)pagemask) & ~((T)pagemask); \
261*d4514f0bSApple OSS Distributions } \
262*d4514f0bSApple OSS Distributions \
263*d4514f0bSApple OSS Distributions /* Round up to the given page size. */ \
264*d4514f0bSApple OSS Distributions __attribute__((overloadable, used)) \
265*d4514f0bSApple OSS Distributions static inline T \
266*d4514f0bSApple OSS Distributions round_up_page(T addr, uint64_t pagesize) { \
267*d4514f0bSApple OSS Distributions return vm_sanitize_map_round_page_mask(addr, pagesize - 1); \
268*d4514f0bSApple OSS Distributions } \
269*d4514f0bSApple OSS Distributions \
270*d4514f0bSApple OSS Distributions /* Round up to the given map's page size. */ \
271*d4514f0bSApple OSS Distributions __attribute__((overloadable, used)) \
272*d4514f0bSApple OSS Distributions static inline T \
273*d4514f0bSApple OSS Distributions round_up_map(MAP_T map, T addr) { \
274*d4514f0bSApple OSS Distributions return vm_sanitize_map_round_page_mask(addr, VM_MAP_PAGE_MASK(map)); \
275*d4514f0bSApple OSS Distributions } \
276*d4514f0bSApple OSS Distributions \
277*d4514f0bSApple OSS Distributions /* Truncate to the given page mask. */ \
278*d4514f0bSApple OSS Distributions __attribute__((overloadable, used)) \
279*d4514f0bSApple OSS Distributions static inline T \
280*d4514f0bSApple OSS Distributions vm_sanitize_map_trunc_page_mask(T addr, uint64_t pagemask) \
281*d4514f0bSApple OSS Distributions { \
282*d4514f0bSApple OSS Distributions return addr & ~((T)pagemask); \
283*d4514f0bSApple OSS Distributions } \
284*d4514f0bSApple OSS Distributions \
285*d4514f0bSApple OSS Distributions /* Truncate to the given page size. */ \
286*d4514f0bSApple OSS Distributions __attribute__((overloadable, used)) \
287*d4514f0bSApple OSS Distributions static inline T \
288*d4514f0bSApple OSS Distributions trunc_down_page(T addr, uint64_t pagesize) \
289*d4514f0bSApple OSS Distributions { \
290*d4514f0bSApple OSS Distributions return vm_sanitize_map_trunc_page_mask(addr, pagesize - 1); \
291*d4514f0bSApple OSS Distributions } \
292*d4514f0bSApple OSS Distributions \
293*d4514f0bSApple OSS Distributions /* Truncate to the given map's page size. */ \
294*d4514f0bSApple OSS Distributions __attribute__((overloadable, used)) \
295*d4514f0bSApple OSS Distributions static inline T \
296*d4514f0bSApple OSS Distributions trunc_down_map(MAP_T map, T addr) \
297*d4514f0bSApple OSS Distributions { \
298*d4514f0bSApple OSS Distributions return vm_sanitize_map_trunc_page_mask(addr, VM_MAP_PAGE_MASK(map)); \
299*d4514f0bSApple OSS Distributions } \
300*d4514f0bSApple OSS Distributions \
301*d4514f0bSApple OSS Distributions __attribute__((overloadable, unavailable("use round_up_page instead"))) \
302*d4514f0bSApple OSS Distributions extern T \
303*d4514f0bSApple OSS Distributions round_up(T addr, uint64_t pagesize); \
304*d4514f0bSApple OSS Distributions __attribute__((overloadable, unavailable("use trunc_down_page instead"))) \
305*d4514f0bSApple OSS Distributions extern T \
306*d4514f0bSApple OSS Distributions trunc_down(T addr, uint64_t pagesize);
307*d4514f0bSApple OSS Distributions
308*d4514f0bSApple OSS Distributions IMPL(uint64_t)
IMPL(uint32_t)309*d4514f0bSApple OSS Distributions IMPL(uint32_t)
310*d4514f0bSApple OSS Distributions #undef IMPL
311*d4514f0bSApple OSS Distributions
312*d4514f0bSApple OSS Distributions
313*d4514f0bSApple OSS Distributions // duplicate the logic of VM's vm_map_range_overflows()
314*d4514f0bSApple OSS Distributions // false == good start+size combo, true == bad combo
315*d4514f0bSApple OSS Distributions #define IMPL(T) \
316*d4514f0bSApple OSS Distributions __attribute__((overloadable, used)) \
317*d4514f0bSApple OSS Distributions static bool \
318*d4514f0bSApple OSS Distributions vm_sanitize_range_overflows_allow_zero(T start, T size, T pgmask) \
319*d4514f0bSApple OSS Distributions { \
320*d4514f0bSApple OSS Distributions if (size == 0) { \
321*d4514f0bSApple OSS Distributions return false; \
322*d4514f0bSApple OSS Distributions } \
323*d4514f0bSApple OSS Distributions \
324*d4514f0bSApple OSS Distributions T sum; \
325*d4514f0bSApple OSS Distributions if (__builtin_add_overflow(start, size, &sum)) { \
326*d4514f0bSApple OSS Distributions return true; \
327*d4514f0bSApple OSS Distributions } \
328*d4514f0bSApple OSS Distributions \
329*d4514f0bSApple OSS Distributions T aligned_start = vm_sanitize_map_trunc_page_mask(start, pgmask); \
330*d4514f0bSApple OSS Distributions T aligned_end = vm_sanitize_map_round_page_mask(start + size, pgmask); \
331*d4514f0bSApple OSS Distributions if (aligned_end <= aligned_start) { \
332*d4514f0bSApple OSS Distributions return true; \
333*d4514f0bSApple OSS Distributions } \
334*d4514f0bSApple OSS Distributions \
335*d4514f0bSApple OSS Distributions return false; \
336*d4514f0bSApple OSS Distributions } \
337*d4514f0bSApple OSS Distributions \
338*d4514f0bSApple OSS Distributions /* like vm_sanitize_range_overflows_allow_zero(), but without the */ \
339*d4514f0bSApple OSS Distributions /* unconditional approval of size==0 */ \
340*d4514f0bSApple OSS Distributions __attribute__((overloadable, used)) \
341*d4514f0bSApple OSS Distributions static bool \
342*d4514f0bSApple OSS Distributions vm_sanitize_range_overflows_strict_zero(T start, T size, T pgmask) \
343*d4514f0bSApple OSS Distributions { \
344*d4514f0bSApple OSS Distributions T sum; \
345*d4514f0bSApple OSS Distributions if (__builtin_add_overflow(start, size, &sum)) { \
346*d4514f0bSApple OSS Distributions return true; \
347*d4514f0bSApple OSS Distributions } \
348*d4514f0bSApple OSS Distributions \
349*d4514f0bSApple OSS Distributions T aligned_start = vm_sanitize_map_trunc_page_mask(start, pgmask); \
350*d4514f0bSApple OSS Distributions T aligned_end = vm_sanitize_map_round_page_mask(start + size, pgmask); \
351*d4514f0bSApple OSS Distributions if (aligned_end <= aligned_start) { \
352*d4514f0bSApple OSS Distributions return true; \
353*d4514f0bSApple OSS Distributions } \
354*d4514f0bSApple OSS Distributions \
355*d4514f0bSApple OSS Distributions return false; \
356*d4514f0bSApple OSS Distributions } \
357*d4514f0bSApple OSS Distributions
358*d4514f0bSApple OSS Distributions IMPL(uint64_t)
359*d4514f0bSApple OSS Distributions IMPL(uint32_t)
360*d4514f0bSApple OSS Distributions #undef IMPL
361*d4514f0bSApple OSS Distributions
362*d4514f0bSApple OSS Distributions
363*d4514f0bSApple OSS Distributions // return true if the process is running under Rosetta translation
364*d4514f0bSApple OSS Distributions // https://developer.apple.com/documentation/apple-silicon/about-the-rosetta-translation-environment#Determine-Whether-Your-App-Is-Running-as-a-Translated-Binary
365*d4514f0bSApple OSS Distributions static bool
366*d4514f0bSApple OSS Distributions isRosetta()
367*d4514f0bSApple OSS Distributions {
368*d4514f0bSApple OSS Distributions #if KERNEL
369*d4514f0bSApple OSS Distributions return false;
370*d4514f0bSApple OSS Distributions #else
371*d4514f0bSApple OSS Distributions int out_value = 0;
372*d4514f0bSApple OSS Distributions size_t io_size = sizeof(out_value);
373*d4514f0bSApple OSS Distributions if (sysctlbyname("sysctl.proc_translated", &out_value, &io_size, NULL, 0) == 0) {
374*d4514f0bSApple OSS Distributions assert(io_size >= sizeof(out_value));
375*d4514f0bSApple OSS Distributions return out_value;
376*d4514f0bSApple OSS Distributions }
377*d4514f0bSApple OSS Distributions return false;
378*d4514f0bSApple OSS Distributions #endif
379*d4514f0bSApple OSS Distributions }
380*d4514f0bSApple OSS Distributions
381*d4514f0bSApple OSS Distributions // Needed to distinguish between rosetta kernel runs and generating trials names from kern golden files.
382*d4514f0bSApple OSS Distributions #if KERNEL
383*d4514f0bSApple OSS Distributions #define kern_trialname_generation FALSE
384*d4514f0bSApple OSS Distributions #else
385*d4514f0bSApple OSS Distributions static bool kern_trialname_generation = FALSE;
386*d4514f0bSApple OSS Distributions #endif
387*d4514f0bSApple OSS Distributions static addr_t trial_page_size = 0;
388*d4514f0bSApple OSS Distributions
389*d4514f0bSApple OSS Distributions static inline addr_t
adjust_page_size()390*d4514f0bSApple OSS Distributions adjust_page_size()
391*d4514f0bSApple OSS Distributions {
392*d4514f0bSApple OSS Distributions addr_t test_page_size = PAGE_SIZE;
393*d4514f0bSApple OSS Distributions #if !KERNEL && __x86_64__
394*d4514f0bSApple OSS Distributions // Handle kernel page size variation while recreating trials names for golden files in userspace.
395*d4514f0bSApple OSS Distributions if (kern_trialname_generation && isRosetta()) {
396*d4514f0bSApple OSS Distributions test_page_size = trial_page_size;
397*d4514f0bSApple OSS Distributions }
398*d4514f0bSApple OSS Distributions #endif // !KERNEL && __x86_64__
399*d4514f0bSApple OSS Distributions return test_page_size;
400*d4514f0bSApple OSS Distributions }
401*d4514f0bSApple OSS Distributions
402*d4514f0bSApple OSS Distributions #if KERNEL
403*d4514f0bSApple OSS Distributions // Knobs controlled from userspace (and passed in MSB of the file_descriptor)
404*d4514f0bSApple OSS Distributions extern bool kernel_generate_golden;
405*d4514f0bSApple OSS Distributions #else
406*d4514f0bSApple OSS Distributions // Knobs controlled by environment variables
407*d4514f0bSApple OSS Distributions extern bool dump;
408*d4514f0bSApple OSS Distributions extern bool generate_golden;
409*d4514f0bSApple OSS Distributions extern bool dump_golden;
410*d4514f0bSApple OSS Distributions extern int out_param_bad_count;
411*d4514f0bSApple OSS Distributions extern bool should_test_results;
412*d4514f0bSApple OSS Distributions static void
read_env()413*d4514f0bSApple OSS Distributions read_env()
414*d4514f0bSApple OSS Distributions {
415*d4514f0bSApple OSS Distributions dump = (getenv("DUMP_RESULTS") != NULL);
416*d4514f0bSApple OSS Distributions dump_golden = (getenv("DUMP_GOLDEN_IMAGE") != NULL);
417*d4514f0bSApple OSS Distributions // Shouldn't do both
418*d4514f0bSApple OSS Distributions generate_golden = (getenv("GENERATE_GOLDEN_IMAGE") != NULL) && !dump_golden;
419*d4514f0bSApple OSS Distributions // Only test when no other golden image flag is set
420*d4514f0bSApple OSS Distributions should_test_results = (getenv("SKIP_TESTS") == NULL) && !dump_golden && !generate_golden;
421*d4514f0bSApple OSS Distributions }
422*d4514f0bSApple OSS Distributions #endif
423*d4514f0bSApple OSS Distributions
424*d4514f0bSApple OSS Distributions
425*d4514f0bSApple OSS Distributions /////////////////////////////////////////////////////
426*d4514f0bSApple OSS Distributions // String functions that work in both kernel and userspace.
427*d4514f0bSApple OSS Distributions
428*d4514f0bSApple OSS Distributions // Test output function.
429*d4514f0bSApple OSS Distributions // This prints either to stdout (userspace tests) or to a userspace buffer (kernel sysctl tests)
430*d4514f0bSApple OSS Distributions // Golden tests generation in userspace also writes to a buffer (GOLDEN_OUTPUT_BUF)
431*d4514f0bSApple OSS Distributions #if KERNEL
432*d4514f0bSApple OSS Distributions extern void testprintf(const char *, ...) __printflike(1, 2);
433*d4514f0bSApple OSS Distributions #define goldenprintf testprintf
434*d4514f0bSApple OSS Distributions #else
435*d4514f0bSApple OSS Distributions #define testprintf printf
436*d4514f0bSApple OSS Distributions extern void goldenprintf(const char *, ...) __printflike(1, 2);
437*d4514f0bSApple OSS Distributions #endif
438*d4514f0bSApple OSS Distributions
439*d4514f0bSApple OSS Distributions // kstrdup() is like strdup() but in the kernel it uses kalloc_data()
440*d4514f0bSApple OSS Distributions static inline char *
kstrdup(const char * str)441*d4514f0bSApple OSS Distributions kstrdup(const char *str)
442*d4514f0bSApple OSS Distributions {
443*d4514f0bSApple OSS Distributions #if KERNEL
444*d4514f0bSApple OSS Distributions size_t size = strlen(str) + 1;
445*d4514f0bSApple OSS Distributions char *copy = kalloc_data(size, Z_WAITOK | Z_ZERO);
446*d4514f0bSApple OSS Distributions memcpy(copy, str, size);
447*d4514f0bSApple OSS Distributions return copy;
448*d4514f0bSApple OSS Distributions #else
449*d4514f0bSApple OSS Distributions return strdup(str);
450*d4514f0bSApple OSS Distributions #endif
451*d4514f0bSApple OSS Distributions }
452*d4514f0bSApple OSS Distributions
453*d4514f0bSApple OSS Distributions // kfree_str() is like free() but in the kernel it uses kfree_data_addr()
454*d4514f0bSApple OSS Distributions static inline void
kfree_str(char * str)455*d4514f0bSApple OSS Distributions kfree_str(char *str)
456*d4514f0bSApple OSS Distributions {
457*d4514f0bSApple OSS Distributions #if KERNEL
458*d4514f0bSApple OSS Distributions kfree_data_addr(str);
459*d4514f0bSApple OSS Distributions #else
460*d4514f0bSApple OSS Distributions free(str);
461*d4514f0bSApple OSS Distributions #endif
462*d4514f0bSApple OSS Distributions }
463*d4514f0bSApple OSS Distributions
464*d4514f0bSApple OSS Distributions // kasprintf() is like asprintf() but in the kernel it uses kalloc_data()
465*d4514f0bSApple OSS Distributions
466*d4514f0bSApple OSS Distributions #if !KERNEL
467*d4514f0bSApple OSS Distributions # define kasprintf asprintf
468*d4514f0bSApple OSS Distributions #else
469*d4514f0bSApple OSS Distributions extern int vsnprintf(char *, size_t, const char *, va_list) __printflike(3, 0);
470*d4514f0bSApple OSS Distributions static inline int
kasprintf(char ** __restrict out_str,const char * __restrict format,...)471*d4514f0bSApple OSS Distributions kasprintf(char ** __restrict out_str, const char * __restrict format, ...) __printflike(2, 3)
472*d4514f0bSApple OSS Distributions {
473*d4514f0bSApple OSS Distributions va_list args1, args2;
474*d4514f0bSApple OSS Distributions
475*d4514f0bSApple OSS Distributions // compute length
476*d4514f0bSApple OSS Distributions char c;
477*d4514f0bSApple OSS Distributions va_start(args1, format);
478*d4514f0bSApple OSS Distributions va_copy(args2, args1);
479*d4514f0bSApple OSS Distributions int len1 = vsnprintf(&c, sizeof(c), format, args1);
480*d4514f0bSApple OSS Distributions va_end(args1);
481*d4514f0bSApple OSS Distributions if (len1 < 0) {
482*d4514f0bSApple OSS Distributions *out_str = NULL;
483*d4514f0bSApple OSS Distributions return len1;
484*d4514f0bSApple OSS Distributions }
485*d4514f0bSApple OSS Distributions
486*d4514f0bSApple OSS Distributions // allocate and print
487*d4514f0bSApple OSS Distributions char *str = kalloc_data(len1 + 1, Z_NOFAIL);
488*d4514f0bSApple OSS Distributions int len2 = vsnprintf(str, len1 + 1, format, args2);
489*d4514f0bSApple OSS Distributions va_end(args2);
490*d4514f0bSApple OSS Distributions if (len2 < 0) {
491*d4514f0bSApple OSS Distributions kfree_data_addr(str);
492*d4514f0bSApple OSS Distributions *out_str = NULL;
493*d4514f0bSApple OSS Distributions return len1;
494*d4514f0bSApple OSS Distributions }
495*d4514f0bSApple OSS Distributions assert(len1 == len2);
496*d4514f0bSApple OSS Distributions
497*d4514f0bSApple OSS Distributions *out_str = str;
498*d4514f0bSApple OSS Distributions return len1;
499*d4514f0bSApple OSS Distributions }
500*d4514f0bSApple OSS Distributions // KERNEL
501*d4514f0bSApple OSS Distributions #endif
502*d4514f0bSApple OSS Distributions
503*d4514f0bSApple OSS Distributions
504*d4514f0bSApple OSS Distributions /////////////////////////////////////////////////////
505*d4514f0bSApple OSS Distributions // Record trials and return values from tested functions (BSD int or Mach kern_return_t)
506*d4514f0bSApple OSS Distributions
507*d4514f0bSApple OSS Distributions // Maintain list of known trials "smart" generator functions (trial formulae) as
508*d4514f0bSApple OSS Distributions // these are included in the golden result list (keeping the enum forces people to
509*d4514f0bSApple OSS Distributions // maintain the list up-to-date when adding new functions).
510*d4514f0bSApple OSS Distributions #define TRIALSFORMULA_ENUM(VARIANT) \
511*d4514f0bSApple OSS Distributions VARIANT(eUNKNOWN_TRIALS) \
512*d4514f0bSApple OSS Distributions VARIANT(eSMART_VM_MAP_KERNEL_FLAGS_TRIALS) \
513*d4514f0bSApple OSS Distributions VARIANT(eSMART_VM_INHERIT_TRIALS) \
514*d4514f0bSApple OSS Distributions VARIANT(eSMART_MMAP_KERNEL_FLAGS_TRIALS) \
515*d4514f0bSApple OSS Distributions VARIANT(eSMART_MMAP_FLAGS_TRIALS) \
516*d4514f0bSApple OSS Distributions VARIANT(eSMART_GENERIC_FLAG_TRIALS) \
517*d4514f0bSApple OSS Distributions VARIANT(eSMART_VM_TAG_TRIALS) \
518*d4514f0bSApple OSS Distributions VARIANT(eSMART_VM_PROT_TRIALS) \
519*d4514f0bSApple OSS Distributions VARIANT(eSMART_VM_PROT_PAIR_TRIALS) \
520*d4514f0bSApple OSS Distributions VARIANT(eSMART_LEDGER_TAG_TRIALS) \
521*d4514f0bSApple OSS Distributions VARIANT(eSMART_LEDGER_FLAG_TRIALS) \
522*d4514f0bSApple OSS Distributions VARIANT(eSMART_ADDR_TRIALS) \
523*d4514f0bSApple OSS Distributions VARIANT(eSMART_SIZE_TRIALS) \
524*d4514f0bSApple OSS Distributions VARIANT(eSMART_START_SIZE_TRIALS) \
525*d4514f0bSApple OSS Distributions VARIANT(eSMART_START_SIZE_OFFSET_OBJECT_TRIALS) \
526*d4514f0bSApple OSS Distributions VARIANT(eSMART_START_SIZE_OFFSET_TRIALS) \
527*d4514f0bSApple OSS Distributions VARIANT(eSMART_SIZE_SIZE_TRIALS) \
528*d4514f0bSApple OSS Distributions VARIANT(eSMART_SRC_DST_SIZE_TRIALS) \
529*d4514f0bSApple OSS Distributions VARIANT(eSMART_FILEOFF_DST_SIZE_TRIALS) \
530*d4514f0bSApple OSS Distributions VARIANT(eSMART_VM_BEHAVIOR_TRIALS) \
531*d4514f0bSApple OSS Distributions VARIANT(eSMART_VM_ADVISE_TRIALS) \
532*d4514f0bSApple OSS Distributions VARIANT(eSMART_VM_SYNC_TRIALS) \
533*d4514f0bSApple OSS Distributions VARIANT(eSMART_VM_MSYNC_TRIALS) \
534*d4514f0bSApple OSS Distributions VARIANT(eSMART_VM_MACHINE_ATTRIBUTE_TRIALS) \
535*d4514f0bSApple OSS Distributions VARIANT(eSMART_VM_PURGEABLE_AND_STATE_TRIALS) \
536*d4514f0bSApple OSS Distributions VARIANT(eSMART_START_SIZE_START_SIZE_TRIALS) \
537*d4514f0bSApple OSS Distributions VARIANT(eSMART_SHARED_REGION_MAP_AND_SLIDE_2_TRIALS) \
538*d4514f0bSApple OSS Distributions VARIANT(eSMART_RECLAMATION_BUFFER_INIT_TRIALS)
539*d4514f0bSApple OSS Distributions
540*d4514f0bSApple OSS Distributions #define TRIALSFORMULA_ENUM_VARIANT(NAME) NAME,
541*d4514f0bSApple OSS Distributions typedef enum {
542*d4514f0bSApple OSS Distributions TRIALSFORMULA_ENUM(TRIALSFORMULA_ENUM_VARIANT)
543*d4514f0bSApple OSS Distributions } trialsformula_t;
544*d4514f0bSApple OSS Distributions
545*d4514f0bSApple OSS Distributions #define TRIALSARGUMENTS_NONE 0
546*d4514f0bSApple OSS Distributions #define TRIALSARGUMENTS_SIZE 2
547*d4514f0bSApple OSS Distributions
548*d4514f0bSApple OSS Distributions // formula enum id to string
549*d4514f0bSApple OSS Distributions #define TRIALSFORMULA_ENUM_STRING(NAME) case NAME: return #NAME;
550*d4514f0bSApple OSS Distributions const char *
trialsformula_name(trialsformula_t formula)551*d4514f0bSApple OSS Distributions trialsformula_name(trialsformula_t formula)
552*d4514f0bSApple OSS Distributions {
553*d4514f0bSApple OSS Distributions switch (formula) {
554*d4514f0bSApple OSS Distributions TRIALSFORMULA_ENUM(TRIALSFORMULA_ENUM_STRING)
555*d4514f0bSApple OSS Distributions default:
556*d4514f0bSApple OSS Distributions testprintf("Unknown formula_t %d\n", formula);
557*d4514f0bSApple OSS Distributions assert(false);
558*d4514f0bSApple OSS Distributions }
559*d4514f0bSApple OSS Distributions }
560*d4514f0bSApple OSS Distributions
561*d4514f0bSApple OSS Distributions #define TRIALSFORMULA_ENUM_FROM_STRING(NAME) \
562*d4514f0bSApple OSS Distributions if (strncmp(string, #NAME, strlen(#NAME)) == 0) return NAME;
563*d4514f0bSApple OSS Distributions
564*d4514f0bSApple OSS Distributions // formula name to enum id
565*d4514f0bSApple OSS Distributions trialsformula_t
trialsformula_from_string(const char * string)566*d4514f0bSApple OSS Distributions trialsformula_from_string(const char *string)
567*d4514f0bSApple OSS Distributions {
568*d4514f0bSApple OSS Distributions TRIALSFORMULA_ENUM(TRIALSFORMULA_ENUM_FROM_STRING)
569*d4514f0bSApple OSS Distributions // else
570*d4514f0bSApple OSS Distributions testprintf("Unknown formula %s\n", string);
571*d4514f0bSApple OSS Distributions assert(false);
572*d4514f0bSApple OSS Distributions }
573*d4514f0bSApple OSS Distributions
574*d4514f0bSApple OSS Distributions // ret: return value of this trial
575*d4514f0bSApple OSS Distributions // name: name of this trial, including the input values passed in
576*d4514f0bSApple OSS Distributions typedef struct {
577*d4514f0bSApple OSS Distributions int ret;
578*d4514f0bSApple OSS Distributions char *name;
579*d4514f0bSApple OSS Distributions } result_t;
580*d4514f0bSApple OSS Distributions
581*d4514f0bSApple OSS Distributions typedef struct {
582*d4514f0bSApple OSS Distributions const char *testname;
583*d4514f0bSApple OSS Distributions char *testconfig;
584*d4514f0bSApple OSS Distributions trialsformula_t trialsformula;
585*d4514f0bSApple OSS Distributions uint64_t trialsargs[TRIALSARGUMENTS_SIZE];
586*d4514f0bSApple OSS Distributions unsigned capacity;
587*d4514f0bSApple OSS Distributions unsigned count;
588*d4514f0bSApple OSS Distributions unsigned tested_count;
589*d4514f0bSApple OSS Distributions result_t list[];
590*d4514f0bSApple OSS Distributions } results_t;
591*d4514f0bSApple OSS Distributions
592*d4514f0bSApple OSS Distributions extern results_t *golden_list[];
593*d4514f0bSApple OSS Distributions extern results_t *kern_list[];
594*d4514f0bSApple OSS Distributions static uint32_t num_tests = 0; // num of tests in golden list
595*d4514f0bSApple OSS Distributions static uint32_t num_kern_tests = 0; // num of tests in kernel results list
596*d4514f0bSApple OSS Distributions
597*d4514f0bSApple OSS Distributions static __attribute__((overloadable))
598*d4514f0bSApple OSS Distributions results_t *
alloc_results(const char * testname,char * testconfig,trialsformula_t trialsformula,uint64_t trialsargs[static TRIALSARGUMENTS_SIZE],unsigned capacity)599*d4514f0bSApple OSS Distributions alloc_results(const char *testname, char *testconfig,
600*d4514f0bSApple OSS Distributions trialsformula_t trialsformula, uint64_t trialsargs[static TRIALSARGUMENTS_SIZE],
601*d4514f0bSApple OSS Distributions unsigned capacity)
602*d4514f0bSApple OSS Distributions {
603*d4514f0bSApple OSS Distributions results_t *results;
604*d4514f0bSApple OSS Distributions #if KERNEL
605*d4514f0bSApple OSS Distributions results = kalloc_type(results_t, result_t, capacity, Z_WAITOK | Z_ZERO);
606*d4514f0bSApple OSS Distributions #else
607*d4514f0bSApple OSS Distributions results = calloc(sizeof(results_t) + capacity * sizeof(result_t), 1);
608*d4514f0bSApple OSS Distributions #endif
609*d4514f0bSApple OSS Distributions assert(results != NULL);
610*d4514f0bSApple OSS Distributions results->testname = testname;
611*d4514f0bSApple OSS Distributions results->testconfig = testconfig;
612*d4514f0bSApple OSS Distributions results->trialsformula = trialsformula;
613*d4514f0bSApple OSS Distributions for (unsigned i = 0; i < TRIALSARGUMENTS_SIZE; i++) {
614*d4514f0bSApple OSS Distributions results->trialsargs[i] = trialsargs[i];
615*d4514f0bSApple OSS Distributions }
616*d4514f0bSApple OSS Distributions results->capacity = capacity;
617*d4514f0bSApple OSS Distributions results->count = 0;
618*d4514f0bSApple OSS Distributions results->tested_count = 0;
619*d4514f0bSApple OSS Distributions return results;
620*d4514f0bSApple OSS Distributions }
621*d4514f0bSApple OSS Distributions
622*d4514f0bSApple OSS Distributions static char *
alloc_default_testconfig(void)623*d4514f0bSApple OSS Distributions alloc_default_testconfig(void)
624*d4514f0bSApple OSS Distributions {
625*d4514f0bSApple OSS Distributions char *result;
626*d4514f0bSApple OSS Distributions kasprintf(&result, "%s %s %s%s",
627*d4514f0bSApple OSS Distributions OS_NAME, ARCH_NAME,
628*d4514f0bSApple OSS Distributions kern_trialname_generation ? "kernel" : CALLER_NAME,
629*d4514f0bSApple OSS Distributions !kern_trialname_generation && isRosetta() ? " rosetta" : "");
630*d4514f0bSApple OSS Distributions return result;
631*d4514f0bSApple OSS Distributions }
632*d4514f0bSApple OSS Distributions
633*d4514f0bSApple OSS Distributions static __attribute__((overloadable))
634*d4514f0bSApple OSS Distributions results_t *
alloc_results(const char * testname,trialsformula_t trialsformula,uint64_t * trialsargs,size_t trialsargs_count,unsigned capacity)635*d4514f0bSApple OSS Distributions alloc_results(const char *testname,
636*d4514f0bSApple OSS Distributions trialsformula_t trialsformula, uint64_t *trialsargs, size_t trialsargs_count,
637*d4514f0bSApple OSS Distributions unsigned capacity)
638*d4514f0bSApple OSS Distributions {
639*d4514f0bSApple OSS Distributions assert(trialsargs_count == TRIALSARGUMENTS_SIZE);
640*d4514f0bSApple OSS Distributions return alloc_results(testname, alloc_default_testconfig(), trialsformula, trialsargs, capacity);
641*d4514f0bSApple OSS Distributions }
642*d4514f0bSApple OSS Distributions
643*d4514f0bSApple OSS Distributions static __attribute__((overloadable))
644*d4514f0bSApple OSS Distributions results_t *
alloc_results(const char * testname,trialsformula_t trialsformula,uint64_t trialsarg0,unsigned capacity)645*d4514f0bSApple OSS Distributions alloc_results(const char *testname, trialsformula_t trialsformula, uint64_t trialsarg0, unsigned capacity)
646*d4514f0bSApple OSS Distributions {
647*d4514f0bSApple OSS Distributions uint64_t trialsargs[TRIALSARGUMENTS_SIZE] = {trialsarg0, TRIALSARGUMENTS_NONE};
648*d4514f0bSApple OSS Distributions return alloc_results(testname, trialsformula, trialsargs, TRIALSARGUMENTS_SIZE, capacity);
649*d4514f0bSApple OSS Distributions }
650*d4514f0bSApple OSS Distributions
651*d4514f0bSApple OSS Distributions static __attribute__((overloadable))
652*d4514f0bSApple OSS Distributions results_t *
alloc_results(const char * testname,trialsformula_t trialsformula,unsigned capacity)653*d4514f0bSApple OSS Distributions alloc_results(const char *testname, trialsformula_t trialsformula, unsigned capacity)
654*d4514f0bSApple OSS Distributions {
655*d4514f0bSApple OSS Distributions uint64_t trialsargs[TRIALSARGUMENTS_SIZE] = {TRIALSARGUMENTS_NONE, TRIALSARGUMENTS_NONE};
656*d4514f0bSApple OSS Distributions return alloc_results(testname, trialsformula, trialsargs, TRIALSARGUMENTS_SIZE, capacity);
657*d4514f0bSApple OSS Distributions }
658*d4514f0bSApple OSS Distributions
659*d4514f0bSApple OSS Distributions static void __unused
dealloc_results(results_t * results)660*d4514f0bSApple OSS Distributions dealloc_results(results_t *results)
661*d4514f0bSApple OSS Distributions {
662*d4514f0bSApple OSS Distributions for (unsigned int i = 0; i < results->count; i++) {
663*d4514f0bSApple OSS Distributions kfree_str(results->list[i].name);
664*d4514f0bSApple OSS Distributions }
665*d4514f0bSApple OSS Distributions kfree_str(results->testconfig);
666*d4514f0bSApple OSS Distributions #if KERNEL
667*d4514f0bSApple OSS Distributions kfree_type(results_t, result_t, results->capacity, results);
668*d4514f0bSApple OSS Distributions #else
669*d4514f0bSApple OSS Distributions free(results);
670*d4514f0bSApple OSS Distributions #endif
671*d4514f0bSApple OSS Distributions }
672*d4514f0bSApple OSS Distributions
673*d4514f0bSApple OSS Distributions static void __attribute__((overloadable, unused))
append_result(results_t * results,int ret,const char * name)674*d4514f0bSApple OSS Distributions append_result(results_t *results, int ret, const char *name)
675*d4514f0bSApple OSS Distributions {
676*d4514f0bSApple OSS Distributions // halt if the results list is already full
677*d4514f0bSApple OSS Distributions // fixme reallocate instead if we can't always choose the size in advance
678*d4514f0bSApple OSS Distributions assert(results->count < results->capacity);
679*d4514f0bSApple OSS Distributions
680*d4514f0bSApple OSS Distributions // name may be freed before we make use of it
681*d4514f0bSApple OSS Distributions char * name_cpy = kstrdup(name);
682*d4514f0bSApple OSS Distributions assert(name_cpy);
683*d4514f0bSApple OSS Distributions results->list[results->count++] =
684*d4514f0bSApple OSS Distributions (result_t){.ret = ret, .name = name_cpy};
685*d4514f0bSApple OSS Distributions }
686*d4514f0bSApple OSS Distributions
687*d4514f0bSApple OSS Distributions
688*d4514f0bSApple OSS Distributions #define TESTNAME_DELIMITER "TESTNAME "
689*d4514f0bSApple OSS Distributions #define RESULTCOUNT_DELIMITER "RESULT COUNT "
690*d4514f0bSApple OSS Distributions #define TESTRESULT_DELIMITER " "
691*d4514f0bSApple OSS Distributions #define TESTCONFIG_DELIMITER " TESTCONFIG "
692*d4514f0bSApple OSS Distributions #define TRIALSFORMULA_DELIMITER "TRIALSFORMULA "
693*d4514f0bSApple OSS Distributions #define TRIALSARGUMENTS_DELIMITER "TRIALSARGUMENTS"
694*d4514f0bSApple OSS Distributions #define KERN_TESTRESULT_DELIMITER " RESULT "
695*d4514f0bSApple OSS Distributions
696*d4514f0bSApple OSS Distributions // print results, unformatted
697*d4514f0bSApple OSS Distributions // This output is read by populate_kernel_results()
698*d4514f0bSApple OSS Distributions // and by tools/format_vm_parameter_validation.py
699*d4514f0bSApple OSS Distributions static results_t *
__dump_results(results_t * results)700*d4514f0bSApple OSS Distributions __dump_results(results_t *results)
701*d4514f0bSApple OSS Distributions {
702*d4514f0bSApple OSS Distributions testprintf(TESTNAME_DELIMITER "%s\n", results->testname);
703*d4514f0bSApple OSS Distributions testprintf(RESULTCOUNT_DELIMITER "%d\n", results->count);
704*d4514f0bSApple OSS Distributions testprintf(TESTCONFIG_DELIMITER "%s\n", results->testconfig);
705*d4514f0bSApple OSS Distributions
706*d4514f0bSApple OSS Distributions for (unsigned i = 0; i < results->count; i++) {
707*d4514f0bSApple OSS Distributions testprintf(KERN_TESTRESULT_DELIMITER "%d, %s\n", results->list[i].ret, results->list[i].name);
708*d4514f0bSApple OSS Distributions }
709*d4514f0bSApple OSS Distributions
710*d4514f0bSApple OSS Distributions results->tested_count += 1;
711*d4514f0bSApple OSS Distributions return results;
712*d4514f0bSApple OSS Distributions }
713*d4514f0bSApple OSS Distributions
714*d4514f0bSApple OSS Distributions // This output is read by populate_golden_results()
715*d4514f0bSApple OSS Distributions static results_t *
dump_golden_results(results_t * results)716*d4514f0bSApple OSS Distributions dump_golden_results(results_t *results)
717*d4514f0bSApple OSS Distributions {
718*d4514f0bSApple OSS Distributions trial_page_size = PAGE_SIZE;
719*d4514f0bSApple OSS Distributions goldenprintf(TESTNAME_DELIMITER "%s\n", results->testname);
720*d4514f0bSApple OSS Distributions goldenprintf(TRIALSFORMULA_DELIMITER "%s %s %llu,%llu,%llu\n",
721*d4514f0bSApple OSS Distributions trialsformula_name(results->trialsformula), TRIALSARGUMENTS_DELIMITER,
722*d4514f0bSApple OSS Distributions results->trialsargs[0], results->trialsargs[1], trial_page_size);
723*d4514f0bSApple OSS Distributions goldenprintf(RESULTCOUNT_DELIMITER "%d\n", results->count);
724*d4514f0bSApple OSS Distributions
725*d4514f0bSApple OSS Distributions for (unsigned i = 0; i < results->count; i++) {
726*d4514f0bSApple OSS Distributions goldenprintf(TESTRESULT_DELIMITER "%d: %d\n", i, results->list[i].ret);
727*d4514f0bSApple OSS Distributions #if !KERNEL
728*d4514f0bSApple OSS Distributions if (results->list[i].ret == OUT_PARAM_BAD) {
729*d4514f0bSApple OSS Distributions out_param_bad_count += 1;
730*d4514f0bSApple OSS Distributions T_FAIL("Out parameter violation in test %s - %s\n", results->testname, results->list[i].name);
731*d4514f0bSApple OSS Distributions }
732*d4514f0bSApple OSS Distributions #endif
733*d4514f0bSApple OSS Distributions }
734*d4514f0bSApple OSS Distributions
735*d4514f0bSApple OSS Distributions return results;
736*d4514f0bSApple OSS Distributions }
737*d4514f0bSApple OSS Distributions
738*d4514f0bSApple OSS Distributions #if !KERNEL
739*d4514f0bSApple OSS Distributions // Comparator function for sorting result_t list by name
740*d4514f0bSApple OSS Distributions static int
compare_names(const void * a,const void * b)741*d4514f0bSApple OSS Distributions compare_names(const void *a, const void *b)
742*d4514f0bSApple OSS Distributions {
743*d4514f0bSApple OSS Distributions assert(((const result_t *)a)->name);
744*d4514f0bSApple OSS Distributions assert(((const result_t *)b)->name);
745*d4514f0bSApple OSS Distributions return strcmp(((const result_t *)a)->name, ((const result_t *)b)->name);
746*d4514f0bSApple OSS Distributions }
747*d4514f0bSApple OSS Distributions
748*d4514f0bSApple OSS Distributions static unsigned
binary_search(result_t * list,unsigned count,const result_t * trial)749*d4514f0bSApple OSS Distributions binary_search(result_t *list, unsigned count, const result_t *trial)
750*d4514f0bSApple OSS Distributions {
751*d4514f0bSApple OSS Distributions assert(count > 0);
752*d4514f0bSApple OSS Distributions const char *name = trial->name;
753*d4514f0bSApple OSS Distributions unsigned left = 0, right = count - 1;
754*d4514f0bSApple OSS Distributions while (left <= right) {
755*d4514f0bSApple OSS Distributions unsigned mid = left + (right - left) / 2;
756*d4514f0bSApple OSS Distributions int cmp = strcmp(list[mid].name, name);
757*d4514f0bSApple OSS Distributions if (cmp == 0) {
758*d4514f0bSApple OSS Distributions return mid;
759*d4514f0bSApple OSS Distributions } else if (cmp < 0) {
760*d4514f0bSApple OSS Distributions left = mid + 1;
761*d4514f0bSApple OSS Distributions } else {
762*d4514f0bSApple OSS Distributions right = mid - 1;
763*d4514f0bSApple OSS Distributions }
764*d4514f0bSApple OSS Distributions }
765*d4514f0bSApple OSS Distributions return UINT_MAX; // Not found
766*d4514f0bSApple OSS Distributions }
767*d4514f0bSApple OSS Distributions
768*d4514f0bSApple OSS Distributions static inline bool
trial_name_equals(const result_t * a,const result_t * b)769*d4514f0bSApple OSS Distributions trial_name_equals(const result_t *a, const result_t *b)
770*d4514f0bSApple OSS Distributions {
771*d4514f0bSApple OSS Distributions // NB: strlen match need to handle cases where a shorter 'bname' would match a longer 'aname'.
772*d4514f0bSApple OSS Distributions if (strlen(a->name) == strlen(b->name) && compare_names(a, b) == 0) {
773*d4514f0bSApple OSS Distributions return true;
774*d4514f0bSApple OSS Distributions }
775*d4514f0bSApple OSS Distributions return false;
776*d4514f0bSApple OSS Distributions }
777*d4514f0bSApple OSS Distributions
778*d4514f0bSApple OSS Distributions static const result_t *
get_golden_result(results_t * golden_results,const result_t * trial,unsigned trial_idx)779*d4514f0bSApple OSS Distributions get_golden_result(results_t *golden_results, const result_t *trial, unsigned trial_idx)
780*d4514f0bSApple OSS Distributions {
781*d4514f0bSApple OSS Distributions if (golden_results->trialsformula == eUNKNOWN_TRIALS) {
782*d4514f0bSApple OSS Distributions // golden results don't contain trials names
783*d4514f0bSApple OSS Distributions T_LOG("%s: update test's alloc_results to have a valid trialsformula_t\n", golden_results->testname);
784*d4514f0bSApple OSS Distributions return NULL;
785*d4514f0bSApple OSS Distributions }
786*d4514f0bSApple OSS Distributions
787*d4514f0bSApple OSS Distributions if (trial_idx < golden_results->count &&
788*d4514f0bSApple OSS Distributions golden_results->list[trial_idx].name &&
789*d4514f0bSApple OSS Distributions trial_name_equals(&golden_results->list[trial_idx], trial)) {
790*d4514f0bSApple OSS Distributions // "fast search" path taken when golden file is in sync to test.
791*d4514f0bSApple OSS Distributions return &golden_results->list[trial_idx];
792*d4514f0bSApple OSS Distributions }
793*d4514f0bSApple OSS Distributions
794*d4514f0bSApple OSS Distributions // "slow search" path taken when tests idxs are not aligned. Sort the array
795*d4514f0bSApple OSS Distributions // by name and do binary search.
796*d4514f0bSApple OSS Distributions qsort(golden_results->list, golden_results->count, sizeof(result_t), compare_names);
797*d4514f0bSApple OSS Distributions unsigned g_idx = binary_search(golden_results->list, golden_results->count, trial);
798*d4514f0bSApple OSS Distributions if (g_idx < golden_results->count) {
799*d4514f0bSApple OSS Distributions return &golden_results->list[g_idx];
800*d4514f0bSApple OSS Distributions }
801*d4514f0bSApple OSS Distributions
802*d4514f0bSApple OSS Distributions return NULL;
803*d4514f0bSApple OSS Distributions }
804*d4514f0bSApple OSS Distributions
805*d4514f0bSApple OSS Distributions static void
test_results(results_t * golden_results,results_t * results)806*d4514f0bSApple OSS Distributions test_results(results_t *golden_results, results_t *results)
807*d4514f0bSApple OSS Distributions {
808*d4514f0bSApple OSS Distributions bool passed = TRUE;
809*d4514f0bSApple OSS Distributions unsigned result_count = results->count;
810*d4514f0bSApple OSS Distributions unsigned acceptable_count = 0;
811*d4514f0bSApple OSS Distributions const unsigned acceptable_max = 16; // log up to this many ACCEPTABLE results
812*d4514f0bSApple OSS Distributions const result_t *golden_result = NULL;
813*d4514f0bSApple OSS Distributions if (golden_results->count != results->count) {
814*d4514f0bSApple OSS Distributions T_LOG("%s: number of iterations mismatch (%u vs %u)",
815*d4514f0bSApple OSS Distributions results->testname, golden_results->count, results->count);
816*d4514f0bSApple OSS Distributions }
817*d4514f0bSApple OSS Distributions for (unsigned i = 0; i < result_count; i++) {
818*d4514f0bSApple OSS Distributions golden_result = get_golden_result(golden_results, &results->list[i], i);
819*d4514f0bSApple OSS Distributions if (golden_result) {
820*d4514f0bSApple OSS Distributions if (results->list[i].ret == ACCEPTABLE) {
821*d4514f0bSApple OSS Distributions // trial has declared itself to be correct
822*d4514f0bSApple OSS Distributions // no matter what the golden result is
823*d4514f0bSApple OSS Distributions acceptable_count++;
824*d4514f0bSApple OSS Distributions if (acceptable_count <= acceptable_max) {
825*d4514f0bSApple OSS Distributions T_LOG("%s RESULT ACCEPTABLE (expected %d), %s\n",
826*d4514f0bSApple OSS Distributions results->testname,
827*d4514f0bSApple OSS Distributions golden_result->ret, results->list[i].name);
828*d4514f0bSApple OSS Distributions }
829*d4514f0bSApple OSS Distributions } else if (results->list[i].ret != golden_result->ret) {
830*d4514f0bSApple OSS Distributions T_FAIL("%s RESULT %d (expected %d), %s\n",
831*d4514f0bSApple OSS Distributions results->testname, results->list[i].ret,
832*d4514f0bSApple OSS Distributions golden_result->ret, results->list[i].name);
833*d4514f0bSApple OSS Distributions passed = FALSE;
834*d4514f0bSApple OSS Distributions }
835*d4514f0bSApple OSS Distributions } else {
836*d4514f0bSApple OSS Distributions // new trial not present in golden results
837*d4514f0bSApple OSS Distributions T_FAIL("%s NEW RESULT %d, %s - (regenerate golden files to fix this)\n",
838*d4514f0bSApple OSS Distributions results->testname, results->list[i].ret, results->list[i].name);
839*d4514f0bSApple OSS Distributions passed = FALSE;
840*d4514f0bSApple OSS Distributions }
841*d4514f0bSApple OSS Distributions }
842*d4514f0bSApple OSS Distributions
843*d4514f0bSApple OSS Distributions if (acceptable_count > acceptable_max) {
844*d4514f0bSApple OSS Distributions T_LOG("%s %u more RESULT ACCEPTABLE trials not logged\n",
845*d4514f0bSApple OSS Distributions results->testname, acceptable_count - acceptable_max);
846*d4514f0bSApple OSS Distributions }
847*d4514f0bSApple OSS Distributions if (passed) {
848*d4514f0bSApple OSS Distributions T_PASS("%s passed\n", results->testname);
849*d4514f0bSApple OSS Distributions }
850*d4514f0bSApple OSS Distributions }
851*d4514f0bSApple OSS Distributions #endif
852*d4514f0bSApple OSS Distributions
853*d4514f0bSApple OSS Distributions #if !KERNEL
854*d4514f0bSApple OSS Distributions static results_t *
855*d4514f0bSApple OSS Distributions test_name_to_golden_results(const char* testname);
856*d4514f0bSApple OSS Distributions #endif
857*d4514f0bSApple OSS Distributions
858*d4514f0bSApple OSS Distributions static results_t *
process_results(results_t * results)859*d4514f0bSApple OSS Distributions process_results(results_t *results)
860*d4514f0bSApple OSS Distributions {
861*d4514f0bSApple OSS Distributions #if KERNEL
862*d4514f0bSApple OSS Distributions if (kernel_generate_golden) {
863*d4514f0bSApple OSS Distributions return dump_golden_results(results);
864*d4514f0bSApple OSS Distributions } else {
865*d4514f0bSApple OSS Distributions return __dump_results(results);
866*d4514f0bSApple OSS Distributions }
867*d4514f0bSApple OSS Distributions #else
868*d4514f0bSApple OSS Distributions results_t *golden_results = NULL;
869*d4514f0bSApple OSS Distributions
870*d4514f0bSApple OSS Distributions if (dump && !generate_golden) {
871*d4514f0bSApple OSS Distributions __dump_results(results);
872*d4514f0bSApple OSS Distributions }
873*d4514f0bSApple OSS Distributions
874*d4514f0bSApple OSS Distributions if (generate_golden) {
875*d4514f0bSApple OSS Distributions dump_golden_results(results);
876*d4514f0bSApple OSS Distributions }
877*d4514f0bSApple OSS Distributions
878*d4514f0bSApple OSS Distributions if (should_test_results) {
879*d4514f0bSApple OSS Distributions golden_results = test_name_to_golden_results(results->testname);
880*d4514f0bSApple OSS Distributions
881*d4514f0bSApple OSS Distributions if (golden_results) {
882*d4514f0bSApple OSS Distributions test_results(golden_results, results);
883*d4514f0bSApple OSS Distributions } else {
884*d4514f0bSApple OSS Distributions T_FAIL("New test %s found, update golden list to allow return code testing", results->testname);
885*d4514f0bSApple OSS Distributions // Dump results if not done previously
886*d4514f0bSApple OSS Distributions if (!dump) {
887*d4514f0bSApple OSS Distributions __dump_results(results);
888*d4514f0bSApple OSS Distributions }
889*d4514f0bSApple OSS Distributions }
890*d4514f0bSApple OSS Distributions }
891*d4514f0bSApple OSS Distributions
892*d4514f0bSApple OSS Distributions return results;
893*d4514f0bSApple OSS Distributions #endif
894*d4514f0bSApple OSS Distributions }
895*d4514f0bSApple OSS Distributions
896*d4514f0bSApple OSS Distributions static inline mach_vm_address_t
truncate_vm_map_addr_with_flags(MAP_T map,mach_vm_address_t addr,int flags)897*d4514f0bSApple OSS Distributions truncate_vm_map_addr_with_flags(MAP_T map, mach_vm_address_t addr, int flags)
898*d4514f0bSApple OSS Distributions {
899*d4514f0bSApple OSS Distributions mach_vm_address_t truncated_addr = addr;
900*d4514f0bSApple OSS Distributions if (flags & VM_FLAGS_RETURN_4K_DATA_ADDR) {
901*d4514f0bSApple OSS Distributions // VM_FLAGS_RETURN_4K_DATA_ADDR means return a 4k aligned address rather than the
902*d4514f0bSApple OSS Distributions // base of the page. Truncate to 4k.
903*d4514f0bSApple OSS Distributions truncated_addr = trunc_down_page(addr, KB4);
904*d4514f0bSApple OSS Distributions } else if (flags & VM_FLAGS_RETURN_DATA_ADDR) {
905*d4514f0bSApple OSS Distributions // On VM_FLAGS_RETURN_DATA_ADDR, we expect to get back the unaligned address.
906*d4514f0bSApple OSS Distributions // Don't truncate.
907*d4514f0bSApple OSS Distributions } else {
908*d4514f0bSApple OSS Distributions // Otherwise we truncate to the map page size
909*d4514f0bSApple OSS Distributions truncated_addr = trunc_down_map(map, addr);
910*d4514f0bSApple OSS Distributions }
911*d4514f0bSApple OSS Distributions return truncated_addr;
912*d4514f0bSApple OSS Distributions }
913*d4514f0bSApple OSS Distributions
914*d4514f0bSApple OSS Distributions
915*d4514f0bSApple OSS Distributions static inline mach_vm_address_t
get_expected_remap_misalignment(MAP_T map,mach_vm_address_t addr,int flags)916*d4514f0bSApple OSS Distributions get_expected_remap_misalignment(MAP_T map, mach_vm_address_t addr, int flags)
917*d4514f0bSApple OSS Distributions {
918*d4514f0bSApple OSS Distributions mach_vm_address_t misalignment;
919*d4514f0bSApple OSS Distributions if (flags & VM_FLAGS_RETURN_4K_DATA_ADDR) {
920*d4514f0bSApple OSS Distributions // VM_FLAGS_RETURN_4K_DATA_ADDR means return a 4k aligned address rather than the
921*d4514f0bSApple OSS Distributions // base of the page. The misalignment is relative to the first 4k page
922*d4514f0bSApple OSS Distributions misalignment = addr - trunc_down_page(addr, KB4);
923*d4514f0bSApple OSS Distributions } else if (flags & VM_FLAGS_RETURN_DATA_ADDR) {
924*d4514f0bSApple OSS Distributions // On VM_FLAGS_RETURN_DATA_ADDR, we expect to get back the unaligned address.
925*d4514f0bSApple OSS Distributions // The misalignment is therefore the low bits
926*d4514f0bSApple OSS Distributions misalignment = addr - trunc_down_map(map, addr);
927*d4514f0bSApple OSS Distributions } else {
928*d4514f0bSApple OSS Distributions // Otherwise we expect it to be aligned
929*d4514f0bSApple OSS Distributions misalignment = 0;
930*d4514f0bSApple OSS Distributions }
931*d4514f0bSApple OSS Distributions return misalignment;
932*d4514f0bSApple OSS Distributions }
933*d4514f0bSApple OSS Distributions
934*d4514f0bSApple OSS Distributions // absolute and relative offsets are used to specify a trial's values
935*d4514f0bSApple OSS Distributions
936*d4514f0bSApple OSS Distributions typedef struct {
937*d4514f0bSApple OSS Distributions bool is_absolute;
938*d4514f0bSApple OSS Distributions addr_t offset;
939*d4514f0bSApple OSS Distributions } absolute_or_relative_offset_t;
940*d4514f0bSApple OSS Distributions
941*d4514f0bSApple OSS Distributions typedef struct {
942*d4514f0bSApple OSS Distributions unsigned count;
943*d4514f0bSApple OSS Distributions unsigned capacity;
944*d4514f0bSApple OSS Distributions absolute_or_relative_offset_t list[];
945*d4514f0bSApple OSS Distributions } offset_list_t;
946*d4514f0bSApple OSS Distributions
947*d4514f0bSApple OSS Distributions static offset_list_t *
allocate_offsets(unsigned capacity)948*d4514f0bSApple OSS Distributions allocate_offsets(unsigned capacity)
949*d4514f0bSApple OSS Distributions {
950*d4514f0bSApple OSS Distributions offset_list_t *offsets;
951*d4514f0bSApple OSS Distributions #if KERNEL
952*d4514f0bSApple OSS Distributions offsets = kalloc_type(offset_list_t, absolute_or_relative_offset_t, capacity, Z_WAITOK | Z_ZERO);
953*d4514f0bSApple OSS Distributions #else
954*d4514f0bSApple OSS Distributions offsets = calloc(sizeof(offset_list_t) + capacity * sizeof(absolute_or_relative_offset_t), 1);
955*d4514f0bSApple OSS Distributions #endif
956*d4514f0bSApple OSS Distributions offsets->count = 0;
957*d4514f0bSApple OSS Distributions offsets->capacity = capacity;
958*d4514f0bSApple OSS Distributions return offsets;
959*d4514f0bSApple OSS Distributions }
960*d4514f0bSApple OSS Distributions
961*d4514f0bSApple OSS Distributions static void
append_offset(offset_list_t * offsets,bool is_absolute,addr_t offset)962*d4514f0bSApple OSS Distributions append_offset(offset_list_t *offsets, bool is_absolute, addr_t offset)
963*d4514f0bSApple OSS Distributions {
964*d4514f0bSApple OSS Distributions assert(offsets->count < offsets->capacity);
965*d4514f0bSApple OSS Distributions offsets->list[offsets->count].is_absolute = is_absolute;
966*d4514f0bSApple OSS Distributions offsets->list[offsets->count].offset = offset;
967*d4514f0bSApple OSS Distributions offsets->count++;
968*d4514f0bSApple OSS Distributions }
969*d4514f0bSApple OSS Distributions
970*d4514f0bSApple OSS Distributions
971*d4514f0bSApple OSS Distributions /////////////////////////////////////////////////////
972*d4514f0bSApple OSS Distributions // Generation of trials and their parameter values
973*d4514f0bSApple OSS Distributions // A "trial" is a single execution of a function to be tested
974*d4514f0bSApple OSS Distributions
975*d4514f0bSApple OSS Distributions #if KERNEL
976*d4514f0bSApple OSS Distributions #define ALLOC_TRIALS(NAME, new_capacity) \
977*d4514f0bSApple OSS Distributions (NAME ## _trials_t *)kalloc_type(NAME ## _trials_t, NAME ## _trial_t, \
978*d4514f0bSApple OSS Distributions new_capacity, Z_WAITOK | Z_ZERO)
979*d4514f0bSApple OSS Distributions #define FREE_TRIALS(NAME, trials) \
980*d4514f0bSApple OSS Distributions kfree_type(NAME ## _trials_t, NAME ## _trial_t, trials->capacity, trials)
981*d4514f0bSApple OSS Distributions #else
982*d4514f0bSApple OSS Distributions #define ALLOC_TRIALS(NAME, new_capacity) \
983*d4514f0bSApple OSS Distributions (NAME ## _trials_t *)calloc(sizeof(NAME ## _trials_t) + (new_capacity) * sizeof(NAME ## _trial_t), 1)
984*d4514f0bSApple OSS Distributions #define FREE_TRIALS(NAME, trials) \
985*d4514f0bSApple OSS Distributions free(trials)
986*d4514f0bSApple OSS Distributions #endif
987*d4514f0bSApple OSS Distributions
988*d4514f0bSApple OSS Distributions #define TRIALS_IMPL(NAME) \
989*d4514f0bSApple OSS Distributions static NAME ## _trials_t * \
990*d4514f0bSApple OSS Distributions __attribute__((used)) \
991*d4514f0bSApple OSS Distributions allocate_ ## NAME ## _trials(unsigned capacity) \
992*d4514f0bSApple OSS Distributions { \
993*d4514f0bSApple OSS Distributions NAME ## _trials_t *trials = ALLOC_TRIALS(NAME, capacity); \
994*d4514f0bSApple OSS Distributions assert(trials); \
995*d4514f0bSApple OSS Distributions trials->count = 0; \
996*d4514f0bSApple OSS Distributions trials->capacity = capacity; \
997*d4514f0bSApple OSS Distributions return trials; \
998*d4514f0bSApple OSS Distributions } \
999*d4514f0bSApple OSS Distributions \
1000*d4514f0bSApple OSS Distributions static void __attribute__((overloadable, used)) \
1001*d4514f0bSApple OSS Distributions free_trials(NAME ## _trials_t *trials) \
1002*d4514f0bSApple OSS Distributions { \
1003*d4514f0bSApple OSS Distributions FREE_TRIALS(NAME, trials); \
1004*d4514f0bSApple OSS Distributions } \
1005*d4514f0bSApple OSS Distributions \
1006*d4514f0bSApple OSS Distributions static void __attribute__((overloadable, used)) \
1007*d4514f0bSApple OSS Distributions append_trial(NAME ## _trials_t *trials, NAME ## _trial_t new_trial) \
1008*d4514f0bSApple OSS Distributions { \
1009*d4514f0bSApple OSS Distributions assert(trials->count < trials->capacity); \
1010*d4514f0bSApple OSS Distributions trials->list[trials->count++] = new_trial; \
1011*d4514f0bSApple OSS Distributions } \
1012*d4514f0bSApple OSS Distributions \
1013*d4514f0bSApple OSS Distributions static void __attribute__((overloadable, used)) \
1014*d4514f0bSApple OSS Distributions append_trials(NAME ## _trials_t *trials, NAME ## _trial_t *new_trials, unsigned new_count) \
1015*d4514f0bSApple OSS Distributions { \
1016*d4514f0bSApple OSS Distributions for (unsigned i = 0; i < new_count; i++) { \
1017*d4514f0bSApple OSS Distributions append_trial(trials, new_trials[i]); \
1018*d4514f0bSApple OSS Distributions } \
1019*d4514f0bSApple OSS Distributions }
1020*d4514f0bSApple OSS Distributions
1021*d4514f0bSApple OSS Distributions // allocate vm_inherit_t trials, and deallocate it at end of scope
1022*d4514f0bSApple OSS Distributions #define SMART_VM_INHERIT_TRIALS() \
1023*d4514f0bSApple OSS Distributions __attribute__((cleanup(cleanup_vm_inherit_trials))) \
1024*d4514f0bSApple OSS Distributions = allocate_vm_inherit_trials(countof(vm_inherit_trials_values)); \
1025*d4514f0bSApple OSS Distributions append_trials(trials, vm_inherit_trials_values, countof(vm_inherit_trials_values))
1026*d4514f0bSApple OSS Distributions
1027*d4514f0bSApple OSS Distributions // generate vm_inherit_t trials
1028*d4514f0bSApple OSS Distributions
1029*d4514f0bSApple OSS Distributions typedef struct {
1030*d4514f0bSApple OSS Distributions vm_inherit_t value;
1031*d4514f0bSApple OSS Distributions const char * name;
1032*d4514f0bSApple OSS Distributions } vm_inherit_trial_t;
1033*d4514f0bSApple OSS Distributions
1034*d4514f0bSApple OSS Distributions typedef struct {
1035*d4514f0bSApple OSS Distributions unsigned count;
1036*d4514f0bSApple OSS Distributions unsigned capacity;
1037*d4514f0bSApple OSS Distributions vm_inherit_trial_t list[];
1038*d4514f0bSApple OSS Distributions } vm_inherit_trials_t;
1039*d4514f0bSApple OSS Distributions
1040*d4514f0bSApple OSS Distributions
1041*d4514f0bSApple OSS Distributions #define VM_INHERIT_TRIAL(new_value) \
1042*d4514f0bSApple OSS Distributions (vm_inherit_trial_t) {.value = (vm_inherit_t)(new_value), .name = "vm_inherit " #new_value}
1043*d4514f0bSApple OSS Distributions
1044*d4514f0bSApple OSS Distributions static_assert(VM_INHERIT_LAST_VALID == VM_INHERIT_NONE,
1045*d4514f0bSApple OSS Distributions "Update this test with new vm_inherit_t values");
1046*d4514f0bSApple OSS Distributions static vm_inherit_trial_t vm_inherit_trials_values[] = {
1047*d4514f0bSApple OSS Distributions VM_INHERIT_TRIAL(VM_INHERIT_SHARE),
1048*d4514f0bSApple OSS Distributions VM_INHERIT_TRIAL(VM_INHERIT_COPY),
1049*d4514f0bSApple OSS Distributions VM_INHERIT_TRIAL(VM_INHERIT_NONE),
1050*d4514f0bSApple OSS Distributions // end valid ones
1051*d4514f0bSApple OSS Distributions // note: VM_INHERIT_DONATE_COPY is invalid and unimplemented
1052*d4514f0bSApple OSS Distributions // VM_INHERIT_LAST_VALID correctly excludes VM_INHERIT_DONATE_COPY
1053*d4514f0bSApple OSS Distributions VM_INHERIT_TRIAL(VM_INHERIT_LAST_VALID + 1),
1054*d4514f0bSApple OSS Distributions VM_INHERIT_TRIAL(VM_INHERIT_LAST_VALID + 2),
1055*d4514f0bSApple OSS Distributions VM_INHERIT_TRIAL(0xffffffff),
1056*d4514f0bSApple OSS Distributions };
1057*d4514f0bSApple OSS Distributions
TRIALS_IMPL(vm_inherit)1058*d4514f0bSApple OSS Distributions TRIALS_IMPL(vm_inherit)
1059*d4514f0bSApple OSS Distributions
1060*d4514f0bSApple OSS Distributions static void
1061*d4514f0bSApple OSS Distributions cleanup_vm_inherit_trials(vm_inherit_trials_t **trials)
1062*d4514f0bSApple OSS Distributions {
1063*d4514f0bSApple OSS Distributions free_trials(*trials);
1064*d4514f0bSApple OSS Distributions }
1065*d4514f0bSApple OSS Distributions
1066*d4514f0bSApple OSS Distributions // allocate vm_behavior_t trials, and deallocate it at end of scope
1067*d4514f0bSApple OSS Distributions #define SMART_VM_BEHAVIOR_TRIALS() \
1068*d4514f0bSApple OSS Distributions __attribute__((cleanup(cleanup_vm_behavior_trials))) \
1069*d4514f0bSApple OSS Distributions = allocate_vm_behavior_trials(countof(vm_behavior_trials_values)); \
1070*d4514f0bSApple OSS Distributions append_trials(trials, vm_behavior_trials_values, countof(vm_behavior_trials_values))
1071*d4514f0bSApple OSS Distributions
1072*d4514f0bSApple OSS Distributions // generate vm_behavior_t trials
1073*d4514f0bSApple OSS Distributions
1074*d4514f0bSApple OSS Distributions typedef struct {
1075*d4514f0bSApple OSS Distributions vm_behavior_t value;
1076*d4514f0bSApple OSS Distributions const char * name;
1077*d4514f0bSApple OSS Distributions } vm_behavior_trial_t;
1078*d4514f0bSApple OSS Distributions
1079*d4514f0bSApple OSS Distributions typedef struct {
1080*d4514f0bSApple OSS Distributions unsigned count;
1081*d4514f0bSApple OSS Distributions unsigned capacity;
1082*d4514f0bSApple OSS Distributions vm_behavior_trial_t list[];
1083*d4514f0bSApple OSS Distributions } vm_behavior_trials_t;
1084*d4514f0bSApple OSS Distributions
1085*d4514f0bSApple OSS Distributions
1086*d4514f0bSApple OSS Distributions #define VM_BEHAVIOR_TRIAL(new_value) \
1087*d4514f0bSApple OSS Distributions (vm_behavior_trial_t) {.value = (vm_behavior_t)(new_value), .name = "vm_behavior " #new_value}
1088*d4514f0bSApple OSS Distributions
1089*d4514f0bSApple OSS Distributions static vm_behavior_trial_t vm_behavior_trials_values[] = {
1090*d4514f0bSApple OSS Distributions VM_BEHAVIOR_TRIAL(VM_BEHAVIOR_DEFAULT),
1091*d4514f0bSApple OSS Distributions VM_BEHAVIOR_TRIAL(VM_BEHAVIOR_RANDOM),
1092*d4514f0bSApple OSS Distributions VM_BEHAVIOR_TRIAL(VM_BEHAVIOR_SEQUENTIAL),
1093*d4514f0bSApple OSS Distributions VM_BEHAVIOR_TRIAL(VM_BEHAVIOR_RSEQNTL),
1094*d4514f0bSApple OSS Distributions VM_BEHAVIOR_TRIAL(VM_BEHAVIOR_WILLNEED),
1095*d4514f0bSApple OSS Distributions VM_BEHAVIOR_TRIAL(VM_BEHAVIOR_DONTNEED),
1096*d4514f0bSApple OSS Distributions VM_BEHAVIOR_TRIAL(VM_BEHAVIOR_FREE),
1097*d4514f0bSApple OSS Distributions VM_BEHAVIOR_TRIAL(VM_BEHAVIOR_ZERO_WIRED_PAGES),
1098*d4514f0bSApple OSS Distributions VM_BEHAVIOR_TRIAL(VM_BEHAVIOR_REUSABLE),
1099*d4514f0bSApple OSS Distributions VM_BEHAVIOR_TRIAL(VM_BEHAVIOR_REUSE),
1100*d4514f0bSApple OSS Distributions VM_BEHAVIOR_TRIAL(VM_BEHAVIOR_CAN_REUSE),
1101*d4514f0bSApple OSS Distributions VM_BEHAVIOR_TRIAL(VM_BEHAVIOR_PAGEOUT),
1102*d4514f0bSApple OSS Distributions VM_BEHAVIOR_TRIAL(VM_BEHAVIOR_ZERO),
1103*d4514f0bSApple OSS Distributions // end valid ones
1104*d4514f0bSApple OSS Distributions VM_BEHAVIOR_TRIAL(VM_BEHAVIOR_LAST_VALID + 1),
1105*d4514f0bSApple OSS Distributions VM_BEHAVIOR_TRIAL(VM_BEHAVIOR_LAST_VALID + 2),
1106*d4514f0bSApple OSS Distributions VM_BEHAVIOR_TRIAL(0x12345),
1107*d4514f0bSApple OSS Distributions VM_BEHAVIOR_TRIAL(0xffffffff),
1108*d4514f0bSApple OSS Distributions };
1109*d4514f0bSApple OSS Distributions
TRIALS_IMPL(vm_behavior)1110*d4514f0bSApple OSS Distributions TRIALS_IMPL(vm_behavior)
1111*d4514f0bSApple OSS Distributions
1112*d4514f0bSApple OSS Distributions static void
1113*d4514f0bSApple OSS Distributions cleanup_vm_behavior_trials(vm_behavior_trials_t **trials)
1114*d4514f0bSApple OSS Distributions {
1115*d4514f0bSApple OSS Distributions free_trials(*trials);
1116*d4514f0bSApple OSS Distributions }
1117*d4514f0bSApple OSS Distributions
1118*d4514f0bSApple OSS Distributions // allocate vm_sync_t trials, and deallocate it at end of scope
1119*d4514f0bSApple OSS Distributions #define SMART_VM_SYNC_TRIALS() \
1120*d4514f0bSApple OSS Distributions __attribute__((cleanup(cleanup_vm_sync_trials))) \
1121*d4514f0bSApple OSS Distributions = allocate_vm_sync_trials(countof(vm_sync_trials_values)); \
1122*d4514f0bSApple OSS Distributions append_trials(trials, vm_sync_trials_values, countof(vm_sync_trials_values))
1123*d4514f0bSApple OSS Distributions
1124*d4514f0bSApple OSS Distributions // generate vm_sync_t trials
1125*d4514f0bSApple OSS Distributions
1126*d4514f0bSApple OSS Distributions typedef struct {
1127*d4514f0bSApple OSS Distributions vm_sync_t value;
1128*d4514f0bSApple OSS Distributions const char * name;
1129*d4514f0bSApple OSS Distributions } vm_sync_trial_t;
1130*d4514f0bSApple OSS Distributions
1131*d4514f0bSApple OSS Distributions typedef struct {
1132*d4514f0bSApple OSS Distributions unsigned count;
1133*d4514f0bSApple OSS Distributions unsigned capacity;
1134*d4514f0bSApple OSS Distributions vm_sync_trial_t list[];
1135*d4514f0bSApple OSS Distributions } vm_sync_trials_t;
1136*d4514f0bSApple OSS Distributions
1137*d4514f0bSApple OSS Distributions
1138*d4514f0bSApple OSS Distributions #define VM_SYNC_TRIAL(new_value) \
1139*d4514f0bSApple OSS Distributions (vm_sync_trial_t) {.value = (vm_sync_t)(new_value), .name = "vm_sync_t " #new_value}
1140*d4514f0bSApple OSS Distributions
1141*d4514f0bSApple OSS Distributions static vm_sync_trial_t vm_sync_trials_values[] = {
1142*d4514f0bSApple OSS Distributions VM_SYNC_TRIAL(0),
1143*d4514f0bSApple OSS Distributions // start valid values
1144*d4514f0bSApple OSS Distributions VM_SYNC_TRIAL(VM_SYNC_ASYNCHRONOUS),
1145*d4514f0bSApple OSS Distributions VM_SYNC_TRIAL(VM_SYNC_SYNCHRONOUS),
1146*d4514f0bSApple OSS Distributions VM_SYNC_TRIAL(VM_SYNC_INVALIDATE),
1147*d4514f0bSApple OSS Distributions VM_SYNC_TRIAL(VM_SYNC_KILLPAGES),
1148*d4514f0bSApple OSS Distributions VM_SYNC_TRIAL(VM_SYNC_DEACTIVATE),
1149*d4514f0bSApple OSS Distributions VM_SYNC_TRIAL(VM_SYNC_CONTIGUOUS),
1150*d4514f0bSApple OSS Distributions VM_SYNC_TRIAL(VM_SYNC_REUSABLEPAGES),
1151*d4514f0bSApple OSS Distributions // end valid values
1152*d4514f0bSApple OSS Distributions VM_SYNC_TRIAL(1u << 7),
1153*d4514f0bSApple OSS Distributions VM_SYNC_TRIAL(1u << 8),
1154*d4514f0bSApple OSS Distributions VM_SYNC_TRIAL(1u << 9),
1155*d4514f0bSApple OSS Distributions VM_SYNC_TRIAL(1u << 10),
1156*d4514f0bSApple OSS Distributions VM_SYNC_TRIAL(1u << 11),
1157*d4514f0bSApple OSS Distributions VM_SYNC_TRIAL(1u << 12),
1158*d4514f0bSApple OSS Distributions VM_SYNC_TRIAL(1u << 13),
1159*d4514f0bSApple OSS Distributions VM_SYNC_TRIAL(1u << 14),
1160*d4514f0bSApple OSS Distributions VM_SYNC_TRIAL(1u << 15),
1161*d4514f0bSApple OSS Distributions VM_SYNC_TRIAL(1u << 16),
1162*d4514f0bSApple OSS Distributions VM_SYNC_TRIAL(1u << 17),
1163*d4514f0bSApple OSS Distributions VM_SYNC_TRIAL(1u << 18),
1164*d4514f0bSApple OSS Distributions VM_SYNC_TRIAL(1u << 19),
1165*d4514f0bSApple OSS Distributions VM_SYNC_TRIAL(1u << 20),
1166*d4514f0bSApple OSS Distributions VM_SYNC_TRIAL(1u << 21),
1167*d4514f0bSApple OSS Distributions VM_SYNC_TRIAL(1u << 22),
1168*d4514f0bSApple OSS Distributions VM_SYNC_TRIAL(1u << 23),
1169*d4514f0bSApple OSS Distributions VM_SYNC_TRIAL(1u << 24),
1170*d4514f0bSApple OSS Distributions VM_SYNC_TRIAL(1u << 25),
1171*d4514f0bSApple OSS Distributions VM_SYNC_TRIAL(1u << 26),
1172*d4514f0bSApple OSS Distributions VM_SYNC_TRIAL(1u << 27),
1173*d4514f0bSApple OSS Distributions VM_SYNC_TRIAL(1u << 28),
1174*d4514f0bSApple OSS Distributions VM_SYNC_TRIAL(1u << 29),
1175*d4514f0bSApple OSS Distributions VM_SYNC_TRIAL(1u << 30),
1176*d4514f0bSApple OSS Distributions VM_SYNC_TRIAL(1u << 31),
1177*d4514f0bSApple OSS Distributions VM_SYNC_TRIAL(VM_SYNC_ASYNCHRONOUS | VM_SYNC_SYNCHRONOUS),
1178*d4514f0bSApple OSS Distributions VM_SYNC_TRIAL(VM_SYNC_ASYNCHRONOUS | (1u << 7)),
1179*d4514f0bSApple OSS Distributions VM_SYNC_TRIAL(0xffffffff),
1180*d4514f0bSApple OSS Distributions };
1181*d4514f0bSApple OSS Distributions
TRIALS_IMPL(vm_sync)1182*d4514f0bSApple OSS Distributions TRIALS_IMPL(vm_sync)
1183*d4514f0bSApple OSS Distributions
1184*d4514f0bSApple OSS Distributions static void
1185*d4514f0bSApple OSS Distributions cleanup_vm_sync_trials(vm_sync_trials_t **trials)
1186*d4514f0bSApple OSS Distributions {
1187*d4514f0bSApple OSS Distributions free_trials(*trials);
1188*d4514f0bSApple OSS Distributions }
1189*d4514f0bSApple OSS Distributions
1190*d4514f0bSApple OSS Distributions // allocate vm_msync_t trials, and deallocate it at end of scope
1191*d4514f0bSApple OSS Distributions #define SMART_VM_MSYNC_TRIALS() \
1192*d4514f0bSApple OSS Distributions __attribute__((cleanup(cleanup_vm_msync_trials))) \
1193*d4514f0bSApple OSS Distributions = allocate_vm_msync_trials(countof(vm_msync_trials_values)); \
1194*d4514f0bSApple OSS Distributions append_trials(trials, vm_msync_trials_values, countof(vm_msync_trials_values))
1195*d4514f0bSApple OSS Distributions
1196*d4514f0bSApple OSS Distributions // generate vm_msync_t trials
1197*d4514f0bSApple OSS Distributions
1198*d4514f0bSApple OSS Distributions typedef struct {
1199*d4514f0bSApple OSS Distributions int value;
1200*d4514f0bSApple OSS Distributions const char * name;
1201*d4514f0bSApple OSS Distributions } vm_msync_trial_t;
1202*d4514f0bSApple OSS Distributions
1203*d4514f0bSApple OSS Distributions typedef struct {
1204*d4514f0bSApple OSS Distributions unsigned count;
1205*d4514f0bSApple OSS Distributions unsigned capacity;
1206*d4514f0bSApple OSS Distributions vm_msync_trial_t list[];
1207*d4514f0bSApple OSS Distributions } vm_msync_trials_t;
1208*d4514f0bSApple OSS Distributions
1209*d4514f0bSApple OSS Distributions
1210*d4514f0bSApple OSS Distributions #define VM_MSYNC_TRIAL(new_value) \
1211*d4514f0bSApple OSS Distributions (vm_msync_trial_t) {.value = (int)(new_value), .name = "vm_msync_t " #new_value}
1212*d4514f0bSApple OSS Distributions
1213*d4514f0bSApple OSS Distributions static vm_msync_trial_t vm_msync_trials_values[] = {
1214*d4514f0bSApple OSS Distributions VM_MSYNC_TRIAL(0),
1215*d4514f0bSApple OSS Distributions // start valid values
1216*d4514f0bSApple OSS Distributions VM_MSYNC_TRIAL(MS_ASYNC),
1217*d4514f0bSApple OSS Distributions VM_MSYNC_TRIAL(MS_INVALIDATE),
1218*d4514f0bSApple OSS Distributions VM_MSYNC_TRIAL(MS_KILLPAGES),
1219*d4514f0bSApple OSS Distributions VM_MSYNC_TRIAL(MS_DEACTIVATE),
1220*d4514f0bSApple OSS Distributions VM_MSYNC_TRIAL(MS_SYNC),
1221*d4514f0bSApple OSS Distributions VM_MSYNC_TRIAL(MS_ASYNC | MS_INVALIDATE),
1222*d4514f0bSApple OSS Distributions // end valid values
1223*d4514f0bSApple OSS Distributions VM_MSYNC_TRIAL(1u << 5),
1224*d4514f0bSApple OSS Distributions VM_MSYNC_TRIAL(1u << 6),
1225*d4514f0bSApple OSS Distributions VM_MSYNC_TRIAL(1u << 7),
1226*d4514f0bSApple OSS Distributions VM_MSYNC_TRIAL(1u << 8),
1227*d4514f0bSApple OSS Distributions VM_MSYNC_TRIAL(1u << 9),
1228*d4514f0bSApple OSS Distributions VM_MSYNC_TRIAL(1u << 10),
1229*d4514f0bSApple OSS Distributions VM_MSYNC_TRIAL(1u << 11),
1230*d4514f0bSApple OSS Distributions VM_MSYNC_TRIAL(1u << 12),
1231*d4514f0bSApple OSS Distributions VM_MSYNC_TRIAL(1u << 13),
1232*d4514f0bSApple OSS Distributions VM_MSYNC_TRIAL(1u << 14),
1233*d4514f0bSApple OSS Distributions VM_MSYNC_TRIAL(1u << 15),
1234*d4514f0bSApple OSS Distributions VM_MSYNC_TRIAL(1u << 16),
1235*d4514f0bSApple OSS Distributions VM_MSYNC_TRIAL(1u << 17),
1236*d4514f0bSApple OSS Distributions VM_MSYNC_TRIAL(1u << 18),
1237*d4514f0bSApple OSS Distributions VM_MSYNC_TRIAL(1u << 19),
1238*d4514f0bSApple OSS Distributions VM_MSYNC_TRIAL(1u << 20),
1239*d4514f0bSApple OSS Distributions VM_MSYNC_TRIAL(1u << 21),
1240*d4514f0bSApple OSS Distributions VM_MSYNC_TRIAL(1u << 22),
1241*d4514f0bSApple OSS Distributions VM_MSYNC_TRIAL(1u << 23),
1242*d4514f0bSApple OSS Distributions VM_MSYNC_TRIAL(1u << 24),
1243*d4514f0bSApple OSS Distributions VM_MSYNC_TRIAL(1u << 25),
1244*d4514f0bSApple OSS Distributions VM_MSYNC_TRIAL(1u << 26),
1245*d4514f0bSApple OSS Distributions VM_MSYNC_TRIAL(1u << 27),
1246*d4514f0bSApple OSS Distributions VM_MSYNC_TRIAL(1u << 28),
1247*d4514f0bSApple OSS Distributions VM_MSYNC_TRIAL(1u << 29),
1248*d4514f0bSApple OSS Distributions VM_MSYNC_TRIAL(1u << 30),
1249*d4514f0bSApple OSS Distributions VM_MSYNC_TRIAL(1u << 31),
1250*d4514f0bSApple OSS Distributions VM_MSYNC_TRIAL(MS_ASYNC | MS_SYNC),
1251*d4514f0bSApple OSS Distributions VM_MSYNC_TRIAL(0xffffffff),
1252*d4514f0bSApple OSS Distributions };
1253*d4514f0bSApple OSS Distributions
TRIALS_IMPL(vm_msync)1254*d4514f0bSApple OSS Distributions TRIALS_IMPL(vm_msync)
1255*d4514f0bSApple OSS Distributions
1256*d4514f0bSApple OSS Distributions static void __attribute__((used))
1257*d4514f0bSApple OSS Distributions cleanup_vm_msync_trials(vm_msync_trials_t **trials)
1258*d4514f0bSApple OSS Distributions {
1259*d4514f0bSApple OSS Distributions free_trials(*trials);
1260*d4514f0bSApple OSS Distributions }
1261*d4514f0bSApple OSS Distributions
1262*d4514f0bSApple OSS Distributions
1263*d4514f0bSApple OSS Distributions // allocate advise_t trials, and deallocate it at end of scope
1264*d4514f0bSApple OSS Distributions #define SMART_VM_ADVISE_TRIALS() \
1265*d4514f0bSApple OSS Distributions __attribute__((cleanup(cleanup_advise_trials))) \
1266*d4514f0bSApple OSS Distributions = allocate_vm_advise_trials(countof(vm_advise_trials_values)); \
1267*d4514f0bSApple OSS Distributions append_trials(trials, vm_advise_trials_values, countof(vm_advise_trials_values))
1268*d4514f0bSApple OSS Distributions
1269*d4514f0bSApple OSS Distributions // generate advise_t trials
1270*d4514f0bSApple OSS Distributions
1271*d4514f0bSApple OSS Distributions typedef struct {
1272*d4514f0bSApple OSS Distributions int value;
1273*d4514f0bSApple OSS Distributions const char * name;
1274*d4514f0bSApple OSS Distributions } vm_advise_trial_t;
1275*d4514f0bSApple OSS Distributions
1276*d4514f0bSApple OSS Distributions typedef struct {
1277*d4514f0bSApple OSS Distributions unsigned count;
1278*d4514f0bSApple OSS Distributions unsigned capacity;
1279*d4514f0bSApple OSS Distributions vm_advise_trial_t list[];
1280*d4514f0bSApple OSS Distributions } vm_advise_trials_t;
1281*d4514f0bSApple OSS Distributions
1282*d4514f0bSApple OSS Distributions
1283*d4514f0bSApple OSS Distributions #define ADVISE_TRIAL(new_value) \
1284*d4514f0bSApple OSS Distributions (vm_advise_trial_t) {.value = (int)(new_value), .name = "advise " #new_value}
1285*d4514f0bSApple OSS Distributions
1286*d4514f0bSApple OSS Distributions static vm_advise_trial_t vm_advise_trials_values[] = {
1287*d4514f0bSApple OSS Distributions ADVISE_TRIAL(MADV_NORMAL),
1288*d4514f0bSApple OSS Distributions ADVISE_TRIAL(MADV_RANDOM),
1289*d4514f0bSApple OSS Distributions ADVISE_TRIAL(MADV_SEQUENTIAL),
1290*d4514f0bSApple OSS Distributions ADVISE_TRIAL(MADV_WILLNEED),
1291*d4514f0bSApple OSS Distributions ADVISE_TRIAL(MADV_DONTNEED),
1292*d4514f0bSApple OSS Distributions ADVISE_TRIAL(MADV_FREE),
1293*d4514f0bSApple OSS Distributions ADVISE_TRIAL(MADV_ZERO_WIRED_PAGES),
1294*d4514f0bSApple OSS Distributions ADVISE_TRIAL(MADV_FREE_REUSABLE),
1295*d4514f0bSApple OSS Distributions ADVISE_TRIAL(MADV_FREE_REUSE),
1296*d4514f0bSApple OSS Distributions ADVISE_TRIAL(MADV_CAN_REUSE),
1297*d4514f0bSApple OSS Distributions ADVISE_TRIAL(MADV_PAGEOUT),
1298*d4514f0bSApple OSS Distributions ADVISE_TRIAL(MADV_ZERO),
1299*d4514f0bSApple OSS Distributions // end valid ones
1300*d4514f0bSApple OSS Distributions ADVISE_TRIAL(MADV_ZERO + 1),
1301*d4514f0bSApple OSS Distributions ADVISE_TRIAL(MADV_ZERO + 2),
1302*d4514f0bSApple OSS Distributions ADVISE_TRIAL(0xffffffff),
1303*d4514f0bSApple OSS Distributions };
1304*d4514f0bSApple OSS Distributions
TRIALS_IMPL(vm_advise)1305*d4514f0bSApple OSS Distributions TRIALS_IMPL(vm_advise)
1306*d4514f0bSApple OSS Distributions
1307*d4514f0bSApple OSS Distributions static void __attribute__((used))
1308*d4514f0bSApple OSS Distributions cleanup_advise_trials(vm_advise_trials_t **trials)
1309*d4514f0bSApple OSS Distributions {
1310*d4514f0bSApple OSS Distributions free_trials(*trials);
1311*d4514f0bSApple OSS Distributions }
1312*d4514f0bSApple OSS Distributions
1313*d4514f0bSApple OSS Distributions // allocate machine_attribute_t trials, and deallocate it at end of scope
1314*d4514f0bSApple OSS Distributions #define SMART_VM_MACHINE_ATTRIBUTE_TRIALS() \
1315*d4514f0bSApple OSS Distributions __attribute__((cleanup(cleanup_vm_machine_attribute_trials))) \
1316*d4514f0bSApple OSS Distributions = allocate_vm_machine_attribute_trials(countof(vm_machine_attribute_trials_values)); \
1317*d4514f0bSApple OSS Distributions append_trials(trials, vm_machine_attribute_trials_values, countof(vm_machine_attribute_trials_values))
1318*d4514f0bSApple OSS Distributions
1319*d4514f0bSApple OSS Distributions // generate advise_t trials
1320*d4514f0bSApple OSS Distributions
1321*d4514f0bSApple OSS Distributions typedef struct {
1322*d4514f0bSApple OSS Distributions vm_machine_attribute_t value;
1323*d4514f0bSApple OSS Distributions const char * name;
1324*d4514f0bSApple OSS Distributions } vm_machine_attribute_trial_t;
1325*d4514f0bSApple OSS Distributions
1326*d4514f0bSApple OSS Distributions typedef struct {
1327*d4514f0bSApple OSS Distributions unsigned count;
1328*d4514f0bSApple OSS Distributions unsigned capacity;
1329*d4514f0bSApple OSS Distributions vm_machine_attribute_trial_t list[];
1330*d4514f0bSApple OSS Distributions } vm_machine_attribute_trials_t;
1331*d4514f0bSApple OSS Distributions
1332*d4514f0bSApple OSS Distributions
1333*d4514f0bSApple OSS Distributions #define VM_MACHINE_ATTRIBUTE_TRIAL(new_value) \
1334*d4514f0bSApple OSS Distributions (vm_machine_attribute_trial_t) {.value = (vm_machine_attribute_t)(new_value), .name = "vm_machine_attribute_t " #new_value}
1335*d4514f0bSApple OSS Distributions
1336*d4514f0bSApple OSS Distributions static vm_machine_attribute_trial_t vm_machine_attribute_trials_values[] = {
1337*d4514f0bSApple OSS Distributions VM_MACHINE_ATTRIBUTE_TRIAL(0),
1338*d4514f0bSApple OSS Distributions // start valid ones
1339*d4514f0bSApple OSS Distributions VM_MACHINE_ATTRIBUTE_TRIAL(MATTR_CACHE),
1340*d4514f0bSApple OSS Distributions VM_MACHINE_ATTRIBUTE_TRIAL(MATTR_MIGRATE),
1341*d4514f0bSApple OSS Distributions VM_MACHINE_ATTRIBUTE_TRIAL(MATTR_REPLICATE),
1342*d4514f0bSApple OSS Distributions // end valid ones
1343*d4514f0bSApple OSS Distributions VM_MACHINE_ATTRIBUTE_TRIAL(1u << 3),
1344*d4514f0bSApple OSS Distributions VM_MACHINE_ATTRIBUTE_TRIAL(1u << 4),
1345*d4514f0bSApple OSS Distributions VM_MACHINE_ATTRIBUTE_TRIAL(1u << 5),
1346*d4514f0bSApple OSS Distributions VM_MACHINE_ATTRIBUTE_TRIAL(1u << 6),
1347*d4514f0bSApple OSS Distributions VM_MACHINE_ATTRIBUTE_TRIAL(1u << 7),
1348*d4514f0bSApple OSS Distributions VM_MACHINE_ATTRIBUTE_TRIAL(1u << 8),
1349*d4514f0bSApple OSS Distributions VM_MACHINE_ATTRIBUTE_TRIAL(1u << 9),
1350*d4514f0bSApple OSS Distributions VM_MACHINE_ATTRIBUTE_TRIAL(1u << 10),
1351*d4514f0bSApple OSS Distributions VM_MACHINE_ATTRIBUTE_TRIAL(1u << 11),
1352*d4514f0bSApple OSS Distributions VM_MACHINE_ATTRIBUTE_TRIAL(1u << 12),
1353*d4514f0bSApple OSS Distributions VM_MACHINE_ATTRIBUTE_TRIAL(1u << 13),
1354*d4514f0bSApple OSS Distributions VM_MACHINE_ATTRIBUTE_TRIAL(1u << 14),
1355*d4514f0bSApple OSS Distributions VM_MACHINE_ATTRIBUTE_TRIAL(1u << 15),
1356*d4514f0bSApple OSS Distributions VM_MACHINE_ATTRIBUTE_TRIAL(1u << 16),
1357*d4514f0bSApple OSS Distributions VM_MACHINE_ATTRIBUTE_TRIAL(1u << 17),
1358*d4514f0bSApple OSS Distributions VM_MACHINE_ATTRIBUTE_TRIAL(1u << 18),
1359*d4514f0bSApple OSS Distributions VM_MACHINE_ATTRIBUTE_TRIAL(1u << 19),
1360*d4514f0bSApple OSS Distributions VM_MACHINE_ATTRIBUTE_TRIAL(1u << 20),
1361*d4514f0bSApple OSS Distributions VM_MACHINE_ATTRIBUTE_TRIAL(1u << 21),
1362*d4514f0bSApple OSS Distributions VM_MACHINE_ATTRIBUTE_TRIAL(1u << 22),
1363*d4514f0bSApple OSS Distributions VM_MACHINE_ATTRIBUTE_TRIAL(1u << 23),
1364*d4514f0bSApple OSS Distributions VM_MACHINE_ATTRIBUTE_TRIAL(1u << 24),
1365*d4514f0bSApple OSS Distributions VM_MACHINE_ATTRIBUTE_TRIAL(1u << 25),
1366*d4514f0bSApple OSS Distributions VM_MACHINE_ATTRIBUTE_TRIAL(1u << 26),
1367*d4514f0bSApple OSS Distributions VM_MACHINE_ATTRIBUTE_TRIAL(1u << 27),
1368*d4514f0bSApple OSS Distributions VM_MACHINE_ATTRIBUTE_TRIAL(1u << 28),
1369*d4514f0bSApple OSS Distributions VM_MACHINE_ATTRIBUTE_TRIAL(1u << 29),
1370*d4514f0bSApple OSS Distributions VM_MACHINE_ATTRIBUTE_TRIAL(1u << 30),
1371*d4514f0bSApple OSS Distributions VM_MACHINE_ATTRIBUTE_TRIAL(1u << 31),
1372*d4514f0bSApple OSS Distributions };
1373*d4514f0bSApple OSS Distributions
TRIALS_IMPL(vm_machine_attribute)1374*d4514f0bSApple OSS Distributions TRIALS_IMPL(vm_machine_attribute)
1375*d4514f0bSApple OSS Distributions
1376*d4514f0bSApple OSS Distributions static void
1377*d4514f0bSApple OSS Distributions cleanup_vm_machine_attribute_trials(vm_machine_attribute_trials_t **trials)
1378*d4514f0bSApple OSS Distributions {
1379*d4514f0bSApple OSS Distributions free_trials(*trials);
1380*d4514f0bSApple OSS Distributions }
1381*d4514f0bSApple OSS Distributions
1382*d4514f0bSApple OSS Distributions // allocate vm_map_kernel_flags trials, and deallocate it at end of scope
1383*d4514f0bSApple OSS Distributions #define SMART_VM_MAP_KERNEL_FLAGS_TRIALS() \
1384*d4514f0bSApple OSS Distributions __attribute__((cleanup(cleanup_vm_map_kernel_flags_trials))) \
1385*d4514f0bSApple OSS Distributions = generate_vm_map_kernel_flags_trials()
1386*d4514f0bSApple OSS Distributions
1387*d4514f0bSApple OSS Distributions
1388*d4514f0bSApple OSS Distributions // generate vm_map_kernel_flags_t trials
1389*d4514f0bSApple OSS Distributions
1390*d4514f0bSApple OSS Distributions typedef struct {
1391*d4514f0bSApple OSS Distributions int flags;
1392*d4514f0bSApple OSS Distributions char * name;
1393*d4514f0bSApple OSS Distributions } vm_map_kernel_flags_trial_t;
1394*d4514f0bSApple OSS Distributions
1395*d4514f0bSApple OSS Distributions typedef struct {
1396*d4514f0bSApple OSS Distributions unsigned count;
1397*d4514f0bSApple OSS Distributions unsigned capacity;
1398*d4514f0bSApple OSS Distributions vm_map_kernel_flags_trial_t list[];
1399*d4514f0bSApple OSS Distributions } vm_map_kernel_flags_trials_t;
1400*d4514f0bSApple OSS Distributions
1401*d4514f0bSApple OSS Distributions #define VM_MAP_KERNEL_FLAGS_TRIAL(new_flags) \
1402*d4514f0bSApple OSS Distributions (vm_map_kernel_flags_trial_t) {.flags = (int)(new_flags), .name ="vm_map_kernel_flags " #new_flags}
1403*d4514f0bSApple OSS Distributions
TRIALS_IMPL(vm_map_kernel_flags)1404*d4514f0bSApple OSS Distributions TRIALS_IMPL(vm_map_kernel_flags)
1405*d4514f0bSApple OSS Distributions
1406*d4514f0bSApple OSS Distributions static vm_map_kernel_flags_trials_t *
1407*d4514f0bSApple OSS Distributions generate_prefixed_vm_map_kernel_flags_trials(int prefix_flags, const char *prefix_name)
1408*d4514f0bSApple OSS Distributions {
1409*d4514f0bSApple OSS Distributions vm_map_kernel_flags_trials_t *trials;
1410*d4514f0bSApple OSS Distributions trials = allocate_vm_map_kernel_flags_trials(32);
1411*d4514f0bSApple OSS Distributions
1412*d4514f0bSApple OSS Distributions char *str;
1413*d4514f0bSApple OSS Distributions #define APPEND(flag) \
1414*d4514f0bSApple OSS Distributions ({ \
1415*d4514f0bSApple OSS Distributions kasprintf(&str, "vm_map_kernel_flags %s%s%s", \
1416*d4514f0bSApple OSS Distributions prefix_name, prefix_flags == 0 ? "" : " | ", #flag); \
1417*d4514f0bSApple OSS Distributions append_trial(trials, (vm_map_kernel_flags_trial_t){ prefix_flags | (int)flag, str }); \
1418*d4514f0bSApple OSS Distributions })
1419*d4514f0bSApple OSS Distributions
1420*d4514f0bSApple OSS Distributions // First trial is just the prefix flags set, if any.
1421*d4514f0bSApple OSS Distributions // (either ANYWHERE or FIXED | OVERWRITE)
1422*d4514f0bSApple OSS Distributions if (prefix_flags != 0) {
1423*d4514f0bSApple OSS Distributions kasprintf(&str, "vm_map_kernel_flags %s", prefix_name);
1424*d4514f0bSApple OSS Distributions append_trial(trials, (vm_map_kernel_flags_trial_t){ prefix_flags, str });
1425*d4514f0bSApple OSS Distributions }
1426*d4514f0bSApple OSS Distributions
1427*d4514f0bSApple OSS Distributions // Try each other flag with the prefix flags.
1428*d4514f0bSApple OSS Distributions // Skip FIXED and ANYWHERE and OVERWRITE because they cause
1429*d4514f0bSApple OSS Distributions // memory management changes that the caller may not be prepared for.
1430*d4514f0bSApple OSS Distributions // skip 0x00000000 VM_FLAGS_FIXED
1431*d4514f0bSApple OSS Distributions // skip 0x00000001 VM_FLAGS_ANYWHERE
1432*d4514f0bSApple OSS Distributions APPEND(VM_FLAGS_PURGABLE);
1433*d4514f0bSApple OSS Distributions APPEND(VM_FLAGS_4GB_CHUNK);
1434*d4514f0bSApple OSS Distributions APPEND(VM_FLAGS_RANDOM_ADDR);
1435*d4514f0bSApple OSS Distributions APPEND(VM_FLAGS_NO_CACHE);
1436*d4514f0bSApple OSS Distributions APPEND(VM_FLAGS_RESILIENT_CODESIGN);
1437*d4514f0bSApple OSS Distributions APPEND(VM_FLAGS_RESILIENT_MEDIA);
1438*d4514f0bSApple OSS Distributions APPEND(VM_FLAGS_PERMANENT);
1439*d4514f0bSApple OSS Distributions // skip 0x00001000 VM_FLAGS_TPRO; it only works on some hardware.
1440*d4514f0bSApple OSS Distributions APPEND(0x00002000);
1441*d4514f0bSApple OSS Distributions // skip 0x00004000 VM_FLAGS_OVERWRITE
1442*d4514f0bSApple OSS Distributions APPEND(0x00008000);
1443*d4514f0bSApple OSS Distributions APPEND(VM_FLAGS_SUPERPAGE_MASK); // 0x10000, 0x20000, 0x40000
1444*d4514f0bSApple OSS Distributions APPEND(0x00080000);
1445*d4514f0bSApple OSS Distributions APPEND(VM_FLAGS_RETURN_DATA_ADDR);
1446*d4514f0bSApple OSS Distributions APPEND(VM_FLAGS_RETURN_4K_DATA_ADDR);
1447*d4514f0bSApple OSS Distributions APPEND(VM_FLAGS_ALIAS_MASK);
1448*d4514f0bSApple OSS Distributions
1449*d4514f0bSApple OSS Distributions return trials;
1450*d4514f0bSApple OSS Distributions }
1451*d4514f0bSApple OSS Distributions
1452*d4514f0bSApple OSS Distributions static vm_map_kernel_flags_trials_t *
generate_vm_map_kernel_flags_trials()1453*d4514f0bSApple OSS Distributions generate_vm_map_kernel_flags_trials()
1454*d4514f0bSApple OSS Distributions {
1455*d4514f0bSApple OSS Distributions vm_map_kernel_flags_trials_t *fixed =
1456*d4514f0bSApple OSS Distributions generate_prefixed_vm_map_kernel_flags_trials(
1457*d4514f0bSApple OSS Distributions VM_FLAGS_FIXED | VM_FLAGS_OVERWRITE, "VM_FLAGS_FIXED | VM_FLAGS_OVERWRITE");
1458*d4514f0bSApple OSS Distributions vm_map_kernel_flags_trials_t *anywhere =
1459*d4514f0bSApple OSS Distributions generate_prefixed_vm_map_kernel_flags_trials(
1460*d4514f0bSApple OSS Distributions VM_FLAGS_ANYWHERE, "VM_FLAGS_ANYWHERE");
1461*d4514f0bSApple OSS Distributions vm_map_kernel_flags_trials_t *trials =
1462*d4514f0bSApple OSS Distributions allocate_vm_map_kernel_flags_trials(fixed->count + anywhere->count);
1463*d4514f0bSApple OSS Distributions append_trials(trials, fixed->list, fixed->count);
1464*d4514f0bSApple OSS Distributions append_trials(trials, anywhere->list, anywhere->count);
1465*d4514f0bSApple OSS Distributions
1466*d4514f0bSApple OSS Distributions // free not cleanup, trials has stolen their strings
1467*d4514f0bSApple OSS Distributions free_trials(fixed);
1468*d4514f0bSApple OSS Distributions free_trials(anywhere);
1469*d4514f0bSApple OSS Distributions
1470*d4514f0bSApple OSS Distributions return trials;
1471*d4514f0bSApple OSS Distributions }
1472*d4514f0bSApple OSS Distributions
1473*d4514f0bSApple OSS Distributions static void
cleanup_vm_map_kernel_flags_trials(vm_map_kernel_flags_trials_t ** trials)1474*d4514f0bSApple OSS Distributions cleanup_vm_map_kernel_flags_trials(vm_map_kernel_flags_trials_t **trials)
1475*d4514f0bSApple OSS Distributions {
1476*d4514f0bSApple OSS Distributions for (size_t i = 0; i < (*trials)->count; i++) {
1477*d4514f0bSApple OSS Distributions kfree_str((*trials)->list[i].name);
1478*d4514f0bSApple OSS Distributions }
1479*d4514f0bSApple OSS Distributions free_trials(*trials);
1480*d4514f0bSApple OSS Distributions }
1481*d4514f0bSApple OSS Distributions
1482*d4514f0bSApple OSS Distributions
1483*d4514f0bSApple OSS Distributions // generate mmap flags trials
1484*d4514f0bSApple OSS Distributions
1485*d4514f0bSApple OSS Distributions typedef struct {
1486*d4514f0bSApple OSS Distributions int flags;
1487*d4514f0bSApple OSS Distributions const char *name;
1488*d4514f0bSApple OSS Distributions } mmap_flags_trial_t;
1489*d4514f0bSApple OSS Distributions
1490*d4514f0bSApple OSS Distributions typedef struct {
1491*d4514f0bSApple OSS Distributions unsigned count;
1492*d4514f0bSApple OSS Distributions unsigned capacity;
1493*d4514f0bSApple OSS Distributions mmap_flags_trial_t list[];
1494*d4514f0bSApple OSS Distributions } mmap_flags_trials_t;
1495*d4514f0bSApple OSS Distributions
1496*d4514f0bSApple OSS Distributions #define MMAP_FLAGS_TRIAL(new_flags) \
1497*d4514f0bSApple OSS Distributions (mmap_flags_trial_t){ .flags = (int)(new_flags), .name = "mmap flags "#new_flags }
1498*d4514f0bSApple OSS Distributions
1499*d4514f0bSApple OSS Distributions static mmap_flags_trial_t mmap_flags_trials_values[] = {
1500*d4514f0bSApple OSS Distributions MMAP_FLAGS_TRIAL(MAP_FILE),
1501*d4514f0bSApple OSS Distributions MMAP_FLAGS_TRIAL(MAP_ANON),
1502*d4514f0bSApple OSS Distributions MMAP_FLAGS_TRIAL(MAP_FILE | MAP_SHARED),
1503*d4514f0bSApple OSS Distributions MMAP_FLAGS_TRIAL(MAP_FILE | MAP_PRIVATE),
1504*d4514f0bSApple OSS Distributions MMAP_FLAGS_TRIAL(MAP_ANON | MAP_SHARED),
1505*d4514f0bSApple OSS Distributions MMAP_FLAGS_TRIAL(MAP_ANON | MAP_PRIVATE),
1506*d4514f0bSApple OSS Distributions MMAP_FLAGS_TRIAL(MAP_FILE | MAP_SHARED | MAP_PRIVATE),
1507*d4514f0bSApple OSS Distributions MMAP_FLAGS_TRIAL(MAP_FILE | MAP_PRIVATE | MAP_FIXED),
1508*d4514f0bSApple OSS Distributions MMAP_FLAGS_TRIAL(MAP_FILE | MAP_PRIVATE | MAP_RENAME),
1509*d4514f0bSApple OSS Distributions MMAP_FLAGS_TRIAL(MAP_FILE | MAP_PRIVATE | MAP_NORESERVE),
1510*d4514f0bSApple OSS Distributions MMAP_FLAGS_TRIAL(MAP_FILE | MAP_PRIVATE | MAP_RESERVED0080),
1511*d4514f0bSApple OSS Distributions MMAP_FLAGS_TRIAL(MAP_FILE | MAP_PRIVATE | MAP_NOEXTEND),
1512*d4514f0bSApple OSS Distributions MMAP_FLAGS_TRIAL(MAP_FILE | MAP_PRIVATE | MAP_HASSEMAPHORE),
1513*d4514f0bSApple OSS Distributions MMAP_FLAGS_TRIAL(MAP_FILE | MAP_PRIVATE | MAP_NOCACHE),
1514*d4514f0bSApple OSS Distributions MMAP_FLAGS_TRIAL(MAP_FILE | MAP_PRIVATE | MAP_JIT),
1515*d4514f0bSApple OSS Distributions MMAP_FLAGS_TRIAL(MAP_FILE | MAP_PRIVATE | MAP_RESILIENT_CODESIGN),
1516*d4514f0bSApple OSS Distributions MMAP_FLAGS_TRIAL(MAP_FILE | MAP_PRIVATE | MAP_RESILIENT_MEDIA),
1517*d4514f0bSApple OSS Distributions MMAP_FLAGS_TRIAL(MAP_FILE | MAP_PRIVATE | MAP_TRANSLATED_ALLOW_EXECUTE),
1518*d4514f0bSApple OSS Distributions MMAP_FLAGS_TRIAL(MAP_FILE | MAP_PRIVATE | MAP_UNIX03),
1519*d4514f0bSApple OSS Distributions // skip MAP_TPRO; it only works on some hardware
1520*d4514f0bSApple OSS Distributions MMAP_FLAGS_TRIAL(MAP_FILE | MAP_PRIVATE | 1u << 3),
1521*d4514f0bSApple OSS Distributions MMAP_FLAGS_TRIAL(MAP_FILE | MAP_PRIVATE | 1u << 4),
1522*d4514f0bSApple OSS Distributions MMAP_FLAGS_TRIAL(MAP_FILE | MAP_PRIVATE | 1u << 5),
1523*d4514f0bSApple OSS Distributions MMAP_FLAGS_TRIAL(MAP_FILE | MAP_PRIVATE | 1u << 6),
1524*d4514f0bSApple OSS Distributions MMAP_FLAGS_TRIAL(MAP_FILE | MAP_PRIVATE | 1u << 7),
1525*d4514f0bSApple OSS Distributions MMAP_FLAGS_TRIAL(MAP_FILE | MAP_PRIVATE | 1u << 8),
1526*d4514f0bSApple OSS Distributions MMAP_FLAGS_TRIAL(MAP_FILE | MAP_PRIVATE | 1u << 9),
1527*d4514f0bSApple OSS Distributions MMAP_FLAGS_TRIAL(MAP_FILE | MAP_PRIVATE | 1u << 10),
1528*d4514f0bSApple OSS Distributions MMAP_FLAGS_TRIAL(MAP_FILE | MAP_PRIVATE | 1u << 11),
1529*d4514f0bSApple OSS Distributions MMAP_FLAGS_TRIAL(MAP_FILE | MAP_PRIVATE | 1u << 12),
1530*d4514f0bSApple OSS Distributions MMAP_FLAGS_TRIAL(MAP_FILE | MAP_PRIVATE | 1u << 13),
1531*d4514f0bSApple OSS Distributions MMAP_FLAGS_TRIAL(MAP_FILE | MAP_PRIVATE | 1u << 14),
1532*d4514f0bSApple OSS Distributions MMAP_FLAGS_TRIAL(MAP_FILE | MAP_PRIVATE | 1u << 15),
1533*d4514f0bSApple OSS Distributions MMAP_FLAGS_TRIAL(MAP_FILE | MAP_PRIVATE | 1u << 16),
1534*d4514f0bSApple OSS Distributions MMAP_FLAGS_TRIAL(MAP_FILE | MAP_PRIVATE | 1u << 17),
1535*d4514f0bSApple OSS Distributions MMAP_FLAGS_TRIAL(MAP_FILE | MAP_PRIVATE | 1u << 18),
1536*d4514f0bSApple OSS Distributions // skip MAP_TPRO (1<<19); it only works on some hardware
1537*d4514f0bSApple OSS Distributions MMAP_FLAGS_TRIAL(MAP_FILE | MAP_PRIVATE | 1u << 20),
1538*d4514f0bSApple OSS Distributions MMAP_FLAGS_TRIAL(MAP_FILE | MAP_PRIVATE | 1u << 21),
1539*d4514f0bSApple OSS Distributions MMAP_FLAGS_TRIAL(MAP_FILE | MAP_PRIVATE | 1u << 22),
1540*d4514f0bSApple OSS Distributions MMAP_FLAGS_TRIAL(MAP_FILE | MAP_PRIVATE | 1u << 23),
1541*d4514f0bSApple OSS Distributions MMAP_FLAGS_TRIAL(MAP_FILE | MAP_PRIVATE | 1u << 24),
1542*d4514f0bSApple OSS Distributions MMAP_FLAGS_TRIAL(MAP_FILE | MAP_PRIVATE | 1u << 25),
1543*d4514f0bSApple OSS Distributions MMAP_FLAGS_TRIAL(MAP_FILE | MAP_PRIVATE | 1u << 26),
1544*d4514f0bSApple OSS Distributions MMAP_FLAGS_TRIAL(MAP_FILE | MAP_PRIVATE | 1u << 27),
1545*d4514f0bSApple OSS Distributions MMAP_FLAGS_TRIAL(MAP_FILE | MAP_PRIVATE | 1u << 28),
1546*d4514f0bSApple OSS Distributions MMAP_FLAGS_TRIAL(MAP_FILE | MAP_PRIVATE | 1u << 29),
1547*d4514f0bSApple OSS Distributions MMAP_FLAGS_TRIAL(MAP_FILE | MAP_PRIVATE | 1u << 30),
1548*d4514f0bSApple OSS Distributions MMAP_FLAGS_TRIAL(MAP_FILE | MAP_PRIVATE | 1u << 31),
1549*d4514f0bSApple OSS Distributions };
1550*d4514f0bSApple OSS Distributions
TRIALS_IMPL(mmap_flags)1551*d4514f0bSApple OSS Distributions TRIALS_IMPL(mmap_flags)
1552*d4514f0bSApple OSS Distributions
1553*d4514f0bSApple OSS Distributions static void
1554*d4514f0bSApple OSS Distributions cleanup_mmap_flags_trials(mmap_flags_trials_t **trials)
1555*d4514f0bSApple OSS Distributions {
1556*d4514f0bSApple OSS Distributions free_trials(*trials);
1557*d4514f0bSApple OSS Distributions }
1558*d4514f0bSApple OSS Distributions
1559*d4514f0bSApple OSS Distributions // allocate mmap_flag trials, and deallocate it at end of scope
1560*d4514f0bSApple OSS Distributions #define SMART_MMAP_FLAGS_TRIALS() \
1561*d4514f0bSApple OSS Distributions __attribute__((cleanup(cleanup_mmap_flags_trials))) \
1562*d4514f0bSApple OSS Distributions = allocate_mmap_flags_trials(countof(mmap_flags_trials_values)); \
1563*d4514f0bSApple OSS Distributions append_trials(trials, mmap_flags_trials_values, countof(mmap_flags_trials_values))
1564*d4514f0bSApple OSS Distributions
1565*d4514f0bSApple OSS Distributions // generate generic flag trials
1566*d4514f0bSApple OSS Distributions
1567*d4514f0bSApple OSS Distributions typedef struct {
1568*d4514f0bSApple OSS Distributions int flag;
1569*d4514f0bSApple OSS Distributions const char *name;
1570*d4514f0bSApple OSS Distributions } generic_flag_trial_t;
1571*d4514f0bSApple OSS Distributions
1572*d4514f0bSApple OSS Distributions typedef struct {
1573*d4514f0bSApple OSS Distributions unsigned count;
1574*d4514f0bSApple OSS Distributions unsigned capacity;
1575*d4514f0bSApple OSS Distributions generic_flag_trial_t list[];
1576*d4514f0bSApple OSS Distributions } generic_flag_trials_t;
1577*d4514f0bSApple OSS Distributions
1578*d4514f0bSApple OSS Distributions #define GENERIC_FLAG_TRIAL(new_flag) \
1579*d4514f0bSApple OSS Distributions (generic_flag_trial_t){ .flag = (int)(new_flag), .name = "generic flag "#new_flag }
1580*d4514f0bSApple OSS Distributions
1581*d4514f0bSApple OSS Distributions static generic_flag_trial_t generic_flag_trials_values[] = {
1582*d4514f0bSApple OSS Distributions GENERIC_FLAG_TRIAL(0),
1583*d4514f0bSApple OSS Distributions GENERIC_FLAG_TRIAL(1),
1584*d4514f0bSApple OSS Distributions GENERIC_FLAG_TRIAL(2),
1585*d4514f0bSApple OSS Distributions GENERIC_FLAG_TRIAL(3),
1586*d4514f0bSApple OSS Distributions GENERIC_FLAG_TRIAL(4),
1587*d4514f0bSApple OSS Distributions GENERIC_FLAG_TRIAL(5),
1588*d4514f0bSApple OSS Distributions GENERIC_FLAG_TRIAL(6),
1589*d4514f0bSApple OSS Distributions GENERIC_FLAG_TRIAL(7),
1590*d4514f0bSApple OSS Distributions GENERIC_FLAG_TRIAL(1u << 3),
1591*d4514f0bSApple OSS Distributions GENERIC_FLAG_TRIAL(1u << 4),
1592*d4514f0bSApple OSS Distributions GENERIC_FLAG_TRIAL(1u << 5),
1593*d4514f0bSApple OSS Distributions GENERIC_FLAG_TRIAL(1u << 6),
1594*d4514f0bSApple OSS Distributions GENERIC_FLAG_TRIAL(1u << 7),
1595*d4514f0bSApple OSS Distributions GENERIC_FLAG_TRIAL(1u << 8),
1596*d4514f0bSApple OSS Distributions GENERIC_FLAG_TRIAL(1u << 9),
1597*d4514f0bSApple OSS Distributions GENERIC_FLAG_TRIAL(1u << 10),
1598*d4514f0bSApple OSS Distributions GENERIC_FLAG_TRIAL(1u << 11),
1599*d4514f0bSApple OSS Distributions GENERIC_FLAG_TRIAL(1u << 12),
1600*d4514f0bSApple OSS Distributions GENERIC_FLAG_TRIAL(1u << 13),
1601*d4514f0bSApple OSS Distributions GENERIC_FLAG_TRIAL(1u << 14),
1602*d4514f0bSApple OSS Distributions GENERIC_FLAG_TRIAL(1u << 15),
1603*d4514f0bSApple OSS Distributions GENERIC_FLAG_TRIAL(1u << 16),
1604*d4514f0bSApple OSS Distributions GENERIC_FLAG_TRIAL(1u << 17),
1605*d4514f0bSApple OSS Distributions GENERIC_FLAG_TRIAL(1u << 18),
1606*d4514f0bSApple OSS Distributions GENERIC_FLAG_TRIAL(1u << 19),
1607*d4514f0bSApple OSS Distributions GENERIC_FLAG_TRIAL(1u << 20),
1608*d4514f0bSApple OSS Distributions GENERIC_FLAG_TRIAL(1u << 21),
1609*d4514f0bSApple OSS Distributions GENERIC_FLAG_TRIAL(1u << 22),
1610*d4514f0bSApple OSS Distributions GENERIC_FLAG_TRIAL(1u << 23),
1611*d4514f0bSApple OSS Distributions GENERIC_FLAG_TRIAL(1u << 24),
1612*d4514f0bSApple OSS Distributions GENERIC_FLAG_TRIAL(1u << 25),
1613*d4514f0bSApple OSS Distributions GENERIC_FLAG_TRIAL(1u << 26),
1614*d4514f0bSApple OSS Distributions GENERIC_FLAG_TRIAL(1u << 27),
1615*d4514f0bSApple OSS Distributions GENERIC_FLAG_TRIAL(1u << 28),
1616*d4514f0bSApple OSS Distributions GENERIC_FLAG_TRIAL(1u << 29),
1617*d4514f0bSApple OSS Distributions GENERIC_FLAG_TRIAL(1u << 30),
1618*d4514f0bSApple OSS Distributions GENERIC_FLAG_TRIAL(1u << 31),
1619*d4514f0bSApple OSS Distributions };
1620*d4514f0bSApple OSS Distributions
TRIALS_IMPL(generic_flag)1621*d4514f0bSApple OSS Distributions TRIALS_IMPL(generic_flag)
1622*d4514f0bSApple OSS Distributions
1623*d4514f0bSApple OSS Distributions static void
1624*d4514f0bSApple OSS Distributions cleanup_generic_flag_trials(generic_flag_trials_t **trials)
1625*d4514f0bSApple OSS Distributions {
1626*d4514f0bSApple OSS Distributions free_trials(*trials);
1627*d4514f0bSApple OSS Distributions }
1628*d4514f0bSApple OSS Distributions
1629*d4514f0bSApple OSS Distributions // allocate mmap_flag trials, and deallocate it at end of scope
1630*d4514f0bSApple OSS Distributions #define SMART_GENERIC_FLAG_TRIALS() \
1631*d4514f0bSApple OSS Distributions __attribute__((cleanup(cleanup_generic_flag_trials))) \
1632*d4514f0bSApple OSS Distributions = allocate_generic_flag_trials(countof(generic_flag_trials_values)); \
1633*d4514f0bSApple OSS Distributions append_trials(trials, generic_flag_trials_values, countof(generic_flag_trials_values))
1634*d4514f0bSApple OSS Distributions
1635*d4514f0bSApple OSS Distributions
1636*d4514f0bSApple OSS Distributions // generate vm_prot_t trials
1637*d4514f0bSApple OSS Distributions
1638*d4514f0bSApple OSS Distributions #ifndef KERNEL
1639*d4514f0bSApple OSS Distributions typedef int vm_tag_t;
1640*d4514f0bSApple OSS Distributions #endif /* KERNEL */
1641*d4514f0bSApple OSS Distributions
1642*d4514f0bSApple OSS Distributions typedef struct {
1643*d4514f0bSApple OSS Distributions vm_tag_t tag;
1644*d4514f0bSApple OSS Distributions const char *name;
1645*d4514f0bSApple OSS Distributions } vm_tag_trial_t;
1646*d4514f0bSApple OSS Distributions
1647*d4514f0bSApple OSS Distributions typedef struct {
1648*d4514f0bSApple OSS Distributions unsigned count;
1649*d4514f0bSApple OSS Distributions unsigned capacity;
1650*d4514f0bSApple OSS Distributions vm_tag_trial_t list[];
1651*d4514f0bSApple OSS Distributions } vm_tag_trials_t;
1652*d4514f0bSApple OSS Distributions
1653*d4514f0bSApple OSS Distributions #if KERNEL
1654*d4514f0bSApple OSS Distributions #define KERNEL_VM_TAG_TRIAL(new_tag) \
1655*d4514f0bSApple OSS Distributions (vm_tag_trial_t){ .tag = (vm_tag_t)(new_tag), .name = "vm_tag "#new_tag }
1656*d4514f0bSApple OSS Distributions
1657*d4514f0bSApple OSS Distributions #define VM_TAG_TRIAL KERNEL_VM_TAG_TRIAL
1658*d4514f0bSApple OSS Distributions #else
1659*d4514f0bSApple OSS Distributions #define USER_VM_TAG_TRIAL(new_tag) \
1660*d4514f0bSApple OSS Distributions (vm_tag_trial_t){ .tag = (vm_tag_t)0, .name = "vm_tag "#new_tag }
1661*d4514f0bSApple OSS Distributions
1662*d4514f0bSApple OSS Distributions #define VM_TAG_TRIAL USER_VM_TAG_TRIAL
1663*d4514f0bSApple OSS Distributions #endif
1664*d4514f0bSApple OSS Distributions
1665*d4514f0bSApple OSS Distributions static vm_tag_trial_t vm_tag_trials_values[] = {
1666*d4514f0bSApple OSS Distributions VM_TAG_TRIAL(VM_KERN_MEMORY_NONE),
1667*d4514f0bSApple OSS Distributions VM_TAG_TRIAL(VM_KERN_MEMORY_OSFMK),
1668*d4514f0bSApple OSS Distributions VM_TAG_TRIAL(VM_KERN_MEMORY_BSD),
1669*d4514f0bSApple OSS Distributions VM_TAG_TRIAL(VM_KERN_MEMORY_IOKIT),
1670*d4514f0bSApple OSS Distributions VM_TAG_TRIAL(VM_KERN_MEMORY_LIBKERN),
1671*d4514f0bSApple OSS Distributions VM_TAG_TRIAL(VM_KERN_MEMORY_OSKEXT),
1672*d4514f0bSApple OSS Distributions VM_TAG_TRIAL(VM_KERN_MEMORY_KEXT),
1673*d4514f0bSApple OSS Distributions VM_TAG_TRIAL(VM_KERN_MEMORY_IPC),
1674*d4514f0bSApple OSS Distributions VM_TAG_TRIAL(VM_KERN_MEMORY_STACK),
1675*d4514f0bSApple OSS Distributions VM_TAG_TRIAL(VM_KERN_MEMORY_CPU),
1676*d4514f0bSApple OSS Distributions VM_TAG_TRIAL(VM_KERN_MEMORY_PMAP),
1677*d4514f0bSApple OSS Distributions VM_TAG_TRIAL(VM_KERN_MEMORY_PTE),
1678*d4514f0bSApple OSS Distributions VM_TAG_TRIAL(VM_KERN_MEMORY_ZONE),
1679*d4514f0bSApple OSS Distributions VM_TAG_TRIAL(VM_KERN_MEMORY_KALLOC),
1680*d4514f0bSApple OSS Distributions VM_TAG_TRIAL(VM_KERN_MEMORY_COMPRESSOR),
1681*d4514f0bSApple OSS Distributions VM_TAG_TRIAL(VM_KERN_MEMORY_COMPRESSED_DATA),
1682*d4514f0bSApple OSS Distributions VM_TAG_TRIAL(VM_KERN_MEMORY_PHANTOM_CACHE),
1683*d4514f0bSApple OSS Distributions VM_TAG_TRIAL(VM_KERN_MEMORY_WAITQ),
1684*d4514f0bSApple OSS Distributions VM_TAG_TRIAL(VM_KERN_MEMORY_DIAG),
1685*d4514f0bSApple OSS Distributions VM_TAG_TRIAL(VM_KERN_MEMORY_LOG),
1686*d4514f0bSApple OSS Distributions VM_TAG_TRIAL(VM_KERN_MEMORY_FILE),
1687*d4514f0bSApple OSS Distributions VM_TAG_TRIAL(VM_KERN_MEMORY_MBUF),
1688*d4514f0bSApple OSS Distributions VM_TAG_TRIAL(VM_KERN_MEMORY_UBC),
1689*d4514f0bSApple OSS Distributions VM_TAG_TRIAL(VM_KERN_MEMORY_SECURITY),
1690*d4514f0bSApple OSS Distributions VM_TAG_TRIAL(VM_KERN_MEMORY_MLOCK),
1691*d4514f0bSApple OSS Distributions VM_TAG_TRIAL(VM_KERN_MEMORY_REASON),
1692*d4514f0bSApple OSS Distributions VM_TAG_TRIAL(VM_KERN_MEMORY_SKYWALK),
1693*d4514f0bSApple OSS Distributions VM_TAG_TRIAL(VM_KERN_MEMORY_LTABLE),
1694*d4514f0bSApple OSS Distributions VM_TAG_TRIAL(VM_KERN_MEMORY_HV),
1695*d4514f0bSApple OSS Distributions VM_TAG_TRIAL(VM_KERN_MEMORY_KALLOC_DATA),
1696*d4514f0bSApple OSS Distributions VM_TAG_TRIAL(VM_KERN_MEMORY_RETIRED),
1697*d4514f0bSApple OSS Distributions VM_TAG_TRIAL(VM_KERN_MEMORY_KALLOC_TYPE),
1698*d4514f0bSApple OSS Distributions VM_TAG_TRIAL(VM_KERN_MEMORY_TRIAGE),
1699*d4514f0bSApple OSS Distributions VM_TAG_TRIAL(VM_KERN_MEMORY_RECOUNT),
1700*d4514f0bSApple OSS Distributions };
1701*d4514f0bSApple OSS Distributions
TRIALS_IMPL(vm_tag)1702*d4514f0bSApple OSS Distributions TRIALS_IMPL(vm_tag)
1703*d4514f0bSApple OSS Distributions
1704*d4514f0bSApple OSS Distributions static void
1705*d4514f0bSApple OSS Distributions cleanup_vm_tag_trials(vm_tag_trials_t **trials)
1706*d4514f0bSApple OSS Distributions {
1707*d4514f0bSApple OSS Distributions free_trials(*trials);
1708*d4514f0bSApple OSS Distributions }
1709*d4514f0bSApple OSS Distributions
1710*d4514f0bSApple OSS Distributions #define SMART_VM_TAG_TRIALS() \
1711*d4514f0bSApple OSS Distributions __attribute__((cleanup(cleanup_vm_tag_trials))) \
1712*d4514f0bSApple OSS Distributions = allocate_vm_tag_trials(countof(vm_tag_trials_values)); \
1713*d4514f0bSApple OSS Distributions append_trials(trials, vm_tag_trials_values, countof(vm_tag_trials_values))
1714*d4514f0bSApple OSS Distributions
1715*d4514f0bSApple OSS Distributions //END vm_tag_t
1716*d4514f0bSApple OSS Distributions
1717*d4514f0bSApple OSS Distributions // generate vm_prot_t trials
1718*d4514f0bSApple OSS Distributions
1719*d4514f0bSApple OSS Distributions typedef struct {
1720*d4514f0bSApple OSS Distributions vm_prot_t prot;
1721*d4514f0bSApple OSS Distributions const char *name;
1722*d4514f0bSApple OSS Distributions } vm_prot_trial_t;
1723*d4514f0bSApple OSS Distributions
1724*d4514f0bSApple OSS Distributions typedef struct {
1725*d4514f0bSApple OSS Distributions unsigned count;
1726*d4514f0bSApple OSS Distributions unsigned capacity;
1727*d4514f0bSApple OSS Distributions vm_prot_trial_t list[];
1728*d4514f0bSApple OSS Distributions } vm_prot_trials_t;
1729*d4514f0bSApple OSS Distributions
1730*d4514f0bSApple OSS Distributions #define VM_PROT_TRIAL(new_prot) \
1731*d4514f0bSApple OSS Distributions (vm_prot_trial_t){ .prot = (vm_prot_t)(new_prot), .name = "vm_prot "#new_prot }
1732*d4514f0bSApple OSS Distributions
1733*d4514f0bSApple OSS Distributions static vm_prot_trial_t vm_prot_trials_values[] = {
1734*d4514f0bSApple OSS Distributions // none
1735*d4514f0bSApple OSS Distributions VM_PROT_TRIAL(VM_PROT_NONE),
1736*d4514f0bSApple OSS Distributions // ordinary r-- / rw- / r-x
1737*d4514f0bSApple OSS Distributions VM_PROT_TRIAL(VM_PROT_READ),
1738*d4514f0bSApple OSS Distributions VM_PROT_TRIAL(VM_PROT_READ | VM_PROT_WRITE),
1739*d4514f0bSApple OSS Distributions VM_PROT_TRIAL(VM_PROT_READ | VM_PROT_EXECUTE),
1740*d4514f0bSApple OSS Distributions // rwx (w+x often disallowed)
1741*d4514f0bSApple OSS Distributions VM_PROT_TRIAL(VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE),
1742*d4514f0bSApple OSS Distributions // VM_PROT_READ | VM_PROT_x for each other VM_PROT_x bit
1743*d4514f0bSApple OSS Distributions // plus write and execute for some interesting cases
1744*d4514f0bSApple OSS Distributions VM_PROT_TRIAL(VM_PROT_READ | 1u << 3),
1745*d4514f0bSApple OSS Distributions VM_PROT_TRIAL(VM_PROT_READ | 1u << 4),
1746*d4514f0bSApple OSS Distributions VM_PROT_TRIAL(VM_PROT_READ | 1u << 5),
1747*d4514f0bSApple OSS Distributions VM_PROT_TRIAL(VM_PROT_READ | 1u << 6),
1748*d4514f0bSApple OSS Distributions VM_PROT_TRIAL(VM_PROT_READ | 1u << 7),
1749*d4514f0bSApple OSS Distributions VM_PROT_TRIAL(VM_PROT_READ | VM_PROT_WRITE | 1u << 7),
1750*d4514f0bSApple OSS Distributions VM_PROT_TRIAL(VM_PROT_READ | VM_PROT_EXECUTE | 1u << 7),
1751*d4514f0bSApple OSS Distributions VM_PROT_TRIAL(VM_PROT_READ | 1u << 8),
1752*d4514f0bSApple OSS Distributions VM_PROT_TRIAL(VM_PROT_READ | VM_PROT_WRITE | 1u << 8),
1753*d4514f0bSApple OSS Distributions VM_PROT_TRIAL(VM_PROT_READ | VM_PROT_EXECUTE | 1u << 8),
1754*d4514f0bSApple OSS Distributions VM_PROT_TRIAL(VM_PROT_READ | 1u << 9),
1755*d4514f0bSApple OSS Distributions VM_PROT_TRIAL(VM_PROT_READ | 1u << 10),
1756*d4514f0bSApple OSS Distributions VM_PROT_TRIAL(VM_PROT_READ | 1u << 11),
1757*d4514f0bSApple OSS Distributions VM_PROT_TRIAL(VM_PROT_READ | 1u << 12),
1758*d4514f0bSApple OSS Distributions VM_PROT_TRIAL(VM_PROT_READ | 1u << 13),
1759*d4514f0bSApple OSS Distributions VM_PROT_TRIAL(VM_PROT_READ | 1u << 14),
1760*d4514f0bSApple OSS Distributions VM_PROT_TRIAL(VM_PROT_READ | 1u << 15),
1761*d4514f0bSApple OSS Distributions VM_PROT_TRIAL(VM_PROT_READ | 1u << 16),
1762*d4514f0bSApple OSS Distributions VM_PROT_TRIAL(VM_PROT_READ | VM_PROT_WRITE | 1u << 16),
1763*d4514f0bSApple OSS Distributions VM_PROT_TRIAL(VM_PROT_READ | VM_PROT_EXECUTE | 1u << 16),
1764*d4514f0bSApple OSS Distributions VM_PROT_TRIAL(VM_PROT_READ | 1u << 17),
1765*d4514f0bSApple OSS Distributions VM_PROT_TRIAL(VM_PROT_READ | 1u << 18),
1766*d4514f0bSApple OSS Distributions VM_PROT_TRIAL(VM_PROT_READ | 1u << 19),
1767*d4514f0bSApple OSS Distributions VM_PROT_TRIAL(VM_PROT_READ | 1u << 20),
1768*d4514f0bSApple OSS Distributions VM_PROT_TRIAL(VM_PROT_READ | 1u << 21),
1769*d4514f0bSApple OSS Distributions VM_PROT_TRIAL(VM_PROT_READ | 1u << 22),
1770*d4514f0bSApple OSS Distributions VM_PROT_TRIAL(VM_PROT_READ | 1u << 23),
1771*d4514f0bSApple OSS Distributions VM_PROT_TRIAL(VM_PROT_READ | VM_PROT_WRITE | 1u << 23),
1772*d4514f0bSApple OSS Distributions VM_PROT_TRIAL(VM_PROT_READ | 1u << 24),
1773*d4514f0bSApple OSS Distributions VM_PROT_TRIAL(VM_PROT_READ | 1u << 25),
1774*d4514f0bSApple OSS Distributions VM_PROT_TRIAL(VM_PROT_READ | VM_PROT_WRITE | 1u << 25),
1775*d4514f0bSApple OSS Distributions VM_PROT_TRIAL(VM_PROT_READ | VM_PROT_EXECUTE | 1u << 25),
1776*d4514f0bSApple OSS Distributions VM_PROT_TRIAL(VM_PROT_READ | 1u << 26),
1777*d4514f0bSApple OSS Distributions VM_PROT_TRIAL(VM_PROT_READ | 1u << 27),
1778*d4514f0bSApple OSS Distributions VM_PROT_TRIAL(VM_PROT_READ | 1u << 28),
1779*d4514f0bSApple OSS Distributions VM_PROT_TRIAL(VM_PROT_READ | 1u << 29),
1780*d4514f0bSApple OSS Distributions VM_PROT_TRIAL(VM_PROT_READ | 1u << 30),
1781*d4514f0bSApple OSS Distributions VM_PROT_TRIAL(VM_PROT_READ | 1u << 31),
1782*d4514f0bSApple OSS Distributions VM_PROT_TRIAL(VM_PROT_READ | VM_PROT_WRITE | 1u << 31),
1783*d4514f0bSApple OSS Distributions VM_PROT_TRIAL(VM_PROT_READ | VM_PROT_EXECUTE | 1u << 31),
1784*d4514f0bSApple OSS Distributions
1785*d4514f0bSApple OSS Distributions // error case coverage in specific subfunctions
1786*d4514f0bSApple OSS Distributions VM_PROT_TRIAL(VM_PROT_READ | MAP_MEM_ONLY | MAP_MEM_USE_DATA_ADDR),
1787*d4514f0bSApple OSS Distributions VM_PROT_TRIAL(VM_PROT_READ | MAP_MEM_ONLY | MAP_MEM_4K_DATA_ADDR),
1788*d4514f0bSApple OSS Distributions VM_PROT_TRIAL(VM_PROT_READ | MAP_MEM_NAMED_CREATE | MAP_MEM_USE_DATA_ADDR),
1789*d4514f0bSApple OSS Distributions VM_PROT_TRIAL(VM_PROT_READ | MAP_MEM_NAMED_CREATE | MAP_MEM_4K_DATA_ADDR),
1790*d4514f0bSApple OSS Distributions VM_PROT_TRIAL(VM_PROT_READ | MAP_MEM_NAMED_CREATE | MAP_MEM_PURGABLE),
1791*d4514f0bSApple OSS Distributions VM_PROT_TRIAL(VM_PROT_NONE | MAP_MEM_VM_SHARE | VM_PROT_IS_MASK),
1792*d4514f0bSApple OSS Distributions
1793*d4514f0bSApple OSS Distributions // interesting non-error cases for additional test coverage
1794*d4514f0bSApple OSS Distributions VM_PROT_TRIAL(VM_PROT_READ | VM_PROT_WRITE | MAP_MEM_NAMED_CREATE | MAP_MEM_PURGABLE),
1795*d4514f0bSApple OSS Distributions VM_PROT_TRIAL(VM_PROT_READ | VM_PROT_WRITE | MAP_MEM_NAMED_CREATE |
1796*d4514f0bSApple OSS Distributions MAP_MEM_PURGABLE | MAP_MEM_PURGABLE_KERNEL_ONLY),
1797*d4514f0bSApple OSS Distributions };
1798*d4514f0bSApple OSS Distributions
TRIALS_IMPL(vm_prot)1799*d4514f0bSApple OSS Distributions TRIALS_IMPL(vm_prot)
1800*d4514f0bSApple OSS Distributions
1801*d4514f0bSApple OSS Distributions static void
1802*d4514f0bSApple OSS Distributions cleanup_vm_prot_trials(vm_prot_trials_t **trials)
1803*d4514f0bSApple OSS Distributions {
1804*d4514f0bSApple OSS Distributions free_trials(*trials);
1805*d4514f0bSApple OSS Distributions }
1806*d4514f0bSApple OSS Distributions
1807*d4514f0bSApple OSS Distributions // allocate vm_prot trials, and deallocate it at end of scope
1808*d4514f0bSApple OSS Distributions #define SMART_VM_PROT_TRIALS() \
1809*d4514f0bSApple OSS Distributions __attribute__((cleanup(cleanup_vm_prot_trials))) \
1810*d4514f0bSApple OSS Distributions = allocate_vm_prot_trials(countof(vm_prot_trials_values)); \
1811*d4514f0bSApple OSS Distributions append_trials(trials, vm_prot_trials_values, countof(vm_prot_trials_values))
1812*d4514f0bSApple OSS Distributions
1813*d4514f0bSApple OSS Distributions // Trials for pairs of vm_prot_t
1814*d4514f0bSApple OSS Distributions
1815*d4514f0bSApple OSS Distributions typedef struct {
1816*d4514f0bSApple OSS Distributions vm_prot_t cur;
1817*d4514f0bSApple OSS Distributions vm_prot_t max;
1818*d4514f0bSApple OSS Distributions char * name;
1819*d4514f0bSApple OSS Distributions } vm_prot_pair_trial_t;
1820*d4514f0bSApple OSS Distributions
1821*d4514f0bSApple OSS Distributions typedef struct {
1822*d4514f0bSApple OSS Distributions unsigned count;
1823*d4514f0bSApple OSS Distributions unsigned capacity;
1824*d4514f0bSApple OSS Distributions vm_prot_pair_trial_t list[];
1825*d4514f0bSApple OSS Distributions } vm_prot_pair_trials_t;
1826*d4514f0bSApple OSS Distributions
TRIALS_IMPL(vm_prot_pair)1827*d4514f0bSApple OSS Distributions TRIALS_IMPL(vm_prot_pair)
1828*d4514f0bSApple OSS Distributions
1829*d4514f0bSApple OSS Distributions #define VM_PROT_PAIR_TRIAL(new_cur, new_max, new_name) \
1830*d4514f0bSApple OSS Distributions (vm_prot_pair_trial_t){ .cur = (vm_prot_t)(new_cur), \
1831*d4514f0bSApple OSS Distributions .max = (vm_prot_t)(new_max), \
1832*d4514f0bSApple OSS Distributions .name = new_name,}
1833*d4514f0bSApple OSS Distributions
1834*d4514f0bSApple OSS Distributions vm_prot_pair_trials_t *
1835*d4514f0bSApple OSS Distributions generate_vm_prot_pair_trials()
1836*d4514f0bSApple OSS Distributions {
1837*d4514f0bSApple OSS Distributions const unsigned D = countof(vm_prot_trials_values);
1838*d4514f0bSApple OSS Distributions unsigned num_trials = D * D;
1839*d4514f0bSApple OSS Distributions
1840*d4514f0bSApple OSS Distributions vm_prot_pair_trials_t * trials = allocate_vm_prot_pair_trials(num_trials);
1841*d4514f0bSApple OSS Distributions for (size_t i = 0; i < D; i++) {
1842*d4514f0bSApple OSS Distributions for (size_t j = 0; j < D; j++) {
1843*d4514f0bSApple OSS Distributions vm_prot_t cur = vm_prot_trials_values[i].prot;
1844*d4514f0bSApple OSS Distributions vm_prot_t max = vm_prot_trials_values[j].prot;
1845*d4514f0bSApple OSS Distributions char *str;
1846*d4514f0bSApple OSS Distributions kasprintf(&str, "cur: 0x%x, max: 0x%x", cur, max);
1847*d4514f0bSApple OSS Distributions append_trial(trials, VM_PROT_PAIR_TRIAL(cur, max, str));
1848*d4514f0bSApple OSS Distributions }
1849*d4514f0bSApple OSS Distributions }
1850*d4514f0bSApple OSS Distributions return trials;
1851*d4514f0bSApple OSS Distributions }
1852*d4514f0bSApple OSS Distributions
1853*d4514f0bSApple OSS Distributions #define SMART_VM_PROT_PAIR_TRIALS() \
1854*d4514f0bSApple OSS Distributions __attribute__((cleanup(cleanup_vm_prot_pair_trials))) \
1855*d4514f0bSApple OSS Distributions = generate_vm_prot_pair_trials();
1856*d4514f0bSApple OSS Distributions
1857*d4514f0bSApple OSS Distributions static void
cleanup_vm_prot_pair_trials(vm_prot_pair_trials_t ** trials)1858*d4514f0bSApple OSS Distributions cleanup_vm_prot_pair_trials(vm_prot_pair_trials_t **trials)
1859*d4514f0bSApple OSS Distributions {
1860*d4514f0bSApple OSS Distributions for (size_t i = 0; i < (*trials)->count; i++) {
1861*d4514f0bSApple OSS Distributions kfree_str((*trials)->list[i].name);
1862*d4514f0bSApple OSS Distributions }
1863*d4514f0bSApple OSS Distributions free_trials(*trials);
1864*d4514f0bSApple OSS Distributions }
1865*d4514f0bSApple OSS Distributions
1866*d4514f0bSApple OSS Distributions
1867*d4514f0bSApple OSS Distributions // vm_purgeable_t trial contents.
1868*d4514f0bSApple OSS Distributions typedef struct {
1869*d4514f0bSApple OSS Distributions vm_purgable_t value;
1870*d4514f0bSApple OSS Distributions char * name;
1871*d4514f0bSApple OSS Distributions } vm_purgeable_trial_t;
1872*d4514f0bSApple OSS Distributions
1873*d4514f0bSApple OSS Distributions #define VM_PURGEABLE_TRIAL(new_value) \
1874*d4514f0bSApple OSS Distributions (vm_purgeable_trial_t) {.value = (vm_purgable_t)(new_value), .name = "vm_purgeable_t " #new_value}
1875*d4514f0bSApple OSS Distributions
1876*d4514f0bSApple OSS Distributions static vm_purgeable_trial_t vm_purgeable_trials_values[] = {
1877*d4514f0bSApple OSS Distributions VM_PURGEABLE_TRIAL(VM_PURGABLE_SET_STATE),
1878*d4514f0bSApple OSS Distributions VM_PURGEABLE_TRIAL(VM_PURGABLE_GET_STATE),
1879*d4514f0bSApple OSS Distributions VM_PURGEABLE_TRIAL(VM_PURGABLE_PURGE_ALL),
1880*d4514f0bSApple OSS Distributions VM_PURGEABLE_TRIAL(VM_PURGABLE_SET_STATE_FROM_KERNEL),
1881*d4514f0bSApple OSS Distributions // end valid values
1882*d4514f0bSApple OSS Distributions VM_PURGEABLE_TRIAL(VM_PURGABLE_SET_STATE_FROM_KERNEL + 1),
1883*d4514f0bSApple OSS Distributions VM_PURGEABLE_TRIAL(VM_PURGABLE_SET_STATE_FROM_KERNEL + 2),
1884*d4514f0bSApple OSS Distributions VM_PURGEABLE_TRIAL(0x12345),
1885*d4514f0bSApple OSS Distributions VM_PURGEABLE_TRIAL(0xffffffff),
1886*d4514f0bSApple OSS Distributions };
1887*d4514f0bSApple OSS Distributions
1888*d4514f0bSApple OSS Distributions typedef struct {
1889*d4514f0bSApple OSS Distributions int value;
1890*d4514f0bSApple OSS Distributions char * name;
1891*d4514f0bSApple OSS Distributions } vm_purgeable_state_trial_t;
1892*d4514f0bSApple OSS Distributions
1893*d4514f0bSApple OSS Distributions #define VM_PURGEABLE_STATE_TRIAL(new_value) \
1894*d4514f0bSApple OSS Distributions (vm_purgeable_state_trial_t) {.value = (int)(new_value), .name = "state " #new_value}
1895*d4514f0bSApple OSS Distributions
1896*d4514f0bSApple OSS Distributions static vm_purgeable_state_trial_t vm_purgeable_state_trials_values[] = {
1897*d4514f0bSApple OSS Distributions VM_PURGEABLE_STATE_TRIAL(VM_PURGABLE_NO_AGING),
1898*d4514f0bSApple OSS Distributions VM_PURGEABLE_STATE_TRIAL(VM_PURGABLE_DEBUG_EMPTY),
1899*d4514f0bSApple OSS Distributions VM_PURGEABLE_STATE_TRIAL(VM_VOLATILE_GROUP_0),
1900*d4514f0bSApple OSS Distributions VM_PURGEABLE_STATE_TRIAL(VM_VOLATILE_GROUP_7),
1901*d4514f0bSApple OSS Distributions VM_PURGEABLE_STATE_TRIAL(VM_PURGABLE_BEHAVIOR_FIFO),
1902*d4514f0bSApple OSS Distributions VM_PURGEABLE_STATE_TRIAL(VM_PURGABLE_ORDERING_NORMAL),
1903*d4514f0bSApple OSS Distributions VM_PURGEABLE_STATE_TRIAL(VM_PURGABLE_EMPTY),
1904*d4514f0bSApple OSS Distributions VM_PURGEABLE_STATE_TRIAL(VM_PURGABLE_DENY),
1905*d4514f0bSApple OSS Distributions VM_PURGEABLE_STATE_TRIAL(VM_PURGABLE_NONVOLATILE),
1906*d4514f0bSApple OSS Distributions VM_PURGEABLE_STATE_TRIAL(VM_PURGABLE_VOLATILE),
1907*d4514f0bSApple OSS Distributions VM_PURGEABLE_STATE_TRIAL(0x12345),
1908*d4514f0bSApple OSS Distributions VM_PURGEABLE_STATE_TRIAL(0xffffffff),
1909*d4514f0bSApple OSS Distributions };
1910*d4514f0bSApple OSS Distributions
1911*d4514f0bSApple OSS Distributions // Trials for vm_purgeable_t and state
1912*d4514f0bSApple OSS Distributions typedef struct {
1913*d4514f0bSApple OSS Distributions vm_purgable_t control;
1914*d4514f0bSApple OSS Distributions int state;
1915*d4514f0bSApple OSS Distributions char * name;
1916*d4514f0bSApple OSS Distributions } vm_purgeable_and_state_trial_t;
1917*d4514f0bSApple OSS Distributions
1918*d4514f0bSApple OSS Distributions typedef struct {
1919*d4514f0bSApple OSS Distributions unsigned count;
1920*d4514f0bSApple OSS Distributions unsigned capacity;
1921*d4514f0bSApple OSS Distributions vm_purgeable_and_state_trial_t list[];
1922*d4514f0bSApple OSS Distributions } vm_purgeable_and_state_trials_t;
1923*d4514f0bSApple OSS Distributions
TRIALS_IMPL(vm_purgeable_and_state)1924*d4514f0bSApple OSS Distributions TRIALS_IMPL(vm_purgeable_and_state)
1925*d4514f0bSApple OSS Distributions
1926*d4514f0bSApple OSS Distributions #define VM_PURGEABLE_AND_STATE_TRIAL(new_control, new_state, new_name) \
1927*d4514f0bSApple OSS Distributions (vm_purgeable_and_state_trial_t){ .control = (vm_purgable_t)(new_control), \
1928*d4514f0bSApple OSS Distributions .state = (int)(new_state), \
1929*d4514f0bSApple OSS Distributions .name = new_name,}
1930*d4514f0bSApple OSS Distributions
1931*d4514f0bSApple OSS Distributions vm_purgeable_and_state_trials_t *
1932*d4514f0bSApple OSS Distributions generate_vm_purgeable_t_and_state_trials()
1933*d4514f0bSApple OSS Distributions {
1934*d4514f0bSApple OSS Distributions const unsigned purgeable_trial_count = countof(vm_purgeable_trials_values);
1935*d4514f0bSApple OSS Distributions const unsigned state_trial_count = countof(vm_purgeable_state_trials_values);
1936*d4514f0bSApple OSS Distributions unsigned num_trials = purgeable_trial_count * state_trial_count;
1937*d4514f0bSApple OSS Distributions
1938*d4514f0bSApple OSS Distributions vm_purgeable_and_state_trials_t * trials = allocate_vm_purgeable_and_state_trials(num_trials);
1939*d4514f0bSApple OSS Distributions for (size_t i = 0; i < purgeable_trial_count; i++) {
1940*d4514f0bSApple OSS Distributions for (size_t j = 0; j < state_trial_count; j++) {
1941*d4514f0bSApple OSS Distributions vm_purgeable_trial_t control_trial = vm_purgeable_trials_values[i];
1942*d4514f0bSApple OSS Distributions vm_purgeable_state_trial_t state_trial = vm_purgeable_state_trials_values[j];
1943*d4514f0bSApple OSS Distributions char *str;
1944*d4514f0bSApple OSS Distributions kasprintf(&str, "%s, %s", control_trial.name, state_trial.name);
1945*d4514f0bSApple OSS Distributions append_trial(trials, VM_PURGEABLE_AND_STATE_TRIAL(control_trial.value, state_trial.value, str));
1946*d4514f0bSApple OSS Distributions }
1947*d4514f0bSApple OSS Distributions }
1948*d4514f0bSApple OSS Distributions return trials;
1949*d4514f0bSApple OSS Distributions }
1950*d4514f0bSApple OSS Distributions
1951*d4514f0bSApple OSS Distributions #define SMART_VM_PURGEABLE_AND_STATE_TRIALS() \
1952*d4514f0bSApple OSS Distributions __attribute__((cleanup(cleanup_vm_purgeable_t_and_state_trials))) \
1953*d4514f0bSApple OSS Distributions = generate_vm_purgeable_t_and_state_trials();
1954*d4514f0bSApple OSS Distributions
1955*d4514f0bSApple OSS Distributions static void
cleanup_vm_purgeable_t_and_state_trials(vm_purgeable_and_state_trials_t ** trials)1956*d4514f0bSApple OSS Distributions cleanup_vm_purgeable_t_and_state_trials(vm_purgeable_and_state_trials_t **trials)
1957*d4514f0bSApple OSS Distributions {
1958*d4514f0bSApple OSS Distributions for (size_t i = 0; i < (*trials)->count; i++) {
1959*d4514f0bSApple OSS Distributions kfree_str((*trials)->list[i].name);
1960*d4514f0bSApple OSS Distributions }
1961*d4514f0bSApple OSS Distributions free_trials(*trials);
1962*d4514f0bSApple OSS Distributions }
1963*d4514f0bSApple OSS Distributions
1964*d4514f0bSApple OSS Distributions // generate ledger tag trials
1965*d4514f0bSApple OSS Distributions
1966*d4514f0bSApple OSS Distributions typedef struct {
1967*d4514f0bSApple OSS Distributions int tag;
1968*d4514f0bSApple OSS Distributions const char *name;
1969*d4514f0bSApple OSS Distributions } ledger_tag_trial_t;
1970*d4514f0bSApple OSS Distributions
1971*d4514f0bSApple OSS Distributions typedef struct {
1972*d4514f0bSApple OSS Distributions unsigned count;
1973*d4514f0bSApple OSS Distributions unsigned capacity;
1974*d4514f0bSApple OSS Distributions ledger_tag_trial_t list[];
1975*d4514f0bSApple OSS Distributions } ledger_tag_trials_t;
1976*d4514f0bSApple OSS Distributions
1977*d4514f0bSApple OSS Distributions #define LEDGER_TAG_TRIAL(new_tag) \
1978*d4514f0bSApple OSS Distributions (ledger_tag_trial_t){ .tag = (int)(new_tag), .name = "ledger tag "#new_tag }
1979*d4514f0bSApple OSS Distributions
1980*d4514f0bSApple OSS Distributions static ledger_tag_trial_t ledger_tag_trials_values[] = {
1981*d4514f0bSApple OSS Distributions LEDGER_TAG_TRIAL(VM_LEDGER_TAG_NONE),
1982*d4514f0bSApple OSS Distributions LEDGER_TAG_TRIAL(VM_LEDGER_TAG_DEFAULT),
1983*d4514f0bSApple OSS Distributions LEDGER_TAG_TRIAL(VM_LEDGER_TAG_NETWORK),
1984*d4514f0bSApple OSS Distributions LEDGER_TAG_TRIAL(VM_LEDGER_TAG_MEDIA),
1985*d4514f0bSApple OSS Distributions LEDGER_TAG_TRIAL(VM_LEDGER_TAG_GRAPHICS),
1986*d4514f0bSApple OSS Distributions LEDGER_TAG_TRIAL(VM_LEDGER_TAG_NEURAL),
1987*d4514f0bSApple OSS Distributions LEDGER_TAG_TRIAL(VM_LEDGER_TAG_MAX),
1988*d4514f0bSApple OSS Distributions LEDGER_TAG_TRIAL(1u << 16),
1989*d4514f0bSApple OSS Distributions LEDGER_TAG_TRIAL(1u << 17),
1990*d4514f0bSApple OSS Distributions LEDGER_TAG_TRIAL(1u << 18),
1991*d4514f0bSApple OSS Distributions LEDGER_TAG_TRIAL(1u << 19),
1992*d4514f0bSApple OSS Distributions LEDGER_TAG_TRIAL(1u << 20),
1993*d4514f0bSApple OSS Distributions LEDGER_TAG_TRIAL(1u << 21),
1994*d4514f0bSApple OSS Distributions LEDGER_TAG_TRIAL(1u << 22),
1995*d4514f0bSApple OSS Distributions LEDGER_TAG_TRIAL(1u << 23),
1996*d4514f0bSApple OSS Distributions LEDGER_TAG_TRIAL(1u << 24),
1997*d4514f0bSApple OSS Distributions LEDGER_TAG_TRIAL(1u << 25),
1998*d4514f0bSApple OSS Distributions LEDGER_TAG_TRIAL(1u << 26),
1999*d4514f0bSApple OSS Distributions LEDGER_TAG_TRIAL(1u << 27),
2000*d4514f0bSApple OSS Distributions LEDGER_TAG_TRIAL(1u << 28),
2001*d4514f0bSApple OSS Distributions LEDGER_TAG_TRIAL(1u << 29),
2002*d4514f0bSApple OSS Distributions LEDGER_TAG_TRIAL(1u << 30),
2003*d4514f0bSApple OSS Distributions LEDGER_TAG_TRIAL(1u << 31),
2004*d4514f0bSApple OSS Distributions LEDGER_TAG_TRIAL(VM_LEDGER_TAG_UNCHANGED),
2005*d4514f0bSApple OSS Distributions };
2006*d4514f0bSApple OSS Distributions
TRIALS_IMPL(ledger_tag)2007*d4514f0bSApple OSS Distributions TRIALS_IMPL(ledger_tag)
2008*d4514f0bSApple OSS Distributions
2009*d4514f0bSApple OSS Distributions static void
2010*d4514f0bSApple OSS Distributions cleanup_ledger_tag_trials(ledger_tag_trials_t **trials)
2011*d4514f0bSApple OSS Distributions {
2012*d4514f0bSApple OSS Distributions free_trials(*trials);
2013*d4514f0bSApple OSS Distributions }
2014*d4514f0bSApple OSS Distributions
2015*d4514f0bSApple OSS Distributions // allocate ledger tag trials, and deallocate it at end of scope
2016*d4514f0bSApple OSS Distributions #define SMART_LEDGER_TAG_TRIALS() \
2017*d4514f0bSApple OSS Distributions __attribute__((cleanup(cleanup_ledger_tag_trials))) \
2018*d4514f0bSApple OSS Distributions = allocate_ledger_tag_trials(countof(ledger_tag_trials_values)); \
2019*d4514f0bSApple OSS Distributions append_trials(trials, ledger_tag_trials_values, countof(ledger_tag_trials_values))
2020*d4514f0bSApple OSS Distributions
2021*d4514f0bSApple OSS Distributions
2022*d4514f0bSApple OSS Distributions // generate ledger flag trials
2023*d4514f0bSApple OSS Distributions
2024*d4514f0bSApple OSS Distributions typedef struct {
2025*d4514f0bSApple OSS Distributions int flag;
2026*d4514f0bSApple OSS Distributions const char *name;
2027*d4514f0bSApple OSS Distributions } ledger_flag_trial_t;
2028*d4514f0bSApple OSS Distributions
2029*d4514f0bSApple OSS Distributions typedef struct {
2030*d4514f0bSApple OSS Distributions unsigned count;
2031*d4514f0bSApple OSS Distributions unsigned capacity;
2032*d4514f0bSApple OSS Distributions ledger_flag_trial_t list[];
2033*d4514f0bSApple OSS Distributions } ledger_flag_trials_t;
2034*d4514f0bSApple OSS Distributions
2035*d4514f0bSApple OSS Distributions #define LEDGER_FLAG_TRIAL(new_flag) \
2036*d4514f0bSApple OSS Distributions (ledger_flag_trial_t){ .flag = (int)(new_flag), .name = "ledger flag "#new_flag }
2037*d4514f0bSApple OSS Distributions
2038*d4514f0bSApple OSS Distributions static ledger_flag_trial_t ledger_flag_trials_values[] = {
2039*d4514f0bSApple OSS Distributions LEDGER_FLAG_TRIAL(0),
2040*d4514f0bSApple OSS Distributions LEDGER_FLAG_TRIAL(VM_LEDGER_FLAG_NO_FOOTPRINT),
2041*d4514f0bSApple OSS Distributions LEDGER_FLAG_TRIAL(VM_LEDGER_FLAG_NO_FOOTPRINT_FOR_DEBUG),
2042*d4514f0bSApple OSS Distributions LEDGER_FLAG_TRIAL(VM_LEDGER_FLAGS_USER),
2043*d4514f0bSApple OSS Distributions LEDGER_FLAG_TRIAL(VM_LEDGER_FLAG_FROM_KERNEL),
2044*d4514f0bSApple OSS Distributions LEDGER_FLAG_TRIAL(VM_LEDGER_FLAGS_ALL),
2045*d4514f0bSApple OSS Distributions LEDGER_FLAG_TRIAL(1u << 3),
2046*d4514f0bSApple OSS Distributions LEDGER_FLAG_TRIAL(1u << 4),
2047*d4514f0bSApple OSS Distributions LEDGER_FLAG_TRIAL(1u << 5),
2048*d4514f0bSApple OSS Distributions LEDGER_FLAG_TRIAL(1u << 6),
2049*d4514f0bSApple OSS Distributions LEDGER_FLAG_TRIAL(1u << 7),
2050*d4514f0bSApple OSS Distributions LEDGER_FLAG_TRIAL(1u << 8),
2051*d4514f0bSApple OSS Distributions LEDGER_FLAG_TRIAL(1u << 9),
2052*d4514f0bSApple OSS Distributions LEDGER_FLAG_TRIAL(1u << 10),
2053*d4514f0bSApple OSS Distributions LEDGER_FLAG_TRIAL(1u << 11),
2054*d4514f0bSApple OSS Distributions LEDGER_FLAG_TRIAL(1u << 12),
2055*d4514f0bSApple OSS Distributions LEDGER_FLAG_TRIAL(1u << 13),
2056*d4514f0bSApple OSS Distributions LEDGER_FLAG_TRIAL(1u << 14),
2057*d4514f0bSApple OSS Distributions LEDGER_FLAG_TRIAL(1u << 15),
2058*d4514f0bSApple OSS Distributions LEDGER_FLAG_TRIAL(1u << 16),
2059*d4514f0bSApple OSS Distributions LEDGER_FLAG_TRIAL(1u << 17),
2060*d4514f0bSApple OSS Distributions LEDGER_FLAG_TRIAL(1u << 18),
2061*d4514f0bSApple OSS Distributions LEDGER_FLAG_TRIAL(1u << 19),
2062*d4514f0bSApple OSS Distributions LEDGER_FLAG_TRIAL(1u << 20),
2063*d4514f0bSApple OSS Distributions LEDGER_FLAG_TRIAL(1u << 21),
2064*d4514f0bSApple OSS Distributions LEDGER_FLAG_TRIAL(1u << 22),
2065*d4514f0bSApple OSS Distributions LEDGER_FLAG_TRIAL(1u << 23),
2066*d4514f0bSApple OSS Distributions LEDGER_FLAG_TRIAL(1u << 24),
2067*d4514f0bSApple OSS Distributions LEDGER_FLAG_TRIAL(1u << 25),
2068*d4514f0bSApple OSS Distributions LEDGER_FLAG_TRIAL(1u << 26),
2069*d4514f0bSApple OSS Distributions LEDGER_FLAG_TRIAL(1u << 27),
2070*d4514f0bSApple OSS Distributions LEDGER_FLAG_TRIAL(1u << 28),
2071*d4514f0bSApple OSS Distributions LEDGER_FLAG_TRIAL(1u << 29),
2072*d4514f0bSApple OSS Distributions LEDGER_FLAG_TRIAL(1u << 30),
2073*d4514f0bSApple OSS Distributions LEDGER_FLAG_TRIAL(1u << 31),
2074*d4514f0bSApple OSS Distributions };
2075*d4514f0bSApple OSS Distributions
TRIALS_IMPL(ledger_flag)2076*d4514f0bSApple OSS Distributions TRIALS_IMPL(ledger_flag)
2077*d4514f0bSApple OSS Distributions
2078*d4514f0bSApple OSS Distributions static void
2079*d4514f0bSApple OSS Distributions cleanup_ledger_flag_trials(ledger_flag_trials_t **trials)
2080*d4514f0bSApple OSS Distributions {
2081*d4514f0bSApple OSS Distributions free_trials(*trials);
2082*d4514f0bSApple OSS Distributions }
2083*d4514f0bSApple OSS Distributions
2084*d4514f0bSApple OSS Distributions // allocate ledger flag trials, and deallocate it at end of scope
2085*d4514f0bSApple OSS Distributions #define SMART_LEDGER_FLAG_TRIALS() \
2086*d4514f0bSApple OSS Distributions __attribute__((cleanup(cleanup_ledger_flag_trials))) \
2087*d4514f0bSApple OSS Distributions = allocate_ledger_flag_trials(countof(ledger_flag_trials_values)); \
2088*d4514f0bSApple OSS Distributions append_trials(trials, ledger_flag_trials_values, countof(ledger_flag_trials_values))
2089*d4514f0bSApple OSS Distributions
2090*d4514f0bSApple OSS Distributions // generate address-parameter trials
2091*d4514f0bSApple OSS Distributions // where the address has no associated size
2092*d4514f0bSApple OSS Distributions // and the callee's arithmetic includes `round_page(addr)`
2093*d4514f0bSApple OSS Distributions
2094*d4514f0bSApple OSS Distributions typedef struct {
2095*d4514f0bSApple OSS Distributions addr_t addr;
2096*d4514f0bSApple OSS Distributions bool addr_is_absolute;
2097*d4514f0bSApple OSS Distributions char *name;
2098*d4514f0bSApple OSS Distributions } addr_trial_t;
2099*d4514f0bSApple OSS Distributions
2100*d4514f0bSApple OSS Distributions typedef struct {
2101*d4514f0bSApple OSS Distributions unsigned count;
2102*d4514f0bSApple OSS Distributions unsigned capacity;
2103*d4514f0bSApple OSS Distributions addr_trial_t list[];
2104*d4514f0bSApple OSS Distributions } addr_trials_t;
2105*d4514f0bSApple OSS Distributions
2106*d4514f0bSApple OSS Distributions #define ADDR_TRIAL(new_addr, new_absolute, new_name) \
2107*d4514f0bSApple OSS Distributions (addr_trial_t){ .addr = (addr_t)(new_addr), .addr_is_absolute = new_absolute, .name = new_name }
2108*d4514f0bSApple OSS Distributions
2109*d4514f0bSApple OSS Distributions static addr_trial_t __attribute__((overloadable, used))
slide_trial(addr_trial_t trial,mach_vm_address_t slide)2110*d4514f0bSApple OSS Distributions slide_trial(addr_trial_t trial, mach_vm_address_t slide)
2111*d4514f0bSApple OSS Distributions {
2112*d4514f0bSApple OSS Distributions addr_trial_t result = trial;
2113*d4514f0bSApple OSS Distributions if (!trial.addr_is_absolute) {
2114*d4514f0bSApple OSS Distributions result.addr += slide;
2115*d4514f0bSApple OSS Distributions }
2116*d4514f0bSApple OSS Distributions return result;
2117*d4514f0bSApple OSS Distributions }
2118*d4514f0bSApple OSS Distributions
2119*d4514f0bSApple OSS Distributions static const offset_list_t *
get_addr_trial_offsets(void)2120*d4514f0bSApple OSS Distributions get_addr_trial_offsets(void)
2121*d4514f0bSApple OSS Distributions {
2122*d4514f0bSApple OSS Distributions static offset_list_t *offsets;
2123*d4514f0bSApple OSS Distributions addr_t test_page_size = adjust_page_size();
2124*d4514f0bSApple OSS Distributions if (!offsets) {
2125*d4514f0bSApple OSS Distributions offsets = allocate_offsets(20);
2126*d4514f0bSApple OSS Distributions append_offset(offsets, true, 0);
2127*d4514f0bSApple OSS Distributions append_offset(offsets, true, 1);
2128*d4514f0bSApple OSS Distributions append_offset(offsets, true, 2);
2129*d4514f0bSApple OSS Distributions append_offset(offsets, true, test_page_size - 2);
2130*d4514f0bSApple OSS Distributions append_offset(offsets, true, test_page_size - 1);
2131*d4514f0bSApple OSS Distributions append_offset(offsets, true, test_page_size);
2132*d4514f0bSApple OSS Distributions append_offset(offsets, true, test_page_size + 1);
2133*d4514f0bSApple OSS Distributions append_offset(offsets, true, test_page_size + 2);
2134*d4514f0bSApple OSS Distributions append_offset(offsets, true, -(mach_vm_address_t)test_page_size - 2);
2135*d4514f0bSApple OSS Distributions append_offset(offsets, true, -(mach_vm_address_t)test_page_size - 1);
2136*d4514f0bSApple OSS Distributions append_offset(offsets, true, -(mach_vm_address_t)test_page_size);
2137*d4514f0bSApple OSS Distributions append_offset(offsets, true, -(mach_vm_address_t)test_page_size + 1);
2138*d4514f0bSApple OSS Distributions append_offset(offsets, true, -(mach_vm_address_t)test_page_size + 2);
2139*d4514f0bSApple OSS Distributions append_offset(offsets, true, -(mach_vm_address_t)2);
2140*d4514f0bSApple OSS Distributions append_offset(offsets, true, -(mach_vm_address_t)1);
2141*d4514f0bSApple OSS Distributions
2142*d4514f0bSApple OSS Distributions append_offset(offsets, false, 0);
2143*d4514f0bSApple OSS Distributions append_offset(offsets, false, 1);
2144*d4514f0bSApple OSS Distributions append_offset(offsets, false, 2);
2145*d4514f0bSApple OSS Distributions append_offset(offsets, false, test_page_size - 2);
2146*d4514f0bSApple OSS Distributions append_offset(offsets, false, test_page_size - 1);
2147*d4514f0bSApple OSS Distributions }
2148*d4514f0bSApple OSS Distributions return offsets;
2149*d4514f0bSApple OSS Distributions }
2150*d4514f0bSApple OSS Distributions
TRIALS_IMPL(addr)2151*d4514f0bSApple OSS Distributions TRIALS_IMPL(addr)
2152*d4514f0bSApple OSS Distributions
2153*d4514f0bSApple OSS Distributions addr_trials_t *
2154*d4514f0bSApple OSS Distributions generate_addr_trials(addr_t base)
2155*d4514f0bSApple OSS Distributions {
2156*d4514f0bSApple OSS Distributions const offset_list_t *offsets = get_addr_trial_offsets();
2157*d4514f0bSApple OSS Distributions const unsigned ADDRS = offsets->count;
2158*d4514f0bSApple OSS Distributions addr_trials_t *trials = allocate_addr_trials(ADDRS);
2159*d4514f0bSApple OSS Distributions
2160*d4514f0bSApple OSS Distributions for (unsigned a = 0; a < ADDRS; a++) {
2161*d4514f0bSApple OSS Distributions mach_vm_address_t addr_offset = offsets->list[a].offset;
2162*d4514f0bSApple OSS Distributions mach_vm_address_t addr = addr_offset;
2163*d4514f0bSApple OSS Distributions bool addr_is_absolute = offsets->list[a].is_absolute;
2164*d4514f0bSApple OSS Distributions if (!addr_is_absolute) {
2165*d4514f0bSApple OSS Distributions addr += base;
2166*d4514f0bSApple OSS Distributions }
2167*d4514f0bSApple OSS Distributions
2168*d4514f0bSApple OSS Distributions char *str;
2169*d4514f0bSApple OSS Distributions kasprintf(&str, "addr: %s0x%llx",
2170*d4514f0bSApple OSS Distributions addr_is_absolute ? "" : "base+", addr_offset);
2171*d4514f0bSApple OSS Distributions append_trial(trials, ADDR_TRIAL(addr, addr_is_absolute, str));
2172*d4514f0bSApple OSS Distributions }
2173*d4514f0bSApple OSS Distributions return trials;
2174*d4514f0bSApple OSS Distributions }
2175*d4514f0bSApple OSS Distributions
2176*d4514f0bSApple OSS Distributions static void
cleanup_addr_trials(addr_trials_t ** trials)2177*d4514f0bSApple OSS Distributions cleanup_addr_trials(addr_trials_t **trials)
2178*d4514f0bSApple OSS Distributions {
2179*d4514f0bSApple OSS Distributions for (size_t i = 0; i < (*trials)->count; i++) {
2180*d4514f0bSApple OSS Distributions kfree_str((*trials)->list[i].name);
2181*d4514f0bSApple OSS Distributions }
2182*d4514f0bSApple OSS Distributions free_trials(*trials);
2183*d4514f0bSApple OSS Distributions }
2184*d4514f0bSApple OSS Distributions
2185*d4514f0bSApple OSS Distributions // allocate address trials around a base address
2186*d4514f0bSApple OSS Distributions // and deallocate it at end of scope
2187*d4514f0bSApple OSS Distributions #define SMART_ADDR_TRIALS(base) \
2188*d4514f0bSApple OSS Distributions __attribute__((cleanup(cleanup_addr_trials))) \
2189*d4514f0bSApple OSS Distributions = generate_addr_trials(base)
2190*d4514f0bSApple OSS Distributions
2191*d4514f0bSApple OSS Distributions
2192*d4514f0bSApple OSS Distributions /////////////////////////////////////////////////////
2193*d4514f0bSApple OSS Distributions // generate size-parameter trials
2194*d4514f0bSApple OSS Distributions // where the size is not associated with any base address
2195*d4514f0bSApple OSS Distributions // and the callee's arithmetic includes `round_page(size)`
2196*d4514f0bSApple OSS Distributions
2197*d4514f0bSApple OSS Distributions typedef struct {
2198*d4514f0bSApple OSS Distributions addr_t size;
2199*d4514f0bSApple OSS Distributions char *name;
2200*d4514f0bSApple OSS Distributions } size_trial_t;
2201*d4514f0bSApple OSS Distributions
2202*d4514f0bSApple OSS Distributions typedef struct {
2203*d4514f0bSApple OSS Distributions unsigned count;
2204*d4514f0bSApple OSS Distributions unsigned capacity;
2205*d4514f0bSApple OSS Distributions size_trial_t list[];
2206*d4514f0bSApple OSS Distributions } size_trials_t;
2207*d4514f0bSApple OSS Distributions
2208*d4514f0bSApple OSS Distributions #define SIZE_TRIAL(new_size, new_name) \
2209*d4514f0bSApple OSS Distributions (size_trial_t){ .size = (addr_t)(new_size), .name = new_name }
2210*d4514f0bSApple OSS Distributions
2211*d4514f0bSApple OSS Distributions static const offset_list_t *
get_size_trial_offsets(void)2212*d4514f0bSApple OSS Distributions get_size_trial_offsets(void)
2213*d4514f0bSApple OSS Distributions {
2214*d4514f0bSApple OSS Distributions static offset_list_t *offsets;
2215*d4514f0bSApple OSS Distributions addr_t test_page_size = adjust_page_size();
2216*d4514f0bSApple OSS Distributions if (!offsets) {
2217*d4514f0bSApple OSS Distributions offsets = allocate_offsets(15);
2218*d4514f0bSApple OSS Distributions append_offset(offsets, true, 0);
2219*d4514f0bSApple OSS Distributions append_offset(offsets, true, 1);
2220*d4514f0bSApple OSS Distributions append_offset(offsets, true, 2);
2221*d4514f0bSApple OSS Distributions append_offset(offsets, true, test_page_size - 2);
2222*d4514f0bSApple OSS Distributions append_offset(offsets, true, test_page_size - 1);
2223*d4514f0bSApple OSS Distributions append_offset(offsets, true, test_page_size);
2224*d4514f0bSApple OSS Distributions append_offset(offsets, true, test_page_size + 1);
2225*d4514f0bSApple OSS Distributions append_offset(offsets, true, test_page_size + 2);
2226*d4514f0bSApple OSS Distributions append_offset(offsets, true, -(mach_vm_address_t)test_page_size - 2);
2227*d4514f0bSApple OSS Distributions append_offset(offsets, true, -(mach_vm_address_t)test_page_size - 1);
2228*d4514f0bSApple OSS Distributions append_offset(offsets, true, -(mach_vm_address_t)test_page_size);
2229*d4514f0bSApple OSS Distributions append_offset(offsets, true, -(mach_vm_address_t)test_page_size + 1);
2230*d4514f0bSApple OSS Distributions append_offset(offsets, true, -(mach_vm_address_t)test_page_size + 2);
2231*d4514f0bSApple OSS Distributions append_offset(offsets, true, -(mach_vm_address_t)2);
2232*d4514f0bSApple OSS Distributions append_offset(offsets, true, -(mach_vm_address_t)1);
2233*d4514f0bSApple OSS Distributions }
2234*d4514f0bSApple OSS Distributions return offsets;
2235*d4514f0bSApple OSS Distributions }
2236*d4514f0bSApple OSS Distributions
TRIALS_IMPL(size)2237*d4514f0bSApple OSS Distributions TRIALS_IMPL(size)
2238*d4514f0bSApple OSS Distributions
2239*d4514f0bSApple OSS Distributions size_trials_t *
2240*d4514f0bSApple OSS Distributions generate_size_trials(void)
2241*d4514f0bSApple OSS Distributions {
2242*d4514f0bSApple OSS Distributions const offset_list_t *size_offsets = get_size_trial_offsets();
2243*d4514f0bSApple OSS Distributions const unsigned SIZES = size_offsets->count;
2244*d4514f0bSApple OSS Distributions size_trials_t *trials = allocate_size_trials(SIZES);
2245*d4514f0bSApple OSS Distributions
2246*d4514f0bSApple OSS Distributions for (unsigned s = 0; s < SIZES; s++) {
2247*d4514f0bSApple OSS Distributions mach_vm_size_t size = size_offsets->list[s].offset;
2248*d4514f0bSApple OSS Distributions
2249*d4514f0bSApple OSS Distributions char *str;
2250*d4514f0bSApple OSS Distributions kasprintf(&str, "size: 0x%llx", size);
2251*d4514f0bSApple OSS Distributions append_trial(trials, SIZE_TRIAL(size, str));
2252*d4514f0bSApple OSS Distributions }
2253*d4514f0bSApple OSS Distributions return trials;
2254*d4514f0bSApple OSS Distributions }
2255*d4514f0bSApple OSS Distributions
2256*d4514f0bSApple OSS Distributions static void
cleanup_size_trials(size_trials_t ** trials)2257*d4514f0bSApple OSS Distributions cleanup_size_trials(size_trials_t **trials)
2258*d4514f0bSApple OSS Distributions {
2259*d4514f0bSApple OSS Distributions for (size_t i = 0; i < (*trials)->count; i++) {
2260*d4514f0bSApple OSS Distributions kfree_str((*trials)->list[i].name);
2261*d4514f0bSApple OSS Distributions }
2262*d4514f0bSApple OSS Distributions free_trials(*trials);
2263*d4514f0bSApple OSS Distributions }
2264*d4514f0bSApple OSS Distributions
2265*d4514f0bSApple OSS Distributions // allocate size trials, and deallocate it at end of scope
2266*d4514f0bSApple OSS Distributions #define SMART_SIZE_TRIALS() \
2267*d4514f0bSApple OSS Distributions __attribute__((cleanup(cleanup_size_trials))) \
2268*d4514f0bSApple OSS Distributions = generate_size_trials()
2269*d4514f0bSApple OSS Distributions
2270*d4514f0bSApple OSS Distributions /////////////////////////////////////////////////////
2271*d4514f0bSApple OSS Distributions // generate start/size trials
2272*d4514f0bSApple OSS Distributions // using absolute addresses or addresses around a given address
2273*d4514f0bSApple OSS Distributions // where `size` is the size of the thing at `start`
2274*d4514f0bSApple OSS Distributions // and the callee's arithmetic performs `start+size`
2275*d4514f0bSApple OSS Distributions
2276*d4514f0bSApple OSS Distributions typedef struct {
2277*d4514f0bSApple OSS Distributions addr_t start;
2278*d4514f0bSApple OSS Distributions addr_t size;
2279*d4514f0bSApple OSS Distributions char *name;
2280*d4514f0bSApple OSS Distributions bool start_is_absolute; // start computation does not include any allocation's base address
2281*d4514f0bSApple OSS Distributions bool size_is_absolute; // size computation does not include start
2282*d4514f0bSApple OSS Distributions } start_size_trial_t;
2283*d4514f0bSApple OSS Distributions
2284*d4514f0bSApple OSS Distributions typedef struct {
2285*d4514f0bSApple OSS Distributions unsigned count;
2286*d4514f0bSApple OSS Distributions unsigned capacity;
2287*d4514f0bSApple OSS Distributions start_size_trial_t list[];
2288*d4514f0bSApple OSS Distributions } start_size_trials_t;
2289*d4514f0bSApple OSS Distributions
2290*d4514f0bSApple OSS Distributions
2291*d4514f0bSApple OSS Distributions #define START_SIZE_TRIAL(new_start, start_absolute, new_size, size_absolute, new_name) \
2292*d4514f0bSApple OSS Distributions (start_size_trial_t){ .start = (addr_t)(new_start), .size = (addr_t)(new_size), \
2293*d4514f0bSApple OSS Distributions .name = new_name, \
2294*d4514f0bSApple OSS Distributions .start_is_absolute = start_absolute, .size_is_absolute = size_absolute }
2295*d4514f0bSApple OSS Distributions
2296*d4514f0bSApple OSS Distributions static const offset_list_t *
get_start_size_trial_start_offsets(void)2297*d4514f0bSApple OSS Distributions get_start_size_trial_start_offsets(void)
2298*d4514f0bSApple OSS Distributions {
2299*d4514f0bSApple OSS Distributions return get_addr_trial_offsets();
2300*d4514f0bSApple OSS Distributions }
2301*d4514f0bSApple OSS Distributions
2302*d4514f0bSApple OSS Distributions static const offset_list_t *
get_start_size_trial_size_offsets(void)2303*d4514f0bSApple OSS Distributions get_start_size_trial_size_offsets(void)
2304*d4514f0bSApple OSS Distributions {
2305*d4514f0bSApple OSS Distributions static offset_list_t *offsets;
2306*d4514f0bSApple OSS Distributions if (!offsets) {
2307*d4514f0bSApple OSS Distributions // use each size offset twice: once absolute and once relative
2308*d4514f0bSApple OSS Distributions const offset_list_t *old_offsets = get_size_trial_offsets();
2309*d4514f0bSApple OSS Distributions offsets = allocate_offsets(2 * old_offsets->count);
2310*d4514f0bSApple OSS Distributions for (unsigned i = 0; i < old_offsets->count; i++) {
2311*d4514f0bSApple OSS Distributions append_offset(offsets, true, old_offsets->list[i].offset);
2312*d4514f0bSApple OSS Distributions }
2313*d4514f0bSApple OSS Distributions for (unsigned i = 0; i < old_offsets->count; i++) {
2314*d4514f0bSApple OSS Distributions append_offset(offsets, false, old_offsets->list[i].offset);
2315*d4514f0bSApple OSS Distributions }
2316*d4514f0bSApple OSS Distributions }
2317*d4514f0bSApple OSS Distributions return offsets;
2318*d4514f0bSApple OSS Distributions }
2319*d4514f0bSApple OSS Distributions
TRIALS_IMPL(start_size)2320*d4514f0bSApple OSS Distributions TRIALS_IMPL(start_size)
2321*d4514f0bSApple OSS Distributions
2322*d4514f0bSApple OSS Distributions // Return a new start/size trial which is offset by `slide` bytes
2323*d4514f0bSApple OSS Distributions // Only "relative" start and size values get slid.
2324*d4514f0bSApple OSS Distributions // "absolute" values don't change.
2325*d4514f0bSApple OSS Distributions static start_size_trial_t __attribute__((overloadable, used))
2326*d4514f0bSApple OSS Distributions slide_trial(start_size_trial_t trial, mach_vm_address_t slide)
2327*d4514f0bSApple OSS Distributions {
2328*d4514f0bSApple OSS Distributions start_size_trial_t result = trial;
2329*d4514f0bSApple OSS Distributions if (!result.start_is_absolute) {
2330*d4514f0bSApple OSS Distributions result.start += slide;
2331*d4514f0bSApple OSS Distributions if (!result.size_is_absolute) {
2332*d4514f0bSApple OSS Distributions result.size -= slide;
2333*d4514f0bSApple OSS Distributions }
2334*d4514f0bSApple OSS Distributions }
2335*d4514f0bSApple OSS Distributions return result;
2336*d4514f0bSApple OSS Distributions }
2337*d4514f0bSApple OSS Distributions
2338*d4514f0bSApple OSS Distributions start_size_trials_t *
generate_start_size_trials(addr_t base)2339*d4514f0bSApple OSS Distributions generate_start_size_trials(addr_t base)
2340*d4514f0bSApple OSS Distributions {
2341*d4514f0bSApple OSS Distributions const offset_list_t *start_offsets = get_start_size_trial_start_offsets();
2342*d4514f0bSApple OSS Distributions const offset_list_t *size_offsets = get_start_size_trial_size_offsets();
2343*d4514f0bSApple OSS Distributions
2344*d4514f0bSApple OSS Distributions const unsigned ADDRS = start_offsets->count;
2345*d4514f0bSApple OSS Distributions const unsigned SIZES = size_offsets->count;
2346*d4514f0bSApple OSS Distributions
2347*d4514f0bSApple OSS Distributions start_size_trials_t *trials = allocate_start_size_trials(ADDRS * SIZES);
2348*d4514f0bSApple OSS Distributions
2349*d4514f0bSApple OSS Distributions for (unsigned a = 0; a < ADDRS; a++) {
2350*d4514f0bSApple OSS Distributions for (unsigned s = 0; s < SIZES; s++) {
2351*d4514f0bSApple OSS Distributions mach_vm_address_t start_offset = start_offsets->list[a].offset;
2352*d4514f0bSApple OSS Distributions mach_vm_address_t start = start_offset;
2353*d4514f0bSApple OSS Distributions bool start_is_absolute = start_offsets->list[a].is_absolute;
2354*d4514f0bSApple OSS Distributions if (!start_is_absolute) {
2355*d4514f0bSApple OSS Distributions start += base;
2356*d4514f0bSApple OSS Distributions }
2357*d4514f0bSApple OSS Distributions
2358*d4514f0bSApple OSS Distributions mach_vm_size_t size_offset = size_offsets->list[s].offset;
2359*d4514f0bSApple OSS Distributions mach_vm_size_t size = size_offset;
2360*d4514f0bSApple OSS Distributions bool size_is_absolute = size_offsets->list[s].is_absolute;
2361*d4514f0bSApple OSS Distributions if (!size_is_absolute) {
2362*d4514f0bSApple OSS Distributions size = -start + size;
2363*d4514f0bSApple OSS Distributions }
2364*d4514f0bSApple OSS Distributions
2365*d4514f0bSApple OSS Distributions char *str;
2366*d4514f0bSApple OSS Distributions kasprintf(&str, "start: %s0x%llx, size: %s0x%llx",
2367*d4514f0bSApple OSS Distributions start_is_absolute ? "" : "base+", start_offset,
2368*d4514f0bSApple OSS Distributions size_is_absolute ? "" :"-start+", size_offset);
2369*d4514f0bSApple OSS Distributions append_trial(trials, START_SIZE_TRIAL(start, start_is_absolute, size, size_is_absolute, str));
2370*d4514f0bSApple OSS Distributions }
2371*d4514f0bSApple OSS Distributions }
2372*d4514f0bSApple OSS Distributions return trials;
2373*d4514f0bSApple OSS Distributions }
2374*d4514f0bSApple OSS Distributions
2375*d4514f0bSApple OSS Distributions static void
cleanup_start_size_trials(start_size_trials_t ** trials)2376*d4514f0bSApple OSS Distributions cleanup_start_size_trials(start_size_trials_t **trials)
2377*d4514f0bSApple OSS Distributions {
2378*d4514f0bSApple OSS Distributions for (size_t i = 0; i < (*trials)->count; i++) {
2379*d4514f0bSApple OSS Distributions kfree_str((*trials)->list[i].name);
2380*d4514f0bSApple OSS Distributions }
2381*d4514f0bSApple OSS Distributions free_trials(*trials);
2382*d4514f0bSApple OSS Distributions }
2383*d4514f0bSApple OSS Distributions
2384*d4514f0bSApple OSS Distributions // allocate start/size trials around a base address
2385*d4514f0bSApple OSS Distributions // and deallocate it at end of scope
2386*d4514f0bSApple OSS Distributions #define SMART_START_SIZE_TRIALS(base) \
2387*d4514f0bSApple OSS Distributions __attribute__((cleanup(cleanup_start_size_trials))) \
2388*d4514f0bSApple OSS Distributions = generate_start_size_trials(base)
2389*d4514f0bSApple OSS Distributions
2390*d4514f0bSApple OSS Distributions // Trials for start/size/offset/object tuples
2391*d4514f0bSApple OSS Distributions
2392*d4514f0bSApple OSS Distributions typedef struct {
2393*d4514f0bSApple OSS Distributions mach_vm_address_t start;
2394*d4514f0bSApple OSS Distributions mach_vm_size_t size;
2395*d4514f0bSApple OSS Distributions vm_object_offset_t offset;
2396*d4514f0bSApple OSS Distributions mach_vm_size_t obj_size;
2397*d4514f0bSApple OSS Distributions bool start_is_absolute;
2398*d4514f0bSApple OSS Distributions bool size_is_absolute;
2399*d4514f0bSApple OSS Distributions char * name;
2400*d4514f0bSApple OSS Distributions } start_size_offset_object_trial_t;
2401*d4514f0bSApple OSS Distributions
2402*d4514f0bSApple OSS Distributions typedef struct {
2403*d4514f0bSApple OSS Distributions unsigned count;
2404*d4514f0bSApple OSS Distributions unsigned capacity;
2405*d4514f0bSApple OSS Distributions start_size_offset_object_trial_t list[];
2406*d4514f0bSApple OSS Distributions } start_size_offset_object_trials_t;
2407*d4514f0bSApple OSS Distributions
TRIALS_IMPL(start_size_offset_object)2408*d4514f0bSApple OSS Distributions TRIALS_IMPL(start_size_offset_object)
2409*d4514f0bSApple OSS Distributions
2410*d4514f0bSApple OSS Distributions #define START_SIZE_OFFSET_OBJECT_TRIAL(new_start, new_size, new_offset, new_obj_size, new_start_is_absolute, new_size_is_absolute, new_name) \
2411*d4514f0bSApple OSS Distributions (start_size_offset_object_trial_t){ .start = (mach_vm_address_t)(new_start), \
2412*d4514f0bSApple OSS Distributions .size = (mach_vm_size_t)(new_size), \
2413*d4514f0bSApple OSS Distributions .offset = (vm_object_offset_t)(new_offset), \
2414*d4514f0bSApple OSS Distributions .obj_size = (mach_vm_size_t)(new_obj_size), \
2415*d4514f0bSApple OSS Distributions .start_is_absolute = (bool)(new_start_is_absolute), \
2416*d4514f0bSApple OSS Distributions .size_is_absolute = (bool)(new_size_is_absolute), \
2417*d4514f0bSApple OSS Distributions .name = new_name,}
2418*d4514f0bSApple OSS Distributions
2419*d4514f0bSApple OSS Distributions bool
2420*d4514f0bSApple OSS Distributions obj_size_is_ok(mach_vm_size_t obj_size)
2421*d4514f0bSApple OSS Distributions {
2422*d4514f0bSApple OSS Distributions addr_t test_page_size = adjust_page_size();
2423*d4514f0bSApple OSS Distributions if (round_up_page(obj_size, test_page_size) == 0) {
2424*d4514f0bSApple OSS Distributions return false;
2425*d4514f0bSApple OSS Distributions }
2426*d4514f0bSApple OSS Distributions /* in rosetta, PAGE_SIZE is 4K but rounding to 16K also panics */ \
2427*d4514f0bSApple OSS Distributions if (!kern_trialname_generation && isRosetta() && round_up_page(obj_size, KB16) == 0) {
2428*d4514f0bSApple OSS Distributions return false;
2429*d4514f0bSApple OSS Distributions }
2430*d4514f0bSApple OSS Distributions return true;
2431*d4514f0bSApple OSS Distributions }
2432*d4514f0bSApple OSS Distributions
2433*d4514f0bSApple OSS Distributions static start_size_offset_object_trial_t __attribute__((overloadable, used))
slide_trial(start_size_offset_object_trial_t trial,mach_vm_address_t slide)2434*d4514f0bSApple OSS Distributions slide_trial(start_size_offset_object_trial_t trial, mach_vm_address_t slide)
2435*d4514f0bSApple OSS Distributions {
2436*d4514f0bSApple OSS Distributions start_size_offset_object_trial_t result = trial;
2437*d4514f0bSApple OSS Distributions
2438*d4514f0bSApple OSS Distributions if (!trial.start_is_absolute) {
2439*d4514f0bSApple OSS Distributions result.start += slide;
2440*d4514f0bSApple OSS Distributions if (!trial.size_is_absolute) {
2441*d4514f0bSApple OSS Distributions result.size -= slide;
2442*d4514f0bSApple OSS Distributions }
2443*d4514f0bSApple OSS Distributions }
2444*d4514f0bSApple OSS Distributions return result;
2445*d4514f0bSApple OSS Distributions }
2446*d4514f0bSApple OSS Distributions
2447*d4514f0bSApple OSS Distributions static offset_list_t *
get_ssoo_absolute_offsets()2448*d4514f0bSApple OSS Distributions get_ssoo_absolute_offsets()
2449*d4514f0bSApple OSS Distributions {
2450*d4514f0bSApple OSS Distributions static offset_list_t *offsets;
2451*d4514f0bSApple OSS Distributions addr_t test_page_size = adjust_page_size();
2452*d4514f0bSApple OSS Distributions if (!offsets) {
2453*d4514f0bSApple OSS Distributions offsets = allocate_offsets(20);
2454*d4514f0bSApple OSS Distributions append_offset(offsets, true, 0);
2455*d4514f0bSApple OSS Distributions append_offset(offsets, true, 1);
2456*d4514f0bSApple OSS Distributions append_offset(offsets, true, 2);
2457*d4514f0bSApple OSS Distributions append_offset(offsets, true, test_page_size - 2);
2458*d4514f0bSApple OSS Distributions append_offset(offsets, true, test_page_size - 1);
2459*d4514f0bSApple OSS Distributions append_offset(offsets, true, test_page_size);
2460*d4514f0bSApple OSS Distributions append_offset(offsets, true, test_page_size + 1);
2461*d4514f0bSApple OSS Distributions append_offset(offsets, true, test_page_size + 2);
2462*d4514f0bSApple OSS Distributions append_offset(offsets, true, -(mach_vm_address_t)test_page_size - 2);
2463*d4514f0bSApple OSS Distributions append_offset(offsets, true, -(mach_vm_address_t)test_page_size - 1);
2464*d4514f0bSApple OSS Distributions append_offset(offsets, true, -(mach_vm_address_t)test_page_size);
2465*d4514f0bSApple OSS Distributions append_offset(offsets, true, -(mach_vm_address_t)test_page_size + 1);
2466*d4514f0bSApple OSS Distributions append_offset(offsets, true, -(mach_vm_address_t)test_page_size + 2);
2467*d4514f0bSApple OSS Distributions append_offset(offsets, true, -(mach_vm_address_t)2);
2468*d4514f0bSApple OSS Distributions append_offset(offsets, true, -(mach_vm_address_t)1);
2469*d4514f0bSApple OSS Distributions }
2470*d4514f0bSApple OSS Distributions return offsets;
2471*d4514f0bSApple OSS Distributions }
2472*d4514f0bSApple OSS Distributions
2473*d4514f0bSApple OSS Distributions static offset_list_t *
get_ssoo_absolute_and_relative_offsets()2474*d4514f0bSApple OSS Distributions get_ssoo_absolute_and_relative_offsets()
2475*d4514f0bSApple OSS Distributions {
2476*d4514f0bSApple OSS Distributions static offset_list_t *offsets;
2477*d4514f0bSApple OSS Distributions addr_t test_page_size = adjust_page_size();
2478*d4514f0bSApple OSS Distributions if (!offsets) {
2479*d4514f0bSApple OSS Distributions const offset_list_t *old_offsets = get_ssoo_absolute_offsets();
2480*d4514f0bSApple OSS Distributions offsets = allocate_offsets(old_offsets->count + 5);
2481*d4514f0bSApple OSS Distributions // absolute offsets
2482*d4514f0bSApple OSS Distributions for (unsigned i = 0; i < old_offsets->count; i++) {
2483*d4514f0bSApple OSS Distributions append_offset(offsets, true, old_offsets->list[i].offset);
2484*d4514f0bSApple OSS Distributions }
2485*d4514f0bSApple OSS Distributions // relative offsets
2486*d4514f0bSApple OSS Distributions append_offset(offsets, false, 0);
2487*d4514f0bSApple OSS Distributions append_offset(offsets, false, 1);
2488*d4514f0bSApple OSS Distributions append_offset(offsets, false, 2);
2489*d4514f0bSApple OSS Distributions append_offset(offsets, false, test_page_size - 2);
2490*d4514f0bSApple OSS Distributions append_offset(offsets, false, test_page_size - 1);
2491*d4514f0bSApple OSS Distributions }
2492*d4514f0bSApple OSS Distributions return offsets;
2493*d4514f0bSApple OSS Distributions }
2494*d4514f0bSApple OSS Distributions
2495*d4514f0bSApple OSS Distributions start_size_offset_object_trials_t *
generate_start_size_offset_object_trials()2496*d4514f0bSApple OSS Distributions generate_start_size_offset_object_trials()
2497*d4514f0bSApple OSS Distributions {
2498*d4514f0bSApple OSS Distributions const offset_list_t *start_offsets = get_ssoo_absolute_and_relative_offsets();
2499*d4514f0bSApple OSS Distributions const offset_list_t *size_offsets = get_ssoo_absolute_and_relative_offsets();
2500*d4514f0bSApple OSS Distributions const offset_list_t *offset_values = get_ssoo_absolute_offsets();
2501*d4514f0bSApple OSS Distributions const offset_list_t *object_sizes = get_ssoo_absolute_offsets();
2502*d4514f0bSApple OSS Distributions
2503*d4514f0bSApple OSS Distributions unsigned num_trials = 0;
2504*d4514f0bSApple OSS Distributions for (size_t d = 0; d < object_sizes->count; d++) {
2505*d4514f0bSApple OSS Distributions mach_vm_size_t obj_size = object_sizes->list[d].offset;
2506*d4514f0bSApple OSS Distributions if (!obj_size_is_ok(obj_size)) { // make_a_mem_object would fail
2507*d4514f0bSApple OSS Distributions continue;
2508*d4514f0bSApple OSS Distributions }
2509*d4514f0bSApple OSS Distributions num_trials++;
2510*d4514f0bSApple OSS Distributions }
2511*d4514f0bSApple OSS Distributions num_trials *= start_offsets->count * size_offsets->count * offset_values->count;
2512*d4514f0bSApple OSS Distributions
2513*d4514f0bSApple OSS Distributions start_size_offset_object_trials_t * trials = allocate_start_size_offset_object_trials(num_trials);
2514*d4514f0bSApple OSS Distributions for (size_t a = 0; a < start_offsets->count; a++) {
2515*d4514f0bSApple OSS Distributions for (size_t b = 0; b < size_offsets->count; b++) {
2516*d4514f0bSApple OSS Distributions for (size_t c = 0; c < offset_values->count; c++) {
2517*d4514f0bSApple OSS Distributions for (size_t d = 0; d < object_sizes->count; d++) {
2518*d4514f0bSApple OSS Distributions bool start_is_absolute = start_offsets->list[a].is_absolute;
2519*d4514f0bSApple OSS Distributions bool size_is_absolute = size_offsets->list[b].is_absolute;
2520*d4514f0bSApple OSS Distributions mach_vm_address_t start = start_offsets->list[a].offset;
2521*d4514f0bSApple OSS Distributions mach_vm_size_t size = size_offsets->list[b].offset;
2522*d4514f0bSApple OSS Distributions vm_object_offset_t offset = offset_values->list[c].offset;
2523*d4514f0bSApple OSS Distributions mach_vm_size_t obj_size = object_sizes->list[d].offset;
2524*d4514f0bSApple OSS Distributions if (!obj_size_is_ok(obj_size)) { // make_a_mem_object would fail
2525*d4514f0bSApple OSS Distributions continue;
2526*d4514f0bSApple OSS Distributions }
2527*d4514f0bSApple OSS Distributions char *str;
2528*d4514f0bSApple OSS Distributions kasprintf(&str, "start: %s0x%llx, size: %s0x%llx, offset: 0x%llx, obj_size: 0x%llx",
2529*d4514f0bSApple OSS Distributions start_is_absolute ? "" : "base+", start,
2530*d4514f0bSApple OSS Distributions size_is_absolute ? "" :"-start+", size,
2531*d4514f0bSApple OSS Distributions offset,
2532*d4514f0bSApple OSS Distributions obj_size);
2533*d4514f0bSApple OSS Distributions append_trial(trials, START_SIZE_OFFSET_OBJECT_TRIAL(start, size, offset, obj_size, start_is_absolute, size_is_absolute, str));
2534*d4514f0bSApple OSS Distributions }
2535*d4514f0bSApple OSS Distributions }
2536*d4514f0bSApple OSS Distributions }
2537*d4514f0bSApple OSS Distributions }
2538*d4514f0bSApple OSS Distributions return trials;
2539*d4514f0bSApple OSS Distributions }
2540*d4514f0bSApple OSS Distributions
2541*d4514f0bSApple OSS Distributions #define SMART_START_SIZE_OFFSET_OBJECT_TRIALS() \
2542*d4514f0bSApple OSS Distributions __attribute__((cleanup(cleanup_start_size_offset_object_trials))) \
2543*d4514f0bSApple OSS Distributions = generate_start_size_offset_object_trials();
2544*d4514f0bSApple OSS Distributions
2545*d4514f0bSApple OSS Distributions static void
cleanup_start_size_offset_object_trials(start_size_offset_object_trials_t ** trials)2546*d4514f0bSApple OSS Distributions cleanup_start_size_offset_object_trials(start_size_offset_object_trials_t **trials)
2547*d4514f0bSApple OSS Distributions {
2548*d4514f0bSApple OSS Distributions for (size_t i = 0; i < (*trials)->count; i++) {
2549*d4514f0bSApple OSS Distributions kfree_str((*trials)->list[i].name);
2550*d4514f0bSApple OSS Distributions }
2551*d4514f0bSApple OSS Distributions free_trials(*trials);
2552*d4514f0bSApple OSS Distributions }
2553*d4514f0bSApple OSS Distributions
2554*d4514f0bSApple OSS Distributions
2555*d4514f0bSApple OSS Distributions // Trials for start/size/start/size tuples
2556*d4514f0bSApple OSS Distributions
2557*d4514f0bSApple OSS Distributions typedef struct {
2558*d4514f0bSApple OSS Distributions mach_vm_address_t start;
2559*d4514f0bSApple OSS Distributions mach_vm_size_t size;
2560*d4514f0bSApple OSS Distributions mach_vm_address_t second_start;
2561*d4514f0bSApple OSS Distributions mach_vm_size_t second_size;
2562*d4514f0bSApple OSS Distributions bool start_is_absolute;
2563*d4514f0bSApple OSS Distributions bool size_is_absolute;
2564*d4514f0bSApple OSS Distributions bool second_start_is_absolute;
2565*d4514f0bSApple OSS Distributions bool second_size_is_absolute;
2566*d4514f0bSApple OSS Distributions char * name;
2567*d4514f0bSApple OSS Distributions } start_size_start_size_trial_t;
2568*d4514f0bSApple OSS Distributions
2569*d4514f0bSApple OSS Distributions typedef struct {
2570*d4514f0bSApple OSS Distributions unsigned count;
2571*d4514f0bSApple OSS Distributions unsigned capacity;
2572*d4514f0bSApple OSS Distributions start_size_start_size_trial_t list[];
2573*d4514f0bSApple OSS Distributions } start_size_start_size_trials_t;
2574*d4514f0bSApple OSS Distributions
TRIALS_IMPL(start_size_start_size)2575*d4514f0bSApple OSS Distributions TRIALS_IMPL(start_size_start_size)
2576*d4514f0bSApple OSS Distributions
2577*d4514f0bSApple OSS Distributions #define START_SIZE_START_SIZE_TRIAL(new_start, new_size, new_second_start, new_second_size, new_start_is_absolute, \
2578*d4514f0bSApple OSS Distributions new_size_is_absolute, new_second_start_is_absolute, new_second_size_is_absolute, new_name) \
2579*d4514f0bSApple OSS Distributions (start_size_start_size_trial_t){ .start = (mach_vm_address_t)(new_start), \
2580*d4514f0bSApple OSS Distributions .size = (mach_vm_size_t)(new_size), \
2581*d4514f0bSApple OSS Distributions .second_start = (mach_vm_address_t)(new_second_start), \
2582*d4514f0bSApple OSS Distributions .second_size = (mach_vm_size_t)(new_second_size), \
2583*d4514f0bSApple OSS Distributions .start_is_absolute = (bool)(new_start_is_absolute), \
2584*d4514f0bSApple OSS Distributions .size_is_absolute = (bool)(new_size_is_absolute), \
2585*d4514f0bSApple OSS Distributions .second_start_is_absolute = (bool)(new_second_start_is_absolute), \
2586*d4514f0bSApple OSS Distributions .second_size_is_absolute = (bool)(new_second_size_is_absolute),\
2587*d4514f0bSApple OSS Distributions .name = new_name,}
2588*d4514f0bSApple OSS Distributions
2589*d4514f0bSApple OSS Distributions static start_size_start_size_trial_t __attribute__((overloadable, used))
2590*d4514f0bSApple OSS Distributions slide_trial(start_size_start_size_trial_t trial, mach_vm_address_t slide, mach_vm_address_t second_slide)
2591*d4514f0bSApple OSS Distributions {
2592*d4514f0bSApple OSS Distributions start_size_start_size_trial_t result = trial;
2593*d4514f0bSApple OSS Distributions
2594*d4514f0bSApple OSS Distributions if (!trial.start_is_absolute) {
2595*d4514f0bSApple OSS Distributions result.start += slide;
2596*d4514f0bSApple OSS Distributions if (!trial.size_is_absolute) {
2597*d4514f0bSApple OSS Distributions result.size -= slide;
2598*d4514f0bSApple OSS Distributions }
2599*d4514f0bSApple OSS Distributions }
2600*d4514f0bSApple OSS Distributions if (!trial.second_start_is_absolute) {
2601*d4514f0bSApple OSS Distributions result.second_start += second_slide;
2602*d4514f0bSApple OSS Distributions if (!trial.second_size_is_absolute) {
2603*d4514f0bSApple OSS Distributions result.second_size -= second_slide;
2604*d4514f0bSApple OSS Distributions }
2605*d4514f0bSApple OSS Distributions }
2606*d4514f0bSApple OSS Distributions return result;
2607*d4514f0bSApple OSS Distributions }
2608*d4514f0bSApple OSS Distributions
2609*d4514f0bSApple OSS Distributions start_size_start_size_trials_t *
generate_start_size_start_size_trials()2610*d4514f0bSApple OSS Distributions generate_start_size_start_size_trials()
2611*d4514f0bSApple OSS Distributions {
2612*d4514f0bSApple OSS Distributions /*
2613*d4514f0bSApple OSS Distributions * Reuse the starts/sizes from start/size/offset/object
2614*d4514f0bSApple OSS Distributions */
2615*d4514f0bSApple OSS Distributions const offset_list_t *start_offsets = get_ssoo_absolute_and_relative_offsets();
2616*d4514f0bSApple OSS Distributions const offset_list_t *size_offsets = get_ssoo_absolute_and_relative_offsets();
2617*d4514f0bSApple OSS Distributions const offset_list_t *second_start_offsets = get_ssoo_absolute_and_relative_offsets();
2618*d4514f0bSApple OSS Distributions const offset_list_t *second_size_offsets = get_ssoo_absolute_and_relative_offsets();
2619*d4514f0bSApple OSS Distributions
2620*d4514f0bSApple OSS Distributions unsigned num_trials = start_offsets->count * size_offsets->count
2621*d4514f0bSApple OSS Distributions * second_start_offsets->count * second_start_offsets->count;
2622*d4514f0bSApple OSS Distributions
2623*d4514f0bSApple OSS Distributions start_size_start_size_trials_t * trials = allocate_start_size_start_size_trials(num_trials);
2624*d4514f0bSApple OSS Distributions for (size_t a = 0; a < start_offsets->count; a++) {
2625*d4514f0bSApple OSS Distributions for (size_t b = 0; b < size_offsets->count; b++) {
2626*d4514f0bSApple OSS Distributions for (size_t c = 0; c < second_start_offsets->count; c++) {
2627*d4514f0bSApple OSS Distributions for (size_t d = 0; d < second_size_offsets->count; d++) {
2628*d4514f0bSApple OSS Distributions bool start_is_absolute = start_offsets->list[a].is_absolute;
2629*d4514f0bSApple OSS Distributions bool size_is_absolute = size_offsets->list[b].is_absolute;
2630*d4514f0bSApple OSS Distributions bool second_start_is_absolute = second_start_offsets->list[c].is_absolute;
2631*d4514f0bSApple OSS Distributions bool second_size_is_absolute = second_size_offsets->list[d].is_absolute;
2632*d4514f0bSApple OSS Distributions mach_vm_address_t start = start_offsets->list[a].offset;
2633*d4514f0bSApple OSS Distributions mach_vm_size_t size = size_offsets->list[b].offset;
2634*d4514f0bSApple OSS Distributions mach_vm_address_t second_start = second_start_offsets->list[c].offset;
2635*d4514f0bSApple OSS Distributions mach_vm_size_t second_size = second_size_offsets->list[d].offset;
2636*d4514f0bSApple OSS Distributions
2637*d4514f0bSApple OSS Distributions char *str;
2638*d4514f0bSApple OSS Distributions kasprintf(&str, "start: %s0x%llx, size: %s0x%llx, second_start: %s0x%llx, second_size: %s0x%llx",
2639*d4514f0bSApple OSS Distributions start_is_absolute ? "" : "base+", start,
2640*d4514f0bSApple OSS Distributions size_is_absolute ? "" :"-start+", size,
2641*d4514f0bSApple OSS Distributions second_start_is_absolute ? "" : "base+", second_start,
2642*d4514f0bSApple OSS Distributions second_size_is_absolute ? "" : "-start+", second_size);
2643*d4514f0bSApple OSS Distributions append_trial(trials, START_SIZE_START_SIZE_TRIAL(start, size, second_start, second_size,
2644*d4514f0bSApple OSS Distributions start_is_absolute, size_is_absolute,
2645*d4514f0bSApple OSS Distributions second_start_is_absolute, second_size_is_absolute, str));
2646*d4514f0bSApple OSS Distributions }
2647*d4514f0bSApple OSS Distributions }
2648*d4514f0bSApple OSS Distributions }
2649*d4514f0bSApple OSS Distributions }
2650*d4514f0bSApple OSS Distributions return trials;
2651*d4514f0bSApple OSS Distributions }
2652*d4514f0bSApple OSS Distributions
2653*d4514f0bSApple OSS Distributions #define SMART_START_SIZE_START_SIZE_TRIALS() \
2654*d4514f0bSApple OSS Distributions __attribute__((cleanup(cleanup_start_size_start_size_trials))) \
2655*d4514f0bSApple OSS Distributions = generate_start_size_start_size_trials();
2656*d4514f0bSApple OSS Distributions
2657*d4514f0bSApple OSS Distributions static void __attribute__((used))
cleanup_start_size_start_size_trials(start_size_start_size_trials_t ** trials)2658*d4514f0bSApple OSS Distributions cleanup_start_size_start_size_trials(start_size_start_size_trials_t **trials)
2659*d4514f0bSApple OSS Distributions {
2660*d4514f0bSApple OSS Distributions for (size_t i = 0; i < (*trials)->count; i++) {
2661*d4514f0bSApple OSS Distributions kfree_str((*trials)->list[i].name);
2662*d4514f0bSApple OSS Distributions }
2663*d4514f0bSApple OSS Distributions free_trials(*trials);
2664*d4514f0bSApple OSS Distributions }
2665*d4514f0bSApple OSS Distributions
2666*d4514f0bSApple OSS Distributions
2667*d4514f0bSApple OSS Distributions // start/size/offset: test start+size and a second independent address
2668*d4514f0bSApple OSS Distributions // consider src/dst/size instead if the size may be added to both addresses
2669*d4514f0bSApple OSS Distributions
2670*d4514f0bSApple OSS Distributions typedef struct {
2671*d4514f0bSApple OSS Distributions mach_vm_address_t start;
2672*d4514f0bSApple OSS Distributions mach_vm_size_t size;
2673*d4514f0bSApple OSS Distributions vm_object_offset_t offset;
2674*d4514f0bSApple OSS Distributions bool start_is_absolute;
2675*d4514f0bSApple OSS Distributions bool size_is_absolute;
2676*d4514f0bSApple OSS Distributions char * name;
2677*d4514f0bSApple OSS Distributions } start_size_offset_trial_t;
2678*d4514f0bSApple OSS Distributions
2679*d4514f0bSApple OSS Distributions typedef struct {
2680*d4514f0bSApple OSS Distributions unsigned count;
2681*d4514f0bSApple OSS Distributions unsigned capacity;
2682*d4514f0bSApple OSS Distributions start_size_offset_trial_t list[];
2683*d4514f0bSApple OSS Distributions } start_size_offset_trials_t;
2684*d4514f0bSApple OSS Distributions
TRIALS_IMPL(start_size_offset)2685*d4514f0bSApple OSS Distributions TRIALS_IMPL(start_size_offset)
2686*d4514f0bSApple OSS Distributions
2687*d4514f0bSApple OSS Distributions #define START_SIZE_OFFSET_TRIAL(new_start, new_size, new_offset, new_start_is_absolute, new_size_is_absolute, new_name) \
2688*d4514f0bSApple OSS Distributions (start_size_offset_trial_t){ .start = (mach_vm_address_t)(new_start), \
2689*d4514f0bSApple OSS Distributions .size = (mach_vm_size_t)(new_size), \
2690*d4514f0bSApple OSS Distributions .offset = (vm_object_offset_t)(new_offset), \
2691*d4514f0bSApple OSS Distributions .start_is_absolute = (bool)(new_start_is_absolute), \
2692*d4514f0bSApple OSS Distributions .size_is_absolute = (bool)(new_size_is_absolute), \
2693*d4514f0bSApple OSS Distributions .name = new_name,}
2694*d4514f0bSApple OSS Distributions
2695*d4514f0bSApple OSS Distributions
2696*d4514f0bSApple OSS Distributions static start_size_offset_trial_t __attribute__((overloadable, used))
2697*d4514f0bSApple OSS Distributions slide_trial(start_size_offset_trial_t trial, mach_vm_address_t slide)
2698*d4514f0bSApple OSS Distributions {
2699*d4514f0bSApple OSS Distributions start_size_offset_trial_t result = trial;
2700*d4514f0bSApple OSS Distributions
2701*d4514f0bSApple OSS Distributions if (!trial.start_is_absolute) {
2702*d4514f0bSApple OSS Distributions result.start += slide;
2703*d4514f0bSApple OSS Distributions if (!trial.size_is_absolute) {
2704*d4514f0bSApple OSS Distributions result.size -= slide;
2705*d4514f0bSApple OSS Distributions }
2706*d4514f0bSApple OSS Distributions }
2707*d4514f0bSApple OSS Distributions return result;
2708*d4514f0bSApple OSS Distributions }
2709*d4514f0bSApple OSS Distributions
2710*d4514f0bSApple OSS Distributions start_size_offset_trials_t *
generate_start_size_offset_trials()2711*d4514f0bSApple OSS Distributions generate_start_size_offset_trials()
2712*d4514f0bSApple OSS Distributions {
2713*d4514f0bSApple OSS Distributions const offset_list_t *start_offsets = get_ssoo_absolute_and_relative_offsets();
2714*d4514f0bSApple OSS Distributions const offset_list_t *offset_values = get_ssoo_absolute_offsets();
2715*d4514f0bSApple OSS Distributions const offset_list_t *size_offsets = get_ssoo_absolute_and_relative_offsets();
2716*d4514f0bSApple OSS Distributions
2717*d4514f0bSApple OSS Distributions // output is actually ordered start - offset - size
2718*d4514f0bSApple OSS Distributions // because it pretty-prints better than start - size - offset
2719*d4514f0bSApple OSS Distributions unsigned num_trials = start_offsets->count * offset_values->count * size_offsets->count;
2720*d4514f0bSApple OSS Distributions start_size_offset_trials_t * trials = allocate_start_size_offset_trials(num_trials);
2721*d4514f0bSApple OSS Distributions for (size_t a = 0; a < start_offsets->count; a++) {
2722*d4514f0bSApple OSS Distributions for (size_t b = 0; b < offset_values->count; b++) {
2723*d4514f0bSApple OSS Distributions for (size_t c = 0; c < size_offsets->count; c++) {
2724*d4514f0bSApple OSS Distributions bool start_is_absolute = start_offsets->list[a].is_absolute;
2725*d4514f0bSApple OSS Distributions bool size_is_absolute = size_offsets->list[c].is_absolute;
2726*d4514f0bSApple OSS Distributions mach_vm_address_t start = start_offsets->list[a].offset;
2727*d4514f0bSApple OSS Distributions vm_object_offset_t offset = offset_values->list[b].offset;
2728*d4514f0bSApple OSS Distributions mach_vm_size_t size = size_offsets->list[c].offset;
2729*d4514f0bSApple OSS Distributions
2730*d4514f0bSApple OSS Distributions char *str;
2731*d4514f0bSApple OSS Distributions kasprintf(&str, "start: %s0x%llx, offset: 0x%llx, size: %s0x%llx",
2732*d4514f0bSApple OSS Distributions start_is_absolute ? "" : "base+", start,
2733*d4514f0bSApple OSS Distributions offset,
2734*d4514f0bSApple OSS Distributions size_is_absolute ? "" :"-start+", size);
2735*d4514f0bSApple OSS Distributions append_trial(trials, START_SIZE_OFFSET_TRIAL(start, size, offset, start_is_absolute, size_is_absolute, str));
2736*d4514f0bSApple OSS Distributions }
2737*d4514f0bSApple OSS Distributions }
2738*d4514f0bSApple OSS Distributions }
2739*d4514f0bSApple OSS Distributions return trials;
2740*d4514f0bSApple OSS Distributions }
2741*d4514f0bSApple OSS Distributions
2742*d4514f0bSApple OSS Distributions #define SMART_START_SIZE_OFFSET_TRIALS() \
2743*d4514f0bSApple OSS Distributions __attribute__((cleanup(cleanup_start_size_offset_trials))) \
2744*d4514f0bSApple OSS Distributions = generate_start_size_offset_trials();
2745*d4514f0bSApple OSS Distributions
2746*d4514f0bSApple OSS Distributions static void
cleanup_start_size_offset_trials(start_size_offset_trials_t ** trials)2747*d4514f0bSApple OSS Distributions cleanup_start_size_offset_trials(start_size_offset_trials_t **trials)
2748*d4514f0bSApple OSS Distributions {
2749*d4514f0bSApple OSS Distributions for (size_t i = 0; i < (*trials)->count; i++) {
2750*d4514f0bSApple OSS Distributions kfree_str((*trials)->list[i].name);
2751*d4514f0bSApple OSS Distributions }
2752*d4514f0bSApple OSS Distributions free_trials(*trials);
2753*d4514f0bSApple OSS Distributions }
2754*d4514f0bSApple OSS Distributions
2755*d4514f0bSApple OSS Distributions // src/dst/size: test a source address, a dest address,
2756*d4514f0bSApple OSS Distributions // and a common size that may be added to both addresses
2757*d4514f0bSApple OSS Distributions
2758*d4514f0bSApple OSS Distributions typedef struct {
2759*d4514f0bSApple OSS Distributions addr_t src;
2760*d4514f0bSApple OSS Distributions addr_t dst;
2761*d4514f0bSApple OSS Distributions addr_t size;
2762*d4514f0bSApple OSS Distributions char *name;
2763*d4514f0bSApple OSS Distributions bool src_is_absolute; // src computation does not include any allocation's base address
2764*d4514f0bSApple OSS Distributions bool dst_is_absolute; // dst computation does not include any allocation's base address
2765*d4514f0bSApple OSS Distributions bool size_is_src_relative; // size computation includes src
2766*d4514f0bSApple OSS Distributions bool size_is_dst_relative; // size computation includes dst
2767*d4514f0bSApple OSS Distributions } src_dst_size_trial_t;
2768*d4514f0bSApple OSS Distributions
2769*d4514f0bSApple OSS Distributions typedef struct {
2770*d4514f0bSApple OSS Distributions unsigned count;
2771*d4514f0bSApple OSS Distributions unsigned capacity;
2772*d4514f0bSApple OSS Distributions src_dst_size_trial_t list[];
2773*d4514f0bSApple OSS Distributions } src_dst_size_trials_t;
2774*d4514f0bSApple OSS Distributions
TRIALS_IMPL(src_dst_size)2775*d4514f0bSApple OSS Distributions TRIALS_IMPL(src_dst_size)
2776*d4514f0bSApple OSS Distributions
2777*d4514f0bSApple OSS Distributions #define SRC_DST_SIZE_TRIAL(new_src, new_dst, new_size, new_name, src_absolute, dst_absolute, size_src_rel, size_dst_rel) \
2778*d4514f0bSApple OSS Distributions (src_dst_size_trial_t){ \
2779*d4514f0bSApple OSS Distributions .src = (addr_t)(new_src), \
2780*d4514f0bSApple OSS Distributions .dst = (addr_t)(new_dst), \
2781*d4514f0bSApple OSS Distributions .size = (addr_t)(new_size), \
2782*d4514f0bSApple OSS Distributions .name = new_name, \
2783*d4514f0bSApple OSS Distributions .src_is_absolute = src_absolute, \
2784*d4514f0bSApple OSS Distributions .dst_is_absolute = dst_absolute, \
2785*d4514f0bSApple OSS Distributions .size_is_src_relative = size_src_rel, \
2786*d4514f0bSApple OSS Distributions .size_is_dst_relative = size_dst_rel, \
2787*d4514f0bSApple OSS Distributions }
2788*d4514f0bSApple OSS Distributions
2789*d4514f0bSApple OSS Distributions src_dst_size_trials_t * __attribute__((overloadable))
2790*d4514f0bSApple OSS Distributions generate_src_dst_size_trials(const char *srcname, const char *dstname)
2791*d4514f0bSApple OSS Distributions {
2792*d4514f0bSApple OSS Distributions const offset_list_t *addr_offsets = get_addr_trial_offsets();
2793*d4514f0bSApple OSS Distributions const offset_list_t *size_offsets = get_size_trial_offsets();
2794*d4514f0bSApple OSS Distributions unsigned src_count = addr_offsets->count;
2795*d4514f0bSApple OSS Distributions unsigned dst_count = src_count;
2796*d4514f0bSApple OSS Distributions unsigned size_count = 3 * size_offsets->count;
2797*d4514f0bSApple OSS Distributions unsigned num_trials = src_count * dst_count * size_count;
2798*d4514f0bSApple OSS Distributions src_dst_size_trials_t * trials = allocate_src_dst_size_trials(num_trials);
2799*d4514f0bSApple OSS Distributions
2800*d4514f0bSApple OSS Distributions // each size is used three times:
2801*d4514f0bSApple OSS Distributions // once src-relative, once dst-relative, and once absolute
2802*d4514f0bSApple OSS Distributions unsigned size_part = size_count / 3;
2803*d4514f0bSApple OSS Distributions
2804*d4514f0bSApple OSS Distributions for (size_t i = 0; i < src_count; i++) {
2805*d4514f0bSApple OSS Distributions bool rebase_src = !addr_offsets->list[i].is_absolute;
2806*d4514f0bSApple OSS Distributions addr_t src_offset = addr_offsets->list[i].offset;
2807*d4514f0bSApple OSS Distributions
2808*d4514f0bSApple OSS Distributions for (size_t j = 0; j < dst_count; j++) {
2809*d4514f0bSApple OSS Distributions bool rebase_dst = !addr_offsets->list[j].is_absolute;
2810*d4514f0bSApple OSS Distributions addr_t dst_offset = addr_offsets->list[j].offset;
2811*d4514f0bSApple OSS Distributions
2812*d4514f0bSApple OSS Distributions for (size_t k = 0; k < size_count; k++) {
2813*d4514f0bSApple OSS Distributions bool rebase_size_from_src = false;
2814*d4514f0bSApple OSS Distributions bool rebase_size_from_dst = false;
2815*d4514f0bSApple OSS Distributions addr_t size_offset;
2816*d4514f0bSApple OSS Distributions if (k < size_part) {
2817*d4514f0bSApple OSS Distributions size_offset = size_offsets->list[k].offset;
2818*d4514f0bSApple OSS Distributions } else if (k < 2 * size_part) {
2819*d4514f0bSApple OSS Distributions size_offset = size_offsets->list[k - size_part].offset;
2820*d4514f0bSApple OSS Distributions rebase_size_from_src = true;
2821*d4514f0bSApple OSS Distributions rebase_size_from_dst = false;
2822*d4514f0bSApple OSS Distributions } else {
2823*d4514f0bSApple OSS Distributions size_offset = size_offsets->list[k - 2 * size_part].offset;
2824*d4514f0bSApple OSS Distributions rebase_size_from_src = false;
2825*d4514f0bSApple OSS Distributions rebase_size_from_dst = true;
2826*d4514f0bSApple OSS Distributions }
2827*d4514f0bSApple OSS Distributions
2828*d4514f0bSApple OSS Distributions addr_t size;
2829*d4514f0bSApple OSS Distributions char *desc;
2830*d4514f0bSApple OSS Distributions if (rebase_size_from_src) {
2831*d4514f0bSApple OSS Distributions size = -src_offset + size_offset;
2832*d4514f0bSApple OSS Distributions kasprintf(&desc, "%s: %s%lli, %s: %s%lli, size: -%s%+lli",
2833*d4514f0bSApple OSS Distributions srcname, rebase_src ? "base+" : "", (int64_t)src_offset,
2834*d4514f0bSApple OSS Distributions dstname, rebase_dst ? "base+" : "", (int64_t)dst_offset,
2835*d4514f0bSApple OSS Distributions srcname, (int64_t)size_offset);
2836*d4514f0bSApple OSS Distributions } else if (rebase_size_from_dst) {
2837*d4514f0bSApple OSS Distributions size = -dst_offset + size_offset;
2838*d4514f0bSApple OSS Distributions kasprintf(&desc, "%s: %s%lli, %s: %s%lli, size: -%s%+lli",
2839*d4514f0bSApple OSS Distributions srcname, rebase_src ? "base+" : "", (int64_t)src_offset,
2840*d4514f0bSApple OSS Distributions dstname, rebase_dst ? "base+" : "", (int64_t)dst_offset,
2841*d4514f0bSApple OSS Distributions dstname, (int64_t)size_offset);
2842*d4514f0bSApple OSS Distributions } else {
2843*d4514f0bSApple OSS Distributions size = size_offset;
2844*d4514f0bSApple OSS Distributions kasprintf(&desc, "%s: %s%lli, %s: %s%lli, size: %lli",
2845*d4514f0bSApple OSS Distributions srcname, rebase_src ? "base+" : "", (int64_t)src_offset,
2846*d4514f0bSApple OSS Distributions dstname, rebase_dst ? "base+" : "", (int64_t)dst_offset,
2847*d4514f0bSApple OSS Distributions (int64_t)size_offset);
2848*d4514f0bSApple OSS Distributions }
2849*d4514f0bSApple OSS Distributions assert(desc);
2850*d4514f0bSApple OSS Distributions append_trial(trials, SRC_DST_SIZE_TRIAL(src_offset, dst_offset, size, desc,
2851*d4514f0bSApple OSS Distributions !rebase_src, !rebase_dst, rebase_size_from_src, rebase_size_from_dst));
2852*d4514f0bSApple OSS Distributions }
2853*d4514f0bSApple OSS Distributions }
2854*d4514f0bSApple OSS Distributions }
2855*d4514f0bSApple OSS Distributions return trials;
2856*d4514f0bSApple OSS Distributions }
2857*d4514f0bSApple OSS Distributions
2858*d4514f0bSApple OSS Distributions src_dst_size_trials_t * __attribute__((overloadable))
generate_src_dst_size_trials(void)2859*d4514f0bSApple OSS Distributions generate_src_dst_size_trials(void)
2860*d4514f0bSApple OSS Distributions {
2861*d4514f0bSApple OSS Distributions return generate_src_dst_size_trials("src", "dst");
2862*d4514f0bSApple OSS Distributions }
2863*d4514f0bSApple OSS Distributions #define SMART_SRC_DST_SIZE_TRIALS() \
2864*d4514f0bSApple OSS Distributions __attribute__((cleanup(cleanup_src_dst_size_trials))) \
2865*d4514f0bSApple OSS Distributions = generate_src_dst_size_trials();
2866*d4514f0bSApple OSS Distributions
2867*d4514f0bSApple OSS Distributions #define SMART_FILEOFF_DST_SIZE_TRIALS() \
2868*d4514f0bSApple OSS Distributions __attribute__((cleanup(cleanup_src_dst_size_trials))) \
2869*d4514f0bSApple OSS Distributions = generate_src_dst_size_trials("fileoff", "dst");
2870*d4514f0bSApple OSS Distributions
2871*d4514f0bSApple OSS Distributions static void
cleanup_src_dst_size_trials(src_dst_size_trials_t ** trials)2872*d4514f0bSApple OSS Distributions cleanup_src_dst_size_trials(src_dst_size_trials_t **trials)
2873*d4514f0bSApple OSS Distributions {
2874*d4514f0bSApple OSS Distributions for (size_t i = 0; i < (*trials)->count; i++) {
2875*d4514f0bSApple OSS Distributions kfree_str((*trials)->list[i].name);
2876*d4514f0bSApple OSS Distributions }
2877*d4514f0bSApple OSS Distributions free_trials(*trials);
2878*d4514f0bSApple OSS Distributions }
2879*d4514f0bSApple OSS Distributions
2880*d4514f0bSApple OSS Distributions static src_dst_size_trial_t __attribute__((overloadable, used))
slide_trial_src(src_dst_size_trial_t trial,mach_vm_address_t slide)2881*d4514f0bSApple OSS Distributions slide_trial_src(src_dst_size_trial_t trial, mach_vm_address_t slide)
2882*d4514f0bSApple OSS Distributions {
2883*d4514f0bSApple OSS Distributions src_dst_size_trial_t result = trial;
2884*d4514f0bSApple OSS Distributions
2885*d4514f0bSApple OSS Distributions if (!trial.src_is_absolute) {
2886*d4514f0bSApple OSS Distributions result.src += slide;
2887*d4514f0bSApple OSS Distributions if (trial.size_is_src_relative) {
2888*d4514f0bSApple OSS Distributions result.size -= slide;
2889*d4514f0bSApple OSS Distributions }
2890*d4514f0bSApple OSS Distributions }
2891*d4514f0bSApple OSS Distributions return result;
2892*d4514f0bSApple OSS Distributions }
2893*d4514f0bSApple OSS Distributions
2894*d4514f0bSApple OSS Distributions static src_dst_size_trial_t __attribute__((overloadable, used))
slide_trial_dst(src_dst_size_trial_t trial,mach_vm_address_t slide)2895*d4514f0bSApple OSS Distributions slide_trial_dst(src_dst_size_trial_t trial, mach_vm_address_t slide)
2896*d4514f0bSApple OSS Distributions {
2897*d4514f0bSApple OSS Distributions src_dst_size_trial_t result = trial;
2898*d4514f0bSApple OSS Distributions
2899*d4514f0bSApple OSS Distributions if (!trial.dst_is_absolute) {
2900*d4514f0bSApple OSS Distributions result.dst += slide;
2901*d4514f0bSApple OSS Distributions if (trial.size_is_dst_relative) {
2902*d4514f0bSApple OSS Distributions result.size -= slide;
2903*d4514f0bSApple OSS Distributions }
2904*d4514f0bSApple OSS Distributions }
2905*d4514f0bSApple OSS Distributions return result;
2906*d4514f0bSApple OSS Distributions }
2907*d4514f0bSApple OSS Distributions
2908*d4514f0bSApple OSS Distributions #if !KERNEL
2909*d4514f0bSApple OSS Distributions // shared_file_np / shared_file_mapping_slide_np tests
2910*d4514f0bSApple OSS Distributions
2911*d4514f0bSApple OSS Distributions // copied from bsd/vm/vm_unix.c
2912*d4514f0bSApple OSS Distributions #define _SR_FILE_MAPPINGS_MAX_FILES 256
2913*d4514f0bSApple OSS Distributions #define SFM_MAX (_SR_FILE_MAPPINGS_MAX_FILES * 8)
2914*d4514f0bSApple OSS Distributions
2915*d4514f0bSApple OSS Distributions // From Rosetta dyld
2916*d4514f0bSApple OSS Distributions #define kNumSharedCacheMappings 4
2917*d4514f0bSApple OSS Distributions #define kMaxSubcaches 16
2918*d4514f0bSApple OSS Distributions
2919*d4514f0bSApple OSS Distributions typedef struct {
2920*d4514f0bSApple OSS Distributions uint32_t files_count;
2921*d4514f0bSApple OSS Distributions struct shared_file_np *files;
2922*d4514f0bSApple OSS Distributions char *name;
2923*d4514f0bSApple OSS Distributions } shared_file_np_trial_t;
2924*d4514f0bSApple OSS Distributions
2925*d4514f0bSApple OSS Distributions typedef struct {
2926*d4514f0bSApple OSS Distributions unsigned count;
2927*d4514f0bSApple OSS Distributions unsigned capacity;
2928*d4514f0bSApple OSS Distributions shared_file_np_trial_t list[];
2929*d4514f0bSApple OSS Distributions } shared_file_np_trials_t;
2930*d4514f0bSApple OSS Distributions
TRIALS_IMPL(shared_file_np)2931*d4514f0bSApple OSS Distributions TRIALS_IMPL(shared_file_np)
2932*d4514f0bSApple OSS Distributions
2933*d4514f0bSApple OSS Distributions #define SHARED_FILE_NP_TRIAL(new_files_count, new_files, new_name) \
2934*d4514f0bSApple OSS Distributions (shared_file_np_trial_t){ .files_count = (uint32_t)(new_files_count), \
2935*d4514f0bSApple OSS Distributions .files = (struct shared_file_np *)(new_files), \
2936*d4514f0bSApple OSS Distributions .name = "files_count="#new_files_count new_name }
2937*d4514f0bSApple OSS Distributions
2938*d4514f0bSApple OSS Distributions struct shared_file_np *
2939*d4514f0bSApple OSS Distributions alloc_shared_file_np(uint32_t files_count)
2940*d4514f0bSApple OSS Distributions {
2941*d4514f0bSApple OSS Distributions struct shared_file_np *files;
2942*d4514f0bSApple OSS Distributions #if KERNEL
2943*d4514f0bSApple OSS Distributions files = kalloc_type(struct shared_file_np, files_count, Z_WAITOK | Z_ZERO);
2944*d4514f0bSApple OSS Distributions #else
2945*d4514f0bSApple OSS Distributions files = calloc(files_count, sizeof(struct shared_file_np));
2946*d4514f0bSApple OSS Distributions #endif
2947*d4514f0bSApple OSS Distributions return files;
2948*d4514f0bSApple OSS Distributions }
2949*d4514f0bSApple OSS Distributions
2950*d4514f0bSApple OSS Distributions void
free_shared_file_np(shared_file_np_trial_t * trial)2951*d4514f0bSApple OSS Distributions free_shared_file_np(shared_file_np_trial_t *trial)
2952*d4514f0bSApple OSS Distributions {
2953*d4514f0bSApple OSS Distributions #if KERNEL
2954*d4514f0bSApple OSS Distributions // some trials have files_count > 0 but null files.
2955*d4514f0bSApple OSS Distributions if (trial->files) {
2956*d4514f0bSApple OSS Distributions kfree_type(struct shared_file_np, trial->files_count, trial->files);
2957*d4514f0bSApple OSS Distributions }
2958*d4514f0bSApple OSS Distributions #else
2959*d4514f0bSApple OSS Distributions free(trial->files);
2960*d4514f0bSApple OSS Distributions #endif
2961*d4514f0bSApple OSS Distributions }
2962*d4514f0bSApple OSS Distributions
2963*d4514f0bSApple OSS Distributions static int get_fd();
2964*d4514f0bSApple OSS Distributions
2965*d4514f0bSApple OSS Distributions shared_file_np_trials_t *
get_shared_file_np_trials(uint64_t dyld_fd)2966*d4514f0bSApple OSS Distributions get_shared_file_np_trials(uint64_t dyld_fd)
2967*d4514f0bSApple OSS Distributions {
2968*d4514f0bSApple OSS Distributions struct shared_file_np * files = NULL;
2969*d4514f0bSApple OSS Distributions shared_file_np_trials_t *trials = allocate_shared_file_np_trials(11);
2970*d4514f0bSApple OSS Distributions append_trial(trials, SHARED_FILE_NP_TRIAL(0, NULL, " (NULL files)"));
2971*d4514f0bSApple OSS Distributions append_trial(trials, SHARED_FILE_NP_TRIAL(1, NULL, " (NULL files)"));
2972*d4514f0bSApple OSS Distributions append_trial(trials, SHARED_FILE_NP_TRIAL(_SR_FILE_MAPPINGS_MAX_FILES - 1, NULL, " (NULL files)"));
2973*d4514f0bSApple OSS Distributions append_trial(trials, SHARED_FILE_NP_TRIAL(_SR_FILE_MAPPINGS_MAX_FILES, NULL, " (NULL files)"));
2974*d4514f0bSApple OSS Distributions append_trial(trials, SHARED_FILE_NP_TRIAL(_SR_FILE_MAPPINGS_MAX_FILES + 1, NULL, " (NULL files)"));
2975*d4514f0bSApple OSS Distributions files = alloc_shared_file_np(1);
2976*d4514f0bSApple OSS Distributions append_trial(trials, SHARED_FILE_NP_TRIAL(1, files, ""));
2977*d4514f0bSApple OSS Distributions files = alloc_shared_file_np(_SR_FILE_MAPPINGS_MAX_FILES - 1);
2978*d4514f0bSApple OSS Distributions append_trial(trials, SHARED_FILE_NP_TRIAL(_SR_FILE_MAPPINGS_MAX_FILES - 1, files, ""));
2979*d4514f0bSApple OSS Distributions files = alloc_shared_file_np(_SR_FILE_MAPPINGS_MAX_FILES);
2980*d4514f0bSApple OSS Distributions append_trial(trials, SHARED_FILE_NP_TRIAL(_SR_FILE_MAPPINGS_MAX_FILES, files, ""));
2981*d4514f0bSApple OSS Distributions files = alloc_shared_file_np(_SR_FILE_MAPPINGS_MAX_FILES + 1);
2982*d4514f0bSApple OSS Distributions append_trial(trials, SHARED_FILE_NP_TRIAL(_SR_FILE_MAPPINGS_MAX_FILES + 1, files, ""));
2983*d4514f0bSApple OSS Distributions files = alloc_shared_file_np(1);
2984*d4514f0bSApple OSS Distributions files->sf_fd = get_fd();
2985*d4514f0bSApple OSS Distributions files->sf_slide = 4096;
2986*d4514f0bSApple OSS Distributions files->sf_mappings_count = 1;
2987*d4514f0bSApple OSS Distributions append_trial(trials, SHARED_FILE_NP_TRIAL(1, files, " non-zero shared_file_np"));
2988*d4514f0bSApple OSS Distributions files = alloc_shared_file_np(2);
2989*d4514f0bSApple OSS Distributions files[0].sf_fd = (int)dyld_fd;
2990*d4514f0bSApple OSS Distributions files[0].sf_mappings_count = 1;
2991*d4514f0bSApple OSS Distributions files[1].sf_fd = files[0].sf_fd;
2992*d4514f0bSApple OSS Distributions files[1].sf_mappings_count = 4;
2993*d4514f0bSApple OSS Distributions append_trial(trials, SHARED_FILE_NP_TRIAL(2, files, " checks shared_file_np"));
2994*d4514f0bSApple OSS Distributions return trials;
2995*d4514f0bSApple OSS Distributions }
2996*d4514f0bSApple OSS Distributions
2997*d4514f0bSApple OSS Distributions static void
cleanup_shared_file_np_trials(shared_file_np_trials_t ** trials)2998*d4514f0bSApple OSS Distributions cleanup_shared_file_np_trials(shared_file_np_trials_t **trials)
2999*d4514f0bSApple OSS Distributions {
3000*d4514f0bSApple OSS Distributions for (size_t i = 0; i < (*trials)->count; i++) {
3001*d4514f0bSApple OSS Distributions free_shared_file_np(&(*trials)->list[i]);
3002*d4514f0bSApple OSS Distributions }
3003*d4514f0bSApple OSS Distributions free_trials(*trials);
3004*d4514f0bSApple OSS Distributions }
3005*d4514f0bSApple OSS Distributions
3006*d4514f0bSApple OSS Distributions typedef struct {
3007*d4514f0bSApple OSS Distributions uint32_t mappings_count;
3008*d4514f0bSApple OSS Distributions struct shared_file_mapping_slide_np *mappings;
3009*d4514f0bSApple OSS Distributions char *name;
3010*d4514f0bSApple OSS Distributions } shared_file_mapping_slide_np_trial_t;
3011*d4514f0bSApple OSS Distributions
3012*d4514f0bSApple OSS Distributions typedef struct {
3013*d4514f0bSApple OSS Distributions unsigned count;
3014*d4514f0bSApple OSS Distributions unsigned capacity;
3015*d4514f0bSApple OSS Distributions shared_file_mapping_slide_np_trial_t list[];
3016*d4514f0bSApple OSS Distributions } shared_file_mapping_slide_np_trials_t;
3017*d4514f0bSApple OSS Distributions
TRIALS_IMPL(shared_file_mapping_slide_np)3018*d4514f0bSApple OSS Distributions TRIALS_IMPL(shared_file_mapping_slide_np)
3019*d4514f0bSApple OSS Distributions
3020*d4514f0bSApple OSS Distributions #define SHARED_FILE_MAPPING_SLIDE_NP_TRIAL(new_mappings_count, new_mappings, new_name) \
3021*d4514f0bSApple OSS Distributions (shared_file_mapping_slide_np_trial_t){ .mappings_count = (uint32_t)(new_mappings_count), \
3022*d4514f0bSApple OSS Distributions .mappings = (struct shared_file_mapping_slide_np *)(new_mappings), \
3023*d4514f0bSApple OSS Distributions .name = "mappings_count="#new_mappings_count new_name }
3024*d4514f0bSApple OSS Distributions
3025*d4514f0bSApple OSS Distributions struct shared_file_mapping_slide_np *
3026*d4514f0bSApple OSS Distributions alloc_shared_file_mapping_slide_np(uint32_t mappings_count)
3027*d4514f0bSApple OSS Distributions {
3028*d4514f0bSApple OSS Distributions struct shared_file_mapping_slide_np *mappings;
3029*d4514f0bSApple OSS Distributions #if KERNEL
3030*d4514f0bSApple OSS Distributions mappings = kalloc_type(struct shared_file_mapping_slide_np, mappings_count, Z_WAITOK | Z_ZERO);
3031*d4514f0bSApple OSS Distributions #else
3032*d4514f0bSApple OSS Distributions mappings = calloc(mappings_count, sizeof(struct shared_file_mapping_slide_np));
3033*d4514f0bSApple OSS Distributions #endif
3034*d4514f0bSApple OSS Distributions return mappings;
3035*d4514f0bSApple OSS Distributions }
3036*d4514f0bSApple OSS Distributions
3037*d4514f0bSApple OSS Distributions void
free_shared_file_mapping_slide_np(shared_file_mapping_slide_np_trial_t * trial)3038*d4514f0bSApple OSS Distributions free_shared_file_mapping_slide_np(shared_file_mapping_slide_np_trial_t *trial)
3039*d4514f0bSApple OSS Distributions {
3040*d4514f0bSApple OSS Distributions #if KERNEL
3041*d4514f0bSApple OSS Distributions // some trials have files_count > 0 but null files.
3042*d4514f0bSApple OSS Distributions if (trial->mappings) {
3043*d4514f0bSApple OSS Distributions kfree_type(struct shared_file_mapping_slide_np, trial->mappings_count, trial->mappings);
3044*d4514f0bSApple OSS Distributions }
3045*d4514f0bSApple OSS Distributions #else
3046*d4514f0bSApple OSS Distributions free(trial->mappings);
3047*d4514f0bSApple OSS Distributions #endif
3048*d4514f0bSApple OSS Distributions }
3049*d4514f0bSApple OSS Distributions
3050*d4514f0bSApple OSS Distributions typedef enum { MP_NORMAL = 0, MP_ADDR_SIZE = 1, MP_OFFSET_SIZE, MP_PROTS } mapping_slide_np_test_style_t;
3051*d4514f0bSApple OSS Distributions
3052*d4514f0bSApple OSS Distributions static inline struct shared_file_mapping_slide_np *
alloc_and_fill_shared_file_mappings(uint32_t num_mappings,mapping_slide_np_test_style_t style)3053*d4514f0bSApple OSS Distributions alloc_and_fill_shared_file_mappings(uint32_t num_mappings, mapping_slide_np_test_style_t style)
3054*d4514f0bSApple OSS Distributions {
3055*d4514f0bSApple OSS Distributions assert(num_mappings > 0);
3056*d4514f0bSApple OSS Distributions struct shared_file_mapping_slide_np *mappings = alloc_shared_file_mapping_slide_np(num_mappings);
3057*d4514f0bSApple OSS Distributions
3058*d4514f0bSApple OSS Distributions // Checks happen in a for-loop so is desirable to differentiate the first mapping.
3059*d4514f0bSApple OSS Distributions switch (style) {
3060*d4514f0bSApple OSS Distributions case MP_NORMAL:
3061*d4514f0bSApple OSS Distributions mappings[0].sms_slide_size = KB4;
3062*d4514f0bSApple OSS Distributions mappings[0].sms_slide_start = KB4;
3063*d4514f0bSApple OSS Distributions mappings[0].sms_max_prot = VM_PROT_DEFAULT;
3064*d4514f0bSApple OSS Distributions mappings[0].sms_init_prot = VM_PROT_DEFAULT;
3065*d4514f0bSApple OSS Distributions break;
3066*d4514f0bSApple OSS Distributions case MP_ADDR_SIZE:
3067*d4514f0bSApple OSS Distributions mappings[0].sms_address = 1;
3068*d4514f0bSApple OSS Distributions mappings[0].sms_size = UINT64_MAX;
3069*d4514f0bSApple OSS Distributions mappings[0].sms_file_offset = 0;
3070*d4514f0bSApple OSS Distributions mappings[0].sms_slide_size = KB4;
3071*d4514f0bSApple OSS Distributions mappings[0].sms_slide_start = KB4;
3072*d4514f0bSApple OSS Distributions mappings[0].sms_max_prot = VM_PROT_DEFAULT;
3073*d4514f0bSApple OSS Distributions mappings[0].sms_init_prot = VM_PROT_DEFAULT;
3074*d4514f0bSApple OSS Distributions break;
3075*d4514f0bSApple OSS Distributions case MP_OFFSET_SIZE:
3076*d4514f0bSApple OSS Distributions mappings[0].sms_size = 0;
3077*d4514f0bSApple OSS Distributions mappings[0].sms_file_offset = UINT64_MAX;
3078*d4514f0bSApple OSS Distributions mappings[0].sms_slide_size = KB4;
3079*d4514f0bSApple OSS Distributions mappings[0].sms_slide_start = KB4;
3080*d4514f0bSApple OSS Distributions mappings[0].sms_max_prot = VM_PROT_DEFAULT;
3081*d4514f0bSApple OSS Distributions mappings[0].sms_init_prot = VM_PROT_DEFAULT;
3082*d4514f0bSApple OSS Distributions break;
3083*d4514f0bSApple OSS Distributions case MP_PROTS:
3084*d4514f0bSApple OSS Distributions mappings[0].sms_slide_size = KB4;
3085*d4514f0bSApple OSS Distributions mappings[0].sms_slide_start = KB4;
3086*d4514f0bSApple OSS Distributions mappings[0].sms_max_prot = VM_PROT_DEFAULT;
3087*d4514f0bSApple OSS Distributions mappings[0].sms_init_prot = INT_MAX;
3088*d4514f0bSApple OSS Distributions break;
3089*d4514f0bSApple OSS Distributions default:
3090*d4514f0bSApple OSS Distributions assert(0);
3091*d4514f0bSApple OSS Distributions break;
3092*d4514f0bSApple OSS Distributions }
3093*d4514f0bSApple OSS Distributions
3094*d4514f0bSApple OSS Distributions for (size_t idx = 1; idx < num_mappings; idx++) {
3095*d4514f0bSApple OSS Distributions size_t i = idx % 4;
3096*d4514f0bSApple OSS Distributions switch (i) {
3097*d4514f0bSApple OSS Distributions case 0:
3098*d4514f0bSApple OSS Distributions mappings[idx].sms_slide_size = KB4;
3099*d4514f0bSApple OSS Distributions mappings[idx].sms_slide_start = KB4;
3100*d4514f0bSApple OSS Distributions mappings[idx].sms_max_prot = VM_PROT_DEFAULT;
3101*d4514f0bSApple OSS Distributions mappings[idx].sms_init_prot = VM_PROT_DEFAULT;
3102*d4514f0bSApple OSS Distributions break;
3103*d4514f0bSApple OSS Distributions case 1:
3104*d4514f0bSApple OSS Distributions mappings[idx].sms_slide_size = KB4;
3105*d4514f0bSApple OSS Distributions mappings[idx].sms_slide_start = UINT64_MAX;
3106*d4514f0bSApple OSS Distributions mappings[idx].sms_max_prot = VM_PROT_DEFAULT;
3107*d4514f0bSApple OSS Distributions mappings[idx].sms_init_prot = VM_PROT_DEFAULT;
3108*d4514f0bSApple OSS Distributions break;
3109*d4514f0bSApple OSS Distributions case 2:
3110*d4514f0bSApple OSS Distributions mappings[idx].sms_slide_size = 0;
3111*d4514f0bSApple OSS Distributions mappings[idx].sms_slide_start = UINT64_MAX;
3112*d4514f0bSApple OSS Distributions mappings[idx].sms_max_prot = VM_PROT_DEFAULT;
3113*d4514f0bSApple OSS Distributions mappings[idx].sms_init_prot = INT_MAX;
3114*d4514f0bSApple OSS Distributions break;
3115*d4514f0bSApple OSS Distributions case 3:
3116*d4514f0bSApple OSS Distributions mappings[idx].sms_slide_size = KB4;
3117*d4514f0bSApple OSS Distributions mappings[idx].sms_slide_start = 0;
3118*d4514f0bSApple OSS Distributions mappings[idx].sms_max_prot = INT_MAX;
3119*d4514f0bSApple OSS Distributions mappings[idx].sms_init_prot = VM_PROT_DEFAULT;
3120*d4514f0bSApple OSS Distributions break;
3121*d4514f0bSApple OSS Distributions default:
3122*d4514f0bSApple OSS Distributions assert(0);
3123*d4514f0bSApple OSS Distributions break;
3124*d4514f0bSApple OSS Distributions }
3125*d4514f0bSApple OSS Distributions }
3126*d4514f0bSApple OSS Distributions return mappings;
3127*d4514f0bSApple OSS Distributions }
3128*d4514f0bSApple OSS Distributions
3129*d4514f0bSApple OSS Distributions shared_file_mapping_slide_np_trials_t*
get_shared_file_mapping_slide_np_trials(void)3130*d4514f0bSApple OSS Distributions get_shared_file_mapping_slide_np_trials(void)
3131*d4514f0bSApple OSS Distributions {
3132*d4514f0bSApple OSS Distributions struct shared_file_mapping_slide_np *mappings = NULL;
3133*d4514f0bSApple OSS Distributions shared_file_mapping_slide_np_trials_t *trials = allocate_shared_file_mapping_slide_np_trials(14);
3134*d4514f0bSApple OSS Distributions append_trial(trials, SHARED_FILE_MAPPING_SLIDE_NP_TRIAL(0, NULL, " (NULL mappings)"));
3135*d4514f0bSApple OSS Distributions append_trial(trials, SHARED_FILE_MAPPING_SLIDE_NP_TRIAL(1, NULL, " (NULL mappings)"));
3136*d4514f0bSApple OSS Distributions append_trial(trials, SHARED_FILE_MAPPING_SLIDE_NP_TRIAL(SFM_MAX - 1, NULL, " (NULL mappings)"));
3137*d4514f0bSApple OSS Distributions append_trial(trials, SHARED_FILE_MAPPING_SLIDE_NP_TRIAL(SFM_MAX, NULL, " (NULL mappings)"));
3138*d4514f0bSApple OSS Distributions append_trial(trials, SHARED_FILE_MAPPING_SLIDE_NP_TRIAL(SFM_MAX + 1, NULL, " (NULL mappings)"));
3139*d4514f0bSApple OSS Distributions mappings = alloc_and_fill_shared_file_mappings(1, MP_NORMAL);
3140*d4514f0bSApple OSS Distributions append_trial(trials, SHARED_FILE_MAPPING_SLIDE_NP_TRIAL(1, mappings, " (normal)"));
3141*d4514f0bSApple OSS Distributions mappings = alloc_and_fill_shared_file_mappings(1, MP_ADDR_SIZE);
3142*d4514f0bSApple OSS Distributions append_trial(trials, SHARED_FILE_MAPPING_SLIDE_NP_TRIAL(1, mappings, " (sms_address+sms_size check)"));
3143*d4514f0bSApple OSS Distributions mappings = alloc_and_fill_shared_file_mappings(1, MP_OFFSET_SIZE);
3144*d4514f0bSApple OSS Distributions append_trial(trials, SHARED_FILE_MAPPING_SLIDE_NP_TRIAL(1, mappings, " (sms_file_offset+sms_size check)"));
3145*d4514f0bSApple OSS Distributions mappings = alloc_and_fill_shared_file_mappings(1, MP_PROTS);
3146*d4514f0bSApple OSS Distributions append_trial(trials, SHARED_FILE_MAPPING_SLIDE_NP_TRIAL(1, mappings, " (sms_init_prot check)"));
3147*d4514f0bSApple OSS Distributions mappings = alloc_and_fill_shared_file_mappings(SFM_MAX - 1, MP_NORMAL);
3148*d4514f0bSApple OSS Distributions append_trial(trials, SHARED_FILE_MAPPING_SLIDE_NP_TRIAL(SFM_MAX - 1, mappings, ""));
3149*d4514f0bSApple OSS Distributions mappings = alloc_and_fill_shared_file_mappings(SFM_MAX, MP_NORMAL);
3150*d4514f0bSApple OSS Distributions append_trial(trials, SHARED_FILE_MAPPING_SLIDE_NP_TRIAL(SFM_MAX, mappings, ""));
3151*d4514f0bSApple OSS Distributions mappings = alloc_and_fill_shared_file_mappings(SFM_MAX + 1, MP_NORMAL);
3152*d4514f0bSApple OSS Distributions append_trial(trials, SHARED_FILE_MAPPING_SLIDE_NP_TRIAL(SFM_MAX + 1, mappings, ""));
3153*d4514f0bSApple OSS Distributions mappings = alloc_and_fill_shared_file_mappings(kNumSharedCacheMappings, MP_NORMAL);
3154*d4514f0bSApple OSS Distributions append_trial(trials, SHARED_FILE_MAPPING_SLIDE_NP_TRIAL(kNumSharedCacheMappings, mappings, ""));
3155*d4514f0bSApple OSS Distributions mappings = alloc_and_fill_shared_file_mappings(2 * kNumSharedCacheMappings, MP_NORMAL);
3156*d4514f0bSApple OSS Distributions append_trial(trials, SHARED_FILE_MAPPING_SLIDE_NP_TRIAL(2 * kNumSharedCacheMappings, mappings, ""));
3157*d4514f0bSApple OSS Distributions
3158*d4514f0bSApple OSS Distributions return trials;
3159*d4514f0bSApple OSS Distributions }
3160*d4514f0bSApple OSS Distributions
3161*d4514f0bSApple OSS Distributions static void
cleanup_shared_file_mapping_slide_np_trials(shared_file_mapping_slide_np_trials_t ** trials)3162*d4514f0bSApple OSS Distributions cleanup_shared_file_mapping_slide_np_trials(shared_file_mapping_slide_np_trials_t **trials)
3163*d4514f0bSApple OSS Distributions {
3164*d4514f0bSApple OSS Distributions for (size_t i = 0; i < (*trials)->count; i++) {
3165*d4514f0bSApple OSS Distributions free_shared_file_mapping_slide_np(&(*trials)->list[i]);
3166*d4514f0bSApple OSS Distributions }
3167*d4514f0bSApple OSS Distributions free_trials(*trials);
3168*d4514f0bSApple OSS Distributions }
3169*d4514f0bSApple OSS Distributions
3170*d4514f0bSApple OSS Distributions typedef struct {
3171*d4514f0bSApple OSS Distributions uint32_t files_count;
3172*d4514f0bSApple OSS Distributions struct shared_file_np *files;
3173*d4514f0bSApple OSS Distributions uint32_t mappings_count;
3174*d4514f0bSApple OSS Distributions struct shared_file_mapping_slide_np *mappings;
3175*d4514f0bSApple OSS Distributions char *name;
3176*d4514f0bSApple OSS Distributions } shared_region_map_and_slide_2_trial_t;
3177*d4514f0bSApple OSS Distributions
3178*d4514f0bSApple OSS Distributions typedef struct {
3179*d4514f0bSApple OSS Distributions unsigned count;
3180*d4514f0bSApple OSS Distributions unsigned capacity;
3181*d4514f0bSApple OSS Distributions shared_file_np_trials_t *shared_files_trials;
3182*d4514f0bSApple OSS Distributions shared_file_mapping_slide_np_trials_t *shared_mappings_trials;
3183*d4514f0bSApple OSS Distributions shared_region_map_and_slide_2_trial_t list[];
3184*d4514f0bSApple OSS Distributions } shared_region_map_and_slide_2_trials_t;
3185*d4514f0bSApple OSS Distributions
TRIALS_IMPL(shared_region_map_and_slide_2)3186*d4514f0bSApple OSS Distributions TRIALS_IMPL(shared_region_map_and_slide_2)
3187*d4514f0bSApple OSS Distributions
3188*d4514f0bSApple OSS Distributions #define SHARED_REGION_MAP_AND_SLIDE_2_TRIAL(new_files_count, new_files, new_mappings_count, new_mappings, new_name) \
3189*d4514f0bSApple OSS Distributions (shared_region_map_and_slide_2_trial_t){ .files_count = (uint32_t)(new_files_count), \
3190*d4514f0bSApple OSS Distributions .files = (struct shared_file_np *)(new_files), \
3191*d4514f0bSApple OSS Distributions .mappings_count = (uint32_t)(new_mappings_count), \
3192*d4514f0bSApple OSS Distributions .mappings = (struct shared_file_mapping_slide_np *)(new_mappings), \
3193*d4514f0bSApple OSS Distributions .name = new_name }
3194*d4514f0bSApple OSS Distributions
3195*d4514f0bSApple OSS Distributions shared_region_map_and_slide_2_trials_t *
3196*d4514f0bSApple OSS Distributions generate_shared_region_map_and_slide_2_trials(uint64_t dyld_fd)
3197*d4514f0bSApple OSS Distributions {
3198*d4514f0bSApple OSS Distributions shared_file_np_trials_t *shared_files = get_shared_file_np_trials(dyld_fd);
3199*d4514f0bSApple OSS Distributions shared_file_mapping_slide_np_trials_t *shared_mappings = get_shared_file_mapping_slide_np_trials();
3200*d4514f0bSApple OSS Distributions unsigned num_trials = shared_files->count * shared_mappings->count;
3201*d4514f0bSApple OSS Distributions shared_region_map_and_slide_2_trials_t *trials = allocate_shared_region_map_and_slide_2_trials(num_trials);
3202*d4514f0bSApple OSS Distributions trials->shared_files_trials = shared_files;
3203*d4514f0bSApple OSS Distributions trials->shared_mappings_trials = shared_mappings;
3204*d4514f0bSApple OSS Distributions for (size_t i = 0; i < shared_files->count; i++) {
3205*d4514f0bSApple OSS Distributions for (size_t j = 0; j < shared_mappings->count; j++) {
3206*d4514f0bSApple OSS Distributions char *buf;
3207*d4514f0bSApple OSS Distributions shared_file_np_trial_t shared_file = shared_files->list[i];
3208*d4514f0bSApple OSS Distributions shared_file_mapping_slide_np_trial_t shared_mapping = shared_mappings->list[j];
3209*d4514f0bSApple OSS Distributions kasprintf(&buf, "%s, %s", shared_file.name, shared_mapping.name);
3210*d4514f0bSApple OSS Distributions append_trial(trials, SHARED_REGION_MAP_AND_SLIDE_2_TRIAL(shared_file.files_count, shared_file.files, shared_mapping.mappings_count, shared_mapping.mappings, buf));
3211*d4514f0bSApple OSS Distributions }
3212*d4514f0bSApple OSS Distributions }
3213*d4514f0bSApple OSS Distributions return trials;
3214*d4514f0bSApple OSS Distributions }
3215*d4514f0bSApple OSS Distributions
3216*d4514f0bSApple OSS Distributions #define SMART_SHARED_REGION_MAP_AND_SLIDE_2_TRIALS(dyld_fd) \
3217*d4514f0bSApple OSS Distributions __attribute__((cleanup(cleanup_shared_region_map_and_slide_2_trials))) \
3218*d4514f0bSApple OSS Distributions = generate_shared_region_map_and_slide_2_trials(dyld_fd);
3219*d4514f0bSApple OSS Distributions
3220*d4514f0bSApple OSS Distributions static void __attribute__((used))
cleanup_shared_region_map_and_slide_2_trials(shared_region_map_and_slide_2_trials_t ** trials)3221*d4514f0bSApple OSS Distributions cleanup_shared_region_map_and_slide_2_trials(shared_region_map_and_slide_2_trials_t **trials)
3222*d4514f0bSApple OSS Distributions {
3223*d4514f0bSApple OSS Distributions for (size_t i = 0; i < (*trials)->count; i++) {
3224*d4514f0bSApple OSS Distributions kfree_str((*trials)->list[i].name);
3225*d4514f0bSApple OSS Distributions }
3226*d4514f0bSApple OSS Distributions cleanup_shared_file_np_trials(&(*trials)->shared_files_trials);
3227*d4514f0bSApple OSS Distributions cleanup_shared_file_mapping_slide_np_trials(&(*trials)->shared_mappings_trials);
3228*d4514f0bSApple OSS Distributions free_trials(*trials);
3229*d4514f0bSApple OSS Distributions }
3230*d4514f0bSApple OSS Distributions #endif // !KERNEL
3231*d4514f0bSApple OSS Distributions
3232*d4514f0bSApple OSS Distributions /////////////////////////////////////////////////////
3233*d4514f0bSApple OSS Distributions // utility code
3234*d4514f0bSApple OSS Distributions
3235*d4514f0bSApple OSS Distributions // Return true if flags has VM_FLAGS_FIXED
3236*d4514f0bSApple OSS Distributions // This is non-trivial because VM_FLAGS_FIXED is zero;
3237*d4514f0bSApple OSS Distributions // the real value is the absence of VM_FLAGS_ANYWHERE.
3238*d4514f0bSApple OSS Distributions static inline bool
is_fixed(int flags)3239*d4514f0bSApple OSS Distributions is_fixed(int flags)
3240*d4514f0bSApple OSS Distributions {
3241*d4514f0bSApple OSS Distributions static_assert(VM_FLAGS_FIXED == 0, "this test requies VM_FLAGS_FIXED be zero");
3242*d4514f0bSApple OSS Distributions static_assert(VM_FLAGS_ANYWHERE != 0, "this test requires VM_FLAGS_ANYWHERE be nonzero");
3243*d4514f0bSApple OSS Distributions return !(flags & VM_FLAGS_ANYWHERE);
3244*d4514f0bSApple OSS Distributions }
3245*d4514f0bSApple OSS Distributions
3246*d4514f0bSApple OSS Distributions // Return true if flags has VM_FLAGS_FIXED and VM_FLAGS_OVERWRITE set.
3247*d4514f0bSApple OSS Distributions static inline bool
is_fixed_overwrite(int flags)3248*d4514f0bSApple OSS Distributions is_fixed_overwrite(int flags)
3249*d4514f0bSApple OSS Distributions {
3250*d4514f0bSApple OSS Distributions return is_fixed(flags) && (flags & VM_FLAGS_OVERWRITE);
3251*d4514f0bSApple OSS Distributions }
3252*d4514f0bSApple OSS Distributions
3253*d4514f0bSApple OSS Distributions
3254*d4514f0bSApple OSS Distributions // Return true if flags has VM_FLAGS_ANYWHERE and VM_FLAGS_RANDOM_ADDR set.
3255*d4514f0bSApple OSS Distributions static inline bool
is_random_anywhere(int flags)3256*d4514f0bSApple OSS Distributions is_random_anywhere(int flags)
3257*d4514f0bSApple OSS Distributions {
3258*d4514f0bSApple OSS Distributions static_assert(VM_FLAGS_ANYWHERE != 0, "this test requires VM_FLAGS_ANYWHERE be nonzero");
3259*d4514f0bSApple OSS Distributions return (flags & VM_FLAGS_RANDOM_ADDR) && (flags & VM_FLAGS_ANYWHERE);
3260*d4514f0bSApple OSS Distributions }
3261*d4514f0bSApple OSS Distributions
3262*d4514f0bSApple OSS Distributions // Deallocate [start, start+size).
3263*d4514f0bSApple OSS Distributions // Don't deallocate if the allocator failed (allocator_kr)
3264*d4514f0bSApple OSS Distributions // Don't deallocate if flags include FIXED | OVERWRITE (in which case
3265*d4514f0bSApple OSS Distributions // the memory is a pre-existing allocation and should be left alone)
3266*d4514f0bSApple OSS Distributions static void
deallocate_if_not_fixed_overwrite(kern_return_t allocator_kr,MAP_T map,mach_vm_address_t start,mach_vm_size_t size,int flags)3267*d4514f0bSApple OSS Distributions deallocate_if_not_fixed_overwrite(kern_return_t allocator_kr, MAP_T map,
3268*d4514f0bSApple OSS Distributions mach_vm_address_t start, mach_vm_size_t size, int flags)
3269*d4514f0bSApple OSS Distributions {
3270*d4514f0bSApple OSS Distributions if (is_fixed_overwrite(flags)) {
3271*d4514f0bSApple OSS Distributions // fixed-overwrite with pre-existing allocation, don't deallocate
3272*d4514f0bSApple OSS Distributions } else if (allocator_kr != 0) {
3273*d4514f0bSApple OSS Distributions // allocator failed, don't deallocate
3274*d4514f0bSApple OSS Distributions } else {
3275*d4514f0bSApple OSS Distributions (void)mach_vm_deallocate(map, start, size);
3276*d4514f0bSApple OSS Distributions }
3277*d4514f0bSApple OSS Distributions }
3278*d4514f0bSApple OSS Distributions
3279*d4514f0bSApple OSS Distributions // PPL is inefficient at deallocations of very large address ranges.
3280*d4514f0bSApple OSS Distributions // Skip those trials to avoid test timeouts.
3281*d4514f0bSApple OSS Distributions // We assume that tests on other devices will cover any testing gaps.
3282*d4514f0bSApple OSS Distributions static inline bool
dealloc_would_time_out(mach_vm_address_t addr __unused,mach_vm_size_t size __unused,vm_map_t map __unused)3283*d4514f0bSApple OSS Distributions dealloc_would_time_out(
3284*d4514f0bSApple OSS Distributions mach_vm_address_t addr __unused,
3285*d4514f0bSApple OSS Distributions mach_vm_size_t size __unused,
3286*d4514f0bSApple OSS Distributions vm_map_t map __unused)
3287*d4514f0bSApple OSS Distributions {
3288*d4514f0bSApple OSS Distributions #if CONFIG_SPTM
3289*d4514f0bSApple OSS Distributions /* not PPL - okay */
3290*d4514f0bSApple OSS Distributions return false;
3291*d4514f0bSApple OSS Distributions #elif !(__ARM_42BIT_PA_SPACE__ || ARM_LARGE_MEMORY)
3292*d4514f0bSApple OSS Distributions /* PPL but small pmap address space - okay */
3293*d4514f0bSApple OSS Distributions return false;
3294*d4514f0bSApple OSS Distributions #else
3295*d4514f0bSApple OSS Distributions /*
3296*d4514f0bSApple OSS Distributions * PPL with large pmap address space - bad
3297*d4514f0bSApple OSS Distributions * Pre-empt trials of very large allocations.
3298*d4514f0bSApple OSS Distributions */
3299*d4514f0bSApple OSS Distributions return size > 0x8000000000;
3300*d4514f0bSApple OSS Distributions #endif
3301*d4514f0bSApple OSS Distributions }
3302*d4514f0bSApple OSS Distributions
3303*d4514f0bSApple OSS Distributions #if !KERNEL
3304*d4514f0bSApple OSS Distributions
3305*d4514f0bSApple OSS Distributions // SMART_MAP is mach_task_self() in userspace and a new empty map in kernel
3306*d4514f0bSApple OSS Distributions #define SMART_MAP = mach_task_self()
3307*d4514f0bSApple OSS Distributions
3308*d4514f0bSApple OSS Distributions // CURRENT_MAP is mach_task_self() in userspace and current_map() in kernel
3309*d4514f0bSApple OSS Distributions #define CURRENT_MAP = mach_task_self()
3310*d4514f0bSApple OSS Distributions
3311*d4514f0bSApple OSS Distributions #else
3312*d4514f0bSApple OSS Distributions
3313*d4514f0bSApple OSS Distributions static inline vm_map_t
create_map(mach_vm_address_t map_start,mach_vm_address_t map_end)3314*d4514f0bSApple OSS Distributions create_map(mach_vm_address_t map_start, mach_vm_address_t map_end)
3315*d4514f0bSApple OSS Distributions {
3316*d4514f0bSApple OSS Distributions ledger_t ledger = ledger_instantiate(task_ledger_template, LEDGER_CREATE_ACTIVE_ENTRIES);
3317*d4514f0bSApple OSS Distributions pmap_t pmap = pmap_create_options(ledger, 0, PMAP_CREATE_64BIT);
3318*d4514f0bSApple OSS Distributions assert(pmap);
3319*d4514f0bSApple OSS Distributions ledger_dereference(ledger); // now retained by pmap
3320*d4514f0bSApple OSS Distributions vm_map_t map = vm_map_create_options(pmap, map_start, map_end, VM_MAP_CREATE_PAGEABLE);
3321*d4514f0bSApple OSS Distributions assert(map);
3322*d4514f0bSApple OSS Distributions
3323*d4514f0bSApple OSS Distributions return map;
3324*d4514f0bSApple OSS Distributions }
3325*d4514f0bSApple OSS Distributions
3326*d4514f0bSApple OSS Distributions static inline void
cleanup_map(vm_map_t * map)3327*d4514f0bSApple OSS Distributions cleanup_map(vm_map_t *map)
3328*d4514f0bSApple OSS Distributions {
3329*d4514f0bSApple OSS Distributions assert(*map);
3330*d4514f0bSApple OSS Distributions kern_return_t kr = vm_map_terminate(*map);
3331*d4514f0bSApple OSS Distributions assert(kr == 0);
3332*d4514f0bSApple OSS Distributions vm_map_deallocate(*map); // also destroys pmap
3333*d4514f0bSApple OSS Distributions }
3334*d4514f0bSApple OSS Distributions
3335*d4514f0bSApple OSS Distributions // kernel: create a new vm_map and deallocate it at end of scope
3336*d4514f0bSApple OSS Distributions // fixme choose a user-like and a kernel-like address range
3337*d4514f0bSApple OSS Distributions #define SMART_MAP \
3338*d4514f0bSApple OSS Distributions __attribute__((cleanup(cleanup_map))) = create_map(0, 0xffffffffffffffff)
3339*d4514f0bSApple OSS Distributions
3340*d4514f0bSApple OSS Distributions // This map has a map_offset that matches what a user would get. This allows
3341*d4514f0bSApple OSS Distributions // vm_map_user_ranges to work properly when tested from the kernel
3342*d4514f0bSApple OSS Distributions #define SMART_RANGE_MAP \
3343*d4514f0bSApple OSS Distributions __attribute__((cleanup(cleanup_map))) = create_map(0, vm_compute_max_offset(true))
3344*d4514f0bSApple OSS Distributions
3345*d4514f0bSApple OSS Distributions #define CURRENT_MAP = current_map()
3346*d4514f0bSApple OSS Distributions
3347*d4514f0bSApple OSS Distributions #endif
3348*d4514f0bSApple OSS Distributions
3349*d4514f0bSApple OSS Distributions // Allocate with an address hint.
3350*d4514f0bSApple OSS Distributions // Important for kernel tests' empty vm_maps
3351*d4514f0bSApple OSS Distributions // to avoid allocating near address 0 and ~0.
3352*d4514f0bSApple OSS Distributions static kern_return_t
allocate_away_from_zero(MAP_T map,mach_vm_address_t * address,mach_vm_size_t size,mach_vm_size_t align_mask,int additional_map_flags)3353*d4514f0bSApple OSS Distributions allocate_away_from_zero(
3354*d4514f0bSApple OSS Distributions MAP_T map,
3355*d4514f0bSApple OSS Distributions mach_vm_address_t *address,
3356*d4514f0bSApple OSS Distributions mach_vm_size_t size,
3357*d4514f0bSApple OSS Distributions mach_vm_size_t align_mask,
3358*d4514f0bSApple OSS Distributions int additional_map_flags)
3359*d4514f0bSApple OSS Distributions {
3360*d4514f0bSApple OSS Distributions *address = 2ull * 1024 * 1024 * 1024; // 2 GB address hint
3361*d4514f0bSApple OSS Distributions return mach_vm_map(map, address, size, align_mask,
3362*d4514f0bSApple OSS Distributions VM_FLAGS_ANYWHERE | additional_map_flags, 0, 0, 0,
3363*d4514f0bSApple OSS Distributions VM_PROT_DEFAULT, VM_PROT_ALL, VM_INHERIT_DEFAULT);
3364*d4514f0bSApple OSS Distributions }
3365*d4514f0bSApple OSS Distributions
3366*d4514f0bSApple OSS Distributions // allocate a purgeable VM region with size and permissions
3367*d4514f0bSApple OSS Distributions // and deallocate it at end of scope
3368*d4514f0bSApple OSS Distributions #define SMART_ALLOCATE_PURGEABLE_VM(map, size, perm) \
3369*d4514f0bSApple OSS Distributions __attribute__((cleanup(cleanup_allocation))) = create_allocation(map, size, 0, perm, false, VM_FLAGS_PURGABLE)
3370*d4514f0bSApple OSS Distributions
3371*d4514f0bSApple OSS Distributions // allocate a VM region with size and permissions
3372*d4514f0bSApple OSS Distributions // and deallocate it at end of scope
3373*d4514f0bSApple OSS Distributions #define SMART_ALLOCATE_VM(map, size, perm) \
3374*d4514f0bSApple OSS Distributions __attribute__((cleanup(cleanup_allocation))) = create_allocation(map, size, 0, perm, false, 0)
3375*d4514f0bSApple OSS Distributions
3376*d4514f0bSApple OSS Distributions // allocate a VM region with size and permissions and alignment
3377*d4514f0bSApple OSS Distributions // and deallocate it at end of scope
3378*d4514f0bSApple OSS Distributions #define SMART_ALLOCATE_ALIGNED_VM(map, size, align_mask, perm) \
3379*d4514f0bSApple OSS Distributions __attribute__((cleanup(cleanup_allocation))) = create_allocation(map, size, align_mask, perm, false, 0)
3380*d4514f0bSApple OSS Distributions
3381*d4514f0bSApple OSS Distributions // allocate a VM region with size and permissions
3382*d4514f0bSApple OSS Distributions // and deallocate it at end of scope
3383*d4514f0bSApple OSS Distributions // If no such region could be allocated, return {.addr = 0}
3384*d4514f0bSApple OSS Distributions #define SMART_TRY_ALLOCATE_VM(map, size, perm) \
3385*d4514f0bSApple OSS Distributions __attribute__((cleanup(cleanup_allocation))) = create_allocation(map, size, 0, perm, true, 0)
3386*d4514f0bSApple OSS Distributions
3387*d4514f0bSApple OSS Distributions // a VM allocation with unallocated pages around it
3388*d4514f0bSApple OSS Distributions typedef struct {
3389*d4514f0bSApple OSS Distributions MAP_T map;
3390*d4514f0bSApple OSS Distributions addr_t guard_size;
3391*d4514f0bSApple OSS Distributions addr_t guard_prefix; // guard_size bytes
3392*d4514f0bSApple OSS Distributions addr_t unallocated_prefix; // guard_size bytes
3393*d4514f0bSApple OSS Distributions addr_t addr;
3394*d4514f0bSApple OSS Distributions addr_t size;
3395*d4514f0bSApple OSS Distributions addr_t unallocated_suffix; // guard_size bytes
3396*d4514f0bSApple OSS Distributions addr_t guard_suffix; // guard_size bytes
3397*d4514f0bSApple OSS Distributions } allocation_t;
3398*d4514f0bSApple OSS Distributions
3399*d4514f0bSApple OSS Distributions static allocation_t
create_allocation(MAP_T new_map,mach_vm_address_t new_size,mach_vm_size_t align_mask,vm_prot_t perm,bool allow_failure,int additional_map_flags)3400*d4514f0bSApple OSS Distributions create_allocation(MAP_T new_map, mach_vm_address_t new_size, mach_vm_size_t align_mask,
3401*d4514f0bSApple OSS Distributions vm_prot_t perm, bool allow_failure, int additional_map_flags)
3402*d4514f0bSApple OSS Distributions {
3403*d4514f0bSApple OSS Distributions // allocations in address order:
3404*d4514f0bSApple OSS Distributions // 16K guard_prefix (allocated, prot none)
3405*d4514f0bSApple OSS Distributions // 16K unallocated_prefix (unallocated)
3406*d4514f0bSApple OSS Distributions // N addr..addr+size
3407*d4514f0bSApple OSS Distributions // 16K unallocated_suffix (unallocated)
3408*d4514f0bSApple OSS Distributions // 16K guard_suffix (allocated, prot none)
3409*d4514f0bSApple OSS Distributions
3410*d4514f0bSApple OSS Distributions // allocate new_size + 4 * 16K bytes
3411*d4514f0bSApple OSS Distributions // then carve it up into our regions
3412*d4514f0bSApple OSS Distributions
3413*d4514f0bSApple OSS Distributions allocation_t result;
3414*d4514f0bSApple OSS Distributions
3415*d4514f0bSApple OSS Distributions result.map = new_map;
3416*d4514f0bSApple OSS Distributions
3417*d4514f0bSApple OSS Distributions // this implementation only works with some alignment values
3418*d4514f0bSApple OSS Distributions assert(align_mask == 0 || align_mask == KB4 - 1 || align_mask == KB16 - 1);
3419*d4514f0bSApple OSS Distributions
3420*d4514f0bSApple OSS Distributions result.guard_size = KB16;
3421*d4514f0bSApple OSS Distributions result.size = round_up_page(new_size, KB16);
3422*d4514f0bSApple OSS Distributions if (result.size == 0 && allow_failure) {
3423*d4514f0bSApple OSS Distributions return (allocation_t){new_map, 0, 0, 0, 0, 0, 0, 0};
3424*d4514f0bSApple OSS Distributions }
3425*d4514f0bSApple OSS Distributions assert(result.size != 0);
3426*d4514f0bSApple OSS Distributions
3427*d4514f0bSApple OSS Distributions mach_vm_address_t allocated_base;
3428*d4514f0bSApple OSS Distributions mach_vm_size_t allocated_size = result.size;
3429*d4514f0bSApple OSS Distributions if (__builtin_add_overflow(result.size, result.guard_size * 4, &allocated_size)) {
3430*d4514f0bSApple OSS Distributions if (allow_failure) {
3431*d4514f0bSApple OSS Distributions return (allocation_t){new_map, 0, 0, 0, 0, 0, 0, 0};
3432*d4514f0bSApple OSS Distributions } else {
3433*d4514f0bSApple OSS Distributions assert(false);
3434*d4514f0bSApple OSS Distributions }
3435*d4514f0bSApple OSS Distributions }
3436*d4514f0bSApple OSS Distributions
3437*d4514f0bSApple OSS Distributions kern_return_t kr;
3438*d4514f0bSApple OSS Distributions kr = allocate_away_from_zero(result.map, &allocated_base, allocated_size,
3439*d4514f0bSApple OSS Distributions align_mask, additional_map_flags);
3440*d4514f0bSApple OSS Distributions if (kr != 0 && allow_failure) {
3441*d4514f0bSApple OSS Distributions return (allocation_t){new_map, 0, 0, 0, 0, 0, 0, 0};
3442*d4514f0bSApple OSS Distributions }
3443*d4514f0bSApple OSS Distributions assert(kr == 0);
3444*d4514f0bSApple OSS Distributions
3445*d4514f0bSApple OSS Distributions result.guard_prefix = (addr_t)allocated_base;
3446*d4514f0bSApple OSS Distributions result.unallocated_prefix = result.guard_prefix + result.guard_size;
3447*d4514f0bSApple OSS Distributions result.addr = result.unallocated_prefix + result.guard_size;
3448*d4514f0bSApple OSS Distributions result.unallocated_suffix = result.addr + result.size;
3449*d4514f0bSApple OSS Distributions result.guard_suffix = result.unallocated_suffix + result.guard_size;
3450*d4514f0bSApple OSS Distributions
3451*d4514f0bSApple OSS Distributions kr = mach_vm_protect(result.map, result.addr, result.size, false, perm);
3452*d4514f0bSApple OSS Distributions assert(kr == 0);
3453*d4514f0bSApple OSS Distributions kr = mach_vm_protect(result.map, result.guard_prefix, result.guard_size, true, VM_PROT_NONE);
3454*d4514f0bSApple OSS Distributions assert(kr == 0);
3455*d4514f0bSApple OSS Distributions kr = mach_vm_protect(result.map, result.guard_suffix, result.guard_size, true, VM_PROT_NONE);
3456*d4514f0bSApple OSS Distributions assert(kr == 0);
3457*d4514f0bSApple OSS Distributions kr = mach_vm_deallocate(result.map, result.unallocated_prefix, result.guard_size);
3458*d4514f0bSApple OSS Distributions assert(kr == 0);
3459*d4514f0bSApple OSS Distributions kr = mach_vm_deallocate(result.map, result.unallocated_suffix, result.guard_size);
3460*d4514f0bSApple OSS Distributions assert(kr == 0);
3461*d4514f0bSApple OSS Distributions
3462*d4514f0bSApple OSS Distributions return result;
3463*d4514f0bSApple OSS Distributions }
3464*d4514f0bSApple OSS Distributions
3465*d4514f0bSApple OSS Distributions // Mark this allocation as deallocated by something else.
3466*d4514f0bSApple OSS Distributions // This means cleanup_allocation() won't deallocate it twice.
3467*d4514f0bSApple OSS Distributions // cleanup_allocation() will still free the guard pages.
3468*d4514f0bSApple OSS Distributions static void
set_already_deallocated(allocation_t * allocation)3469*d4514f0bSApple OSS Distributions set_already_deallocated(allocation_t *allocation)
3470*d4514f0bSApple OSS Distributions {
3471*d4514f0bSApple OSS Distributions allocation->addr = 0;
3472*d4514f0bSApple OSS Distributions allocation->size = 0;
3473*d4514f0bSApple OSS Distributions }
3474*d4514f0bSApple OSS Distributions
3475*d4514f0bSApple OSS Distributions static void
cleanup_allocation(allocation_t * allocation)3476*d4514f0bSApple OSS Distributions cleanup_allocation(allocation_t *allocation)
3477*d4514f0bSApple OSS Distributions {
3478*d4514f0bSApple OSS Distributions // fixme verify allocations and unallocated spaces still exist where we expect
3479*d4514f0bSApple OSS Distributions if (allocation->size) {
3480*d4514f0bSApple OSS Distributions (void)mach_vm_deallocate(allocation->map, allocation->addr, allocation->size);
3481*d4514f0bSApple OSS Distributions }
3482*d4514f0bSApple OSS Distributions if (allocation->guard_size) {
3483*d4514f0bSApple OSS Distributions (void)mach_vm_deallocate(allocation->map, allocation->guard_prefix, allocation->guard_size);
3484*d4514f0bSApple OSS Distributions (void)mach_vm_deallocate(allocation->map, allocation->guard_suffix, allocation->guard_size);
3485*d4514f0bSApple OSS Distributions }
3486*d4514f0bSApple OSS Distributions }
3487*d4514f0bSApple OSS Distributions
3488*d4514f0bSApple OSS Distributions
3489*d4514f0bSApple OSS Distributions // unallocate a VM region with size
3490*d4514f0bSApple OSS Distributions // and deallocate it at end of scope
3491*d4514f0bSApple OSS Distributions #define SMART_UNALLOCATE_VM(map, size) \
3492*d4514f0bSApple OSS Distributions __attribute__((cleanup(cleanup_unallocation))) = create_unallocation(map, size)
3493*d4514f0bSApple OSS Distributions
3494*d4514f0bSApple OSS Distributions // unallocate a VM region with size
3495*d4514f0bSApple OSS Distributions // and deallocate it at end of scope
3496*d4514f0bSApple OSS Distributions // If no such region could be allocated, return {.addr = 0}
3497*d4514f0bSApple OSS Distributions #define SMART_TRY_UNALLOCATE_VM(map, size) \
3498*d4514f0bSApple OSS Distributions __attribute__((cleanup(cleanup_unallocation))) = create_unallocation(map, size, true)
3499*d4514f0bSApple OSS Distributions
3500*d4514f0bSApple OSS Distributions // a VM space with allocated pages around it
3501*d4514f0bSApple OSS Distributions typedef struct {
3502*d4514f0bSApple OSS Distributions MAP_T map;
3503*d4514f0bSApple OSS Distributions addr_t guard_size;
3504*d4514f0bSApple OSS Distributions addr_t guard_prefix; // 16K
3505*d4514f0bSApple OSS Distributions addr_t addr;
3506*d4514f0bSApple OSS Distributions addr_t size;
3507*d4514f0bSApple OSS Distributions addr_t guard_suffix; // 16K
3508*d4514f0bSApple OSS Distributions } unallocation_t;
3509*d4514f0bSApple OSS Distributions
3510*d4514f0bSApple OSS Distributions static unallocation_t __attribute__((overloadable))
create_unallocation(MAP_T new_map,mach_vm_address_t new_size,bool allow_failure)3511*d4514f0bSApple OSS Distributions create_unallocation(MAP_T new_map, mach_vm_address_t new_size, bool allow_failure)
3512*d4514f0bSApple OSS Distributions {
3513*d4514f0bSApple OSS Distributions // allocations in address order:
3514*d4514f0bSApple OSS Distributions // 16K guard_prefix (allocated, prot none)
3515*d4514f0bSApple OSS Distributions // N addr..addr+size (unallocated)
3516*d4514f0bSApple OSS Distributions // 16K guard_suffix (allocated, prot none)
3517*d4514f0bSApple OSS Distributions
3518*d4514f0bSApple OSS Distributions // allocate new_size + 2 * 16K bytes
3519*d4514f0bSApple OSS Distributions // then carve it up into our regions
3520*d4514f0bSApple OSS Distributions
3521*d4514f0bSApple OSS Distributions unallocation_t result;
3522*d4514f0bSApple OSS Distributions
3523*d4514f0bSApple OSS Distributions result.map = new_map;
3524*d4514f0bSApple OSS Distributions
3525*d4514f0bSApple OSS Distributions result.guard_size = KB16;
3526*d4514f0bSApple OSS Distributions result.size = round_up_page(new_size, KB16);
3527*d4514f0bSApple OSS Distributions if (result.size == 0 && allow_failure) {
3528*d4514f0bSApple OSS Distributions return (unallocation_t){new_map, 0, 0, 0, 0, 0};
3529*d4514f0bSApple OSS Distributions }
3530*d4514f0bSApple OSS Distributions assert(result.size != 0);
3531*d4514f0bSApple OSS Distributions
3532*d4514f0bSApple OSS Distributions mach_vm_address_t allocated_base;
3533*d4514f0bSApple OSS Distributions mach_vm_size_t allocated_size = result.size;
3534*d4514f0bSApple OSS Distributions if (__builtin_add_overflow(result.size, result.guard_size * 2, &allocated_size)) {
3535*d4514f0bSApple OSS Distributions if (allow_failure) {
3536*d4514f0bSApple OSS Distributions return (unallocation_t){new_map, 0, 0, 0, 0, 0};
3537*d4514f0bSApple OSS Distributions } else {
3538*d4514f0bSApple OSS Distributions assert(false);
3539*d4514f0bSApple OSS Distributions }
3540*d4514f0bSApple OSS Distributions }
3541*d4514f0bSApple OSS Distributions kern_return_t kr;
3542*d4514f0bSApple OSS Distributions kr = allocate_away_from_zero(result.map, &allocated_base, allocated_size, 0, 0);
3543*d4514f0bSApple OSS Distributions if (kr != 0 && allow_failure) {
3544*d4514f0bSApple OSS Distributions return (unallocation_t){new_map, 0, 0, 0, 0, 0};
3545*d4514f0bSApple OSS Distributions }
3546*d4514f0bSApple OSS Distributions assert(kr == 0);
3547*d4514f0bSApple OSS Distributions
3548*d4514f0bSApple OSS Distributions result.guard_prefix = (addr_t)allocated_base;
3549*d4514f0bSApple OSS Distributions result.addr = result.guard_prefix + result.guard_size;
3550*d4514f0bSApple OSS Distributions result.guard_suffix = result.addr + result.size;
3551*d4514f0bSApple OSS Distributions
3552*d4514f0bSApple OSS Distributions kr = mach_vm_deallocate(result.map, result.addr, result.size);
3553*d4514f0bSApple OSS Distributions assert(kr == 0);
3554*d4514f0bSApple OSS Distributions kr = mach_vm_protect(result.map, result.guard_prefix, result.guard_size, true, VM_PROT_NONE);
3555*d4514f0bSApple OSS Distributions assert(kr == 0);
3556*d4514f0bSApple OSS Distributions kr = mach_vm_protect(result.map, result.guard_suffix, result.guard_size, true, VM_PROT_NONE);
3557*d4514f0bSApple OSS Distributions assert(kr == 0);
3558*d4514f0bSApple OSS Distributions
3559*d4514f0bSApple OSS Distributions return result;
3560*d4514f0bSApple OSS Distributions }
3561*d4514f0bSApple OSS Distributions
3562*d4514f0bSApple OSS Distributions static unallocation_t __attribute__((overloadable))
create_unallocation(MAP_T new_map,mach_vm_address_t new_size)3563*d4514f0bSApple OSS Distributions create_unallocation(MAP_T new_map, mach_vm_address_t new_size)
3564*d4514f0bSApple OSS Distributions {
3565*d4514f0bSApple OSS Distributions return create_unallocation(new_map, new_size, false /*allow_failure*/);
3566*d4514f0bSApple OSS Distributions }
3567*d4514f0bSApple OSS Distributions
3568*d4514f0bSApple OSS Distributions static void
cleanup_unallocation(unallocation_t * unallocation)3569*d4514f0bSApple OSS Distributions cleanup_unallocation(unallocation_t *unallocation)
3570*d4514f0bSApple OSS Distributions {
3571*d4514f0bSApple OSS Distributions // fixme verify allocations and unallocated spaces still exist where we expect
3572*d4514f0bSApple OSS Distributions if (unallocation->guard_size) {
3573*d4514f0bSApple OSS Distributions (void)mach_vm_deallocate(unallocation->map, unallocation->guard_prefix, unallocation->guard_size);
3574*d4514f0bSApple OSS Distributions (void)mach_vm_deallocate(unallocation->map, unallocation->guard_suffix, unallocation->guard_size);
3575*d4514f0bSApple OSS Distributions }
3576*d4514f0bSApple OSS Distributions }
3577*d4514f0bSApple OSS Distributions
3578*d4514f0bSApple OSS Distributions
3579*d4514f0bSApple OSS Distributions // vm_deferred_reclamation_buffer_init_internal tests
3580*d4514f0bSApple OSS Distributions typedef struct {
3581*d4514f0bSApple OSS Distributions task_t task;
3582*d4514f0bSApple OSS Distributions mach_vm_address_t address;
3583*d4514f0bSApple OSS Distributions mach_vm_size_t size;
3584*d4514f0bSApple OSS Distributions char *name;
3585*d4514f0bSApple OSS Distributions } reclamation_buffer_init_trial_t;
3586*d4514f0bSApple OSS Distributions
3587*d4514f0bSApple OSS Distributions typedef struct {
3588*d4514f0bSApple OSS Distributions unsigned count;
3589*d4514f0bSApple OSS Distributions unsigned capacity;
3590*d4514f0bSApple OSS Distributions reclamation_buffer_init_trial_t list[];
3591*d4514f0bSApple OSS Distributions } reclamation_buffer_init_trials_t;
3592*d4514f0bSApple OSS Distributions
TRIALS_IMPL(reclamation_buffer_init)3593*d4514f0bSApple OSS Distributions TRIALS_IMPL(reclamation_buffer_init)
3594*d4514f0bSApple OSS Distributions
3595*d4514f0bSApple OSS Distributions #define RECLAMATION_BUFFER_INIT_TRIAL(new_task, new_address, new_size, new_name) \
3596*d4514f0bSApple OSS Distributions (reclamation_buffer_init_trial_t){ .task = (task_t)(new_task), \
3597*d4514f0bSApple OSS Distributions .address = (mach_vm_address_t)(new_address), \
3598*d4514f0bSApple OSS Distributions .size = (mach_vm_size_t)(new_size), \
3599*d4514f0bSApple OSS Distributions .name = new_name }
3600*d4514f0bSApple OSS Distributions
3601*d4514f0bSApple OSS Distributions /* fixme reclaim struct declarations unavailable outside __LP64__ */
3602*d4514f0bSApple OSS Distributions #if __LP64__
3603*d4514f0bSApple OSS Distributions #define VM_TEST_RECLAIM_BUFFER_SIZE sizeof(struct mach_vm_reclaim_buffer_v1_s) + 2 * sizeof(struct mach_vm_reclaim_entry_v1_s)
3604*d4514f0bSApple OSS Distributions #else
3605*d4514f0bSApple OSS Distributions #define VM_TEST_RECLAIM_BUFFER_SIZE 64
3606*d4514f0bSApple OSS Distributions #endif
3607*d4514f0bSApple OSS Distributions /* __LP64__ */
3608*d4514f0bSApple OSS Distributions
3609*d4514f0bSApple OSS Distributions #define RECLAMATION_BUFFER_INIT_EXTRA_TRIALS 7
3610*d4514f0bSApple OSS Distributions
3611*d4514f0bSApple OSS Distributions reclamation_buffer_init_trials_t *
3612*d4514f0bSApple OSS Distributions generate_reclamation_buffer_init_trials(void)
3613*d4514f0bSApple OSS Distributions {
3614*d4514f0bSApple OSS Distributions MAP_T map SMART_MAP;
3615*d4514f0bSApple OSS Distributions allocation_t base SMART_ALLOCATE_VM(map, TEST_ALLOC_SIZE, VM_PROT_DEFAULT);
3616*d4514f0bSApple OSS Distributions addr_trials_t *addr_trials SMART_ADDR_TRIALS(0);
3617*d4514f0bSApple OSS Distributions reclamation_buffer_init_trials_t *trials = allocate_reclamation_buffer_init_trials(addr_trials->count + RECLAMATION_BUFFER_INIT_EXTRA_TRIALS);
3618*d4514f0bSApple OSS Distributions for (size_t i = 0; i < addr_trials->count; i++) {
3619*d4514f0bSApple OSS Distributions char *buf;
3620*d4514f0bSApple OSS Distributions mach_vm_size_t size = VM_TEST_RECLAIM_BUFFER_SIZE * i * PAGE_SIZE;
3621*d4514f0bSApple OSS Distributions kasprintf(&buf, "%s, size: 0x%llu", addr_trials->list[i].name, size);
3622*d4514f0bSApple OSS Distributions append_trial(trials, RECLAMATION_BUFFER_INIT_TRIAL(current_task(), addr_trials->list[i].addr, size, buf));
3623*d4514f0bSApple OSS Distributions }
3624*d4514f0bSApple OSS Distributions
3625*d4514f0bSApple OSS Distributions append_trial(trials, RECLAMATION_BUFFER_INIT_TRIAL(current_task(), base.addr, 0, "size: 0"));
3626*d4514f0bSApple OSS Distributions append_trial(trials, RECLAMATION_BUFFER_INIT_TRIAL(current_task(), base.addr, UINT64_MAX - 1, "size: UINT64_MAX - 1"));
3627*d4514f0bSApple OSS Distributions append_trial(trials, RECLAMATION_BUFFER_INIT_TRIAL(current_task(), base.addr, UINT64_MAX, "size: UINT64_MAX"));
3628*d4514f0bSApple OSS Distributions append_trial(trials, RECLAMATION_BUFFER_INIT_TRIAL(current_task(), base.addr, UINT64_MAX - PAGE_SIZE + 1, "size: UINT64_MAX - PAGE_SIZE + 1"));
3629*d4514f0bSApple OSS Distributions append_trial(trials, RECLAMATION_BUFFER_INIT_TRIAL(NULL, NULL, 0, "null task, null address, size: 0"));
3630*d4514f0bSApple OSS Distributions append_trial(trials, RECLAMATION_BUFFER_INIT_TRIAL(current_task(), NULL, 0, "null address, size: 0"));
3631*d4514f0bSApple OSS Distributions append_trial(trials, RECLAMATION_BUFFER_INIT_TRIAL(current_task(), base.addr, VM_TEST_RECLAIM_BUFFER_SIZE, "valid arguments to test KERN_NOT_SUPPORTED"));
3632*d4514f0bSApple OSS Distributions
3633*d4514f0bSApple OSS Distributions return trials;
3634*d4514f0bSApple OSS Distributions }
3635*d4514f0bSApple OSS Distributions
3636*d4514f0bSApple OSS Distributions #define SMART_RECLAMATION_BUFFER_INIT_TRIALS() \
3637*d4514f0bSApple OSS Distributions __attribute__((cleanup(cleanup_reclamation_buffer_init_trials))) \
3638*d4514f0bSApple OSS Distributions = generate_reclamation_buffer_init_trials();
3639*d4514f0bSApple OSS Distributions
3640*d4514f0bSApple OSS Distributions static void __attribute__((used))
cleanup_reclamation_buffer_init_trials(reclamation_buffer_init_trials_t ** trials)3641*d4514f0bSApple OSS Distributions cleanup_reclamation_buffer_init_trials(reclamation_buffer_init_trials_t **trials)
3642*d4514f0bSApple OSS Distributions {
3643*d4514f0bSApple OSS Distributions for (size_t i = 0; i < (*trials)->count - RECLAMATION_BUFFER_INIT_EXTRA_TRIALS; i++) {
3644*d4514f0bSApple OSS Distributions kfree_str((*trials)->list[i].name);
3645*d4514f0bSApple OSS Distributions }
3646*d4514f0bSApple OSS Distributions free_trials(*trials);
3647*d4514f0bSApple OSS Distributions }
3648*d4514f0bSApple OSS Distributions
3649*d4514f0bSApple OSS Distributions static kern_return_t
call_mach_vm_deferred_reclamation_buffer_init(task_t task,mach_vm_address_t address,mach_vm_size_t size)3650*d4514f0bSApple OSS Distributions call_mach_vm_deferred_reclamation_buffer_init(task_t task, mach_vm_address_t address, mach_vm_size_t size)
3651*d4514f0bSApple OSS Distributions {
3652*d4514f0bSApple OSS Distributions kern_return_t kr = 0;
3653*d4514f0bSApple OSS Distributions mach_vm_address_t saved_address = address;
3654*d4514f0bSApple OSS Distributions if (task && size > 0 && address == 0) {
3655*d4514f0bSApple OSS Distributions // prevent assert3u(*address, !=, 0)
3656*d4514f0bSApple OSS Distributions return PANIC;
3657*d4514f0bSApple OSS Distributions }
3658*d4514f0bSApple OSS Distributions
3659*d4514f0bSApple OSS Distributions kr = mach_vm_deferred_reclamation_buffer_init(task, &address, size);
3660*d4514f0bSApple OSS Distributions
3661*d4514f0bSApple OSS Distributions //Out-param validation, failure shouldn't change inout address.
3662*d4514f0bSApple OSS Distributions if (kr != KERN_SUCCESS && saved_address != address) {
3663*d4514f0bSApple OSS Distributions kr = OUT_PARAM_BAD;
3664*d4514f0bSApple OSS Distributions }
3665*d4514f0bSApple OSS Distributions if (kr == KERN_SUCCESS && saved_address == address) {
3666*d4514f0bSApple OSS Distributions kr = OUT_PARAM_BAD;
3667*d4514f0bSApple OSS Distributions }
3668*d4514f0bSApple OSS Distributions
3669*d4514f0bSApple OSS Distributions return kr;
3670*d4514f0bSApple OSS Distributions }
3671*d4514f0bSApple OSS Distributions
3672*d4514f0bSApple OSS Distributions
3673*d4514f0bSApple OSS Distributions // mach_vm_remap_external/vm_remap_external/vm32_remap/mach_vm_remap_new_external infra
3674*d4514f0bSApple OSS Distributions // mach_vm_remap/mach_vm_remap_new_kernel infra
3675*d4514f0bSApple OSS Distributions
3676*d4514f0bSApple OSS Distributions /*
3677*d4514f0bSApple OSS Distributions * This comment describes the testing approach that was fleshed out through
3678*d4514f0bSApple OSS Distributions * writing the tests for the map family of functions, and more fully realized
3679*d4514f0bSApple OSS Distributions * for the remap family of functions.
3680*d4514f0bSApple OSS Distributions *
3681*d4514f0bSApple OSS Distributions * This method attempts to radically minimize code reuse, at the expense of
3682*d4514f0bSApple OSS Distributions * decreased navigability (cmd+click is unlikely to work for you for this code)
3683*d4514f0bSApple OSS Distributions * and increased upfront costs for understanding this code. Maintainability
3684*d4514f0bSApple OSS Distributions * should be better in most cases: if a fix needs to happen, it can be
3685*d4514f0bSApple OSS Distributions * implemented in the right place once and doesn’t need to be copy-and-pasted
3686*d4514f0bSApple OSS Distributions * in multiple duplicated functions. There may however be cases where the
3687*d4514f0bSApple OSS Distributions * change you want to make doesn’t fit the spirit of this approach (for
3688*d4514f0bSApple OSS Distributions * instance changing the behavior of the test for only one function in the
3689*d4514f0bSApple OSS Distributions * family).
3690*d4514f0bSApple OSS Distributions *
3691*d4514f0bSApple OSS Distributions * The framework is built around the idea that there are three types of
3692*d4514f0bSApple OSS Distributions * parameters:
3693*d4514f0bSApple OSS Distributions * 1. Parameters that will be fixed for all calls to the function (e.g. some
3694*d4514f0bSApple OSS Distributions * uncommon type specific to the function that doesn’t impact the input
3695*d4514f0bSApple OSS Distributions * validation flow)
3696*d4514f0bSApple OSS Distributions * 2. Parameters that cause input validation to change significantly (typically
3697*d4514f0bSApple OSS Distributions * flags, e.g. fixed vs anywhere). For those we basically want to treat
3698*d4514f0bSApple OSS Distributions * different values of the flags as calling into different functions (for
3699*d4514f0bSApple OSS Distributions * the purpose of input validation).
3700*d4514f0bSApple OSS Distributions * 3. Parameters that can be tested. For every test this is further broken down
3701*d4514f0bSApple OSS Distributions * into 2 subtypes:
3702*d4514f0bSApple OSS Distributions * A. Parameters being iterated over during the test (e.g. start+size)
3703*d4514f0bSApple OSS Distributions * B. Parameters that should stay fixed during this test (e.g. pick a
3704*d4514f0bSApple OSS Distributions * sane value of prot and pass that same value for all values of
3705*d4514f0bSApple OSS Distributions * start/size)
3706*d4514f0bSApple OSS Distributions *
3707*d4514f0bSApple OSS Distributions * Often, many functions have very similar signatures (they are in the same
3708*d4514f0bSApple OSS Distributions * function family). We want to avoid copy/pasting tests for each function in
3709*d4514f0bSApple OSS Distributions * the family.
3710*d4514f0bSApple OSS Distributions *
3711*d4514f0bSApple OSS Distributions * Here is the flow used for the remap family of functions:
3712*d4514f0bSApple OSS Distributions * 1. Typedef a function type with shared parameters (see remap_fn_t)
3713*d4514f0bSApple OSS Distributions * 2. Define function wrappers that fit the above typedef for each function
3714*d4514f0bSApple OSS Distributions * in the family (see e.g. mach_vm_remap_new_kernel_wrapped). These might
3715*d4514f0bSApple OSS Distributions * set values for “type 1” params.
3716*d4514f0bSApple OSS Distributions * 3. Define “helper” functions that take in parameters of types 2 and 3.A.,
3717*d4514f0bSApple OSS Distributions * and call the wrapper, filling in type 3.B. params. See, e.g.,
3718*d4514f0bSApple OSS Distributions * help_call_remap_fn__src_size. For remap, all helpers can easily be
3719*d4514f0bSApple OSS Distributions * implemented as a single call to a core helper function
3720*d4514f0bSApple OSS Distributions * help_call_remap_fn__src_size_etc.
3721*d4514f0bSApple OSS Distributions * 4. Define generic “caller” functions that take in a wrapper and parameters
3722*d4514f0bSApple OSS Distributions * of type 3.A. and call the helper. Macros are used to mass implement these
3723*d4514f0bSApple OSS Distributions * for all values of type 2 parameters and for all functions in the family.
3724*d4514f0bSApple OSS Distributions * See, e.g., `IMPL_FROM_HELPER(dst_size);`.
3725*d4514f0bSApple OSS Distributions * 5. Specialize the above "caller" functions for each wrapper in the family,
3726*d4514f0bSApple OSS Distributions * again using macros. See `#define IMPL(remap_fn)` and its uses below.
3727*d4514f0bSApple OSS Distributions * This results in a number of specialized caller functions that is the
3728*d4514f0bSApple OSS Distributions * product of the number of functions in the family by the number of
3729*d4514f0bSApple OSS Distributions * variants induced by type 2 parameters.
3730*d4514f0bSApple OSS Distributions * 6. Use macros to call test harnesses on caller functions en masse at test
3731*d4514f0bSApple OSS Distributions * time for all functions. See the call sites in `vm_parameter_validation.c`
3732*d4514f0bSApple OSS Distributions * e.g. `RUN_ALL(mach_vm_remap_new_user, , mach_vm_remap_new);`.
3733*d4514f0bSApple OSS Distributions */
3734*d4514f0bSApple OSS Distributions
3735*d4514f0bSApple OSS Distributions typedef kern_return_t (*remap_fn_t)(vm_map_t target_task,
3736*d4514f0bSApple OSS Distributions mach_vm_address_t *target_address,
3737*d4514f0bSApple OSS Distributions mach_vm_size_t size,
3738*d4514f0bSApple OSS Distributions mach_vm_offset_t mask,
3739*d4514f0bSApple OSS Distributions int flags,
3740*d4514f0bSApple OSS Distributions vm_map_t src_task,
3741*d4514f0bSApple OSS Distributions mach_vm_address_t src_address,
3742*d4514f0bSApple OSS Distributions boolean_t copy,
3743*d4514f0bSApple OSS Distributions vm_prot_t *cur_protection,
3744*d4514f0bSApple OSS Distributions vm_prot_t *max_protection,
3745*d4514f0bSApple OSS Distributions vm_inherit_t inheritance);
3746*d4514f0bSApple OSS Distributions
3747*d4514f0bSApple OSS Distributions // helpers that call a provided function with certain sets of params
3748*d4514f0bSApple OSS Distributions
3749*d4514f0bSApple OSS Distributions static kern_return_t
help_call_remap_fn__src_size_etc(remap_fn_t fn,MAP_T map,int flags,bool copy,mach_vm_address_t src,mach_vm_size_t size,vm_prot_t cur,vm_prot_t max,vm_inherit_t inherit)3750*d4514f0bSApple OSS Distributions help_call_remap_fn__src_size_etc(remap_fn_t fn, MAP_T map, int flags, bool copy, mach_vm_address_t src, mach_vm_size_t size, vm_prot_t cur, vm_prot_t max, vm_inherit_t inherit)
3751*d4514f0bSApple OSS Distributions {
3752*d4514f0bSApple OSS Distributions kern_return_t kr;
3753*d4514f0bSApple OSS Distributions #if KERNEL
3754*d4514f0bSApple OSS Distributions if (is_random_anywhere(flags)) {
3755*d4514f0bSApple OSS Distributions // RANDOM_ADDR is likely to fall outside pmap's range
3756*d4514f0bSApple OSS Distributions return PANIC;
3757*d4514f0bSApple OSS Distributions }
3758*d4514f0bSApple OSS Distributions #endif
3759*d4514f0bSApple OSS Distributions if (is_fixed_overwrite(flags)) {
3760*d4514f0bSApple OSS Distributions // Try to allocate a dest for vm_remap to fixed-overwrite at.
3761*d4514f0bSApple OSS Distributions allocation_t dst_alloc SMART_TRY_ALLOCATE_VM(map, size, VM_PROT_DEFAULT);
3762*d4514f0bSApple OSS Distributions mach_vm_address_t out_addr = dst_alloc.addr;
3763*d4514f0bSApple OSS Distributions if (out_addr == 0) {
3764*d4514f0bSApple OSS Distributions // Failed to allocate. Clear VM_FLAGS_OVERWRITE
3765*d4514f0bSApple OSS Distributions // to prevent wild mappings.
3766*d4514f0bSApple OSS Distributions flags &= ~VM_FLAGS_OVERWRITE;
3767*d4514f0bSApple OSS Distributions }
3768*d4514f0bSApple OSS Distributions kr = fn(map, &out_addr, size, 0, flags,
3769*d4514f0bSApple OSS Distributions map, src, copy, &cur, &max, inherit);
3770*d4514f0bSApple OSS Distributions } else {
3771*d4514f0bSApple OSS Distributions // vm_remap will allocate anywhere. Deallocate if it succeeds.
3772*d4514f0bSApple OSS Distributions mach_vm_address_t out_addr = 0;
3773*d4514f0bSApple OSS Distributions kr = fn(map, &out_addr, size, 0, flags,
3774*d4514f0bSApple OSS Distributions map, src, copy, &cur, &max, inherit);
3775*d4514f0bSApple OSS Distributions if (kr == 0) {
3776*d4514f0bSApple OSS Distributions (void)mach_vm_deallocate(map, out_addr, size);
3777*d4514f0bSApple OSS Distributions }
3778*d4514f0bSApple OSS Distributions }
3779*d4514f0bSApple OSS Distributions return kr;
3780*d4514f0bSApple OSS Distributions }
3781*d4514f0bSApple OSS Distributions
3782*d4514f0bSApple OSS Distributions static kern_return_t
help_call_remap_fn__src_size(remap_fn_t fn,MAP_T map,int unused_flags __unused,bool copy,mach_vm_address_t src,mach_vm_size_t size)3783*d4514f0bSApple OSS Distributions help_call_remap_fn__src_size(remap_fn_t fn, MAP_T map, int unused_flags __unused, bool copy, mach_vm_address_t src, mach_vm_size_t size)
3784*d4514f0bSApple OSS Distributions {
3785*d4514f0bSApple OSS Distributions assert(unused_flags == 0);
3786*d4514f0bSApple OSS Distributions return help_call_remap_fn__src_size_etc(fn, map, VM_FLAGS_ANYWHERE, copy, src, size, 0, 0, VM_INHERIT_NONE);
3787*d4514f0bSApple OSS Distributions }
3788*d4514f0bSApple OSS Distributions
3789*d4514f0bSApple OSS Distributions static kern_return_t
help_call_remap_fn__dst_size(remap_fn_t fn,MAP_T map,int flags,bool copy,mach_vm_address_t dst,mach_vm_size_t size)3790*d4514f0bSApple OSS Distributions help_call_remap_fn__dst_size(remap_fn_t fn, MAP_T map, int flags, bool copy, mach_vm_address_t dst, mach_vm_size_t size)
3791*d4514f0bSApple OSS Distributions {
3792*d4514f0bSApple OSS Distributions allocation_t src SMART_ALLOCATE_VM(map, TEST_ALLOC_SIZE, VM_PROT_DEFAULT);
3793*d4514f0bSApple OSS Distributions mach_vm_address_t out_addr = dst;
3794*d4514f0bSApple OSS Distributions vm_prot_t cur = 0;
3795*d4514f0bSApple OSS Distributions vm_prot_t max = 0;
3796*d4514f0bSApple OSS Distributions kern_return_t kr = fn(map, &out_addr, size, 0, flags,
3797*d4514f0bSApple OSS Distributions map, src.addr, copy, &cur, &max, VM_INHERIT_NONE);
3798*d4514f0bSApple OSS Distributions deallocate_if_not_fixed_overwrite(kr, map, out_addr, size, flags);
3799*d4514f0bSApple OSS Distributions return kr;
3800*d4514f0bSApple OSS Distributions }
3801*d4514f0bSApple OSS Distributions
3802*d4514f0bSApple OSS Distributions static kern_return_t
help_call_remap_fn__inherit(remap_fn_t fn,MAP_T map,int flags,bool copy,mach_vm_address_t src,mach_vm_size_t size,vm_inherit_t inherit)3803*d4514f0bSApple OSS Distributions help_call_remap_fn__inherit(remap_fn_t fn, MAP_T map, int flags, bool copy, mach_vm_address_t src, mach_vm_size_t size, vm_inherit_t inherit)
3804*d4514f0bSApple OSS Distributions {
3805*d4514f0bSApple OSS Distributions return help_call_remap_fn__src_size_etc(fn, map, flags, copy, src, size, 0, 0, inherit);
3806*d4514f0bSApple OSS Distributions }
3807*d4514f0bSApple OSS Distributions
3808*d4514f0bSApple OSS Distributions static kern_return_t
help_call_remap_fn__flags(remap_fn_t fn,MAP_T map,int unused_flags __unused,bool copy,mach_vm_address_t src,mach_vm_size_t size,int trial_flags)3809*d4514f0bSApple OSS Distributions help_call_remap_fn__flags(remap_fn_t fn, MAP_T map, int unused_flags __unused, bool copy, mach_vm_address_t src, mach_vm_size_t size, int trial_flags)
3810*d4514f0bSApple OSS Distributions {
3811*d4514f0bSApple OSS Distributions assert(unused_flags == 0);
3812*d4514f0bSApple OSS Distributions return help_call_remap_fn__src_size_etc(fn, map, trial_flags, copy, src, size, 0, 0, VM_INHERIT_NONE);
3813*d4514f0bSApple OSS Distributions }
3814*d4514f0bSApple OSS Distributions
3815*d4514f0bSApple OSS Distributions static kern_return_t
help_call_remap_fn__prot_pairs(remap_fn_t fn,MAP_T map,int flags,bool copy,mach_vm_address_t src,mach_vm_size_t size,vm_prot_t cur,vm_prot_t max)3816*d4514f0bSApple OSS Distributions help_call_remap_fn__prot_pairs(remap_fn_t fn, MAP_T map, int flags, bool copy, mach_vm_address_t src, mach_vm_size_t size, vm_prot_t cur, vm_prot_t max)
3817*d4514f0bSApple OSS Distributions {
3818*d4514f0bSApple OSS Distributions return help_call_remap_fn__src_size_etc(fn, map, flags, copy, src, size, cur, max, VM_INHERIT_NONE);
3819*d4514f0bSApple OSS Distributions }
3820*d4514f0bSApple OSS Distributions
3821*d4514f0bSApple OSS Distributions static kern_return_t
help_call_remap_fn__src_dst_size(remap_fn_t fn,MAP_T map,int flags,bool copy,mach_vm_address_t src,mach_vm_size_t size,mach_vm_address_t dst)3822*d4514f0bSApple OSS Distributions help_call_remap_fn__src_dst_size(remap_fn_t fn, MAP_T map, int flags, bool copy, mach_vm_address_t src, mach_vm_size_t size, mach_vm_address_t dst)
3823*d4514f0bSApple OSS Distributions {
3824*d4514f0bSApple OSS Distributions mach_vm_address_t out_addr = dst;
3825*d4514f0bSApple OSS Distributions vm_prot_t cur = 0;
3826*d4514f0bSApple OSS Distributions vm_prot_t max = 0;
3827*d4514f0bSApple OSS Distributions kern_return_t kr = fn(map, &out_addr, size, 0, flags,
3828*d4514f0bSApple OSS Distributions map, src, copy, &cur, &max, VM_INHERIT_NONE);
3829*d4514f0bSApple OSS Distributions deallocate_if_not_fixed_overwrite(kr, map, out_addr, size, flags);
3830*d4514f0bSApple OSS Distributions return kr;
3831*d4514f0bSApple OSS Distributions }
3832*d4514f0bSApple OSS Distributions
3833*d4514f0bSApple OSS Distributions #define GET_INSTANCE(_0, _1, _2, _3, _4, _5, _6, _7, _8, NAME, ...) NAME
3834*d4514f0bSApple OSS Distributions
3835*d4514f0bSApple OSS Distributions #define DROP_TYPES_8(a, b, ...) , b DROP_TYPES_6(__VA_ARGS__)
3836*d4514f0bSApple OSS Distributions #define DROP_TYPES_6(a, b, ...) , b DROP_TYPES_4(__VA_ARGS__)
3837*d4514f0bSApple OSS Distributions #define DROP_TYPES_4(a, b, ...) , b DROP_TYPES_2(__VA_ARGS__)
3838*d4514f0bSApple OSS Distributions #define DROP_TYPES_2(a, b, ...) , b
3839*d4514f0bSApple OSS Distributions #define DROP_TYPES_0()
3840*d4514f0bSApple OSS Distributions
3841*d4514f0bSApple OSS Distributions // Parses lists of "type1, arg1, type2, arg" into "arg1, arg2"
3842*d4514f0bSApple OSS Distributions #define DROP_TYPES(...) GET_INSTANCE(_0 __VA_OPT__(,) __VA_ARGS__, DROP_TYPES_8, DROP_TYPES_8, DROP_TYPES_6, DROP_TYPES_6, DROP_TYPES_4, DROP_TYPES_4, DROP_TYPES_2, DROP_TYPES_2, DROP_TYPES_0, DROP_TYPES_0)(__VA_ARGS__)
3843*d4514f0bSApple OSS Distributions
3844*d4514f0bSApple OSS Distributions #define DROP_COMMAS_8(a, b, ...) , a b DROP_COMMAS_6(__VA_ARGS__)
3845*d4514f0bSApple OSS Distributions #define DROP_COMMAS_6(a, b, ...) , a b DROP_COMMAS_4(__VA_ARGS__)
3846*d4514f0bSApple OSS Distributions #define DROP_COMMAS_4(a, b, ...) , a b DROP_COMMAS_2(__VA_ARGS__)
3847*d4514f0bSApple OSS Distributions #define DROP_COMMAS_2(a, b) , a b
3848*d4514f0bSApple OSS Distributions #define DROP_COMMAS_0()
3849*d4514f0bSApple OSS Distributions
3850*d4514f0bSApple OSS Distributions // Parses lists of "type1, arg1, type2, arg" into "type1 arg1, type2 arg2"
3851*d4514f0bSApple OSS Distributions #define DROP_COMMAS(...) GET_INSTANCE(_0 __VA_OPT__(,) __VA_ARGS__, DROP_COMMAS_8, DROP_COMMAS_8, DROP_COMMAS_6, DROP_COMMAS_6, DROP_COMMAS_4, DROP_COMMAS_4, DROP_COMMAS_2, DROP_COMMAS_2, DROP_COMMAS_0)(__VA_ARGS__)
3852*d4514f0bSApple OSS Distributions
3853*d4514f0bSApple OSS Distributions // specialize helpers into implementations of call functions that are still agnostic to the remap function
3854*d4514f0bSApple OSS Distributions
3855*d4514f0bSApple OSS Distributions #define IMPL_ONE_FROM_HELPER(type, variant, flags, copy, ...) \
3856*d4514f0bSApple OSS Distributions static kern_return_t \
3857*d4514f0bSApple OSS Distributions call_remap_fn ## __ ## variant ## __ ## type(remap_fn_t fn, MAP_T map, mach_vm_address_t src, mach_vm_size_t size DROP_COMMAS(__VA_ARGS__)) { \
3858*d4514f0bSApple OSS Distributions return help_call_remap_fn__ ## type(fn, map, flags, copy, src, size DROP_TYPES(__VA_ARGS__)); \
3859*d4514f0bSApple OSS Distributions }
3860*d4514f0bSApple OSS Distributions
3861*d4514f0bSApple OSS Distributions #define IMPL_FROM_HELPER(type, ...) \
3862*d4514f0bSApple OSS Distributions IMPL_ONE_FROM_HELPER(type, fixed, VM_FLAGS_FIXED | VM_FLAGS_OVERWRITE, false, ##__VA_ARGS__) \
3863*d4514f0bSApple OSS Distributions IMPL_ONE_FROM_HELPER(type, fixed_copy, VM_FLAGS_FIXED | VM_FLAGS_OVERWRITE, true, ##__VA_ARGS__) \
3864*d4514f0bSApple OSS Distributions IMPL_ONE_FROM_HELPER(type, anywhere, VM_FLAGS_ANYWHERE, false, ##__VA_ARGS__) \
3865*d4514f0bSApple OSS Distributions
3866*d4514f0bSApple OSS Distributions IMPL_FROM_HELPER(dst_size);
3867*d4514f0bSApple OSS Distributions IMPL_FROM_HELPER(inherit, vm_inherit_t, inherit);
3868*d4514f0bSApple OSS Distributions IMPL_FROM_HELPER(prot_pairs, vm_prot_t, cur, vm_prot_t, max);
3869*d4514f0bSApple OSS Distributions IMPL_FROM_HELPER(src_dst_size, mach_vm_address_t, dst);
3870*d4514f0bSApple OSS Distributions
3871*d4514f0bSApple OSS Distributions IMPL_ONE_FROM_HELPER(flags, nocopy, 0 /*ignored*/, false, int, flag)
3872*d4514f0bSApple OSS Distributions IMPL_ONE_FROM_HELPER(flags, copy, 0 /*ignored*/, true, int, flag)
3873*d4514f0bSApple OSS Distributions
3874*d4514f0bSApple OSS Distributions IMPL_ONE_FROM_HELPER(src_size, nocopy, 0 /*ignored*/, false)
3875*d4514f0bSApple OSS Distributions IMPL_ONE_FROM_HELPER(src_size, copy, 0 /*ignored*/, true)
3876*d4514f0bSApple OSS Distributions
3877*d4514f0bSApple OSS Distributions #undef IMPL_FROM_HELPER
3878*d4514f0bSApple OSS Distributions #undef IMPL_ONE_FROM_HELPER
3879*d4514f0bSApple OSS Distributions
3880*d4514f0bSApple OSS Distributions // define call functions that are specific to the remap function, and rely on implementations above under the hood
3881*d4514f0bSApple OSS Distributions
3882*d4514f0bSApple OSS Distributions #define IMPL_REMAP_FN_HELPER(remap_fn, instance, type, ...) \
3883*d4514f0bSApple OSS Distributions static kern_return_t \
3884*d4514f0bSApple OSS Distributions call_ ## remap_fn ## __ ## instance ## __ ## type(MAP_T map DROP_COMMAS(__VA_ARGS__)) \
3885*d4514f0bSApple OSS Distributions { \
3886*d4514f0bSApple OSS Distributions return call_remap_fn__ ## instance ## __ ## type(remap_fn, map DROP_TYPES(__VA_ARGS__)); \
3887*d4514f0bSApple OSS Distributions }
3888*d4514f0bSApple OSS Distributions
3889*d4514f0bSApple OSS Distributions #define IMPL_REMAP_FN_SRC_SIZE(remap_fn, instance) IMPL_REMAP_FN_HELPER(remap_fn, instance, src_size, mach_vm_address_t, src, mach_vm_size_t, size)
3890*d4514f0bSApple OSS Distributions #define IMPL_REMAP_FN_DST_SIZE(remap_fn, instance) IMPL_REMAP_FN_HELPER(remap_fn, instance, dst_size, mach_vm_address_t, src, mach_vm_size_t, size)
3891*d4514f0bSApple OSS Distributions #define IMPL_REMAP_FN_SRC_DST_SIZE(remap_fn, instance) IMPL_REMAP_FN_HELPER(remap_fn, instance, src_dst_size, mach_vm_address_t, src, mach_vm_size_t, size, mach_vm_address_t, dst)
3892*d4514f0bSApple OSS Distributions #define IMPL_REMAP_FN_SRC_SIZE_INHERIT(remap_fn, instance) IMPL_REMAP_FN_HELPER(remap_fn, instance, inherit, mach_vm_address_t, src, mach_vm_size_t, size, vm_inherit_t, inherit)
3893*d4514f0bSApple OSS Distributions #define IMPL_REMAP_FN_SRC_SIZE_FLAGS(remap_fn, instance) IMPL_REMAP_FN_HELPER(remap_fn, instance, flags, mach_vm_address_t, src, mach_vm_size_t, size, int, flags)
3894*d4514f0bSApple OSS Distributions #define IMPL_REMAP_FN_PROT_PAIRS(remap_fn, instance) IMPL_REMAP_FN_HELPER(remap_fn, instance, prot_pairs, mach_vm_address_t, src, mach_vm_size_t, size, vm_prot_t, cur, vm_prot_t, max)
3895*d4514f0bSApple OSS Distributions
3896*d4514f0bSApple OSS Distributions #define IMPL(remap_fn) \
3897*d4514f0bSApple OSS Distributions IMPL_REMAP_FN_SRC_SIZE(remap_fn, nocopy); \
3898*d4514f0bSApple OSS Distributions IMPL_REMAP_FN_SRC_SIZE(remap_fn, copy); \
3899*d4514f0bSApple OSS Distributions \
3900*d4514f0bSApple OSS Distributions IMPL_REMAP_FN_DST_SIZE(remap_fn, fixed); \
3901*d4514f0bSApple OSS Distributions IMPL_REMAP_FN_DST_SIZE(remap_fn, fixed_copy); \
3902*d4514f0bSApple OSS Distributions IMPL_REMAP_FN_DST_SIZE(remap_fn, anywhere); \
3903*d4514f0bSApple OSS Distributions \
3904*d4514f0bSApple OSS Distributions IMPL_REMAP_FN_SRC_SIZE_INHERIT(remap_fn, fixed); \
3905*d4514f0bSApple OSS Distributions IMPL_REMAP_FN_SRC_SIZE_INHERIT(remap_fn, fixed_copy); \
3906*d4514f0bSApple OSS Distributions IMPL_REMAP_FN_SRC_SIZE_INHERIT(remap_fn, anywhere); \
3907*d4514f0bSApple OSS Distributions \
3908*d4514f0bSApple OSS Distributions IMPL_REMAP_FN_SRC_SIZE_FLAGS(remap_fn, nocopy); \
3909*d4514f0bSApple OSS Distributions IMPL_REMAP_FN_SRC_SIZE_FLAGS(remap_fn, copy); \
3910*d4514f0bSApple OSS Distributions \
3911*d4514f0bSApple OSS Distributions IMPL_REMAP_FN_PROT_PAIRS(remap_fn, fixed); \
3912*d4514f0bSApple OSS Distributions IMPL_REMAP_FN_PROT_PAIRS(remap_fn, fixed_copy); \
3913*d4514f0bSApple OSS Distributions IMPL_REMAP_FN_PROT_PAIRS(remap_fn, anywhere); \
3914*d4514f0bSApple OSS Distributions \
3915*d4514f0bSApple OSS Distributions IMPL_REMAP_FN_SRC_DST_SIZE(remap_fn, fixed); \
3916*d4514f0bSApple OSS Distributions IMPL_REMAP_FN_SRC_DST_SIZE(remap_fn, fixed_copy); \
3917*d4514f0bSApple OSS Distributions IMPL_REMAP_FN_SRC_DST_SIZE(remap_fn, anywhere); \
3918*d4514f0bSApple OSS Distributions
3919*d4514f0bSApple OSS Distributions static inline void
check_mach_vm_map_outparam_changes(kern_return_t * kr,mach_vm_address_t addr,mach_vm_address_t saved_addr,int flags,MAP_T map)3920*d4514f0bSApple OSS Distributions check_mach_vm_map_outparam_changes(kern_return_t * kr, mach_vm_address_t addr, mach_vm_address_t saved_addr,
3921*d4514f0bSApple OSS Distributions int flags, MAP_T map)
3922*d4514f0bSApple OSS Distributions {
3923*d4514f0bSApple OSS Distributions if (*kr == KERN_SUCCESS) {
3924*d4514f0bSApple OSS Distributions if (is_fixed(flags)) {
3925*d4514f0bSApple OSS Distributions if (addr != truncate_vm_map_addr_with_flags(map, saved_addr, flags)) {
3926*d4514f0bSApple OSS Distributions *kr = OUT_PARAM_BAD;
3927*d4514f0bSApple OSS Distributions }
3928*d4514f0bSApple OSS Distributions }
3929*d4514f0bSApple OSS Distributions } else {
3930*d4514f0bSApple OSS Distributions if (addr != saved_addr) {
3931*d4514f0bSApple OSS Distributions *kr = OUT_PARAM_BAD;
3932*d4514f0bSApple OSS Distributions }
3933*d4514f0bSApple OSS Distributions }
3934*d4514f0bSApple OSS Distributions }
3935*d4514f0bSApple OSS Distributions
3936*d4514f0bSApple OSS Distributions static inline void
check_mach_vm_remap_outparam_changes(kern_return_t * kr,mach_vm_address_t addr,mach_vm_address_t saved_addr,int flags,vm_prot_t cur_prot,vm_prot_t saved_cur_prot,vm_prot_t max_prot,vm_prot_t saved_max_prot,MAP_T map,mach_vm_address_t src_addr)3937*d4514f0bSApple OSS Distributions check_mach_vm_remap_outparam_changes(kern_return_t * kr, mach_vm_address_t addr, mach_vm_address_t saved_addr,
3938*d4514f0bSApple OSS Distributions int flags, vm_prot_t cur_prot, vm_prot_t saved_cur_prot, vm_prot_t max_prot, vm_prot_t saved_max_prot, MAP_T map,
3939*d4514f0bSApple OSS Distributions mach_vm_address_t src_addr)
3940*d4514f0bSApple OSS Distributions {
3941*d4514f0bSApple OSS Distributions if (*kr == KERN_SUCCESS) {
3942*d4514f0bSApple OSS Distributions if (is_fixed(flags)) {
3943*d4514f0bSApple OSS Distributions mach_vm_address_t expected_misalignment = get_expected_remap_misalignment(map, src_addr, flags);
3944*d4514f0bSApple OSS Distributions if (addr != trunc_down_map(map, saved_addr) + expected_misalignment) {
3945*d4514f0bSApple OSS Distributions *kr = OUT_PARAM_BAD;
3946*d4514f0bSApple OSS Distributions }
3947*d4514f0bSApple OSS Distributions }
3948*d4514f0bSApple OSS Distributions } else {
3949*d4514f0bSApple OSS Distributions if ((addr != saved_addr) || (cur_prot != saved_cur_prot) ||
3950*d4514f0bSApple OSS Distributions (max_prot != saved_max_prot)) {
3951*d4514f0bSApple OSS Distributions *kr = OUT_PARAM_BAD;
3952*d4514f0bSApple OSS Distributions }
3953*d4514f0bSApple OSS Distributions }
3954*d4514f0bSApple OSS Distributions }
3955*d4514f0bSApple OSS Distributions
3956*d4514f0bSApple OSS Distributions #if KERNEL
3957*d4514f0bSApple OSS Distributions
3958*d4514f0bSApple OSS Distributions static inline kern_return_t
mach_vm_remap_wrapped_kern(vm_map_t target_task,mach_vm_address_t * target_address,mach_vm_size_t size,mach_vm_offset_t mask,int flags,vm_map_t src_task,mach_vm_address_t src_address,boolean_t copy,vm_prot_t * cur_protection,vm_prot_t * max_protection,vm_inherit_t inheritance)3959*d4514f0bSApple OSS Distributions mach_vm_remap_wrapped_kern(vm_map_t target_task,
3960*d4514f0bSApple OSS Distributions mach_vm_address_t *target_address,
3961*d4514f0bSApple OSS Distributions mach_vm_size_t size,
3962*d4514f0bSApple OSS Distributions mach_vm_offset_t mask,
3963*d4514f0bSApple OSS Distributions int flags,
3964*d4514f0bSApple OSS Distributions vm_map_t src_task,
3965*d4514f0bSApple OSS Distributions mach_vm_address_t src_address,
3966*d4514f0bSApple OSS Distributions boolean_t copy,
3967*d4514f0bSApple OSS Distributions vm_prot_t *cur_protection,
3968*d4514f0bSApple OSS Distributions vm_prot_t *max_protection,
3969*d4514f0bSApple OSS Distributions vm_inherit_t inheritance)
3970*d4514f0bSApple OSS Distributions {
3971*d4514f0bSApple OSS Distributions if (dealloc_would_time_out(*target_address, size, target_task)) {
3972*d4514f0bSApple OSS Distributions return ACCEPTABLE;
3973*d4514f0bSApple OSS Distributions }
3974*d4514f0bSApple OSS Distributions
3975*d4514f0bSApple OSS Distributions mach_vm_address_t saved_addr = *target_address;
3976*d4514f0bSApple OSS Distributions vm_prot_t saved_cur_prot = *cur_protection;
3977*d4514f0bSApple OSS Distributions vm_prot_t saved_max_prot = *max_protection;
3978*d4514f0bSApple OSS Distributions kern_return_t kr = mach_vm_remap(target_task, target_address, size, mask, flags, src_task, src_address, copy, cur_protection, max_protection, inheritance);
3979*d4514f0bSApple OSS Distributions check_mach_vm_remap_outparam_changes(&kr, *target_address, saved_addr, flags,
3980*d4514f0bSApple OSS Distributions *cur_protection, saved_cur_prot, *max_protection, saved_max_prot, target_task, src_address);
3981*d4514f0bSApple OSS Distributions return kr;
3982*d4514f0bSApple OSS Distributions }
IMPL(mach_vm_remap_wrapped_kern)3983*d4514f0bSApple OSS Distributions IMPL(mach_vm_remap_wrapped_kern)
3984*d4514f0bSApple OSS Distributions
3985*d4514f0bSApple OSS Distributions static inline kern_return_t
3986*d4514f0bSApple OSS Distributions mach_vm_remap_new_kernel_wrapped(vm_map_t target_task,
3987*d4514f0bSApple OSS Distributions mach_vm_address_t *target_address,
3988*d4514f0bSApple OSS Distributions mach_vm_size_t size,
3989*d4514f0bSApple OSS Distributions mach_vm_offset_t mask,
3990*d4514f0bSApple OSS Distributions int flags,
3991*d4514f0bSApple OSS Distributions vm_map_t src_task,
3992*d4514f0bSApple OSS Distributions mach_vm_address_t src_address,
3993*d4514f0bSApple OSS Distributions boolean_t copy,
3994*d4514f0bSApple OSS Distributions vm_prot_t *cur_protection,
3995*d4514f0bSApple OSS Distributions vm_prot_t *max_protection,
3996*d4514f0bSApple OSS Distributions vm_inherit_t inheritance)
3997*d4514f0bSApple OSS Distributions {
3998*d4514f0bSApple OSS Distributions if (dealloc_would_time_out(*target_address, size, target_task)) {
3999*d4514f0bSApple OSS Distributions return ACCEPTABLE;
4000*d4514f0bSApple OSS Distributions }
4001*d4514f0bSApple OSS Distributions
4002*d4514f0bSApple OSS Distributions mach_vm_address_t saved_addr = *target_address;
4003*d4514f0bSApple OSS Distributions vm_prot_t saved_cur_prot = *cur_protection;
4004*d4514f0bSApple OSS Distributions vm_prot_t saved_max_prot = *max_protection;
4005*d4514f0bSApple OSS Distributions kern_return_t kr = mach_vm_remap_new_kernel(target_task, target_address, size, mask, FLAGS_AND_TAG(flags, VM_KERN_MEMORY_OSFMK), src_task, src_address, copy, cur_protection, max_protection, inheritance);
4006*d4514f0bSApple OSS Distributions // remap_new sets VM_FLAGS_RETURN_DATA_ADDR
4007*d4514f0bSApple OSS Distributions check_mach_vm_remap_outparam_changes(&kr, *target_address, saved_addr, flags | VM_FLAGS_RETURN_DATA_ADDR,
4008*d4514f0bSApple OSS Distributions *cur_protection, saved_cur_prot, *max_protection, saved_max_prot, target_task, src_address);
4009*d4514f0bSApple OSS Distributions return kr;
4010*d4514f0bSApple OSS Distributions }
4011*d4514f0bSApple OSS Distributions IMPL(mach_vm_remap_new_kernel_wrapped)
4012*d4514f0bSApple OSS Distributions
4013*d4514f0bSApple OSS Distributions #else /* !KERNEL */
4014*d4514f0bSApple OSS Distributions
4015*d4514f0bSApple OSS Distributions static inline kern_return_t
4016*d4514f0bSApple OSS Distributions mach_vm_remap_user(vm_map_t target_task,
4017*d4514f0bSApple OSS Distributions mach_vm_address_t *target_address,
4018*d4514f0bSApple OSS Distributions mach_vm_size_t size,
4019*d4514f0bSApple OSS Distributions mach_vm_offset_t mask,
4020*d4514f0bSApple OSS Distributions int flags,
4021*d4514f0bSApple OSS Distributions vm_map_t src_task,
4022*d4514f0bSApple OSS Distributions mach_vm_address_t src_address,
4023*d4514f0bSApple OSS Distributions boolean_t copy,
4024*d4514f0bSApple OSS Distributions vm_prot_t *cur_protection,
4025*d4514f0bSApple OSS Distributions vm_prot_t *max_protection,
4026*d4514f0bSApple OSS Distributions vm_inherit_t inheritance)
4027*d4514f0bSApple OSS Distributions {
4028*d4514f0bSApple OSS Distributions mach_vm_address_t saved_addr = *target_address;
4029*d4514f0bSApple OSS Distributions vm_prot_t saved_cur_prot = *cur_protection;
4030*d4514f0bSApple OSS Distributions vm_prot_t saved_max_prot = *max_protection;
4031*d4514f0bSApple OSS Distributions kern_return_t kr = mach_vm_remap(target_task, target_address, size, mask, flags, src_task, src_address, copy, cur_protection, max_protection, inheritance);
4032*d4514f0bSApple OSS Distributions check_mach_vm_remap_outparam_changes(&kr, *target_address, saved_addr, flags,
4033*d4514f0bSApple OSS Distributions *cur_protection, saved_cur_prot, *max_protection, saved_max_prot, target_task, src_address);
4034*d4514f0bSApple OSS Distributions return kr;
4035*d4514f0bSApple OSS Distributions }
4036*d4514f0bSApple OSS Distributions IMPL(mach_vm_remap_user)
4037*d4514f0bSApple OSS Distributions
4038*d4514f0bSApple OSS Distributions static inline kern_return_t
4039*d4514f0bSApple OSS Distributions mach_vm_remap_new_user(vm_map_t target_task,
4040*d4514f0bSApple OSS Distributions mach_vm_address_t *target_address,
4041*d4514f0bSApple OSS Distributions mach_vm_size_t size,
4042*d4514f0bSApple OSS Distributions mach_vm_offset_t mask,
4043*d4514f0bSApple OSS Distributions int flags,
4044*d4514f0bSApple OSS Distributions vm_map_t src_task,
4045*d4514f0bSApple OSS Distributions mach_vm_address_t src_address,
4046*d4514f0bSApple OSS Distributions boolean_t copy,
4047*d4514f0bSApple OSS Distributions vm_prot_t *cur_protection,
4048*d4514f0bSApple OSS Distributions vm_prot_t *max_protection,
4049*d4514f0bSApple OSS Distributions vm_inherit_t inheritance)
4050*d4514f0bSApple OSS Distributions {
4051*d4514f0bSApple OSS Distributions mach_vm_address_t saved_addr = *target_address;
4052*d4514f0bSApple OSS Distributions vm_prot_t saved_cur_prot = *cur_protection;
4053*d4514f0bSApple OSS Distributions vm_prot_t saved_max_prot = *max_protection;
4054*d4514f0bSApple OSS Distributions kern_return_t kr = mach_vm_remap_new(target_task, target_address, size, mask, flags, src_task, src_address, copy, cur_protection, max_protection, inheritance);
4055*d4514f0bSApple OSS Distributions // remap_new sets VM_FLAGS_RETURN_DATA_ADDR
4056*d4514f0bSApple OSS Distributions check_mach_vm_remap_outparam_changes(&kr, *target_address, saved_addr, flags | VM_FLAGS_RETURN_DATA_ADDR,
4057*d4514f0bSApple OSS Distributions *cur_protection, saved_cur_prot, *max_protection, saved_max_prot, target_task, src_address);
4058*d4514f0bSApple OSS Distributions return kr;
4059*d4514f0bSApple OSS Distributions }
4060*d4514f0bSApple OSS Distributions IMPL(mach_vm_remap_new_user)
4061*d4514f0bSApple OSS Distributions
4062*d4514f0bSApple OSS Distributions #if TEST_OLD_STYLE_MACH
4063*d4514f0bSApple OSS Distributions static inline kern_return_t
4064*d4514f0bSApple OSS Distributions vm_remap_retyped(vm_map_t target_task,
4065*d4514f0bSApple OSS Distributions mach_vm_address_t *target_address,
4066*d4514f0bSApple OSS Distributions mach_vm_size_t size,
4067*d4514f0bSApple OSS Distributions mach_vm_offset_t mask,
4068*d4514f0bSApple OSS Distributions int flags,
4069*d4514f0bSApple OSS Distributions vm_map_t src_task,
4070*d4514f0bSApple OSS Distributions mach_vm_address_t src_address,
4071*d4514f0bSApple OSS Distributions boolean_t copy,
4072*d4514f0bSApple OSS Distributions vm_prot_t *cur_protection,
4073*d4514f0bSApple OSS Distributions vm_prot_t *max_protection,
4074*d4514f0bSApple OSS Distributions vm_inherit_t inheritance)
4075*d4514f0bSApple OSS Distributions {
4076*d4514f0bSApple OSS Distributions vm_address_t addr = (vm_address_t)*target_address;
4077*d4514f0bSApple OSS Distributions vm_prot_t saved_cur_prot = *cur_protection;
4078*d4514f0bSApple OSS Distributions vm_prot_t saved_max_prot = *max_protection;
4079*d4514f0bSApple OSS Distributions kern_return_t kr = vm_remap(target_task, &addr, (vm_size_t)size, (vm_address_t)mask, flags, src_task, (vm_address_t)src_address, copy, cur_protection, max_protection, inheritance);
4080*d4514f0bSApple OSS Distributions check_mach_vm_remap_outparam_changes(&kr, addr, (vm_address_t) *target_address, flags,
4081*d4514f0bSApple OSS Distributions *cur_protection, saved_cur_prot, *max_protection, saved_max_prot, target_task, src_address);
4082*d4514f0bSApple OSS Distributions *target_address = addr;
4083*d4514f0bSApple OSS Distributions return kr;
4084*d4514f0bSApple OSS Distributions }
4085*d4514f0bSApple OSS Distributions
4086*d4514f0bSApple OSS Distributions IMPL(vm_remap_retyped)
4087*d4514f0bSApple OSS Distributions
4088*d4514f0bSApple OSS Distributions #endif /* TEST_OLD_STYLE_MACH */
4089*d4514f0bSApple OSS Distributions #endif /* !KERNEL */
4090*d4514f0bSApple OSS Distributions
4091*d4514f0bSApple OSS Distributions #undef IMPL
4092*d4514f0bSApple OSS Distributions #undef IMPL_REMAP_FN_SRC_SIZE
4093*d4514f0bSApple OSS Distributions #undef IMPL_REMAP_FN_DST_SIZE
4094*d4514f0bSApple OSS Distributions #undef IMPL_REMAP_FN_SRC_DST_SIZE
4095*d4514f0bSApple OSS Distributions #undef IMPL_REMAP_FN_SRC_SIZE_INHERIT
4096*d4514f0bSApple OSS Distributions #undef IMPL_REMAP_FN_SRC_SIZE_FLAGS
4097*d4514f0bSApple OSS Distributions #undef IMPL_REMAP_FN_PROT_PAIRS
4098*d4514f0bSApple OSS Distributions #undef IMPL_REMAP_FN_HELPER
4099*d4514f0bSApple OSS Distributions
4100*d4514f0bSApple OSS Distributions
4101*d4514f0bSApple OSS Distributions /////////////////////////////////////////////////////
4102*d4514f0bSApple OSS Distributions // Test runners for functions with commonly-used parameter types and setup code.
4103*d4514f0bSApple OSS Distributions
4104*d4514f0bSApple OSS Distributions #define IMPL(NAME, T) \
4105*d4514f0bSApple OSS Distributions /* Test a Mach function */ \
4106*d4514f0bSApple OSS Distributions /* Run each trial with an allocated vm region and start/size parameters that reference it. */ \
4107*d4514f0bSApple OSS Distributions typedef kern_return_t (*NAME ## mach_with_start_size_fn)(MAP_T map, T start, T size); \
4108*d4514f0bSApple OSS Distributions \
4109*d4514f0bSApple OSS Distributions /* ...and the allocation has a specified minimum alignment */ \
4110*d4514f0bSApple OSS Distributions static results_t * __attribute__((used)) \
4111*d4514f0bSApple OSS Distributions test_ ## NAME ## mach_with_allocated_aligned_start_size(NAME ## mach_with_start_size_fn fn, T align_mask, const char *testname) \
4112*d4514f0bSApple OSS Distributions { \
4113*d4514f0bSApple OSS Distributions MAP_T map SMART_MAP; \
4114*d4514f0bSApple OSS Distributions allocation_t base SMART_ALLOCATE_ALIGNED_VM(map, TEST_ALLOC_SIZE, align_mask, VM_PROT_DEFAULT); \
4115*d4514f0bSApple OSS Distributions start_size_trials_t *trials SMART_START_SIZE_TRIALS(base.addr); \
4116*d4514f0bSApple OSS Distributions results_t *results = alloc_results(testname, eSMART_START_SIZE_TRIALS, base.addr, trials->count); \
4117*d4514f0bSApple OSS Distributions \
4118*d4514f0bSApple OSS Distributions for (unsigned i = 0; i < trials->count; i++) { \
4119*d4514f0bSApple OSS Distributions T start = (T)trials->list[i].start; \
4120*d4514f0bSApple OSS Distributions T size = (T)trials->list[i].size; \
4121*d4514f0bSApple OSS Distributions kern_return_t ret = fn(map, start, size); \
4122*d4514f0bSApple OSS Distributions append_result(results, ret, trials->list[i].name); \
4123*d4514f0bSApple OSS Distributions } \
4124*d4514f0bSApple OSS Distributions return results; \
4125*d4514f0bSApple OSS Distributions } \
4126*d4514f0bSApple OSS Distributions \
4127*d4514f0bSApple OSS Distributions /* ...and the allocation gets default alignment */ \
4128*d4514f0bSApple OSS Distributions static results_t * __attribute__((used)) \
4129*d4514f0bSApple OSS Distributions test_ ## NAME ## mach_with_allocated_start_size(NAME ## mach_with_start_size_fn fn, const char *testname) \
4130*d4514f0bSApple OSS Distributions { \
4131*d4514f0bSApple OSS Distributions return test_ ## NAME ## mach_with_allocated_aligned_start_size(fn, 0, testname); \
4132*d4514f0bSApple OSS Distributions } \
4133*d4514f0bSApple OSS Distributions \
4134*d4514f0bSApple OSS Distributions /* Test a Mach function. */ \
4135*d4514f0bSApple OSS Distributions /* Run each trial with an allocated vm region and an addr parameter that reference it. */ \
4136*d4514f0bSApple OSS Distributions typedef kern_return_t (*NAME ## mach_with_addr_fn)(MAP_T map, T addr); \
4137*d4514f0bSApple OSS Distributions \
4138*d4514f0bSApple OSS Distributions static results_t * __attribute__((used)) \
4139*d4514f0bSApple OSS Distributions test_ ## NAME ## mach_with_allocated_addr_of_size_n(NAME ## mach_with_addr_fn fn, size_t obj_size, const char *testname) \
4140*d4514f0bSApple OSS Distributions { \
4141*d4514f0bSApple OSS Distributions MAP_T map SMART_MAP; \
4142*d4514f0bSApple OSS Distributions allocation_t base SMART_ALLOCATE_VM(map, TEST_ALLOC_SIZE, VM_PROT_DEFAULT); \
4143*d4514f0bSApple OSS Distributions addr_trials_t *trials SMART_ADDR_TRIALS(base.addr); \
4144*d4514f0bSApple OSS Distributions /* Do all the addr trials and an additional trial such that obj_size + addr == 0 */ \
4145*d4514f0bSApple OSS Distributions uint64_t trial_args[TRIALSARGUMENTS_SIZE] = {base.addr, obj_size}; \
4146*d4514f0bSApple OSS Distributions results_t *results = alloc_results(testname, eSMART_ADDR_TRIALS, trial_args, TRIALSARGUMENTS_SIZE, trials->count+1); \
4147*d4514f0bSApple OSS Distributions \
4148*d4514f0bSApple OSS Distributions for (unsigned i = 0; i < trials->count; i++) { \
4149*d4514f0bSApple OSS Distributions T addr = (T)trials->list[i].addr; \
4150*d4514f0bSApple OSS Distributions kern_return_t ret = fn(map, addr); \
4151*d4514f0bSApple OSS Distributions append_result(results, ret, trials->list[i].name); \
4152*d4514f0bSApple OSS Distributions } \
4153*d4514f0bSApple OSS Distributions kern_return_t ret = fn(map, - ((T) obj_size)); \
4154*d4514f0bSApple OSS Distributions char *trial_desc; \
4155*d4514f0bSApple OSS Distributions kasprintf(&trial_desc, "addr: -0x%lx", obj_size); \
4156*d4514f0bSApple OSS Distributions append_result(results, ret, trial_desc); \
4157*d4514f0bSApple OSS Distributions kfree_str(trial_desc); \
4158*d4514f0bSApple OSS Distributions return results; \
4159*d4514f0bSApple OSS Distributions } \
4160*d4514f0bSApple OSS Distributions \
4161*d4514f0bSApple OSS Distributions /* Test a Mach function. */ \
4162*d4514f0bSApple OSS Distributions /* Run each trial with an allocated vm region and an addr parameter that reference it. */ \
4163*d4514f0bSApple OSS Distributions typedef kern_return_t (*NAME ## mach_with_addr_fn)(MAP_T map, T addr); \
4164*d4514f0bSApple OSS Distributions \
4165*d4514f0bSApple OSS Distributions static results_t * __attribute__((used)) \
4166*d4514f0bSApple OSS Distributions test_ ## NAME ## mach_with_allocated_addr(NAME ## mach_with_addr_fn fn, const char *testname) \
4167*d4514f0bSApple OSS Distributions { \
4168*d4514f0bSApple OSS Distributions MAP_T map SMART_MAP; \
4169*d4514f0bSApple OSS Distributions allocation_t base SMART_ALLOCATE_VM(map, TEST_ALLOC_SIZE, VM_PROT_DEFAULT); \
4170*d4514f0bSApple OSS Distributions addr_trials_t *trials SMART_ADDR_TRIALS(base.addr); \
4171*d4514f0bSApple OSS Distributions results_t *results = alloc_results(testname, eSMART_ADDR_TRIALS, base.addr, trials->count); \
4172*d4514f0bSApple OSS Distributions \
4173*d4514f0bSApple OSS Distributions for (unsigned i = 0; i < trials->count; i++) { \
4174*d4514f0bSApple OSS Distributions T addr = (T)trials->list[i].addr; \
4175*d4514f0bSApple OSS Distributions kern_return_t ret = fn(map, addr); \
4176*d4514f0bSApple OSS Distributions append_result(results, ret, trials->list[i].name); \
4177*d4514f0bSApple OSS Distributions } \
4178*d4514f0bSApple OSS Distributions return results; \
4179*d4514f0bSApple OSS Distributions } \
4180*d4514f0bSApple OSS Distributions \
4181*d4514f0bSApple OSS Distributions static results_t * __attribute__((used)) \
4182*d4514f0bSApple OSS Distributions test_ ## NAME ## mach_with_allocated_purgeable_addr(NAME ## mach_with_addr_fn fn, const char *testname) \
4183*d4514f0bSApple OSS Distributions { \
4184*d4514f0bSApple OSS Distributions MAP_T map SMART_MAP; \
4185*d4514f0bSApple OSS Distributions allocation_t base SMART_ALLOCATE_PURGEABLE_VM(map, TEST_ALLOC_SIZE, VM_PROT_DEFAULT); \
4186*d4514f0bSApple OSS Distributions addr_trials_t *trials SMART_ADDR_TRIALS(base.addr); \
4187*d4514f0bSApple OSS Distributions results_t *results = alloc_results(testname, eSMART_ADDR_TRIALS, base.addr, trials->count); \
4188*d4514f0bSApple OSS Distributions \
4189*d4514f0bSApple OSS Distributions for (unsigned i = 0; i < trials->count; i++) { \
4190*d4514f0bSApple OSS Distributions T addr = (T)trials->list[i].addr; \
4191*d4514f0bSApple OSS Distributions kern_return_t ret = fn(map, addr); \
4192*d4514f0bSApple OSS Distributions append_result(results, ret, trials->list[i].name); \
4193*d4514f0bSApple OSS Distributions } \
4194*d4514f0bSApple OSS Distributions return results; \
4195*d4514f0bSApple OSS Distributions } \
4196*d4514f0bSApple OSS Distributions \
4197*d4514f0bSApple OSS Distributions /* Test a Mach function. */ \
4198*d4514f0bSApple OSS Distributions /* Run each trial with a size parameter. */ \
4199*d4514f0bSApple OSS Distributions typedef kern_return_t (*NAME ## mach_with_size_fn)(MAP_T map, T size); \
4200*d4514f0bSApple OSS Distributions \
4201*d4514f0bSApple OSS Distributions static results_t * __attribute__((used)) \
4202*d4514f0bSApple OSS Distributions test_ ## NAME ## mach_with_size(NAME ## mach_with_size_fn fn, const char *testname) \
4203*d4514f0bSApple OSS Distributions { \
4204*d4514f0bSApple OSS Distributions MAP_T map SMART_MAP; \
4205*d4514f0bSApple OSS Distributions size_trials_t *trials SMART_SIZE_TRIALS(); \
4206*d4514f0bSApple OSS Distributions results_t *results = alloc_results(testname, eSMART_SIZE_TRIALS, trials->count); \
4207*d4514f0bSApple OSS Distributions \
4208*d4514f0bSApple OSS Distributions for (unsigned i = 0; i < trials->count; i++) { \
4209*d4514f0bSApple OSS Distributions T size = (T)trials->list[i].size; \
4210*d4514f0bSApple OSS Distributions kern_return_t ret = fn(map, size); \
4211*d4514f0bSApple OSS Distributions append_result(results, ret, trials->list[i].name); \
4212*d4514f0bSApple OSS Distributions } \
4213*d4514f0bSApple OSS Distributions return results; \
4214*d4514f0bSApple OSS Distributions } \
4215*d4514f0bSApple OSS Distributions \
4216*d4514f0bSApple OSS Distributions /* Test a Mach function. */ \
4217*d4514f0bSApple OSS Distributions /* Run each trial with a size parameter. */ \
4218*d4514f0bSApple OSS Distributions typedef kern_return_t (*NAME ## mach_with_start_size_offset_object_fn)(MAP_T map, T addr, T size, T offset, T obj_size); \
4219*d4514f0bSApple OSS Distributions \
4220*d4514f0bSApple OSS Distributions static results_t * __attribute__((used)) \
4221*d4514f0bSApple OSS Distributions test_ ## NAME ## mach_with_allocated_start_size_offset_object(NAME ## mach_with_start_size_offset_object_fn fn, const char *testname) \
4222*d4514f0bSApple OSS Distributions { \
4223*d4514f0bSApple OSS Distributions MAP_T map SMART_MAP; \
4224*d4514f0bSApple OSS Distributions allocation_t base SMART_ALLOCATE_VM(map, TEST_ALLOC_SIZE, VM_PROT_DEFAULT); \
4225*d4514f0bSApple OSS Distributions start_size_offset_object_trials_t *trials SMART_START_SIZE_OFFSET_OBJECT_TRIALS(); \
4226*d4514f0bSApple OSS Distributions results_t *results = alloc_results(testname, eSMART_START_SIZE_OFFSET_OBJECT_TRIALS, trials->count); \
4227*d4514f0bSApple OSS Distributions \
4228*d4514f0bSApple OSS Distributions for (unsigned i = 0; i < trials->count; i++) { \
4229*d4514f0bSApple OSS Distributions start_size_offset_object_trial_t trial = slide_trial(trials->list[i], base.addr); \
4230*d4514f0bSApple OSS Distributions T start = (T)trial.start; \
4231*d4514f0bSApple OSS Distributions T size = (T)trial.size; \
4232*d4514f0bSApple OSS Distributions T offset = (T)trial.offset; \
4233*d4514f0bSApple OSS Distributions T obj_size = (T)trial.obj_size; \
4234*d4514f0bSApple OSS Distributions kern_return_t ret = fn(map, start, size, offset, obj_size); \
4235*d4514f0bSApple OSS Distributions append_result(results, ret, trials->list[i].name); \
4236*d4514f0bSApple OSS Distributions } \
4237*d4514f0bSApple OSS Distributions return results; \
4238*d4514f0bSApple OSS Distributions } \
4239*d4514f0bSApple OSS Distributions /* Test a Mach function. */ \
4240*d4514f0bSApple OSS Distributions /* Run each trial with a size parameter. */ \
4241*d4514f0bSApple OSS Distributions typedef kern_return_t (*NAME ## mach_with_start_size_offset_fn)(MAP_T map, T addr, T size, T offset, T obj_size); \
4242*d4514f0bSApple OSS Distributions \
4243*d4514f0bSApple OSS Distributions static results_t * __attribute__((used)) \
4244*d4514f0bSApple OSS Distributions test_ ## NAME ## mach_with_allocated_start_size_offset(NAME ## mach_with_start_size_offset_fn fn, const char *testname) \
4245*d4514f0bSApple OSS Distributions { \
4246*d4514f0bSApple OSS Distributions MAP_T map SMART_MAP; \
4247*d4514f0bSApple OSS Distributions allocation_t base SMART_ALLOCATE_VM(map, TEST_ALLOC_SIZE, VM_PROT_DEFAULT); \
4248*d4514f0bSApple OSS Distributions start_size_offset_trials_t *trials SMART_START_SIZE_OFFSET_TRIALS(); \
4249*d4514f0bSApple OSS Distributions results_t *results = alloc_results(testname, eSMART_START_SIZE_OFFSET_TRIALS, trials->count); \
4250*d4514f0bSApple OSS Distributions \
4251*d4514f0bSApple OSS Distributions for (unsigned i = 0; i < trials->count; i++) { \
4252*d4514f0bSApple OSS Distributions start_size_offset_trial_t trial = slide_trial(trials->list[i], base.addr); \
4253*d4514f0bSApple OSS Distributions T start = (T)trial.start; \
4254*d4514f0bSApple OSS Distributions T size = (T)trial.size; \
4255*d4514f0bSApple OSS Distributions T offset = (T)trial.offset; \
4256*d4514f0bSApple OSS Distributions kern_return_t ret = fn(map, start, size, offset, 1); \
4257*d4514f0bSApple OSS Distributions append_result(results, ret, trials->list[i].name); \
4258*d4514f0bSApple OSS Distributions } \
4259*d4514f0bSApple OSS Distributions return results; \
4260*d4514f0bSApple OSS Distributions } \
4261*d4514f0bSApple OSS Distributions \
4262*d4514f0bSApple OSS Distributions /* Test a Mach function. */ \
4263*d4514f0bSApple OSS Distributions /* Run each trial with an allocated vm region and a set of mmap flags. */ \
4264*d4514f0bSApple OSS Distributions typedef kern_return_t (*NAME ## mach_with_allocated_mmap_flags_fn)(MAP_T map, T addr, T size, int flags); \
4265*d4514f0bSApple OSS Distributions \
4266*d4514f0bSApple OSS Distributions static results_t * __attribute__((used)) \
4267*d4514f0bSApple OSS Distributions test_ ## NAME ## mach_with_allocated_mmap_flags(NAME ## mach_with_allocated_mmap_flags_fn fn, const char *testname) \
4268*d4514f0bSApple OSS Distributions { \
4269*d4514f0bSApple OSS Distributions MAP_T map SMART_MAP; \
4270*d4514f0bSApple OSS Distributions allocation_t base SMART_ALLOCATE_VM(map, TEST_ALLOC_SIZE, VM_PROT_DEFAULT); \
4271*d4514f0bSApple OSS Distributions mmap_flags_trials_t *trials SMART_MMAP_FLAGS_TRIALS(); \
4272*d4514f0bSApple OSS Distributions results_t *results = alloc_results(testname, eSMART_MMAP_FLAGS_TRIALS, trials->count); \
4273*d4514f0bSApple OSS Distributions \
4274*d4514f0bSApple OSS Distributions for (unsigned i = 0; i < trials->count; i++) { \
4275*d4514f0bSApple OSS Distributions int flags = trials->list[i].flags; \
4276*d4514f0bSApple OSS Distributions kern_return_t ret = fn(map, (T)base.addr, (T)base.size, flags); \
4277*d4514f0bSApple OSS Distributions append_result(results, ret, trials->list[i].name); \
4278*d4514f0bSApple OSS Distributions } \
4279*d4514f0bSApple OSS Distributions return results; \
4280*d4514f0bSApple OSS Distributions } \
4281*d4514f0bSApple OSS Distributions \
4282*d4514f0bSApple OSS Distributions /* Test a Mach function. */ \
4283*d4514f0bSApple OSS Distributions /* Run each trial with an allocated vm region and a generic 32 bit flag. */ \
4284*d4514f0bSApple OSS Distributions typedef kern_return_t (*NAME ## mach_with_allocated_generic_flag)(MAP_T map, T addr, T size, int flag); \
4285*d4514f0bSApple OSS Distributions \
4286*d4514f0bSApple OSS Distributions static results_t * __attribute__((used)) \
4287*d4514f0bSApple OSS Distributions test_ ## NAME ## mach_with_allocated_generic_flag(NAME ## mach_with_allocated_generic_flag fn, const char *testname) \
4288*d4514f0bSApple OSS Distributions { \
4289*d4514f0bSApple OSS Distributions MAP_T map SMART_MAP; \
4290*d4514f0bSApple OSS Distributions allocation_t base SMART_ALLOCATE_VM(map, TEST_ALLOC_SIZE, VM_PROT_DEFAULT); \
4291*d4514f0bSApple OSS Distributions generic_flag_trials_t *trials SMART_GENERIC_FLAG_TRIALS(); \
4292*d4514f0bSApple OSS Distributions results_t *results = alloc_results(testname, eSMART_GENERIC_FLAG_TRIALS, trials->count); \
4293*d4514f0bSApple OSS Distributions \
4294*d4514f0bSApple OSS Distributions for (unsigned i = 0; i < trials->count; i++) { \
4295*d4514f0bSApple OSS Distributions int flag = trials->list[i].flag; \
4296*d4514f0bSApple OSS Distributions kern_return_t ret = fn(map, (T)base.addr, (T)base.size, flag); \
4297*d4514f0bSApple OSS Distributions append_result(results, ret, trials->list[i].name); \
4298*d4514f0bSApple OSS Distributions } \
4299*d4514f0bSApple OSS Distributions return results; \
4300*d4514f0bSApple OSS Distributions } \
4301*d4514f0bSApple OSS Distributions \
4302*d4514f0bSApple OSS Distributions /* Test a Mach function. */ \
4303*d4514f0bSApple OSS Distributions /* Run each trial with a vm_prot_t. */ \
4304*d4514f0bSApple OSS Distributions typedef kern_return_t (*NAME ## mach_with_prot_fn)(MAP_T map, T size, vm_prot_t prot); \
4305*d4514f0bSApple OSS Distributions \
4306*d4514f0bSApple OSS Distributions static results_t * __attribute__((used)) \
4307*d4514f0bSApple OSS Distributions test_ ## NAME ## mach_vm_prot(NAME ## mach_with_prot_fn fn, const char *testname) \
4308*d4514f0bSApple OSS Distributions { \
4309*d4514f0bSApple OSS Distributions MAP_T map SMART_MAP; \
4310*d4514f0bSApple OSS Distributions vm_prot_trials_t *trials SMART_VM_PROT_TRIALS(); \
4311*d4514f0bSApple OSS Distributions results_t *results = alloc_results(testname, eSMART_VM_PROT_TRIALS, trials->count); \
4312*d4514f0bSApple OSS Distributions \
4313*d4514f0bSApple OSS Distributions for (unsigned i = 0; i < trials->count; i++) { \
4314*d4514f0bSApple OSS Distributions kern_return_t ret = fn(map, TEST_ALLOC_SIZE, trials->list[i].prot); \
4315*d4514f0bSApple OSS Distributions append_result(results, ret, trials->list[i].name); \
4316*d4514f0bSApple OSS Distributions } \
4317*d4514f0bSApple OSS Distributions return results; \
4318*d4514f0bSApple OSS Distributions } \
4319*d4514f0bSApple OSS Distributions \
4320*d4514f0bSApple OSS Distributions /* Test a Mach function. */ \
4321*d4514f0bSApple OSS Distributions /* Run each trial with a pair of vm_prot_t's. */ \
4322*d4514f0bSApple OSS Distributions typedef kern_return_t (*NAME ## mach_with_prot_pair_fn)(MAP_T map, vm_prot_t cur, vm_prot_t max); \
4323*d4514f0bSApple OSS Distributions \
4324*d4514f0bSApple OSS Distributions static results_t * __attribute__((used)) \
4325*d4514f0bSApple OSS Distributions test_ ## NAME ## mach_vm_prot_pair(NAME ## mach_with_prot_pair_fn fn, const char *testname) \
4326*d4514f0bSApple OSS Distributions { \
4327*d4514f0bSApple OSS Distributions MAP_T map SMART_MAP; \
4328*d4514f0bSApple OSS Distributions vm_prot_pair_trials_t *trials SMART_VM_PROT_PAIR_TRIALS(); \
4329*d4514f0bSApple OSS Distributions results_t *results = alloc_results(testname, eSMART_VM_PROT_PAIR_TRIALS, trials->count); \
4330*d4514f0bSApple OSS Distributions \
4331*d4514f0bSApple OSS Distributions for (unsigned i = 0; i < trials->count; i++) { \
4332*d4514f0bSApple OSS Distributions kern_return_t ret = fn(map, trials->list[i].cur, trials->list[i].max); \
4333*d4514f0bSApple OSS Distributions append_result(results, ret, trials->list[i].name); \
4334*d4514f0bSApple OSS Distributions } \
4335*d4514f0bSApple OSS Distributions return results; \
4336*d4514f0bSApple OSS Distributions } \
4337*d4514f0bSApple OSS Distributions \
4338*d4514f0bSApple OSS Distributions /* Test a Mach function. */ \
4339*d4514f0bSApple OSS Distributions /* Run each trial with a pair of vm_prot_t's. */ \
4340*d4514f0bSApple OSS Distributions typedef kern_return_t (*NAME ## mach_with_allocated_prot_pair_fn)(MAP_T map, T addr, T size, vm_prot_t cur, vm_prot_t max); \
4341*d4514f0bSApple OSS Distributions \
4342*d4514f0bSApple OSS Distributions static results_t * __attribute__((used)) \
4343*d4514f0bSApple OSS Distributions test_ ## NAME ## mach_with_allocated_vm_prot_pair(NAME ## mach_with_allocated_prot_pair_fn fn, const char *testname) \
4344*d4514f0bSApple OSS Distributions { \
4345*d4514f0bSApple OSS Distributions MAP_T map SMART_MAP; \
4346*d4514f0bSApple OSS Distributions allocation_t base SMART_ALLOCATE_VM(map, TEST_ALLOC_SIZE, VM_PROT_DEFAULT); \
4347*d4514f0bSApple OSS Distributions vm_prot_pair_trials_t *trials SMART_VM_PROT_PAIR_TRIALS(); \
4348*d4514f0bSApple OSS Distributions results_t *results = alloc_results(testname, eSMART_VM_PROT_PAIR_TRIALS, trials->count); \
4349*d4514f0bSApple OSS Distributions \
4350*d4514f0bSApple OSS Distributions for (unsigned i = 0; i < trials->count; i++) { \
4351*d4514f0bSApple OSS Distributions kern_return_t ret = fn(map, (T)base.addr, (T)base.size, trials->list[i].cur, trials->list[i].max); \
4352*d4514f0bSApple OSS Distributions append_result(results, ret, trials->list[i].name); \
4353*d4514f0bSApple OSS Distributions } \
4354*d4514f0bSApple OSS Distributions return results; \
4355*d4514f0bSApple OSS Distributions } \
4356*d4514f0bSApple OSS Distributions \
4357*d4514f0bSApple OSS Distributions /* Test a Mach function. */ \
4358*d4514f0bSApple OSS Distributions /* Run each trial with an allocated vm region and a vm_prot_t. */ \
4359*d4514f0bSApple OSS Distributions typedef kern_return_t (*NAME ## mach_with_allocated_prot_fn)(MAP_T map, T addr, T size, vm_prot_t prot); \
4360*d4514f0bSApple OSS Distributions \
4361*d4514f0bSApple OSS Distributions static results_t * __attribute__((used)) \
4362*d4514f0bSApple OSS Distributions test_ ## NAME ## mach_with_allocated_vm_prot_t(NAME ## mach_with_allocated_prot_fn fn, const char *testname) \
4363*d4514f0bSApple OSS Distributions { \
4364*d4514f0bSApple OSS Distributions MAP_T map SMART_MAP; \
4365*d4514f0bSApple OSS Distributions allocation_t base SMART_ALLOCATE_VM(map, TEST_ALLOC_SIZE, VM_PROT_DEFAULT); \
4366*d4514f0bSApple OSS Distributions vm_prot_trials_t *trials SMART_VM_PROT_TRIALS(); \
4367*d4514f0bSApple OSS Distributions results_t *results = alloc_results(testname, eSMART_VM_PROT_TRIALS, trials->count); \
4368*d4514f0bSApple OSS Distributions \
4369*d4514f0bSApple OSS Distributions for (unsigned i = 0; i < trials->count; i++) { \
4370*d4514f0bSApple OSS Distributions vm_prot_t prot = trials->list[i].prot; \
4371*d4514f0bSApple OSS Distributions kern_return_t ret = fn(map, (T)base.addr, (T)base.size, prot); \
4372*d4514f0bSApple OSS Distributions append_result(results, ret, trials->list[i].name); \
4373*d4514f0bSApple OSS Distributions } \
4374*d4514f0bSApple OSS Distributions return results; \
4375*d4514f0bSApple OSS Distributions } \
4376*d4514f0bSApple OSS Distributions \
4377*d4514f0bSApple OSS Distributions /* Test a Mach function. */ \
4378*d4514f0bSApple OSS Distributions /* Run each trial with a ledger flag. */ \
4379*d4514f0bSApple OSS Distributions typedef kern_return_t (*NAME ## mach_ledger_flag_fn)(MAP_T map, int ledger_flag); \
4380*d4514f0bSApple OSS Distributions \
4381*d4514f0bSApple OSS Distributions static results_t * __attribute__((used)) \
4382*d4514f0bSApple OSS Distributions test_ ## NAME ## mach_with_ledger_flag(NAME ## mach_ledger_flag_fn fn, const char *testname) \
4383*d4514f0bSApple OSS Distributions { \
4384*d4514f0bSApple OSS Distributions MAP_T map SMART_MAP; \
4385*d4514f0bSApple OSS Distributions ledger_flag_trials_t *trials SMART_LEDGER_FLAG_TRIALS(); \
4386*d4514f0bSApple OSS Distributions results_t *results = alloc_results(testname, eSMART_LEDGER_FLAG_TRIALS, trials->count); \
4387*d4514f0bSApple OSS Distributions \
4388*d4514f0bSApple OSS Distributions for (unsigned i = 0; i < trials->count; i++) { \
4389*d4514f0bSApple OSS Distributions kern_return_t ret = fn(map, trials->list[i].flag); \
4390*d4514f0bSApple OSS Distributions append_result(results, ret, trials->list[i].name); \
4391*d4514f0bSApple OSS Distributions } \
4392*d4514f0bSApple OSS Distributions return results; \
4393*d4514f0bSApple OSS Distributions } \
4394*d4514f0bSApple OSS Distributions /* Test a Mach function. */ \
4395*d4514f0bSApple OSS Distributions /* Run each trial with a ledger tag. */ \
4396*d4514f0bSApple OSS Distributions typedef kern_return_t (*NAME ## mach_ledger_tag_fn)(MAP_T map, int ledger_tag); \
4397*d4514f0bSApple OSS Distributions \
4398*d4514f0bSApple OSS Distributions static results_t * __attribute__((used)) \
4399*d4514f0bSApple OSS Distributions test_ ## NAME ## mach_with_ledger_tag(NAME ## mach_ledger_tag_fn fn, const char *testname) \
4400*d4514f0bSApple OSS Distributions { \
4401*d4514f0bSApple OSS Distributions MAP_T map SMART_MAP; \
4402*d4514f0bSApple OSS Distributions ledger_tag_trials_t *trials SMART_LEDGER_TAG_TRIALS(); \
4403*d4514f0bSApple OSS Distributions results_t *results = alloc_results(testname, eSMART_LEDGER_TAG_TRIALS, trials->count); \
4404*d4514f0bSApple OSS Distributions \
4405*d4514f0bSApple OSS Distributions for (unsigned i = 0; i < trials->count; i++) { \
4406*d4514f0bSApple OSS Distributions kern_return_t ret = fn(map, trials->list[i].tag); \
4407*d4514f0bSApple OSS Distributions append_result(results, ret, trials->list[i].name); \
4408*d4514f0bSApple OSS Distributions } \
4409*d4514f0bSApple OSS Distributions return results; \
4410*d4514f0bSApple OSS Distributions } \
4411*d4514f0bSApple OSS Distributions \
4412*d4514f0bSApple OSS Distributions /* Test a Mach function. */ \
4413*d4514f0bSApple OSS Distributions /* Run each trial with an allocated region and a vm_inherit_t. */ \
4414*d4514f0bSApple OSS Distributions typedef kern_return_t (*NAME ## mach_inherit_fn)(MAP_T map, T addr, T size, vm_inherit_t inherit); \
4415*d4514f0bSApple OSS Distributions \
4416*d4514f0bSApple OSS Distributions static results_t * __attribute__((used)) \
4417*d4514f0bSApple OSS Distributions test_ ## NAME ## mach_with_allocated_vm_inherit_t(NAME ## mach_inherit_fn fn, const char * testname) { \
4418*d4514f0bSApple OSS Distributions MAP_T map SMART_MAP; \
4419*d4514f0bSApple OSS Distributions allocation_t base SMART_ALLOCATE_VM(map, TEST_ALLOC_SIZE, VM_PROT_DEFAULT); \
4420*d4514f0bSApple OSS Distributions vm_inherit_trials_t *trials SMART_VM_INHERIT_TRIALS(); \
4421*d4514f0bSApple OSS Distributions results_t *results = alloc_results(testname, eSMART_VM_INHERIT_TRIALS, trials->count); \
4422*d4514f0bSApple OSS Distributions \
4423*d4514f0bSApple OSS Distributions for (unsigned i = 0; i < trials->count; i++) { \
4424*d4514f0bSApple OSS Distributions vm_inherit_trial_t trial = trials->list[i]; \
4425*d4514f0bSApple OSS Distributions int ret = fn(map, (T)base.addr, (T)base.size, trial.value); \
4426*d4514f0bSApple OSS Distributions append_result(results, ret, trial.name); \
4427*d4514f0bSApple OSS Distributions } \
4428*d4514f0bSApple OSS Distributions return results; \
4429*d4514f0bSApple OSS Distributions } \
4430*d4514f0bSApple OSS Distributions /* Test a Mach function. */ \
4431*d4514f0bSApple OSS Distributions /* Run each trial with an allocated vm region and a vm_prot_t. */ \
4432*d4514f0bSApple OSS Distributions typedef kern_return_t (*NAME ## with_start_end_fn)(MAP_T map, T addr, T end); \
4433*d4514f0bSApple OSS Distributions \
4434*d4514f0bSApple OSS Distributions static results_t * __attribute__((used)) \
4435*d4514f0bSApple OSS Distributions test_ ## NAME ## mach_with_allocated_start_end(NAME ## with_start_end_fn fn, const char *testname) \
4436*d4514f0bSApple OSS Distributions { \
4437*d4514f0bSApple OSS Distributions MAP_T map SMART_MAP; \
4438*d4514f0bSApple OSS Distributions allocation_t base SMART_ALLOCATE_VM(map, TEST_ALLOC_SIZE, VM_PROT_DEFAULT); \
4439*d4514f0bSApple OSS Distributions start_size_trials_t *trials SMART_START_SIZE_TRIALS(base.addr); \
4440*d4514f0bSApple OSS Distributions results_t *results = alloc_results(testname, eSMART_START_SIZE_TRIALS, base.addr, trials->count); \
4441*d4514f0bSApple OSS Distributions \
4442*d4514f0bSApple OSS Distributions for (unsigned i = 0; i < trials->count; i++) { \
4443*d4514f0bSApple OSS Distributions T start = (T)trials->list[i].start; \
4444*d4514f0bSApple OSS Distributions T size = (T)trials->list[i].size; \
4445*d4514f0bSApple OSS Distributions kern_return_t ret = fn(map, start, start + size); \
4446*d4514f0bSApple OSS Distributions append_result(results, ret, trials->list[i].name); \
4447*d4514f0bSApple OSS Distributions } \
4448*d4514f0bSApple OSS Distributions return results; \
4449*d4514f0bSApple OSS Distributions } \
4450*d4514f0bSApple OSS Distributions /* Test a Mach function. */ \
4451*d4514f0bSApple OSS Distributions /* Run each trial with an allocated vm region and a vm_prot_t. */ \
4452*d4514f0bSApple OSS Distributions typedef kern_return_t (*NAME ## with_tag_fn)(MAP_T map, T addr, T end, vm_tag_t tag); \
4453*d4514f0bSApple OSS Distributions \
4454*d4514f0bSApple OSS Distributions static results_t * __attribute__((used)) \
4455*d4514f0bSApple OSS Distributions test_ ## NAME ## mach_with_allocated_tag(NAME ## with_tag_fn fn, const char *testname) \
4456*d4514f0bSApple OSS Distributions { \
4457*d4514f0bSApple OSS Distributions MAP_T map SMART_MAP; \
4458*d4514f0bSApple OSS Distributions allocation_t base SMART_ALLOCATE_VM(map, TEST_ALLOC_SIZE, VM_PROT_DEFAULT); \
4459*d4514f0bSApple OSS Distributions vm_tag_trials_t *trials SMART_VM_TAG_TRIALS(); \
4460*d4514f0bSApple OSS Distributions results_t *results = alloc_results(testname, eSMART_VM_TAG_TRIALS, trials->count); \
4461*d4514f0bSApple OSS Distributions \
4462*d4514f0bSApple OSS Distributions for (unsigned i = 0; i < trials->count; i++) { \
4463*d4514f0bSApple OSS Distributions kern_return_t ret = fn(map, (T)base.addr, (T)(base.addr + base.size), trials->list[i].tag); \
4464*d4514f0bSApple OSS Distributions append_result(results, ret, trials->list[i].name); \
4465*d4514f0bSApple OSS Distributions } \
4466*d4514f0bSApple OSS Distributions return results; \
4467*d4514f0bSApple OSS Distributions } \
4468*d4514f0bSApple OSS Distributions /* Test a Mach function. */ \
4469*d4514f0bSApple OSS Distributions /* Run each trial with an allocated region and a vm_behavior_t. */ \
4470*d4514f0bSApple OSS Distributions typedef kern_return_t (*NAME ## mach_behavior_fn)(MAP_T map, T addr, T size, vm_behavior_t behavior); \
4471*d4514f0bSApple OSS Distributions \
4472*d4514f0bSApple OSS Distributions static results_t * __attribute__((used)) \
4473*d4514f0bSApple OSS Distributions test_ ## NAME ## mach_with_allocated_aligned_vm_behavior_t(NAME ## mach_behavior_fn fn, mach_vm_size_t align_mask, const char * testname) { \
4474*d4514f0bSApple OSS Distributions MAP_T map SMART_MAP; \
4475*d4514f0bSApple OSS Distributions allocation_t base SMART_ALLOCATE_ALIGNED_VM(map, TEST_ALLOC_SIZE, align_mask, VM_PROT_DEFAULT); \
4476*d4514f0bSApple OSS Distributions vm_behavior_trials_t *trials SMART_VM_BEHAVIOR_TRIALS(); \
4477*d4514f0bSApple OSS Distributions results_t *results = alloc_results(testname, eSMART_VM_BEHAVIOR_TRIALS, trials->count); \
4478*d4514f0bSApple OSS Distributions \
4479*d4514f0bSApple OSS Distributions for (unsigned i = 0; i < trials->count; i++) { \
4480*d4514f0bSApple OSS Distributions vm_behavior_trial_t trial = trials->list[i]; \
4481*d4514f0bSApple OSS Distributions int ret = fn(map, (T)base.addr, (T)base.size, trial.value); \
4482*d4514f0bSApple OSS Distributions append_result(results, ret, trial.name); \
4483*d4514f0bSApple OSS Distributions } \
4484*d4514f0bSApple OSS Distributions return results; \
4485*d4514f0bSApple OSS Distributions } \
4486*d4514f0bSApple OSS Distributions \
4487*d4514f0bSApple OSS Distributions static results_t * __attribute__((used)) \
4488*d4514f0bSApple OSS Distributions test_ ## NAME ## mach_with_allocated_vm_behavior_t(NAME ## mach_behavior_fn fn, const char * testname) { \
4489*d4514f0bSApple OSS Distributions return test_ ## NAME ## mach_with_allocated_aligned_vm_behavior_t(fn, 0, testname); \
4490*d4514f0bSApple OSS Distributions } \
4491*d4514f0bSApple OSS Distributions \
4492*d4514f0bSApple OSS Distributions /* Test a Mach function. */ \
4493*d4514f0bSApple OSS Distributions /* Run each trial with an allocated region and a vm_sync_t. */ \
4494*d4514f0bSApple OSS Distributions typedef kern_return_t (*NAME ## mach_sync_fn)(MAP_T map, T addr, T size, vm_sync_t behavior); \
4495*d4514f0bSApple OSS Distributions \
4496*d4514f0bSApple OSS Distributions static results_t * __attribute__((used)) \
4497*d4514f0bSApple OSS Distributions test_ ## NAME ## mach_with_allocated_vm_sync_t(NAME ## mach_sync_fn fn, const char * testname) { \
4498*d4514f0bSApple OSS Distributions MAP_T map SMART_MAP; \
4499*d4514f0bSApple OSS Distributions allocation_t base SMART_ALLOCATE_VM(map, TEST_ALLOC_SIZE, VM_PROT_DEFAULT); \
4500*d4514f0bSApple OSS Distributions vm_sync_trials_t *trials SMART_VM_SYNC_TRIALS(); \
4501*d4514f0bSApple OSS Distributions results_t *results = alloc_results(testname, eSMART_VM_SYNC_TRIALS, trials->count); \
4502*d4514f0bSApple OSS Distributions \
4503*d4514f0bSApple OSS Distributions for (unsigned i = 0; i < trials->count; i++) { \
4504*d4514f0bSApple OSS Distributions vm_sync_trial_t trial = trials->list[i]; \
4505*d4514f0bSApple OSS Distributions int ret = fn(map, (T)base.addr, (T)base.size, trial.value); \
4506*d4514f0bSApple OSS Distributions append_result(results, ret, trial.name); \
4507*d4514f0bSApple OSS Distributions } \
4508*d4514f0bSApple OSS Distributions return results; \
4509*d4514f0bSApple OSS Distributions } \
4510*d4514f0bSApple OSS Distributions /* Test a Mach function. */ \
4511*d4514f0bSApple OSS Distributions /* Run each trial with an allocated region and a vm_machine_attribute_t. */ \
4512*d4514f0bSApple OSS Distributions typedef kern_return_t (*NAME ## mach_attribute_fn)(MAP_T map, T addr, T size, vm_machine_attribute_t attr); \
4513*d4514f0bSApple OSS Distributions \
4514*d4514f0bSApple OSS Distributions static results_t * __attribute__((used)) \
4515*d4514f0bSApple OSS Distributions test_ ## NAME ## mach_with_allocated_vm_machine_attribute_t(NAME ## mach_attribute_fn fn, const char * testname) { \
4516*d4514f0bSApple OSS Distributions MAP_T map SMART_MAP; \
4517*d4514f0bSApple OSS Distributions allocation_t base SMART_ALLOCATE_VM(map, TEST_ALLOC_SIZE, VM_PROT_DEFAULT); \
4518*d4514f0bSApple OSS Distributions vm_machine_attribute_trials_t *trials SMART_VM_MACHINE_ATTRIBUTE_TRIALS(); \
4519*d4514f0bSApple OSS Distributions results_t *results = alloc_results(testname, eSMART_VM_MACHINE_ATTRIBUTE_TRIALS, trials->count); \
4520*d4514f0bSApple OSS Distributions \
4521*d4514f0bSApple OSS Distributions for (unsigned i = 0; i < trials->count; i++) { \
4522*d4514f0bSApple OSS Distributions vm_machine_attribute_trial_t trial = trials->list[i]; \
4523*d4514f0bSApple OSS Distributions int ret = fn(map, (T)base.addr, (T)base.size, trial.value); \
4524*d4514f0bSApple OSS Distributions append_result(results, ret, trial.name); \
4525*d4514f0bSApple OSS Distributions } \
4526*d4514f0bSApple OSS Distributions return results; \
4527*d4514f0bSApple OSS Distributions } \
4528*d4514f0bSApple OSS Distributions /* Test a Mach function. */ \
4529*d4514f0bSApple OSS Distributions /* Run each trial with an allocated region and a purgeable trial. */ \
4530*d4514f0bSApple OSS Distributions typedef kern_return_t (*NAME ## mach_purgable_fn)(MAP_T map, T addr, vm_purgable_t control, int state); \
4531*d4514f0bSApple OSS Distributions \
4532*d4514f0bSApple OSS Distributions static results_t * __attribute__((used)) \
4533*d4514f0bSApple OSS Distributions test_ ## NAME ## mach_with_allocated_purgeable_and_state(NAME ## mach_purgable_fn fn, const char * testname) { \
4534*d4514f0bSApple OSS Distributions MAP_T map SMART_MAP; \
4535*d4514f0bSApple OSS Distributions vm_purgeable_and_state_trials_t *trials SMART_VM_PURGEABLE_AND_STATE_TRIALS(); \
4536*d4514f0bSApple OSS Distributions results_t *results = alloc_results(testname, eSMART_VM_PURGEABLE_AND_STATE_TRIALS, trials->count); \
4537*d4514f0bSApple OSS Distributions \
4538*d4514f0bSApple OSS Distributions for (unsigned i = 0; i < trials->count; i++) { \
4539*d4514f0bSApple OSS Distributions allocation_t base SMART_ALLOCATE_PURGEABLE_VM(map, TEST_ALLOC_SIZE, VM_PROT_DEFAULT); \
4540*d4514f0bSApple OSS Distributions vm_purgeable_and_state_trial_t trial = trials->list[i]; \
4541*d4514f0bSApple OSS Distributions int ret = fn(map, (T)base.addr, trial.control, trial.state); \
4542*d4514f0bSApple OSS Distributions append_result(results, ret, trial.name); \
4543*d4514f0bSApple OSS Distributions } \
4544*d4514f0bSApple OSS Distributions return results; \
4545*d4514f0bSApple OSS Distributions }
4546*d4514f0bSApple OSS Distributions
4547*d4514f0bSApple OSS Distributions IMPL(, uint64_t)
4548*d4514f0bSApple OSS Distributions #if TEST_OLD_STYLE_MACH
IMPL(old,uint32_t)4549*d4514f0bSApple OSS Distributions IMPL(old, uint32_t)
4550*d4514f0bSApple OSS Distributions #endif
4551*d4514f0bSApple OSS Distributions #undef IMPL
4552*d4514f0bSApple OSS Distributions
4553*d4514f0bSApple OSS Distributions #if KERNEL && CONFIG_MAP_RANGES
4554*d4514f0bSApple OSS Distributions /*
4555*d4514f0bSApple OSS Distributions * The vm_range_create tests assume we don't ever do range_creates that should succeed
4556*d4514f0bSApple OSS Distributions * that take more than 2 * PAGE_SIZE. This enforces that.
4557*d4514f0bSApple OSS Distributions */
4558*d4514f0bSApple OSS Distributions void
4559*d4514f0bSApple OSS Distributions verify_largest_valid_trial_size_fits(start_size_start_size_trial_t trial)
4560*d4514f0bSApple OSS Distributions {
4561*d4514f0bSApple OSS Distributions if (trial.size > 2 * PAGE_SIZE) {
4562*d4514f0bSApple OSS Distributions assert(trial.size > 0xfffffffffffffff);
4563*d4514f0bSApple OSS Distributions }
4564*d4514f0bSApple OSS Distributions if (trial.second_size > 2 * PAGE_SIZE) {
4565*d4514f0bSApple OSS Distributions assert(trial.second_size > 0xfffffffffffffff);
4566*d4514f0bSApple OSS Distributions }
4567*d4514f0bSApple OSS Distributions }
4568*d4514f0bSApple OSS Distributions
4569*d4514f0bSApple OSS Distributions /* Run each trial with start/size/start/size parameters. */
4570*d4514f0bSApple OSS Distributions typedef kern_return_t (mach_with_start_size_start_size_fn)(MAP_T map, mach_vm_address_t addr,
4571*d4514f0bSApple OSS Distributions mach_vm_size_t size, mach_vm_address_t second_addr, mach_vm_size_t second_size);
4572*d4514f0bSApple OSS Distributions
4573*d4514f0bSApple OSS Distributions static results_t * __attribute__((used))
test_mach_vm_range_create(mach_with_start_size_start_size_fn fn,const char * testname)4574*d4514f0bSApple OSS Distributions test_mach_vm_range_create(mach_with_start_size_start_size_fn fn, const char *testname)
4575*d4514f0bSApple OSS Distributions {
4576*d4514f0bSApple OSS Distributions start_size_start_size_trials_t *trials SMART_START_SIZE_START_SIZE_TRIALS();
4577*d4514f0bSApple OSS Distributions results_t *results = alloc_results(testname, eSMART_START_SIZE_START_SIZE_TRIALS, trials->count);
4578*d4514f0bSApple OSS Distributions
4579*d4514f0bSApple OSS Distributions for (unsigned i = 0; i < trials->count; i++) {
4580*d4514f0bSApple OSS Distributions /*
4581*d4514f0bSApple OSS Distributions * Allocate and configure a new map for every trial so that the map has no user ranges.
4582*d4514f0bSApple OSS Distributions */
4583*d4514f0bSApple OSS Distributions MAP_T map SMART_RANGE_MAP;
4584*d4514f0bSApple OSS Distributions bool has_ranges = vm_map_range_configure(map, false) == KERN_SUCCESS;
4585*d4514f0bSApple OSS Distributions bool has_space_in_ranges = false;
4586*d4514f0bSApple OSS Distributions
4587*d4514f0bSApple OSS Distributions struct mach_vm_range void1 = {
4588*d4514f0bSApple OSS Distributions .min_address = map->default_range.max_address,
4589*d4514f0bSApple OSS Distributions .max_address = map->data_range.min_address,
4590*d4514f0bSApple OSS Distributions };
4591*d4514f0bSApple OSS Distributions struct mach_vm_range void2 = {
4592*d4514f0bSApple OSS Distributions .min_address = map->data_range.max_address,
4593*d4514f0bSApple OSS Distributions .max_address = vm_map_max(map),
4594*d4514f0bSApple OSS Distributions };
4595*d4514f0bSApple OSS Distributions struct mach_vm_range range_to_test;
4596*d4514f0bSApple OSS Distributions
4597*d4514f0bSApple OSS Distributions /*
4598*d4514f0bSApple OSS Distributions * For our tests to succeed for good cases, but also trigger failures
4599*d4514f0bSApple OSS Distributions * when overlap occurs we need:
4600*d4514f0bSApple OSS Distributions * range1 = {.start = addr}, range2 = {.start = addr + PAGE_SIZE * 2}.
4601*d4514f0bSApple OSS Distributions * We also want at least 2 * PAGE_SIZE memory available after the start of range2.
4602*d4514f0bSApple OSS Distributions * We additionally start our first range 2 PAGE_SIZE away from the start.
4603*d4514f0bSApple OSS Distributions */
4604*d4514f0bSApple OSS Distributions if (void1.min_address + (PAGE_SIZE * 6) < void1.max_address) {
4605*d4514f0bSApple OSS Distributions range_to_test = void1;
4606*d4514f0bSApple OSS Distributions has_space_in_ranges = true;
4607*d4514f0bSApple OSS Distributions } else if (void2.min_address + (PAGE_SIZE * 6) < void2.max_address) {
4608*d4514f0bSApple OSS Distributions range_to_test = void2;
4609*d4514f0bSApple OSS Distributions has_space_in_ranges = true;
4610*d4514f0bSApple OSS Distributions }
4611*d4514f0bSApple OSS Distributions
4612*d4514f0bSApple OSS Distributions mach_vm_address_t addr_base = range_to_test.min_address + PAGE_SIZE * 2;
4613*d4514f0bSApple OSS Distributions if (has_ranges && has_space_in_ranges) {
4614*d4514f0bSApple OSS Distributions mach_vm_address_t second_addr_base = addr_base + PAGE_SIZE * 2;
4615*d4514f0bSApple OSS Distributions
4616*d4514f0bSApple OSS Distributions start_size_start_size_trial_t trial = slide_trial(trials->list[i], addr_base, second_addr_base);
4617*d4514f0bSApple OSS Distributions
4618*d4514f0bSApple OSS Distributions verify_largest_valid_trial_size_fits(trial);
4619*d4514f0bSApple OSS Distributions
4620*d4514f0bSApple OSS Distributions mach_vm_address_t start = trial.start;
4621*d4514f0bSApple OSS Distributions mach_vm_size_t size = trial.size;
4622*d4514f0bSApple OSS Distributions mach_vm_address_t second_start = trial.second_start;
4623*d4514f0bSApple OSS Distributions mach_vm_size_t second_size = trial.second_size;
4624*d4514f0bSApple OSS Distributions kern_return_t ret = fn(map, start, size, second_start, second_size);
4625*d4514f0bSApple OSS Distributions append_result(results, ret, trials->list[i].name);
4626*d4514f0bSApple OSS Distributions } else {
4627*d4514f0bSApple OSS Distributions append_result(results, IGNORED, trials->list[i].name);
4628*d4514f0bSApple OSS Distributions }
4629*d4514f0bSApple OSS Distributions }
4630*d4514f0bSApple OSS Distributions return results;
4631*d4514f0bSApple OSS Distributions }
4632*d4514f0bSApple OSS Distributions #endif /* KERNEL && CONFIG_MAP_RANGES */
4633*d4514f0bSApple OSS Distributions
4634*d4514f0bSApple OSS Distributions // Test a mach allocation function with a start/size
4635*d4514f0bSApple OSS Distributions static results_t *
test_mach_allocation_func_with_start_size(kern_return_t (* func)(MAP_T map,mach_vm_address_t * start,mach_vm_size_t size),const char * testname)4636*d4514f0bSApple OSS Distributions test_mach_allocation_func_with_start_size(kern_return_t (*func)(MAP_T map, mach_vm_address_t * start, mach_vm_size_t size), const char * testname)
4637*d4514f0bSApple OSS Distributions {
4638*d4514f0bSApple OSS Distributions MAP_T map SMART_MAP;
4639*d4514f0bSApple OSS Distributions start_size_trials_t *trials SMART_START_SIZE_TRIALS(0);
4640*d4514f0bSApple OSS Distributions results_t *results = alloc_results(testname, eSMART_START_SIZE_TRIALS, 0, trials->count);
4641*d4514f0bSApple OSS Distributions
4642*d4514f0bSApple OSS Distributions for (unsigned i = 0; i < trials->count; i++) {
4643*d4514f0bSApple OSS Distributions unallocation_t dst SMART_UNALLOCATE_VM(map, TEST_ALLOC_SIZE);
4644*d4514f0bSApple OSS Distributions start_size_trial_t trial = slide_trial(trials->list[i], dst.addr);
4645*d4514f0bSApple OSS Distributions mach_vm_address_t addr = trial.start;
4646*d4514f0bSApple OSS Distributions kern_return_t ret = func(map, &addr, trial.size);
4647*d4514f0bSApple OSS Distributions if (ret == 0) {
4648*d4514f0bSApple OSS Distributions (void)mach_vm_deallocate(map, addr, trial.size);
4649*d4514f0bSApple OSS Distributions }
4650*d4514f0bSApple OSS Distributions append_result(results, ret, trial.name);
4651*d4514f0bSApple OSS Distributions }
4652*d4514f0bSApple OSS Distributions return results;
4653*d4514f0bSApple OSS Distributions }
4654*d4514f0bSApple OSS Distributions
4655*d4514f0bSApple OSS Distributions // Test a mach allocation function with a vm_map_kernel_flags_t
4656*d4514f0bSApple OSS Distributions static results_t *
test_mach_allocation_func_with_vm_map_kernel_flags_t(kern_return_t (* func)(MAP_T map,mach_vm_address_t * start,mach_vm_size_t size,int flags),const char * testname)4657*d4514f0bSApple OSS Distributions test_mach_allocation_func_with_vm_map_kernel_flags_t(kern_return_t (*func)(MAP_T map, mach_vm_address_t * start, mach_vm_size_t size, int flags), const char * testname)
4658*d4514f0bSApple OSS Distributions {
4659*d4514f0bSApple OSS Distributions MAP_T map SMART_MAP;
4660*d4514f0bSApple OSS Distributions vm_map_kernel_flags_trials_t * trials SMART_VM_MAP_KERNEL_FLAGS_TRIALS();
4661*d4514f0bSApple OSS Distributions results_t *results = alloc_results(testname, eSMART_VM_MAP_KERNEL_FLAGS_TRIALS, trials->count);
4662*d4514f0bSApple OSS Distributions
4663*d4514f0bSApple OSS Distributions for (unsigned i = 0; i < trials->count; i++) {
4664*d4514f0bSApple OSS Distributions allocation_t fixed_overwrite_dst SMART_ALLOCATE_VM(map, TEST_ALLOC_SIZE, VM_PROT_DEFAULT);
4665*d4514f0bSApple OSS Distributions vm_map_kernel_flags_trial_t trial = trials->list[i];
4666*d4514f0bSApple OSS Distributions #if KERNEL
4667*d4514f0bSApple OSS Distributions if (is_random_anywhere(trial.flags)) {
4668*d4514f0bSApple OSS Distributions // RANDOM_ADDR is likely to fall outside pmap's range
4669*d4514f0bSApple OSS Distributions append_result(results, PANIC, trial.name);
4670*d4514f0bSApple OSS Distributions continue;
4671*d4514f0bSApple OSS Distributions }
4672*d4514f0bSApple OSS Distributions #endif
4673*d4514f0bSApple OSS Distributions mach_vm_address_t addr = 0;
4674*d4514f0bSApple OSS Distributions if (is_fixed_overwrite(trial.flags)) {
4675*d4514f0bSApple OSS Distributions // use a pre-existing destination for fixed-overwrite
4676*d4514f0bSApple OSS Distributions addr = fixed_overwrite_dst.addr;
4677*d4514f0bSApple OSS Distributions }
4678*d4514f0bSApple OSS Distributions kern_return_t ret = func(map, &addr, TEST_ALLOC_SIZE, trial.flags);
4679*d4514f0bSApple OSS Distributions deallocate_if_not_fixed_overwrite(ret, map, addr, TEST_ALLOC_SIZE, trial.flags);
4680*d4514f0bSApple OSS Distributions append_result(results, ret, trial.name);
4681*d4514f0bSApple OSS Distributions }
4682*d4514f0bSApple OSS Distributions return results;
4683*d4514f0bSApple OSS Distributions }
4684*d4514f0bSApple OSS Distributions
4685*d4514f0bSApple OSS Distributions static results_t *
test_mach_with_allocated_vm_map_kernel_flags_t(kern_return_t (* func)(MAP_T map,mach_vm_address_t src,mach_vm_size_t size,int flags),const char * testname)4686*d4514f0bSApple OSS Distributions test_mach_with_allocated_vm_map_kernel_flags_t(kern_return_t (*func)(MAP_T map, mach_vm_address_t src, mach_vm_size_t size, int flags), const char * testname)
4687*d4514f0bSApple OSS Distributions {
4688*d4514f0bSApple OSS Distributions MAP_T map SMART_MAP;
4689*d4514f0bSApple OSS Distributions
4690*d4514f0bSApple OSS Distributions allocation_t base SMART_ALLOCATE_VM(map, TEST_ALLOC_SIZE, VM_PROT_DEFAULT);
4691*d4514f0bSApple OSS Distributions vm_map_kernel_flags_trials_t * trials SMART_VM_MAP_KERNEL_FLAGS_TRIALS();
4692*d4514f0bSApple OSS Distributions results_t *results = alloc_results(testname, eSMART_VM_MAP_KERNEL_FLAGS_TRIALS, trials->count);
4693*d4514f0bSApple OSS Distributions
4694*d4514f0bSApple OSS Distributions for (unsigned i = 0; i < trials->count; i++) {
4695*d4514f0bSApple OSS Distributions kern_return_t ret = func(map, base.addr, base.size, trials->list[i].flags);
4696*d4514f0bSApple OSS Distributions append_result(results, ret, trials->list[i].name);
4697*d4514f0bSApple OSS Distributions }
4698*d4514f0bSApple OSS Distributions return results;
4699*d4514f0bSApple OSS Distributions }
4700*d4514f0bSApple OSS Distributions
4701*d4514f0bSApple OSS Distributions static results_t *
test_unix_with_allocated_vm_prot_t(int (* func)(void * start,size_t size,int flags),const char * testname)4702*d4514f0bSApple OSS Distributions test_unix_with_allocated_vm_prot_t(int (*func)(void * start, size_t size, int flags), const char * testname)
4703*d4514f0bSApple OSS Distributions {
4704*d4514f0bSApple OSS Distributions MAP_T map CURRENT_MAP;
4705*d4514f0bSApple OSS Distributions allocation_t base SMART_ALLOCATE_VM(map, TEST_ALLOC_SIZE, VM_PROT_DEFAULT);
4706*d4514f0bSApple OSS Distributions vm_prot_trials_t * trials SMART_VM_PROT_TRIALS();
4707*d4514f0bSApple OSS Distributions results_t *results = alloc_results(testname, eSMART_VM_PROT_TRIALS, trials->count);
4708*d4514f0bSApple OSS Distributions
4709*d4514f0bSApple OSS Distributions for (unsigned i = 0; i < trials->count; i++) {
4710*d4514f0bSApple OSS Distributions int ret = func((void *) base.addr, (size_t) base.size, (int) trials->list[i].prot);
4711*d4514f0bSApple OSS Distributions append_result(results, ret, trials->list[i].name);
4712*d4514f0bSApple OSS Distributions }
4713*d4514f0bSApple OSS Distributions return results;
4714*d4514f0bSApple OSS Distributions }
4715*d4514f0bSApple OSS Distributions
4716*d4514f0bSApple OSS Distributions // Test a Unix function.
4717*d4514f0bSApple OSS Distributions // Run each trial with an allocated vm region and start/size parameters that reference it.
4718*d4514f0bSApple OSS Distributions typedef int (*unix_with_start_size_fn)(void *start, size_t size);
4719*d4514f0bSApple OSS Distributions
4720*d4514f0bSApple OSS Distributions static results_t * __unused
test_unix_with_allocated_aligned_start_size(unix_with_start_size_fn fn,mach_vm_size_t align_mask,const char * testname)4721*d4514f0bSApple OSS Distributions test_unix_with_allocated_aligned_start_size(unix_with_start_size_fn fn, mach_vm_size_t align_mask, const char *testname)
4722*d4514f0bSApple OSS Distributions {
4723*d4514f0bSApple OSS Distributions MAP_T map CURRENT_MAP;
4724*d4514f0bSApple OSS Distributions allocation_t base SMART_ALLOCATE_ALIGNED_VM(map, TEST_ALLOC_SIZE, align_mask, VM_PROT_DEFAULT);
4725*d4514f0bSApple OSS Distributions start_size_trials_t *trials SMART_START_SIZE_TRIALS(base.addr);
4726*d4514f0bSApple OSS Distributions results_t *results = alloc_results(testname, eSMART_START_SIZE_TRIALS, base.addr, trials->count);
4727*d4514f0bSApple OSS Distributions
4728*d4514f0bSApple OSS Distributions for (unsigned i = 0; i < trials->count; i++) {
4729*d4514f0bSApple OSS Distributions addr_t start = trials->list[i].start;
4730*d4514f0bSApple OSS Distributions addr_t size = trials->list[i].size;
4731*d4514f0bSApple OSS Distributions int ret = fn((void*)(uintptr_t)start, (size_t)size);
4732*d4514f0bSApple OSS Distributions append_result(results, ret, trials->list[i].name);
4733*d4514f0bSApple OSS Distributions }
4734*d4514f0bSApple OSS Distributions return results;
4735*d4514f0bSApple OSS Distributions }
4736*d4514f0bSApple OSS Distributions
4737*d4514f0bSApple OSS Distributions static results_t * __unused
test_unix_with_allocated_start_size(unix_with_start_size_fn fn,const char * testname)4738*d4514f0bSApple OSS Distributions test_unix_with_allocated_start_size(unix_with_start_size_fn fn, const char *testname)
4739*d4514f0bSApple OSS Distributions {
4740*d4514f0bSApple OSS Distributions return test_unix_with_allocated_aligned_start_size(fn, 0, testname);
4741*d4514f0bSApple OSS Distributions }
4742*d4514f0bSApple OSS Distributions
4743*d4514f0bSApple OSS Distributions #if KERNEL
4744*d4514f0bSApple OSS Distributions static results_t * __unused
test_kext_unix_with_allocated_start_size(unix_with_start_size_fn fn,const char * testname)4745*d4514f0bSApple OSS Distributions test_kext_unix_with_allocated_start_size(unix_with_start_size_fn fn, const char *testname)
4746*d4514f0bSApple OSS Distributions {
4747*d4514f0bSApple OSS Distributions MAP_T map CURRENT_MAP;
4748*d4514f0bSApple OSS Distributions allocation_t base SMART_ALLOCATE_VM(map, TEST_ALLOC_SIZE, VM_PROT_DEFAULT);
4749*d4514f0bSApple OSS Distributions start_size_trials_t *trials SMART_START_SIZE_TRIALS(base.addr);
4750*d4514f0bSApple OSS Distributions results_t *results = alloc_results(testname, eSMART_START_SIZE_TRIALS, base.addr, trials->count);
4751*d4514f0bSApple OSS Distributions
4752*d4514f0bSApple OSS Distributions for (unsigned i = 0; i < trials->count; i++) {
4753*d4514f0bSApple OSS Distributions addr_t start = trials->list[i].start;
4754*d4514f0bSApple OSS Distributions addr_t size = trials->list[i].size;
4755*d4514f0bSApple OSS Distributions int ret = fn((void*)(uintptr_t)start, (size_t)size);
4756*d4514f0bSApple OSS Distributions append_result(results, ret, trials->list[i].name);
4757*d4514f0bSApple OSS Distributions }
4758*d4514f0bSApple OSS Distributions return results;
4759*d4514f0bSApple OSS Distributions }
4760*d4514f0bSApple OSS Distributions
4761*d4514f0bSApple OSS Distributions /* Test a Kext function requiring memory allocated with a specific tag. */
4762*d4514f0bSApple OSS Distributions /* Run each trial with an allocated vm region and an addr parameter that reference it. */
4763*d4514f0bSApple OSS Distributions
4764*d4514f0bSApple OSS Distributions static results_t * __attribute__((used))
test_kext_tagged_with_allocated_addr(kern_return_t (* func)(MAP_T map,mach_vm_address_t addr),const char * testname)4765*d4514f0bSApple OSS Distributions test_kext_tagged_with_allocated_addr(kern_return_t (*func)(MAP_T map, mach_vm_address_t addr), const char *testname)
4766*d4514f0bSApple OSS Distributions {
4767*d4514f0bSApple OSS Distributions MAP_T map CURRENT_MAP;
4768*d4514f0bSApple OSS Distributions allocation_t base SMART_ALLOCATE_VM(map, TEST_ALLOC_SIZE, VM_PROT_DEFAULT);
4769*d4514f0bSApple OSS Distributions addr_trials_t *trials SMART_ADDR_TRIALS(base.addr);
4770*d4514f0bSApple OSS Distributions results_t *results = alloc_results(testname, eSMART_ADDR_TRIALS, base.addr, trials->count);
4771*d4514f0bSApple OSS Distributions
4772*d4514f0bSApple OSS Distributions for (unsigned i = 0; i < trials->count; i++) {
4773*d4514f0bSApple OSS Distributions mach_vm_address_t addr = (mach_vm_address_t)trials->list[i].addr;
4774*d4514f0bSApple OSS Distributions kern_return_t ret = func(map, addr);
4775*d4514f0bSApple OSS Distributions append_result(results, ret, trials->list[i].name);
4776*d4514f0bSApple OSS Distributions }
4777*d4514f0bSApple OSS Distributions return results;
4778*d4514f0bSApple OSS Distributions }
4779*d4514f0bSApple OSS Distributions #endif /* KERNEL */
4780*d4514f0bSApple OSS Distributions
4781*d4514f0bSApple OSS Distributions static results_t * __attribute__((used))
test_with_int64(kern_return_t (* func)(int64_t),const char * testname)4782*d4514f0bSApple OSS Distributions test_with_int64(kern_return_t (*func)(int64_t), const char *testname)
4783*d4514f0bSApple OSS Distributions {
4784*d4514f0bSApple OSS Distributions size_trials_t *trials SMART_SIZE_TRIALS();
4785*d4514f0bSApple OSS Distributions results_t *results = alloc_results(testname, eSMART_SIZE_TRIALS, trials->count);
4786*d4514f0bSApple OSS Distributions
4787*d4514f0bSApple OSS Distributions for (unsigned i = 0; i < trials->count; i++) {
4788*d4514f0bSApple OSS Distributions int64_t val = (int64_t)trials->list[i].size;
4789*d4514f0bSApple OSS Distributions kern_return_t ret = func(val);
4790*d4514f0bSApple OSS Distributions append_result(results, ret, trials->list[i].name);
4791*d4514f0bSApple OSS Distributions }
4792*d4514f0bSApple OSS Distributions return results;
4793*d4514f0bSApple OSS Distributions }
4794*d4514f0bSApple OSS Distributions
4795*d4514f0bSApple OSS Distributions
4796*d4514f0bSApple OSS Distributions #if !KERNEL
4797*d4514f0bSApple OSS Distributions
4798*d4514f0bSApple OSS Distributions // For deallocators like munmap and vm_deallocate.
4799*d4514f0bSApple OSS Distributions // Return a non-zero error code if we should avoid performing this trial.
4800*d4514f0bSApple OSS Distributions // Call this BEFORE sliding the trial to a non-zero base address.
4801*d4514f0bSApple OSS Distributions extern
4802*d4514f0bSApple OSS Distributions kern_return_t
4803*d4514f0bSApple OSS Distributions short_circuit_deallocator(MAP_T map, start_size_trial_t trial);
4804*d4514f0bSApple OSS Distributions
4805*d4514f0bSApple OSS Distributions // implemented in vm_parameter_validation.c
4806*d4514f0bSApple OSS Distributions
4807*d4514f0bSApple OSS Distributions #else /* KERNEL */
4808*d4514f0bSApple OSS Distributions
4809*d4514f0bSApple OSS Distributions static inline
4810*d4514f0bSApple OSS Distributions kern_return_t
short_circuit_deallocator(MAP_T map __unused,start_size_trial_t trial __unused)4811*d4514f0bSApple OSS Distributions short_circuit_deallocator(MAP_T map __unused, start_size_trial_t trial __unused)
4812*d4514f0bSApple OSS Distributions {
4813*d4514f0bSApple OSS Distributions // Kernel tests run with an empty vm_map so we're free to deallocate whatever we want.
4814*d4514f0bSApple OSS Distributions return 0;
4815*d4514f0bSApple OSS Distributions }
4816*d4514f0bSApple OSS Distributions
4817*d4514f0bSApple OSS Distributions #endif /* KERNEL */
4818*d4514f0bSApple OSS Distributions
4819*d4514f0bSApple OSS Distributions
4820*d4514f0bSApple OSS Distributions // Test mach_vm_deallocate or munmap.
4821*d4514f0bSApple OSS Distributions // Similar to test_mach_with_allocated_addr_size, but mach_vm_deallocate is destructive
4822*d4514f0bSApple OSS Distributions // so we can't test all values and we need to re-allocate the vm allocation each time.
4823*d4514f0bSApple OSS Distributions static results_t *
test_deallocator(kern_return_t (* func)(MAP_T map,mach_vm_address_t start,mach_vm_size_t size),const char * testname)4824*d4514f0bSApple OSS Distributions test_deallocator(kern_return_t (*func)(MAP_T map, mach_vm_address_t start, mach_vm_size_t size), const char *testname)
4825*d4514f0bSApple OSS Distributions {
4826*d4514f0bSApple OSS Distributions MAP_T map SMART_MAP;
4827*d4514f0bSApple OSS Distributions
4828*d4514f0bSApple OSS Distributions // allocate trials relative to address zero
4829*d4514f0bSApple OSS Distributions // later we slide them to each allocation's address
4830*d4514f0bSApple OSS Distributions start_size_trials_t *trials SMART_START_SIZE_TRIALS(0);
4831*d4514f0bSApple OSS Distributions
4832*d4514f0bSApple OSS Distributions results_t *results = alloc_results(testname, eSMART_START_SIZE_TRIALS, 0, trials->count);
4833*d4514f0bSApple OSS Distributions
4834*d4514f0bSApple OSS Distributions for (unsigned i = 0; i < trials->count; i++) {
4835*d4514f0bSApple OSS Distributions start_size_trial_t trial = trials->list[i];
4836*d4514f0bSApple OSS Distributions allocation_t base SMART_ALLOCATE_VM(map, TEST_ALLOC_SIZE, VM_PROT_DEFAULT);
4837*d4514f0bSApple OSS Distributions
4838*d4514f0bSApple OSS Distributions // Avoid trials that might deallocate wildly.
4839*d4514f0bSApple OSS Distributions // Check this BEFORE sliding the trial.
4840*d4514f0bSApple OSS Distributions kern_return_t ret = short_circuit_deallocator(map, trial);
4841*d4514f0bSApple OSS Distributions if (ret == 0) {
4842*d4514f0bSApple OSS Distributions // Adjust start and/or size, if that value includes the allocated address
4843*d4514f0bSApple OSS Distributions trial = slide_trial(trial, base.addr);
4844*d4514f0bSApple OSS Distributions
4845*d4514f0bSApple OSS Distributions ret = func(map, trial.start, trial.size);
4846*d4514f0bSApple OSS Distributions if (ret == 0) {
4847*d4514f0bSApple OSS Distributions // Deallocation succeeded. Don't deallocate again.
4848*d4514f0bSApple OSS Distributions set_already_deallocated(&base);
4849*d4514f0bSApple OSS Distributions }
4850*d4514f0bSApple OSS Distributions }
4851*d4514f0bSApple OSS Distributions append_result(results, ret, trial.name);
4852*d4514f0bSApple OSS Distributions }
4853*d4514f0bSApple OSS Distributions
4854*d4514f0bSApple OSS Distributions return results;
4855*d4514f0bSApple OSS Distributions }
4856*d4514f0bSApple OSS Distributions
4857*d4514f0bSApple OSS Distributions static results_t *
test_allocated_src_unallocated_dst_size(kern_return_t (* func)(MAP_T map,mach_vm_address_t src,mach_vm_size_t size,mach_vm_address_t dst),const char * testname)4858*d4514f0bSApple OSS Distributions test_allocated_src_unallocated_dst_size(kern_return_t (*func)(MAP_T map, mach_vm_address_t src, mach_vm_size_t size, mach_vm_address_t dst), const char * testname)
4859*d4514f0bSApple OSS Distributions {
4860*d4514f0bSApple OSS Distributions MAP_T map SMART_MAP;
4861*d4514f0bSApple OSS Distributions allocation_t src_base SMART_ALLOCATE_VM(map, TEST_ALLOC_SIZE, VM_PROT_DEFAULT);
4862*d4514f0bSApple OSS Distributions src_dst_size_trials_t * trials SMART_SRC_DST_SIZE_TRIALS();
4863*d4514f0bSApple OSS Distributions results_t *results = alloc_results(testname, eSMART_SRC_DST_SIZE_TRIALS, trials->count);
4864*d4514f0bSApple OSS Distributions
4865*d4514f0bSApple OSS Distributions for (unsigned i = 0; i < trials->count; i++) {
4866*d4514f0bSApple OSS Distributions src_dst_size_trial_t trial = trials->list[i];
4867*d4514f0bSApple OSS Distributions unallocation_t dst_base SMART_UNALLOCATE_VM(map, TEST_ALLOC_SIZE);
4868*d4514f0bSApple OSS Distributions trial = slide_trial_src(trial, src_base.addr);
4869*d4514f0bSApple OSS Distributions trial = slide_trial_dst(trial, dst_base.addr);
4870*d4514f0bSApple OSS Distributions int ret = func(map, trial.src, trial.size, trial.dst);
4871*d4514f0bSApple OSS Distributions // func deallocates its own allocation
4872*d4514f0bSApple OSS Distributions append_result(results, ret, trial.name);
4873*d4514f0bSApple OSS Distributions }
4874*d4514f0bSApple OSS Distributions return results;
4875*d4514f0bSApple OSS Distributions }
4876*d4514f0bSApple OSS Distributions
4877*d4514f0bSApple OSS Distributions
4878*d4514f0bSApple OSS Distributions static inline void
check_mach_vm_allocate_outparam_changes(kern_return_t * kr,mach_vm_address_t addr,mach_vm_size_t size,mach_vm_address_t saved_start,int flags,MAP_T map)4879*d4514f0bSApple OSS Distributions check_mach_vm_allocate_outparam_changes(kern_return_t * kr, mach_vm_address_t addr, mach_vm_size_t size,
4880*d4514f0bSApple OSS Distributions mach_vm_address_t saved_start, int flags, MAP_T map)
4881*d4514f0bSApple OSS Distributions {
4882*d4514f0bSApple OSS Distributions if (*kr == KERN_SUCCESS) {
4883*d4514f0bSApple OSS Distributions if (size == 0) {
4884*d4514f0bSApple OSS Distributions if (addr != 0) {
4885*d4514f0bSApple OSS Distributions *kr = OUT_PARAM_BAD;
4886*d4514f0bSApple OSS Distributions }
4887*d4514f0bSApple OSS Distributions } else {
4888*d4514f0bSApple OSS Distributions if (is_fixed(flags)) {
4889*d4514f0bSApple OSS Distributions if (addr != trunc_down_map(map, saved_start)) {
4890*d4514f0bSApple OSS Distributions *kr = OUT_PARAM_BAD;
4891*d4514f0bSApple OSS Distributions }
4892*d4514f0bSApple OSS Distributions }
4893*d4514f0bSApple OSS Distributions }
4894*d4514f0bSApple OSS Distributions } else {
4895*d4514f0bSApple OSS Distributions if (saved_start != addr) {
4896*d4514f0bSApple OSS Distributions *kr = OUT_PARAM_BAD;
4897*d4514f0bSApple OSS Distributions }
4898*d4514f0bSApple OSS Distributions }
4899*d4514f0bSApple OSS Distributions }
4900*d4514f0bSApple OSS Distributions
4901*d4514f0bSApple OSS Distributions static kern_return_t
call_mach_vm_behavior_set__start_size__default(MAP_T map,mach_vm_address_t start,mach_vm_size_t size)4902*d4514f0bSApple OSS Distributions call_mach_vm_behavior_set__start_size__default(MAP_T map, mach_vm_address_t start, mach_vm_size_t size)
4903*d4514f0bSApple OSS Distributions {
4904*d4514f0bSApple OSS Distributions kern_return_t kr = mach_vm_behavior_set(map, start, size, VM_BEHAVIOR_DEFAULT);
4905*d4514f0bSApple OSS Distributions return kr;
4906*d4514f0bSApple OSS Distributions }
4907*d4514f0bSApple OSS Distributions
4908*d4514f0bSApple OSS Distributions /*
4909*d4514f0bSApple OSS Distributions * VM_BEHAVIOR_CAN_REUSE is additionally tested as it uses slightly different page rounding semantics
4910*d4514f0bSApple OSS Distributions */
4911*d4514f0bSApple OSS Distributions static kern_return_t
call_mach_vm_behavior_set__start_size__can_reuse(MAP_T map,mach_vm_address_t start,mach_vm_size_t size)4912*d4514f0bSApple OSS Distributions call_mach_vm_behavior_set__start_size__can_reuse(MAP_T map, mach_vm_address_t start, mach_vm_size_t size)
4913*d4514f0bSApple OSS Distributions {
4914*d4514f0bSApple OSS Distributions kern_return_t kr = mach_vm_behavior_set(map, start, size, VM_BEHAVIOR_CAN_REUSE);
4915*d4514f0bSApple OSS Distributions return kr;
4916*d4514f0bSApple OSS Distributions }
4917*d4514f0bSApple OSS Distributions
4918*d4514f0bSApple OSS Distributions static kern_return_t
call_mach_vm_behavior_set__vm_behavior(MAP_T map,mach_vm_address_t start,mach_vm_size_t size,vm_behavior_t behavior)4919*d4514f0bSApple OSS Distributions call_mach_vm_behavior_set__vm_behavior(MAP_T map, mach_vm_address_t start, mach_vm_size_t size, vm_behavior_t behavior)
4920*d4514f0bSApple OSS Distributions {
4921*d4514f0bSApple OSS Distributions kern_return_t kr = mach_vm_behavior_set(map, start, size, behavior);
4922*d4514f0bSApple OSS Distributions return kr;
4923*d4514f0bSApple OSS Distributions }
4924*d4514f0bSApple OSS Distributions
4925*d4514f0bSApple OSS Distributions static void
check_mach_vm_purgable_control_outparam_changes(kern_return_t * kr,int state,int saved_state,int control)4926*d4514f0bSApple OSS Distributions check_mach_vm_purgable_control_outparam_changes(kern_return_t * kr, int state, int saved_state, int control)
4927*d4514f0bSApple OSS Distributions {
4928*d4514f0bSApple OSS Distributions if (*kr == KERN_SUCCESS) {
4929*d4514f0bSApple OSS Distributions if (control == VM_PURGABLE_PURGE_ALL || VM_PURGABLE_SET_STATE) {
4930*d4514f0bSApple OSS Distributions if (state != saved_state) {
4931*d4514f0bSApple OSS Distributions *kr = OUT_PARAM_BAD;
4932*d4514f0bSApple OSS Distributions }
4933*d4514f0bSApple OSS Distributions }
4934*d4514f0bSApple OSS Distributions if (control == VM_PURGABLE_GET_STATE) {
4935*d4514f0bSApple OSS Distributions /*
4936*d4514f0bSApple OSS Distributions * The default state is VM_PURGABLE_NONVOLATILE for a newly created region
4937*d4514f0bSApple OSS Distributions */
4938*d4514f0bSApple OSS Distributions if (state != VM_PURGABLE_NONVOLATILE) {
4939*d4514f0bSApple OSS Distributions *kr = OUT_PARAM_BAD;
4940*d4514f0bSApple OSS Distributions }
4941*d4514f0bSApple OSS Distributions }
4942*d4514f0bSApple OSS Distributions } else {
4943*d4514f0bSApple OSS Distributions if (state != saved_state) {
4944*d4514f0bSApple OSS Distributions *kr = OUT_PARAM_BAD;
4945*d4514f0bSApple OSS Distributions }
4946*d4514f0bSApple OSS Distributions }
4947*d4514f0bSApple OSS Distributions }
4948*d4514f0bSApple OSS Distributions
4949*d4514f0bSApple OSS Distributions static void
check_mach_vm_region_outparam_changes(kern_return_t * kr,MAP_T map,void * info,void * saved_info,size_t info_size,mach_port_t object_name,mach_port_t saved_object_name,mach_vm_address_t addr,mach_vm_address_t saved_addr,mach_vm_size_t size,mach_vm_size_t saved_size)4950*d4514f0bSApple OSS Distributions check_mach_vm_region_outparam_changes(kern_return_t * kr, MAP_T map, void * info, void * saved_info, size_t info_size,
4951*d4514f0bSApple OSS Distributions mach_port_t object_name, mach_port_t saved_object_name, mach_vm_address_t addr, mach_vm_address_t saved_addr,
4952*d4514f0bSApple OSS Distributions mach_vm_size_t size, mach_vm_size_t saved_size)
4953*d4514f0bSApple OSS Distributions {
4954*d4514f0bSApple OSS Distributions if (*kr == KERN_SUCCESS) {
4955*d4514f0bSApple OSS Distributions if (object_name != 0) {
4956*d4514f0bSApple OSS Distributions *kr = OUT_PARAM_BAD;
4957*d4514f0bSApple OSS Distributions }
4958*d4514f0bSApple OSS Distributions if (addr < trunc_down_map(map, saved_addr)) {
4959*d4514f0bSApple OSS Distributions *kr = OUT_PARAM_BAD;
4960*d4514f0bSApple OSS Distributions }
4961*d4514f0bSApple OSS Distributions if (size == saved_size) {
4962*d4514f0bSApple OSS Distributions *kr = OUT_PARAM_BAD;
4963*d4514f0bSApple OSS Distributions }
4964*d4514f0bSApple OSS Distributions if (memcmp(info, saved_info, info_size) == 0) {
4965*d4514f0bSApple OSS Distributions *kr = OUT_PARAM_BAD;
4966*d4514f0bSApple OSS Distributions }
4967*d4514f0bSApple OSS Distributions } else {
4968*d4514f0bSApple OSS Distributions if (object_name != saved_object_name || addr != saved_addr || size != saved_size || memcmp(info, saved_info, info_size) != 0) {
4969*d4514f0bSApple OSS Distributions *kr = OUT_PARAM_BAD;
4970*d4514f0bSApple OSS Distributions }
4971*d4514f0bSApple OSS Distributions }
4972*d4514f0bSApple OSS Distributions }
4973*d4514f0bSApple OSS Distributions
4974*d4514f0bSApple OSS Distributions static int
call_mach_vm_region(MAP_T map,mach_vm_address_t addr)4975*d4514f0bSApple OSS Distributions call_mach_vm_region(MAP_T map, mach_vm_address_t addr)
4976*d4514f0bSApple OSS Distributions {
4977*d4514f0bSApple OSS Distributions mach_vm_address_t addr_cpy = addr;
4978*d4514f0bSApple OSS Distributions mach_vm_size_t size_out = UNLIKELY_INITIAL_SIZE;
4979*d4514f0bSApple OSS Distributions mach_vm_size_t saved_size = size_out;
4980*d4514f0bSApple OSS Distributions mach_port_t object_name_out = UNLIKELY_INITIAL_MACH_PORT;
4981*d4514f0bSApple OSS Distributions mach_port_t saved_name = object_name_out;
4982*d4514f0bSApple OSS Distributions vm_region_basic_info_data_64_t info;
4983*d4514f0bSApple OSS Distributions info.inheritance = INVALID_INHERIT;
4984*d4514f0bSApple OSS Distributions vm_region_basic_info_data_64_t saved_info = info;
4985*d4514f0bSApple OSS Distributions
4986*d4514f0bSApple OSS Distributions mach_msg_type_number_t infoCnt = VM_REGION_BASIC_INFO_COUNT_64;
4987*d4514f0bSApple OSS Distributions kern_return_t kr = mach_vm_region(map, &addr_cpy, &size_out, VM_REGION_BASIC_INFO_64, (vm_region_info_t)&info,
4988*d4514f0bSApple OSS Distributions &infoCnt, &object_name_out);
4989*d4514f0bSApple OSS Distributions check_mach_vm_region_outparam_changes(&kr, map, &info, &saved_info, sizeof(info), object_name_out, saved_name, addr_cpy, addr, size_out, saved_size);
4990*d4514f0bSApple OSS Distributions
4991*d4514f0bSApple OSS Distributions return kr;
4992*d4514f0bSApple OSS Distributions }
4993*d4514f0bSApple OSS Distributions
4994*d4514f0bSApple OSS Distributions #if TEST_OLD_STYLE_MACH || KERNEL
4995*d4514f0bSApple OSS Distributions static int
call_vm_region(MAP_T map,vm_address_t addr)4996*d4514f0bSApple OSS Distributions call_vm_region(MAP_T map, vm_address_t addr)
4997*d4514f0bSApple OSS Distributions {
4998*d4514f0bSApple OSS Distributions vm_address_t addr_cpy = addr;
4999*d4514f0bSApple OSS Distributions vm_size_t size_out = UNLIKELY_INITIAL_SIZE;
5000*d4514f0bSApple OSS Distributions vm_size_t saved_size = size_out;
5001*d4514f0bSApple OSS Distributions mach_port_t object_name_out = UNLIKELY_INITIAL_MACH_PORT;
5002*d4514f0bSApple OSS Distributions mach_port_t saved_name = object_name_out;
5003*d4514f0bSApple OSS Distributions vm_region_basic_info_data_64_t info;
5004*d4514f0bSApple OSS Distributions info.inheritance = INVALID_INHERIT;
5005*d4514f0bSApple OSS Distributions vm_region_basic_info_data_64_t saved_info = info;
5006*d4514f0bSApple OSS Distributions
5007*d4514f0bSApple OSS Distributions mach_msg_type_number_t infoCnt = VM_REGION_BASIC_INFO_COUNT_64;
5008*d4514f0bSApple OSS Distributions kern_return_t kr = vm_region(map, &addr_cpy, &size_out, VM_REGION_BASIC_INFO_64, (vm_region_info_t)&info,
5009*d4514f0bSApple OSS Distributions &infoCnt, &object_name_out);
5010*d4514f0bSApple OSS Distributions check_mach_vm_region_outparam_changes(&kr, map, &info, &saved_info, sizeof(info), object_name_out, saved_name, addr_cpy, addr, size_out, saved_size);
5011*d4514f0bSApple OSS Distributions
5012*d4514f0bSApple OSS Distributions return kr;
5013*d4514f0bSApple OSS Distributions }
5014*d4514f0bSApple OSS Distributions #endif /* TEST_OLD_STYLE_MACH || KERNEL */
5015*d4514f0bSApple OSS Distributions
5016*d4514f0bSApple OSS Distributions static void
check_mach_vm_page_info_outparam_changes(kern_return_t * kr,vm_page_info_basic_data_t info,vm_page_info_basic_data_t saved_info,mach_msg_type_number_t count,mach_msg_type_number_t saved_count)5017*d4514f0bSApple OSS Distributions check_mach_vm_page_info_outparam_changes(kern_return_t * kr, vm_page_info_basic_data_t info, vm_page_info_basic_data_t saved_info,
5018*d4514f0bSApple OSS Distributions mach_msg_type_number_t count, mach_msg_type_number_t saved_count)
5019*d4514f0bSApple OSS Distributions {
5020*d4514f0bSApple OSS Distributions if (*kr == KERN_SUCCESS) {
5021*d4514f0bSApple OSS Distributions if (memcmp(&info, &saved_info, sizeof(vm_page_info_basic_data_t)) == 0) {
5022*d4514f0bSApple OSS Distributions *kr = OUT_PARAM_BAD;
5023*d4514f0bSApple OSS Distributions }
5024*d4514f0bSApple OSS Distributions } else {
5025*d4514f0bSApple OSS Distributions if (memcmp(&info, &saved_info, sizeof(vm_page_info_basic_data_t)) != 0) {
5026*d4514f0bSApple OSS Distributions *kr = OUT_PARAM_BAD;
5027*d4514f0bSApple OSS Distributions }
5028*d4514f0bSApple OSS Distributions }
5029*d4514f0bSApple OSS Distributions if (count != saved_count) {
5030*d4514f0bSApple OSS Distributions *kr = OUT_PARAM_BAD;
5031*d4514f0bSApple OSS Distributions }
5032*d4514f0bSApple OSS Distributions }
5033*d4514f0bSApple OSS Distributions
5034*d4514f0bSApple OSS Distributions #pragma clang diagnostic pop
5035*d4514f0bSApple OSS Distributions
5036*d4514f0bSApple OSS Distributions // VM_PARAMETER_VALIDATION_H
5037*d4514f0bSApple OSS Distributions #endif
5038