xref: /xnu-11215.81.4/tests/vm/vm_parameter_validation.c (revision d4514f0bc1d3f944c22d92e68b646ac3fb40d452)
1*d4514f0bSApple OSS Distributions #include <darwintest.h>
2*d4514f0bSApple OSS Distributions #include <darwintest_utils.h>
3*d4514f0bSApple OSS Distributions #include <test_utils.h>
4*d4514f0bSApple OSS Distributions 
5*d4514f0bSApple OSS Distributions #include <sys/types.h>
6*d4514f0bSApple OSS Distributions #include <sys/sysctl.h>
7*d4514f0bSApple OSS Distributions #include <mach/mach.h>
8*d4514f0bSApple OSS Distributions #include <mach/mach_vm.h>
9*d4514f0bSApple OSS Distributions #include <mach/memory_entry.h>
10*d4514f0bSApple OSS Distributions #include <mach/shared_region.h>
11*d4514f0bSApple OSS Distributions #include <mach/vm_reclaim.h>
12*d4514f0bSApple OSS Distributions #include <mach/vm_types.h>
13*d4514f0bSApple OSS Distributions #include <sys/mman.h>
14*d4514f0bSApple OSS Distributions #include <unistd.h>
15*d4514f0bSApple OSS Distributions #include <TargetConditionals.h>
16*d4514f0bSApple OSS Distributions #include <mach-o/dyld.h>
17*d4514f0bSApple OSS Distributions #include <libgen.h>
18*d4514f0bSApple OSS Distributions 
19*d4514f0bSApple OSS Distributions #include <os/bsd.h> // For os_parse_boot_arg_int
20*d4514f0bSApple OSS Distributions 
21*d4514f0bSApple OSS Distributions // workarounds for buggy MIG declarations
22*d4514f0bSApple OSS Distributions // see tests/vm/vm_parameter_validation_replacement_*.defs
23*d4514f0bSApple OSS Distributions // and tests/Makefile for details
24*d4514f0bSApple OSS Distributions #include "vm_parameter_validation_replacement_mach_host.h"
25*d4514f0bSApple OSS Distributions #include "vm_parameter_validation_replacement_host_priv.h"
26*d4514f0bSApple OSS Distributions 
27*d4514f0bSApple OSS Distributions // code shared with kernel/kext tests
28*d4514f0bSApple OSS Distributions #include "../../osfmk/tests/vm_parameter_validation.h"
29*d4514f0bSApple OSS Distributions 
30*d4514f0bSApple OSS Distributions #define GOLDEN_FILES_VERSION "vm_parameter_validation_golden_images_46d15ea.tar.xz"
31*d4514f0bSApple OSS Distributions #define GOLDEN_FILES_ASSET_FILE_POINTER GOLDEN_FILES_VERSION
32*d4514f0bSApple OSS Distributions 
33*d4514f0bSApple OSS Distributions T_GLOBAL_META(
34*d4514f0bSApple OSS Distributions 	T_META_NAMESPACE("xnu.vm"),
35*d4514f0bSApple OSS Distributions 	T_META_RADAR_COMPONENT_NAME("xnu"),
36*d4514f0bSApple OSS Distributions 	T_META_RADAR_COMPONENT_VERSION("VM"),
37*d4514f0bSApple OSS Distributions 	T_META_S3_ASSET(GOLDEN_FILES_ASSET_FILE_POINTER),
38*d4514f0bSApple OSS Distributions 	T_META_ASROOT(true),  /* required for vm_wire tests on macOS */
39*d4514f0bSApple OSS Distributions 	T_META_RUN_CONCURRENTLY(false), /* vm_parameter_validation_kern uses kernel globals */
40*d4514f0bSApple OSS Distributions 	T_META_ALL_VALID_ARCHS(true),
41*d4514f0bSApple OSS Distributions 	XNU_T_META_REQUIRES_DEVELOPMENT_KERNEL
42*d4514f0bSApple OSS Distributions 	);
43*d4514f0bSApple OSS Distributions 
44*d4514f0bSApple OSS Distributions /*
45*d4514f0bSApple OSS Distributions  * vm_parameter_validation.c
46*d4514f0bSApple OSS Distributions  * Test parameter validation of vm's userspace API
47*d4514f0bSApple OSS Distributions  *
48*d4514f0bSApple OSS Distributions  * The test compares the return values against a 'golden' list, which is a text
49*d4514f0bSApple OSS Distributions  * file previously generated and compressed in .xz files, per platform.
50*d4514f0bSApple OSS Distributions  * When vm_parameter_validation runs, it calls assets/vm_parameter_validation/decompress.sh,
51*d4514f0bSApple OSS Distributions  * which detects the platform and decompresses the corresponding user and kern
52*d4514f0bSApple OSS Distributions  * golden files.
53*d4514f0bSApple OSS Distributions  *
54*d4514f0bSApple OSS Distributions  * Any return code mismatch is reported as a failure, printing test name and iteration.
55*d4514f0bSApple OSS Distributions  * New tests not present in the 'golden' list will run but they are also reported as a failure.
56*d4514f0bSApple OSS Distributions  *
57*d4514f0bSApple OSS Distributions  * There are two environment variable flags that makes development work easier and
58*d4514f0bSApple OSS Distributions  * can temporarily disable golden list testing.
59*d4514f0bSApple OSS Distributions  *
60*d4514f0bSApple OSS Distributions  * SKIP_TESTS
61*d4514f0bSApple OSS Distributions  * When running with SKIP_TESTS set, the test will not compare the results
62*d4514f0bSApple OSS Distributions  * against the golden files.
63*d4514f0bSApple OSS Distributions  *
64*d4514f0bSApple OSS Distributions  * DUMP_RESULTS
65*d4514f0bSApple OSS Distributions  * When running with DUMP_RESULTS set, the test will print all the returned values
66*d4514f0bSApple OSS Distributions  * (as opposed to only the failing ones). To pretty-print this output use the python script:
67*d4514f0bSApple OSS Distributions  * DUMP_RESULTS=1 vm_parameter_validation | tools/format_vm_parameter_validation.py
68*d4514f0bSApple OSS Distributions  */
69*d4514f0bSApple OSS Distributions 
70*d4514f0bSApple OSS Distributions 
71*d4514f0bSApple OSS Distributions 
72*d4514f0bSApple OSS Distributions /*
73*d4514f0bSApple OSS Distributions  * xnu/libsyscall/mach/mach_vm.c intercepts some VM calls from userspace,
74*d4514f0bSApple OSS Distributions  * sometimes doing something other than the expected MIG call.
75*d4514f0bSApple OSS Distributions  * This test generates its own MIG userspace call sites to call the kernel
76*d4514f0bSApple OSS Distributions  * entrypoints directly, bypassing libsyscall's interference.
77*d4514f0bSApple OSS Distributions  *
78*d4514f0bSApple OSS Distributions  * The custom MIG call sites are generated into:
79*d4514f0bSApple OSS Distributions  * vm_parameter_validation_vm_map_user.c
80*d4514f0bSApple OSS Distributions  * vm_parameter_validation_mach_vm_user.c
81*d4514f0bSApple OSS Distributions  */
82*d4514f0bSApple OSS Distributions 
83*d4514f0bSApple OSS Distributions #pragma clang diagnostic ignored "-Wdeclaration-after-statement"
84*d4514f0bSApple OSS Distributions #pragma clang diagnostic ignored "-Wmissing-prototypes"
85*d4514f0bSApple OSS Distributions #pragma clang diagnostic ignored "-Wpedantic"
86*d4514f0bSApple OSS Distributions 
87*d4514f0bSApple OSS Distributions /*
88*d4514f0bSApple OSS Distributions  * Our wire tests often try to wire the whole address space.
89*d4514f0bSApple OSS Distributions  * In that case the error code is determined by the first range of addresses
90*d4514f0bSApple OSS Distributions  * that cannot be wired.
91*d4514f0bSApple OSS Distributions  * In most cases that is a protection failure on a malloc guard page. But
92*d4514f0bSApple OSS Distributions  * sometimes, circumstances outside of our control change the address map of
93*d4514f0bSApple OSS Distributions  * our test process and add holes, which means we get a bad address error
94*d4514f0bSApple OSS Distributions  * instead, and the test fails because the return code doesn't match what's
95*d4514f0bSApple OSS Distributions  * recorded in the golden files.
96*d4514f0bSApple OSS Distributions  * To avoid this, we want to keep a guard page inside our data section.
97*d4514f0bSApple OSS Distributions  * Because that data section is one of the first things in our address space,
98*d4514f0bSApple OSS Distributions  * the behavior of wire is (more) predictable.
99*d4514f0bSApple OSS Distributions  */
100*d4514f0bSApple OSS Distributions static _Alignas(KB16) char guard_page[KB16];
101*d4514f0bSApple OSS Distributions 
102*d4514f0bSApple OSS Distributions static void
set_up_guard_page(void)103*d4514f0bSApple OSS Distributions set_up_guard_page(void)
104*d4514f0bSApple OSS Distributions {
105*d4514f0bSApple OSS Distributions 	/*
106*d4514f0bSApple OSS Distributions 	 * Ensure that _Alignas worked as expected.
107*d4514f0bSApple OSS Distributions 	 */
108*d4514f0bSApple OSS Distributions 	assert(0 == (((mach_vm_address_t)guard_page) & PAGE_MASK));
109*d4514f0bSApple OSS Distributions 	/*
110*d4514f0bSApple OSS Distributions 	 * Remove all permissions on guard_page such that it is a guard page.
111*d4514f0bSApple OSS Distributions 	 */
112*d4514f0bSApple OSS Distributions 	assert(0 == mprotect(guard_page, sizeof(guard_page), 0));
113*d4514f0bSApple OSS Distributions }
114*d4514f0bSApple OSS Distributions 
115*d4514f0bSApple OSS Distributions // Return a file descriptor that tests can read and write.
116*d4514f0bSApple OSS Distributions // A single temporary file is shared among all tests.
117*d4514f0bSApple OSS Distributions static int
get_fd()118*d4514f0bSApple OSS Distributions get_fd()
119*d4514f0bSApple OSS Distributions {
120*d4514f0bSApple OSS Distributions 	static int fd = -1;
121*d4514f0bSApple OSS Distributions 	if (fd > 0) {
122*d4514f0bSApple OSS Distributions 		return fd;
123*d4514f0bSApple OSS Distributions 	}
124*d4514f0bSApple OSS Distributions 
125*d4514f0bSApple OSS Distributions 	char filename[] = "/tmp/vm_parameter_validation_XXXXXX";
126*d4514f0bSApple OSS Distributions 	fd = mkstemp(filename);
127*d4514f0bSApple OSS Distributions 	assert(fd > 2);  // not stdin/stdout/stderr
128*d4514f0bSApple OSS Distributions 	return fd;
129*d4514f0bSApple OSS Distributions }
130*d4514f0bSApple OSS Distributions 
131*d4514f0bSApple OSS Distributions static int rosetta_dyld_fd = -1;
132*d4514f0bSApple OSS Distributions // Return a file descriptor that Rosetta dyld will accept
133*d4514f0bSApple OSS Distributions static int
get_dyld_fd()134*d4514f0bSApple OSS Distributions get_dyld_fd()
135*d4514f0bSApple OSS Distributions {
136*d4514f0bSApple OSS Distributions 	if (rosetta_dyld_fd >= 0) {
137*d4514f0bSApple OSS Distributions 		return rosetta_dyld_fd;
138*d4514f0bSApple OSS Distributions 	}
139*d4514f0bSApple OSS Distributions 
140*d4514f0bSApple OSS Distributions 	if (!isRosetta()) {
141*d4514f0bSApple OSS Distributions 		rosetta_dyld_fd = 0;
142*d4514f0bSApple OSS Distributions 		return rosetta_dyld_fd;
143*d4514f0bSApple OSS Distributions 	}
144*d4514f0bSApple OSS Distributions 
145*d4514f0bSApple OSS Distributions 	rosetta_dyld_fd = 0;
146*d4514f0bSApple OSS Distributions 	return rosetta_dyld_fd;
147*d4514f0bSApple OSS Distributions }
148*d4514f0bSApple OSS Distributions 
149*d4514f0bSApple OSS Distributions // Close the Rosetta dyld fd (only one test calls this)
150*d4514f0bSApple OSS Distributions static void
close_dyld_fd()151*d4514f0bSApple OSS Distributions close_dyld_fd()
152*d4514f0bSApple OSS Distributions {
153*d4514f0bSApple OSS Distributions 	if (isRosetta()) {
154*d4514f0bSApple OSS Distributions 		assert(rosetta_dyld_fd > 2);
155*d4514f0bSApple OSS Distributions 		if (close(rosetta_dyld_fd) != 0) {
156*d4514f0bSApple OSS Distributions 			assert(0);
157*d4514f0bSApple OSS Distributions 		}
158*d4514f0bSApple OSS Distributions 		rosetta_dyld_fd = -1;
159*d4514f0bSApple OSS Distributions 	}
160*d4514f0bSApple OSS Distributions }
161*d4514f0bSApple OSS Distributions 
162*d4514f0bSApple OSS Distributions static int
munmap_helper(void * ptr,size_t size)163*d4514f0bSApple OSS Distributions munmap_helper(void *ptr, size_t size)
164*d4514f0bSApple OSS Distributions {
165*d4514f0bSApple OSS Distributions 	mach_vm_address_t start, end;
166*d4514f0bSApple OSS Distributions 	if (0 != size) { // munmap rejects size == 0 even though mmap accepts it
167*d4514f0bSApple OSS Distributions 		/*
168*d4514f0bSApple OSS Distributions 		 * munmap expects aligned inputs, even though mmap sometimes
169*d4514f0bSApple OSS Distributions 		 * returns unaligned values
170*d4514f0bSApple OSS Distributions 		 */
171*d4514f0bSApple OSS Distributions 		start = ((mach_vm_address_t)ptr) & ~PAGE_MASK;
172*d4514f0bSApple OSS Distributions 		end = (((mach_vm_address_t)ptr) + size + PAGE_MASK) & ~PAGE_MASK;
173*d4514f0bSApple OSS Distributions 		return munmap((void*)start, end - start);
174*d4514f0bSApple OSS Distributions 	}
175*d4514f0bSApple OSS Distributions 	return 0;
176*d4514f0bSApple OSS Distributions }
177*d4514f0bSApple OSS Distributions 
178*d4514f0bSApple OSS Distributions // Some tests provoke EXC_GUARD exceptions.
179*d4514f0bSApple OSS Distributions // We disable EXC_GUARD if possible. If we can't, we disable those tests instead.
180*d4514f0bSApple OSS Distributions static bool EXC_GUARD_ENABLED = true;
181*d4514f0bSApple OSS Distributions 
182*d4514f0bSApple OSS Distributions static int
call_munlock(void * start,size_t size)183*d4514f0bSApple OSS Distributions call_munlock(void *start, size_t size)
184*d4514f0bSApple OSS Distributions {
185*d4514f0bSApple OSS Distributions 	int err = munlock(start, size);
186*d4514f0bSApple OSS Distributions 	return err ? errno : 0;
187*d4514f0bSApple OSS Distributions }
188*d4514f0bSApple OSS Distributions 
189*d4514f0bSApple OSS Distributions static int
call_mlock(void * start,size_t size)190*d4514f0bSApple OSS Distributions call_mlock(void *start, size_t size)
191*d4514f0bSApple OSS Distributions {
192*d4514f0bSApple OSS Distributions 	int err = mlock(start, size);
193*d4514f0bSApple OSS Distributions 	return err ? errno : 0;
194*d4514f0bSApple OSS Distributions }
195*d4514f0bSApple OSS Distributions 
196*d4514f0bSApple OSS Distributions extern int __munmap(void *, size_t);
197*d4514f0bSApple OSS Distributions 
198*d4514f0bSApple OSS Distributions static kern_return_t
call_munmap(MAP_T map __unused,mach_vm_address_t start,mach_vm_size_t size)199*d4514f0bSApple OSS Distributions call_munmap(MAP_T map __unused, mach_vm_address_t start, mach_vm_size_t size)
200*d4514f0bSApple OSS Distributions {
201*d4514f0bSApple OSS Distributions 	int err = __munmap((void*)start, (size_t)size);
202*d4514f0bSApple OSS Distributions 	return err ? errno : 0;
203*d4514f0bSApple OSS Distributions }
204*d4514f0bSApple OSS Distributions 
205*d4514f0bSApple OSS Distributions static int
call_mremap_encrypted(void * start,size_t size)206*d4514f0bSApple OSS Distributions call_mremap_encrypted(void *start, size_t size)
207*d4514f0bSApple OSS Distributions {
208*d4514f0bSApple OSS Distributions 	int err = mremap_encrypted(start, size, CRYPTID_NO_ENCRYPTION, /*cputype=*/ 0, /*cpusubtype=*/ 0);
209*d4514f0bSApple OSS Distributions 	return err ? errno : 0;
210*d4514f0bSApple OSS Distributions }
211*d4514f0bSApple OSS Distributions 
212*d4514f0bSApple OSS Distributions /////////////////////////////////////////////////////
213*d4514f0bSApple OSS Distributions // Mach tests
214*d4514f0bSApple OSS Distributions 
215*d4514f0bSApple OSS Distributions static mach_port_t
make_a_mem_object(mach_vm_size_t size)216*d4514f0bSApple OSS Distributions make_a_mem_object(mach_vm_size_t size)
217*d4514f0bSApple OSS Distributions {
218*d4514f0bSApple OSS Distributions 	mach_port_t out_handle;
219*d4514f0bSApple OSS Distributions 	kern_return_t kr = mach_memory_object_memory_entry_64(mach_host_self(), 1, size, VM_PROT_READ | VM_PROT_WRITE, 0, &out_handle);
220*d4514f0bSApple OSS Distributions 	assert(kr == 0);
221*d4514f0bSApple OSS Distributions 	return out_handle;
222*d4514f0bSApple OSS Distributions }
223*d4514f0bSApple OSS Distributions 
224*d4514f0bSApple OSS Distributions static mach_port_t
make_a_mem_entry(vm_size_t size)225*d4514f0bSApple OSS Distributions make_a_mem_entry(vm_size_t size)
226*d4514f0bSApple OSS Distributions {
227*d4514f0bSApple OSS Distributions 	mach_port_t port;
228*d4514f0bSApple OSS Distributions 	memory_object_size_t s = (memory_object_size_t)size;
229*d4514f0bSApple OSS Distributions 	kern_return_t kr = mach_make_memory_entry_64(mach_host_self(), &s, (memory_object_offset_t)0, MAP_MEM_NAMED_CREATE | MAP_MEM_LEDGER_TAGGED, &port, MACH_PORT_NULL);
230*d4514f0bSApple OSS Distributions 	T_QUIET; T_ASSERT_MACH_SUCCESS(kr, "allocate memory entry");
231*d4514f0bSApple OSS Distributions 	return port;
232*d4514f0bSApple OSS Distributions }
233*d4514f0bSApple OSS Distributions 
234*d4514f0bSApple OSS Distributions static inline void
check_mach_memory_entry_outparam_changes(kern_return_t * kr,mach_port_t out_handle,mach_port_t saved_handle)235*d4514f0bSApple OSS Distributions check_mach_memory_entry_outparam_changes(kern_return_t * kr, mach_port_t out_handle, mach_port_t saved_handle)
236*d4514f0bSApple OSS Distributions {
237*d4514f0bSApple OSS Distributions 	if (*kr != KERN_SUCCESS) {
238*d4514f0bSApple OSS Distributions 		if (out_handle != (mach_port_t) saved_handle) {
239*d4514f0bSApple OSS Distributions 			*kr = OUT_PARAM_BAD;
240*d4514f0bSApple OSS Distributions 		}
241*d4514f0bSApple OSS Distributions 	}
242*d4514f0bSApple OSS Distributions }
243*d4514f0bSApple OSS Distributions // mach_make_memory_entry is really several functions wearing a trenchcoat.
244*d4514f0bSApple OSS Distributions // Run a separate test for each variation.
245*d4514f0bSApple OSS Distributions 
246*d4514f0bSApple OSS Distributions // mach_make_memory_entry also has a confusing number of entrypoints:
247*d4514f0bSApple OSS Distributions // U64: mach_make_memory_entry_64(64) (mach_make_memory_entry is the same MIG message)
248*d4514f0bSApple OSS Distributions // U32: mach_make_memory_entry(32), mach_make_memory_entry_64(64), _mach_make_memory_entry(64) (each is a unique MIG message)
249*d4514f0bSApple OSS Distributions #define IMPL(FN, T)                                                               \
250*d4514f0bSApple OSS Distributions 	static kern_return_t                                                      \
251*d4514f0bSApple OSS Distributions 	call_ ## FN ## __start_size__memonly(MAP_T map, T start, T size)                      \
252*d4514f0bSApple OSS Distributions 	{                                                                         \
253*d4514f0bSApple OSS Distributions 	        mach_port_t memobject = make_a_mem_object(TEST_ALLOC_SIZE + 1);          \
254*d4514f0bSApple OSS Distributions 	        T io_size = size;                                                 \
255*d4514f0bSApple OSS Distributions 	        mach_port_t invalid_value = UNLIKELY_INITIAL_MACH_PORT;            \
256*d4514f0bSApple OSS Distributions 	        mach_port_t out_handle = invalid_value;                           \
257*d4514f0bSApple OSS Distributions 	        kern_return_t kr = FN(map, &io_size, start,                       \
258*d4514f0bSApple OSS Distributions 	                              VM_PROT_READ | MAP_MEM_ONLY, &out_handle, memobject); \
259*d4514f0bSApple OSS Distributions 	        if (kr == 0) {                                                    \
260*d4514f0bSApple OSS Distributions 	                (void)mach_port_deallocate(mach_task_self(), out_handle); \
261*d4514f0bSApple OSS Distributions 	/* MAP_MEM_ONLY doesn't use the size. It should not change it. */         \
262*d4514f0bSApple OSS Distributions 	                if(io_size != size) {                                     \
263*d4514f0bSApple OSS Distributions 	                        kr = OUT_PARAM_BAD;                               \
264*d4514f0bSApple OSS Distributions 	                }                                                         \
265*d4514f0bSApple OSS Distributions 	        }                                                                 \
266*d4514f0bSApple OSS Distributions 	        (void)mach_port_deallocate(mach_task_self(), memobject);          \
267*d4514f0bSApple OSS Distributions 	        check_mach_memory_entry_outparam_changes(&kr, out_handle, invalid_value); \
268*d4514f0bSApple OSS Distributions 	        return kr;                                                        \
269*d4514f0bSApple OSS Distributions 	}                                                                         \
270*d4514f0bSApple OSS Distributions                                                                                   \
271*d4514f0bSApple OSS Distributions 	static kern_return_t                                                      \
272*d4514f0bSApple OSS Distributions 	call_ ## FN ## __start_size__namedcreate(MAP_T map, T start, T size)                  \
273*d4514f0bSApple OSS Distributions 	{                                                                         \
274*d4514f0bSApple OSS Distributions 	        mach_port_t memobject = make_a_mem_object(TEST_ALLOC_SIZE + 1);          \
275*d4514f0bSApple OSS Distributions 	        T io_size = size;                                                 \
276*d4514f0bSApple OSS Distributions 	        mach_port_t invalid_value = UNLIKELY_INITIAL_MACH_PORT;            \
277*d4514f0bSApple OSS Distributions 	        mach_port_t out_handle = invalid_value;                           \
278*d4514f0bSApple OSS Distributions 	        kern_return_t kr = FN(map, &io_size, start,                       \
279*d4514f0bSApple OSS Distributions 	                              VM_PROT_READ | MAP_MEM_NAMED_CREATE, &out_handle, memobject); \
280*d4514f0bSApple OSS Distributions 	        if (kr == 0) {                                                    \
281*d4514f0bSApple OSS Distributions 	                (void)mach_port_deallocate(mach_task_self(), out_handle); \
282*d4514f0bSApple OSS Distributions 	        }                                                                 \
283*d4514f0bSApple OSS Distributions 	        (void)mach_port_deallocate(mach_task_self(), memobject);          \
284*d4514f0bSApple OSS Distributions 	        check_mach_memory_entry_outparam_changes(&kr, out_handle, invalid_value); \
285*d4514f0bSApple OSS Distributions 	        return kr;                                                        \
286*d4514f0bSApple OSS Distributions 	}                                                                         \
287*d4514f0bSApple OSS Distributions                                                                                   \
288*d4514f0bSApple OSS Distributions 	static kern_return_t                                                      \
289*d4514f0bSApple OSS Distributions 	call_ ## FN ## __start_size__copy(MAP_T map, T start, T size)                         \
290*d4514f0bSApple OSS Distributions 	{                                                                         \
291*d4514f0bSApple OSS Distributions 	        mach_port_t memobject = make_a_mem_object(TEST_ALLOC_SIZE + 1);          \
292*d4514f0bSApple OSS Distributions 	        T io_size = size;                                                 \
293*d4514f0bSApple OSS Distributions 	        mach_port_t invalid_value = UNLIKELY_INITIAL_MACH_PORT;            \
294*d4514f0bSApple OSS Distributions 	        mach_port_t out_handle = invalid_value;                           \
295*d4514f0bSApple OSS Distributions 	        kern_return_t kr = FN(map, &io_size, start,                       \
296*d4514f0bSApple OSS Distributions 	                              VM_PROT_READ | MAP_MEM_VM_COPY, &out_handle, memobject); \
297*d4514f0bSApple OSS Distributions 	        if (kr == 0) {                                                    \
298*d4514f0bSApple OSS Distributions 	                (void)mach_port_deallocate(mach_task_self(), out_handle); \
299*d4514f0bSApple OSS Distributions 	        }                                                                 \
300*d4514f0bSApple OSS Distributions 	        (void)mach_port_deallocate(mach_task_self(), memobject);          \
301*d4514f0bSApple OSS Distributions 	        check_mach_memory_entry_outparam_changes(&kr, out_handle, invalid_value); \
302*d4514f0bSApple OSS Distributions 	        return kr;                                                        \
303*d4514f0bSApple OSS Distributions 	}                                                                         \
304*d4514f0bSApple OSS Distributions                                                                                   \
305*d4514f0bSApple OSS Distributions 	static kern_return_t                                                      \
306*d4514f0bSApple OSS Distributions 	call_ ## FN ## __start_size__share(MAP_T map, T start, T size)                         \
307*d4514f0bSApple OSS Distributions 	{                                                                         \
308*d4514f0bSApple OSS Distributions 	        mach_port_t memobject = make_a_mem_object(TEST_ALLOC_SIZE + 1);          \
309*d4514f0bSApple OSS Distributions 	        T io_size = size;                                                 \
310*d4514f0bSApple OSS Distributions 	        mach_port_t invalid_value = UNLIKELY_INITIAL_MACH_PORT;            \
311*d4514f0bSApple OSS Distributions 	        mach_port_t out_handle = invalid_value;                           \
312*d4514f0bSApple OSS Distributions 	        kern_return_t kr = FN(map, &io_size, start,                       \
313*d4514f0bSApple OSS Distributions 	                              VM_PROT_READ | MAP_MEM_VM_SHARE, &out_handle, memobject); \
314*d4514f0bSApple OSS Distributions 	        if (kr == 0) {                                                    \
315*d4514f0bSApple OSS Distributions 	                (void)mach_port_deallocate(mach_task_self(), out_handle); \
316*d4514f0bSApple OSS Distributions 	        }                                                                 \
317*d4514f0bSApple OSS Distributions 	        (void)mach_port_deallocate(mach_task_self(), memobject);          \
318*d4514f0bSApple OSS Distributions 	        check_mach_memory_entry_outparam_changes(&kr, out_handle, invalid_value); \
319*d4514f0bSApple OSS Distributions 	        return kr;                                                        \
320*d4514f0bSApple OSS Distributions 	}                                                                         \
321*d4514f0bSApple OSS Distributions                                                                                   \
322*d4514f0bSApple OSS Distributions 	static kern_return_t                                                      \
323*d4514f0bSApple OSS Distributions 	call_ ## FN ## __start_size__namedreuse(MAP_T map, T start, T size)                   \
324*d4514f0bSApple OSS Distributions 	{                                                                         \
325*d4514f0bSApple OSS Distributions 	        mach_port_t memobject = make_a_mem_object(TEST_ALLOC_SIZE + 1);          \
326*d4514f0bSApple OSS Distributions 	        T io_size = size;                                                 \
327*d4514f0bSApple OSS Distributions 	        mach_port_t invalid_value = UNLIKELY_INITIAL_MACH_PORT;            \
328*d4514f0bSApple OSS Distributions 	        mach_port_t out_handle = invalid_value;                           \
329*d4514f0bSApple OSS Distributions 	        kern_return_t kr = FN(map, &io_size, start,                       \
330*d4514f0bSApple OSS Distributions 	                              VM_PROT_READ | MAP_MEM_NAMED_REUSE, &out_handle, memobject); \
331*d4514f0bSApple OSS Distributions 	        if (kr == 0) {                                                    \
332*d4514f0bSApple OSS Distributions 	                (void)mach_port_deallocate(mach_task_self(), out_handle); \
333*d4514f0bSApple OSS Distributions 	        }                                                                 \
334*d4514f0bSApple OSS Distributions 	        (void)mach_port_deallocate(mach_task_self(), memobject);          \
335*d4514f0bSApple OSS Distributions 	        check_mach_memory_entry_outparam_changes(&kr, out_handle, invalid_value); \
336*d4514f0bSApple OSS Distributions 	        return kr;                                                        \
337*d4514f0bSApple OSS Distributions 	}                                                                         \
338*d4514f0bSApple OSS Distributions                                                                                   \
339*d4514f0bSApple OSS Distributions 	static kern_return_t                                                      \
340*d4514f0bSApple OSS Distributions 	call_ ## FN ## __vm_prot(MAP_T map, T start, T size, vm_prot_t prot)      \
341*d4514f0bSApple OSS Distributions 	{                                                                         \
342*d4514f0bSApple OSS Distributions 	        mach_port_t memobject = make_a_mem_object(TEST_ALLOC_SIZE + 1);          \
343*d4514f0bSApple OSS Distributions 	        T io_size = size;                                                 \
344*d4514f0bSApple OSS Distributions 	        mach_port_t invalid_value = UNLIKELY_INITIAL_MACH_PORT;            \
345*d4514f0bSApple OSS Distributions 	        mach_port_t out_handle = invalid_value;                           \
346*d4514f0bSApple OSS Distributions 	        kern_return_t kr = FN(map, &io_size, start,                       \
347*d4514f0bSApple OSS Distributions 	                              prot, &out_handle, memobject); \
348*d4514f0bSApple OSS Distributions 	        if (kr == 0) {                                                    \
349*d4514f0bSApple OSS Distributions 	                (void)mach_port_deallocate(mach_task_self(), out_handle); \
350*d4514f0bSApple OSS Distributions 	        }                                                                 \
351*d4514f0bSApple OSS Distributions 	        (void)mach_port_deallocate(mach_task_self(), memobject);          \
352*d4514f0bSApple OSS Distributions 	        check_mach_memory_entry_outparam_changes(&kr, out_handle, invalid_value); \
353*d4514f0bSApple OSS Distributions 	        return kr;                                                        \
354*d4514f0bSApple OSS Distributions 	}
355*d4514f0bSApple OSS Distributions 
IMPL(mach_make_memory_entry_64,mach_vm_address_t)356*d4514f0bSApple OSS Distributions IMPL(mach_make_memory_entry_64, mach_vm_address_t)
357*d4514f0bSApple OSS Distributions #if TEST_OLD_STYLE_MACH
358*d4514f0bSApple OSS Distributions IMPL(mach_make_memory_entry, vm_address_t)
359*d4514f0bSApple OSS Distributions IMPL(_mach_make_memory_entry, mach_vm_address_t)
360*d4514f0bSApple OSS Distributions #endif
361*d4514f0bSApple OSS Distributions #undef IMPL
362*d4514f0bSApple OSS Distributions 
363*d4514f0bSApple OSS Distributions static inline void
364*d4514f0bSApple OSS Distributions check_mach_memory_object_memory_entry_outparam_changes(kern_return_t * kr, mach_port_t out_handle,
365*d4514f0bSApple OSS Distributions     mach_port_t saved_out_handle)
366*d4514f0bSApple OSS Distributions {
367*d4514f0bSApple OSS Distributions 	if (*kr != KERN_SUCCESS) {
368*d4514f0bSApple OSS Distributions 		if (out_handle != saved_out_handle) {
369*d4514f0bSApple OSS Distributions 			*kr = OUT_PARAM_BAD;
370*d4514f0bSApple OSS Distributions 		}
371*d4514f0bSApple OSS Distributions 	}
372*d4514f0bSApple OSS Distributions }
373*d4514f0bSApple OSS Distributions 
374*d4514f0bSApple OSS Distributions #define IMPL(FN) \
375*d4514f0bSApple OSS Distributions 	static kern_return_t                                            \
376*d4514f0bSApple OSS Distributions 	call_ ## FN ## __size(MAP_T map __unused, mach_vm_size_t size)  \
377*d4514f0bSApple OSS Distributions 	{                                                               \
378*d4514f0bSApple OSS Distributions 	        kern_return_t kr;                                       \
379*d4514f0bSApple OSS Distributions 	        mach_port_t invalid_value = UNLIKELY_INITIAL_MACH_PORT;  \
380*d4514f0bSApple OSS Distributions 	        mach_port_t out_entry = invalid_value;                  \
381*d4514f0bSApple OSS Distributions 	        kr = FN(mach_host_self(), 1, size, VM_PROT_READ | VM_PROT_WRITE, 0, &out_entry); \
382*d4514f0bSApple OSS Distributions 	        if (kr == 0) {                                          \
383*d4514f0bSApple OSS Distributions 	                (void)mach_port_deallocate(mach_task_self(), out_entry); \
384*d4514f0bSApple OSS Distributions 	        }                                                       \
385*d4514f0bSApple OSS Distributions 	        check_mach_memory_object_memory_entry_outparam_changes(&kr, out_entry, invalid_value); \
386*d4514f0bSApple OSS Distributions 	        return kr;                                              \
387*d4514f0bSApple OSS Distributions 	}                                                               \
388*d4514f0bSApple OSS Distributions 	static kern_return_t                                            \
389*d4514f0bSApple OSS Distributions 	call_ ## FN ## __vm_prot(MAP_T map __unused, mach_vm_size_t size, vm_prot_t prot) \
390*d4514f0bSApple OSS Distributions 	{                                                               \
391*d4514f0bSApple OSS Distributions 	        kern_return_t kr;                                       \
392*d4514f0bSApple OSS Distributions 	        mach_port_t invalid_value = UNLIKELY_INITIAL_MACH_PORT;  \
393*d4514f0bSApple OSS Distributions 	        mach_port_t out_entry = invalid_value;                  \
394*d4514f0bSApple OSS Distributions 	        kr = FN(mach_host_self(), 1, size, prot, 0, &out_entry); \
395*d4514f0bSApple OSS Distributions 	        if (kr == 0) {                                          \
396*d4514f0bSApple OSS Distributions 	                (void)mach_port_deallocate(mach_task_self(), out_entry); \
397*d4514f0bSApple OSS Distributions 	        }                                                       \
398*d4514f0bSApple OSS Distributions 	        check_mach_memory_object_memory_entry_outparam_changes(&kr, out_entry, invalid_value); \
399*d4514f0bSApple OSS Distributions 	        return kr;                                              \
400*d4514f0bSApple OSS Distributions 	}
401*d4514f0bSApple OSS Distributions 
402*d4514f0bSApple OSS Distributions // The declaration of mach_memory_object_memory_entry is buggy on U32.
403*d4514f0bSApple OSS Distributions // We compile in our own MIG user stub for it with a "replacement_" prefix.
404*d4514f0bSApple OSS Distributions // rdar://117927965
405*d4514f0bSApple OSS Distributions IMPL(replacement_mach_memory_object_memory_entry)
IMPL(mach_memory_object_memory_entry_64)406*d4514f0bSApple OSS Distributions IMPL(mach_memory_object_memory_entry_64)
407*d4514f0bSApple OSS Distributions #undef IMPL
408*d4514f0bSApple OSS Distributions 
409*d4514f0bSApple OSS Distributions static inline void
410*d4514f0bSApple OSS Distributions check_vm_read_outparam_changes(kern_return_t * kr, mach_vm_size_t size, mach_vm_size_t requested_size,
411*d4514f0bSApple OSS Distributions     mach_vm_address_t addr)
412*d4514f0bSApple OSS Distributions {
413*d4514f0bSApple OSS Distributions 	if (*kr == KERN_SUCCESS) {
414*d4514f0bSApple OSS Distributions 		if (size != requested_size) {
415*d4514f0bSApple OSS Distributions 			*kr = OUT_PARAM_BAD;
416*d4514f0bSApple OSS Distributions 		}
417*d4514f0bSApple OSS Distributions 		if (size == 0) {
418*d4514f0bSApple OSS Distributions 			if (addr != 0) {
419*d4514f0bSApple OSS Distributions 				*kr = OUT_PARAM_BAD;
420*d4514f0bSApple OSS Distributions 			}
421*d4514f0bSApple OSS Distributions 		}
422*d4514f0bSApple OSS Distributions 	}
423*d4514f0bSApple OSS Distributions }
424*d4514f0bSApple OSS Distributions 
425*d4514f0bSApple OSS Distributions 
426*d4514f0bSApple OSS Distributions static kern_return_t
call_mach_vm_read(MAP_T map,mach_vm_address_t start,mach_vm_size_t size)427*d4514f0bSApple OSS Distributions call_mach_vm_read(MAP_T map, mach_vm_address_t start, mach_vm_size_t size)
428*d4514f0bSApple OSS Distributions {
429*d4514f0bSApple OSS Distributions 	vm_offset_t out_addr = UNLIKELY_INITIAL_ADDRESS;
430*d4514f0bSApple OSS Distributions 	mach_msg_type_number_t out_size = UNLIKELY_INITIAL_SIZE;
431*d4514f0bSApple OSS Distributions 	kern_return_t kr = mach_vm_read(map, start, size, &out_addr, &out_size);
432*d4514f0bSApple OSS Distributions 	if (kr == 0) {
433*d4514f0bSApple OSS Distributions 		(void)mach_vm_deallocate(mach_task_self(), out_addr, out_size);
434*d4514f0bSApple OSS Distributions 	}
435*d4514f0bSApple OSS Distributions 	check_vm_read_outparam_changes(&kr, out_size, size, out_addr);
436*d4514f0bSApple OSS Distributions 	return kr;
437*d4514f0bSApple OSS Distributions }
438*d4514f0bSApple OSS Distributions #if TEST_OLD_STYLE_MACH
439*d4514f0bSApple OSS Distributions static kern_return_t
call_vm_read(MAP_T map,vm_address_t start,vm_size_t size)440*d4514f0bSApple OSS Distributions call_vm_read(MAP_T map, vm_address_t start, vm_size_t size)
441*d4514f0bSApple OSS Distributions {
442*d4514f0bSApple OSS Distributions 	vm_offset_t out_addr = UNLIKELY_INITIAL_ADDRESS;
443*d4514f0bSApple OSS Distributions 	mach_msg_type_number_t out_size = UNLIKELY_INITIAL_SIZE;
444*d4514f0bSApple OSS Distributions 	kern_return_t kr = vm_read(map, start, size, &out_addr, &out_size);
445*d4514f0bSApple OSS Distributions 	if (kr == 0) {
446*d4514f0bSApple OSS Distributions 		(void)mach_vm_deallocate(mach_task_self(), out_addr, out_size);
447*d4514f0bSApple OSS Distributions 	}
448*d4514f0bSApple OSS Distributions 	check_vm_read_outparam_changes(&kr, out_size, size, out_addr);
449*d4514f0bSApple OSS Distributions 	return kr;
450*d4514f0bSApple OSS Distributions }
451*d4514f0bSApple OSS Distributions #endif
452*d4514f0bSApple OSS Distributions 
453*d4514f0bSApple OSS Distributions static kern_return_t
call_mach_vm_read_list(MAP_T map,mach_vm_address_t start,mach_vm_size_t size)454*d4514f0bSApple OSS Distributions call_mach_vm_read_list(MAP_T map, mach_vm_address_t start, mach_vm_size_t size)
455*d4514f0bSApple OSS Distributions {
456*d4514f0bSApple OSS Distributions 	mach_vm_read_entry_t re = {{.address = start, .size = size}};
457*d4514f0bSApple OSS Distributions 	kern_return_t kr = mach_vm_read_list(map, re, 1);
458*d4514f0bSApple OSS Distributions 	if (kr == 0) {
459*d4514f0bSApple OSS Distributions 		(void)mach_vm_deallocate(mach_task_self(), re[0].address, re[0].size);
460*d4514f0bSApple OSS Distributions 	}
461*d4514f0bSApple OSS Distributions 	return kr;
462*d4514f0bSApple OSS Distributions }
463*d4514f0bSApple OSS Distributions #if TEST_OLD_STYLE_MACH
464*d4514f0bSApple OSS Distributions static kern_return_t
call_vm_read_list(MAP_T map,vm_address_t start,vm_size_t size)465*d4514f0bSApple OSS Distributions call_vm_read_list(MAP_T map, vm_address_t start, vm_size_t size)
466*d4514f0bSApple OSS Distributions {
467*d4514f0bSApple OSS Distributions 	vm_read_entry_t re = {{.address = start, .size = size}};
468*d4514f0bSApple OSS Distributions 	kern_return_t kr = vm_read_list(map, re, 1);
469*d4514f0bSApple OSS Distributions 	if (kr == 0) {
470*d4514f0bSApple OSS Distributions 		(void)mach_vm_deallocate(mach_task_self(), re[0].address, re[0].size);
471*d4514f0bSApple OSS Distributions 	}
472*d4514f0bSApple OSS Distributions 	return kr;
473*d4514f0bSApple OSS Distributions }
474*d4514f0bSApple OSS Distributions #endif
475*d4514f0bSApple OSS Distributions 
476*d4514f0bSApple OSS Distributions static inline void
check_vm_read_overwrite_outparam_changes(kern_return_t * kr,mach_vm_size_t size,mach_vm_size_t requested_size)477*d4514f0bSApple OSS Distributions check_vm_read_overwrite_outparam_changes(kern_return_t * kr, mach_vm_size_t size, mach_vm_size_t requested_size)
478*d4514f0bSApple OSS Distributions {
479*d4514f0bSApple OSS Distributions 	if (*kr == KERN_SUCCESS) {
480*d4514f0bSApple OSS Distributions 		if (size != requested_size) {
481*d4514f0bSApple OSS Distributions 			*kr = OUT_PARAM_BAD;
482*d4514f0bSApple OSS Distributions 		}
483*d4514f0bSApple OSS Distributions 	}
484*d4514f0bSApple OSS Distributions }
485*d4514f0bSApple OSS Distributions 
486*d4514f0bSApple OSS Distributions static kern_return_t __unused
call_mach_vm_read_overwrite__ssz(MAP_T map,mach_vm_address_t start,mach_vm_address_t start_2,mach_vm_size_t size)487*d4514f0bSApple OSS Distributions call_mach_vm_read_overwrite__ssz(MAP_T map, mach_vm_address_t start, mach_vm_address_t start_2, mach_vm_size_t size)
488*d4514f0bSApple OSS Distributions {
489*d4514f0bSApple OSS Distributions 	mach_vm_size_t out_size;
490*d4514f0bSApple OSS Distributions 	kern_return_t kr = mach_vm_read_overwrite(map, start, size, start_2, &out_size);
491*d4514f0bSApple OSS Distributions 	check_vm_read_overwrite_outparam_changes(&kr, out_size, size);
492*d4514f0bSApple OSS Distributions 	return kr;
493*d4514f0bSApple OSS Distributions }
494*d4514f0bSApple OSS Distributions 
495*d4514f0bSApple OSS Distributions static kern_return_t
call_mach_vm_read_overwrite__src(MAP_T map,mach_vm_address_t src,mach_vm_size_t size)496*d4514f0bSApple OSS Distributions call_mach_vm_read_overwrite__src(MAP_T map, mach_vm_address_t src, mach_vm_size_t size)
497*d4514f0bSApple OSS Distributions {
498*d4514f0bSApple OSS Distributions 	mach_vm_size_t out_size;
499*d4514f0bSApple OSS Distributions 	allocation_t dst SMART_ALLOCATE_VM(map, TEST_ALLOC_SIZE, VM_PROT_DEFAULT);
500*d4514f0bSApple OSS Distributions 	kern_return_t kr = mach_vm_read_overwrite(map, src, size, dst.addr, &out_size);
501*d4514f0bSApple OSS Distributions 	check_vm_read_overwrite_outparam_changes(&kr, out_size, size);
502*d4514f0bSApple OSS Distributions 	return kr;
503*d4514f0bSApple OSS Distributions }
504*d4514f0bSApple OSS Distributions 
505*d4514f0bSApple OSS Distributions static kern_return_t
call_mach_vm_read_overwrite__dst(MAP_T map,mach_vm_address_t dst,mach_vm_size_t size)506*d4514f0bSApple OSS Distributions call_mach_vm_read_overwrite__dst(MAP_T map, mach_vm_address_t dst, mach_vm_size_t size)
507*d4514f0bSApple OSS Distributions {
508*d4514f0bSApple OSS Distributions 	mach_vm_size_t out_size;
509*d4514f0bSApple OSS Distributions 	allocation_t src SMART_ALLOCATE_VM(map, TEST_ALLOC_SIZE, VM_PROT_DEFAULT);
510*d4514f0bSApple OSS Distributions 	kern_return_t kr = mach_vm_read_overwrite(map, src.addr, size, dst, &out_size);
511*d4514f0bSApple OSS Distributions 	check_vm_read_overwrite_outparam_changes(&kr, out_size, size);
512*d4514f0bSApple OSS Distributions 	return kr;
513*d4514f0bSApple OSS Distributions }
514*d4514f0bSApple OSS Distributions 
515*d4514f0bSApple OSS Distributions #if TEST_OLD_STYLE_MACH
516*d4514f0bSApple OSS Distributions static kern_return_t __unused
call_vm_read_overwrite__ssz(MAP_T map,vm_address_t start,vm_address_t start_2,vm_size_t size)517*d4514f0bSApple OSS Distributions call_vm_read_overwrite__ssz(MAP_T map, vm_address_t start, vm_address_t start_2, vm_size_t size)
518*d4514f0bSApple OSS Distributions {
519*d4514f0bSApple OSS Distributions 	vm_size_t out_size;
520*d4514f0bSApple OSS Distributions 	kern_return_t kr = vm_read_overwrite(map, start, size, start_2, &out_size);
521*d4514f0bSApple OSS Distributions 	check_vm_read_overwrite_outparam_changes(&kr, out_size, size);
522*d4514f0bSApple OSS Distributions 	return kr;
523*d4514f0bSApple OSS Distributions }
524*d4514f0bSApple OSS Distributions 
525*d4514f0bSApple OSS Distributions static kern_return_t
call_vm_read_overwrite__src(MAP_T map,vm_address_t src,vm_size_t size)526*d4514f0bSApple OSS Distributions call_vm_read_overwrite__src(MAP_T map, vm_address_t src, vm_size_t size)
527*d4514f0bSApple OSS Distributions {
528*d4514f0bSApple OSS Distributions 	vm_size_t out_size;
529*d4514f0bSApple OSS Distributions 	allocation_t dst SMART_ALLOCATE_VM(map, TEST_ALLOC_SIZE, VM_PROT_DEFAULT);
530*d4514f0bSApple OSS Distributions 	kern_return_t kr = vm_read_overwrite(map, src, size, (vm_address_t) dst.addr, &out_size);
531*d4514f0bSApple OSS Distributions 	check_vm_read_overwrite_outparam_changes(&kr, out_size, size);
532*d4514f0bSApple OSS Distributions 	return kr;
533*d4514f0bSApple OSS Distributions }
534*d4514f0bSApple OSS Distributions 
535*d4514f0bSApple OSS Distributions static kern_return_t
call_vm_read_overwrite__dst(MAP_T map,vm_address_t dst,vm_size_t size)536*d4514f0bSApple OSS Distributions call_vm_read_overwrite__dst(MAP_T map, vm_address_t dst, vm_size_t size)
537*d4514f0bSApple OSS Distributions {
538*d4514f0bSApple OSS Distributions 	vm_size_t out_size;
539*d4514f0bSApple OSS Distributions 	allocation_t src SMART_ALLOCATE_VM(map, TEST_ALLOC_SIZE, VM_PROT_DEFAULT);
540*d4514f0bSApple OSS Distributions 	kern_return_t kr = vm_read_overwrite(map, (vm_address_t) src.addr, size, dst, &out_size);
541*d4514f0bSApple OSS Distributions 	check_vm_read_overwrite_outparam_changes(&kr, out_size, size);
542*d4514f0bSApple OSS Distributions 	return kr;
543*d4514f0bSApple OSS Distributions }
544*d4514f0bSApple OSS Distributions #endif
545*d4514f0bSApple OSS Distributions 
546*d4514f0bSApple OSS Distributions 
547*d4514f0bSApple OSS Distributions 
548*d4514f0bSApple OSS Distributions static kern_return_t __unused
call_mach_vm_copy__ssz(MAP_T map,mach_vm_address_t start,mach_vm_address_t start_2,mach_vm_size_t size)549*d4514f0bSApple OSS Distributions call_mach_vm_copy__ssz(MAP_T map, mach_vm_address_t start, mach_vm_address_t start_2, mach_vm_size_t size)
550*d4514f0bSApple OSS Distributions {
551*d4514f0bSApple OSS Distributions 	kern_return_t kr = mach_vm_copy(map, start, size, start_2);
552*d4514f0bSApple OSS Distributions 	return kr;
553*d4514f0bSApple OSS Distributions }
554*d4514f0bSApple OSS Distributions 
555*d4514f0bSApple OSS Distributions static kern_return_t
call_mach_vm_copy__src(MAP_T map,mach_vm_address_t src,mach_vm_size_t size)556*d4514f0bSApple OSS Distributions call_mach_vm_copy__src(MAP_T map, mach_vm_address_t src, mach_vm_size_t size)
557*d4514f0bSApple OSS Distributions {
558*d4514f0bSApple OSS Distributions 	allocation_t dst SMART_ALLOCATE_VM(map, TEST_ALLOC_SIZE, VM_PROT_DEFAULT);
559*d4514f0bSApple OSS Distributions 	kern_return_t kr = mach_vm_copy(map, src, size, dst.addr);
560*d4514f0bSApple OSS Distributions 	return kr;
561*d4514f0bSApple OSS Distributions }
562*d4514f0bSApple OSS Distributions 
563*d4514f0bSApple OSS Distributions static kern_return_t
call_mach_vm_copy__dst(MAP_T map,mach_vm_address_t dst,mach_vm_size_t size)564*d4514f0bSApple OSS Distributions call_mach_vm_copy__dst(MAP_T map, mach_vm_address_t dst, mach_vm_size_t size)
565*d4514f0bSApple OSS Distributions {
566*d4514f0bSApple OSS Distributions 	allocation_t src SMART_ALLOCATE_VM(map, TEST_ALLOC_SIZE, VM_PROT_DEFAULT);
567*d4514f0bSApple OSS Distributions 	kern_return_t kr = mach_vm_copy(map, src.addr, size, dst);
568*d4514f0bSApple OSS Distributions 	return kr;
569*d4514f0bSApple OSS Distributions }
570*d4514f0bSApple OSS Distributions 
571*d4514f0bSApple OSS Distributions #if TEST_OLD_STYLE_MACH
572*d4514f0bSApple OSS Distributions static kern_return_t __unused
call_vm_copy__ssz(MAP_T map,mach_vm_address_t start,mach_vm_address_t start_2,mach_vm_size_t size)573*d4514f0bSApple OSS Distributions call_vm_copy__ssz(MAP_T map, mach_vm_address_t start, mach_vm_address_t start_2, mach_vm_size_t size)
574*d4514f0bSApple OSS Distributions {
575*d4514f0bSApple OSS Distributions 	kern_return_t kr = vm_copy(map, (vm_address_t) start, (vm_size_t) size, (vm_address_t) start_2);
576*d4514f0bSApple OSS Distributions 	return kr;
577*d4514f0bSApple OSS Distributions }
578*d4514f0bSApple OSS Distributions 
579*d4514f0bSApple OSS Distributions static kern_return_t
call_vm_copy__src(MAP_T map,vm_address_t src,vm_size_t size)580*d4514f0bSApple OSS Distributions call_vm_copy__src(MAP_T map, vm_address_t src, vm_size_t size)
581*d4514f0bSApple OSS Distributions {
582*d4514f0bSApple OSS Distributions 	allocation_t dst SMART_ALLOCATE_VM(map, TEST_ALLOC_SIZE, VM_PROT_DEFAULT);
583*d4514f0bSApple OSS Distributions 	kern_return_t kr = vm_copy(map, src, size, (vm_address_t) dst.addr);
584*d4514f0bSApple OSS Distributions 	return kr;
585*d4514f0bSApple OSS Distributions }
586*d4514f0bSApple OSS Distributions 
587*d4514f0bSApple OSS Distributions static kern_return_t
call_vm_copy__dst(MAP_T map,vm_address_t dst,vm_size_t size)588*d4514f0bSApple OSS Distributions call_vm_copy__dst(MAP_T map, vm_address_t dst, vm_size_t size)
589*d4514f0bSApple OSS Distributions {
590*d4514f0bSApple OSS Distributions 	allocation_t src SMART_ALLOCATE_VM(map, TEST_ALLOC_SIZE, VM_PROT_DEFAULT);
591*d4514f0bSApple OSS Distributions 	kern_return_t kr = vm_copy(map, (vm_address_t) src.addr, size, dst);
592*d4514f0bSApple OSS Distributions 	return kr;
593*d4514f0bSApple OSS Distributions }
594*d4514f0bSApple OSS Distributions #endif
595*d4514f0bSApple OSS Distributions 
596*d4514f0bSApple OSS Distributions static kern_return_t __unused
call_mach_vm_write__ssz(MAP_T map,mach_vm_address_t start,mach_vm_address_t start_2,mach_vm_size_t size)597*d4514f0bSApple OSS Distributions call_mach_vm_write__ssz(MAP_T map, mach_vm_address_t start, mach_vm_address_t start_2, mach_vm_size_t size)
598*d4514f0bSApple OSS Distributions {
599*d4514f0bSApple OSS Distributions 	kern_return_t kr = mach_vm_write(map, start, (vm_offset_t) start_2, (mach_msg_type_number_t) size);
600*d4514f0bSApple OSS Distributions 	return kr;
601*d4514f0bSApple OSS Distributions }
602*d4514f0bSApple OSS Distributions 
603*d4514f0bSApple OSS Distributions static kern_return_t
call_mach_vm_write__src(MAP_T map,mach_vm_address_t start,mach_vm_size_t size)604*d4514f0bSApple OSS Distributions call_mach_vm_write__src(MAP_T map, mach_vm_address_t start, mach_vm_size_t size)
605*d4514f0bSApple OSS Distributions {
606*d4514f0bSApple OSS Distributions 	allocation_t dst SMART_ALLOCATE_VM(map, TEST_ALLOC_SIZE, VM_PROT_DEFAULT);
607*d4514f0bSApple OSS Distributions 	kern_return_t kr = mach_vm_write(map, dst.addr, (vm_offset_t) start, (mach_msg_type_number_t) size);
608*d4514f0bSApple OSS Distributions 	return kr;
609*d4514f0bSApple OSS Distributions }
610*d4514f0bSApple OSS Distributions 
611*d4514f0bSApple OSS Distributions static kern_return_t
call_mach_vm_write__dst(MAP_T map,mach_vm_address_t start,mach_vm_size_t size)612*d4514f0bSApple OSS Distributions call_mach_vm_write__dst(MAP_T map, mach_vm_address_t start, mach_vm_size_t size)
613*d4514f0bSApple OSS Distributions {
614*d4514f0bSApple OSS Distributions 	allocation_t src SMART_ALLOCATE_VM(map, TEST_ALLOC_SIZE, VM_PROT_DEFAULT);
615*d4514f0bSApple OSS Distributions 	kern_return_t kr = mach_vm_write(map, start, (vm_offset_t) src.addr, (mach_msg_type_number_t) size);
616*d4514f0bSApple OSS Distributions 	return kr;
617*d4514f0bSApple OSS Distributions }
618*d4514f0bSApple OSS Distributions 
619*d4514f0bSApple OSS Distributions #if TEST_OLD_STYLE_MACH
620*d4514f0bSApple OSS Distributions static kern_return_t __unused
call_vm_write__ssz(MAP_T map,mach_vm_address_t start,mach_vm_address_t start_2,mach_vm_size_t size)621*d4514f0bSApple OSS Distributions call_vm_write__ssz(MAP_T map, mach_vm_address_t start, mach_vm_address_t start_2, mach_vm_size_t size)
622*d4514f0bSApple OSS Distributions {
623*d4514f0bSApple OSS Distributions 	kern_return_t kr = vm_write(map, (vm_address_t) start, (vm_offset_t) start_2, (mach_msg_type_number_t) size);
624*d4514f0bSApple OSS Distributions 	return kr;
625*d4514f0bSApple OSS Distributions }
626*d4514f0bSApple OSS Distributions 
627*d4514f0bSApple OSS Distributions static kern_return_t
call_vm_write__src(MAP_T map,vm_address_t start,vm_size_t size)628*d4514f0bSApple OSS Distributions call_vm_write__src(MAP_T map, vm_address_t start, vm_size_t size)
629*d4514f0bSApple OSS Distributions {
630*d4514f0bSApple OSS Distributions 	allocation_t dst SMART_ALLOCATE_VM(map, TEST_ALLOC_SIZE, VM_PROT_DEFAULT);
631*d4514f0bSApple OSS Distributions 	kern_return_t kr = vm_write(map, (vm_address_t) dst.addr, start, (mach_msg_type_number_t) size);
632*d4514f0bSApple OSS Distributions 	return kr;
633*d4514f0bSApple OSS Distributions }
634*d4514f0bSApple OSS Distributions 
635*d4514f0bSApple OSS Distributions static kern_return_t
call_vm_write__dst(MAP_T map,vm_address_t start,vm_size_t size)636*d4514f0bSApple OSS Distributions call_vm_write__dst(MAP_T map, vm_address_t start, vm_size_t size)
637*d4514f0bSApple OSS Distributions {
638*d4514f0bSApple OSS Distributions 	allocation_t src SMART_ALLOCATE_VM(map, TEST_ALLOC_SIZE, VM_PROT_DEFAULT);
639*d4514f0bSApple OSS Distributions 	kern_return_t kr = vm_write(map, start, (vm_offset_t) src.addr, (mach_msg_type_number_t) size);
640*d4514f0bSApple OSS Distributions 	return kr;
641*d4514f0bSApple OSS Distributions }
642*d4514f0bSApple OSS Distributions #endif
643*d4514f0bSApple OSS Distributions 
644*d4514f0bSApple OSS Distributions // mach_vm_wire, vm_wire (start/size)
645*d4514f0bSApple OSS Distributions // "wire" and "unwire" paths diverge internally; test both
646*d4514f0bSApple OSS Distributions #define IMPL(FN, T, FLAVOR, PROT)                                       \
647*d4514f0bSApple OSS Distributions 	static kern_return_t                                            \
648*d4514f0bSApple OSS Distributions 	call_ ## FN ## __ ## FLAVOR(MAP_T map, T start, T size)         \
649*d4514f0bSApple OSS Distributions 	{                                                               \
650*d4514f0bSApple OSS Distributions 	        mach_port_t host_priv = HOST_PRIV_NULL;                 \
651*d4514f0bSApple OSS Distributions 	        kern_return_t kr = host_get_host_priv_port(mach_host_self(), &host_priv); \
652*d4514f0bSApple OSS Distributions 	        assert(kr == 0);  /* host priv port on macOS requires entitlements or root */ \
653*d4514f0bSApple OSS Distributions 	        kr = FN(host_priv, map, start, size, PROT);             \
654*d4514f0bSApple OSS Distributions 	        return kr;                                              \
655*d4514f0bSApple OSS Distributions 	}
656*d4514f0bSApple OSS Distributions IMPL(mach_vm_wire, mach_vm_address_t, wire, VM_PROT_READ)
657*d4514f0bSApple OSS Distributions IMPL(mach_vm_wire, mach_vm_address_t, unwire, VM_PROT_NONE)
658*d4514f0bSApple OSS Distributions // The declaration of vm_wire is buggy on U32.
659*d4514f0bSApple OSS Distributions // We compile in our own MIG user stub for it with a "replacement_" prefix.
660*d4514f0bSApple OSS Distributions // rdar://118258929
661*d4514f0bSApple OSS Distributions IMPL(replacement_vm_wire, mach_vm_address_t, wire, VM_PROT_READ)
662*d4514f0bSApple OSS Distributions IMPL(replacement_vm_wire, mach_vm_address_t, unwire, VM_PROT_NONE)
663*d4514f0bSApple OSS Distributions #undef IMPL
664*d4514f0bSApple OSS Distributions 
665*d4514f0bSApple OSS Distributions // mach_vm_wire, vm_wire (vm_prot_t)
666*d4514f0bSApple OSS Distributions #define IMPL(FN, T)                                                     \
667*d4514f0bSApple OSS Distributions 	static kern_return_t                                            \
668*d4514f0bSApple OSS Distributions 	call_ ## FN ## __vm_prot(MAP_T map, T start, T size, vm_prot_t prot) \
669*d4514f0bSApple OSS Distributions 	{                                                               \
670*d4514f0bSApple OSS Distributions 	        mach_port_t host_priv = HOST_PRIV_NULL;                 \
671*d4514f0bSApple OSS Distributions 	        kern_return_t kr = host_get_host_priv_port(mach_host_self(), &host_priv); \
672*d4514f0bSApple OSS Distributions 	        assert(kr == 0);  /* host priv port on macOS requires entitlements or root */ \
673*d4514f0bSApple OSS Distributions 	        kr = FN(host_priv, map, start, size, prot);             \
674*d4514f0bSApple OSS Distributions 	        return kr;                                              \
675*d4514f0bSApple OSS Distributions 	}
676*d4514f0bSApple OSS Distributions IMPL(mach_vm_wire, mach_vm_address_t)
677*d4514f0bSApple OSS Distributions // The declaration of vm_wire is buggy on U32.
678*d4514f0bSApple OSS Distributions // We compile in our own MIG user stub for it with a "replacement_" prefix.
679*d4514f0bSApple OSS Distributions // rdar://118258929
680*d4514f0bSApple OSS Distributions IMPL(replacement_vm_wire, mach_vm_address_t)
681*d4514f0bSApple OSS Distributions #undef IMPL
682*d4514f0bSApple OSS Distributions 
683*d4514f0bSApple OSS Distributions 
684*d4514f0bSApple OSS Distributions // mach_vm_map/vm32_map/vm32_map_64 infra
685*d4514f0bSApple OSS Distributions 
686*d4514f0bSApple OSS Distributions typedef kern_return_t (*map_fn_t)(vm_map_t target_task,
687*d4514f0bSApple OSS Distributions     mach_vm_address_t *address,
688*d4514f0bSApple OSS Distributions     mach_vm_size_t size,
689*d4514f0bSApple OSS Distributions     mach_vm_offset_t mask,
690*d4514f0bSApple OSS Distributions     int flags,
691*d4514f0bSApple OSS Distributions     mem_entry_name_port_t object,
692*d4514f0bSApple OSS Distributions     memory_object_offset_t offset,
693*d4514f0bSApple OSS Distributions     boolean_t copy,
694*d4514f0bSApple OSS Distributions     vm_prot_t cur_protection,
695*d4514f0bSApple OSS Distributions     vm_prot_t max_protection,
696*d4514f0bSApple OSS Distributions     vm_inherit_t inheritance);
697*d4514f0bSApple OSS Distributions 
698*d4514f0bSApple OSS Distributions static kern_return_t
call_map_fn__allocate_fixed(map_fn_t fn,MAP_T map,mach_vm_address_t start,mach_vm_size_t size)699*d4514f0bSApple OSS Distributions call_map_fn__allocate_fixed(map_fn_t fn, MAP_T map, mach_vm_address_t start, mach_vm_size_t size)
700*d4514f0bSApple OSS Distributions {
701*d4514f0bSApple OSS Distributions 	mach_vm_address_t out_addr = start;
702*d4514f0bSApple OSS Distributions 	kern_return_t kr = fn(map, &out_addr, size, 0, VM_FLAGS_FIXED | VM_FLAGS_OVERWRITE,
703*d4514f0bSApple OSS Distributions 	    0, 0, 0, 0, 0, VM_INHERIT_NONE);
704*d4514f0bSApple OSS Distributions 	// fixed-overwrite with pre-existing allocation, don't deallocate
705*d4514f0bSApple OSS Distributions 	return kr;
706*d4514f0bSApple OSS Distributions }
707*d4514f0bSApple OSS Distributions 
708*d4514f0bSApple OSS Distributions static kern_return_t
call_map_fn__allocate_fixed_copy(map_fn_t fn,MAP_T map,mach_vm_address_t start,mach_vm_size_t size)709*d4514f0bSApple OSS Distributions call_map_fn__allocate_fixed_copy(map_fn_t fn, MAP_T map, mach_vm_address_t start, mach_vm_size_t size)
710*d4514f0bSApple OSS Distributions {
711*d4514f0bSApple OSS Distributions 	mach_vm_address_t out_addr = start;
712*d4514f0bSApple OSS Distributions 	kern_return_t kr = fn(map, &out_addr, size, 0, VM_FLAGS_FIXED | VM_FLAGS_OVERWRITE,
713*d4514f0bSApple OSS Distributions 	    0, 0, true, 0, 0, VM_INHERIT_NONE);
714*d4514f0bSApple OSS Distributions 	// fixed-overwrite with pre-existing allocation, don't deallocate
715*d4514f0bSApple OSS Distributions 	return kr;
716*d4514f0bSApple OSS Distributions }
717*d4514f0bSApple OSS Distributions 
718*d4514f0bSApple OSS Distributions static kern_return_t
call_map_fn__allocate_anywhere(map_fn_t fn,MAP_T map,mach_vm_address_t start_hint,mach_vm_size_t size)719*d4514f0bSApple OSS Distributions call_map_fn__allocate_anywhere(map_fn_t fn, MAP_T map, mach_vm_address_t start_hint, mach_vm_size_t size)
720*d4514f0bSApple OSS Distributions {
721*d4514f0bSApple OSS Distributions 	mach_vm_address_t out_addr = start_hint;
722*d4514f0bSApple OSS Distributions 	kern_return_t kr = fn(map, &out_addr, size, 0, VM_FLAGS_ANYWHERE, 0, 0, 0, 0, 0, VM_INHERIT_NONE);
723*d4514f0bSApple OSS Distributions 	if (kr == 0) {
724*d4514f0bSApple OSS Distributions 		(void)mach_vm_deallocate(map, out_addr, size);
725*d4514f0bSApple OSS Distributions 	}
726*d4514f0bSApple OSS Distributions 	return kr;
727*d4514f0bSApple OSS Distributions }
728*d4514f0bSApple OSS Distributions 
729*d4514f0bSApple OSS Distributions static kern_return_t
call_map_fn__memobject_fixed(map_fn_t fn,MAP_T map,mach_vm_address_t start,mach_vm_size_t size)730*d4514f0bSApple OSS Distributions call_map_fn__memobject_fixed(map_fn_t fn, MAP_T map, mach_vm_address_t start, mach_vm_size_t size)
731*d4514f0bSApple OSS Distributions {
732*d4514f0bSApple OSS Distributions 	mach_port_t memobject = make_a_mem_object(TEST_ALLOC_SIZE + 1);
733*d4514f0bSApple OSS Distributions 	mach_vm_address_t out_addr = start;
734*d4514f0bSApple OSS Distributions 	kern_return_t kr = fn(map, &out_addr, size, 0, VM_FLAGS_FIXED | VM_FLAGS_OVERWRITE,
735*d4514f0bSApple OSS Distributions 	    memobject, KB16, false, VM_PROT_DEFAULT, VM_PROT_DEFAULT, VM_INHERIT_DEFAULT);
736*d4514f0bSApple OSS Distributions 	(void)mach_port_deallocate(mach_task_self(), memobject);
737*d4514f0bSApple OSS Distributions 	// fixed-overwrite with pre-existing allocation, don't deallocate
738*d4514f0bSApple OSS Distributions 	return kr;
739*d4514f0bSApple OSS Distributions }
740*d4514f0bSApple OSS Distributions 
741*d4514f0bSApple OSS Distributions static kern_return_t
call_map_fn__memobject_fixed_copy(map_fn_t fn,MAP_T map,mach_vm_address_t start,mach_vm_size_t size)742*d4514f0bSApple OSS Distributions call_map_fn__memobject_fixed_copy(map_fn_t fn, MAP_T map, mach_vm_address_t start, mach_vm_size_t size)
743*d4514f0bSApple OSS Distributions {
744*d4514f0bSApple OSS Distributions 	mach_port_t memobject = make_a_mem_object(TEST_ALLOC_SIZE + 1);
745*d4514f0bSApple OSS Distributions 	mach_vm_address_t out_addr = start;
746*d4514f0bSApple OSS Distributions 	kern_return_t kr = fn(map, &out_addr, size, 0, VM_FLAGS_FIXED | VM_FLAGS_OVERWRITE,
747*d4514f0bSApple OSS Distributions 	    memobject, KB16, true, VM_PROT_DEFAULT, VM_PROT_DEFAULT, VM_INHERIT_DEFAULT);
748*d4514f0bSApple OSS Distributions 	(void)mach_port_deallocate(mach_task_self(), memobject);
749*d4514f0bSApple OSS Distributions 	// fixed-overwrite with pre-existing allocation, don't deallocate
750*d4514f0bSApple OSS Distributions 	return kr;
751*d4514f0bSApple OSS Distributions }
752*d4514f0bSApple OSS Distributions 
753*d4514f0bSApple OSS Distributions static kern_return_t
call_map_fn__memobject_anywhere(map_fn_t fn,MAP_T map,mach_vm_address_t start_hint,mach_vm_size_t size)754*d4514f0bSApple OSS Distributions call_map_fn__memobject_anywhere(map_fn_t fn, MAP_T map, mach_vm_address_t start_hint, mach_vm_size_t size)
755*d4514f0bSApple OSS Distributions {
756*d4514f0bSApple OSS Distributions 	mach_port_t memobject = make_a_mem_object(TEST_ALLOC_SIZE + 1);
757*d4514f0bSApple OSS Distributions 	mach_vm_address_t out_addr = start_hint;
758*d4514f0bSApple OSS Distributions 	kern_return_t kr = fn(map, &out_addr, size, 0, VM_FLAGS_ANYWHERE, memobject,
759*d4514f0bSApple OSS Distributions 	    KB16, false, VM_PROT_DEFAULT, VM_PROT_DEFAULT, VM_INHERIT_DEFAULT);
760*d4514f0bSApple OSS Distributions 	if (kr == 0) {
761*d4514f0bSApple OSS Distributions 		(void)mach_vm_deallocate(map, out_addr, size);
762*d4514f0bSApple OSS Distributions 	}
763*d4514f0bSApple OSS Distributions 	(void)mach_port_deallocate(mach_task_self(), memobject);
764*d4514f0bSApple OSS Distributions 	return kr;
765*d4514f0bSApple OSS Distributions }
766*d4514f0bSApple OSS Distributions 
767*d4514f0bSApple OSS Distributions static kern_return_t
helper_call_map_fn__memobject__ssoo(map_fn_t fn,MAP_T map,int flags,bool copy,mach_vm_address_t start,mach_vm_size_t size,vm_object_offset_t offset,mach_vm_size_t obj_size)768*d4514f0bSApple OSS Distributions helper_call_map_fn__memobject__ssoo(map_fn_t fn, MAP_T map, int flags, bool copy, mach_vm_address_t start, mach_vm_size_t size, vm_object_offset_t offset, mach_vm_size_t obj_size)
769*d4514f0bSApple OSS Distributions {
770*d4514f0bSApple OSS Distributions 	mach_port_t memobject = make_a_mem_object(obj_size);
771*d4514f0bSApple OSS Distributions 	mach_vm_address_t out_addr = start;
772*d4514f0bSApple OSS Distributions 	kern_return_t kr = fn(map, &out_addr, size, 0, flags, memobject,
773*d4514f0bSApple OSS Distributions 	    offset, copy, VM_PROT_DEFAULT, VM_PROT_DEFAULT, VM_INHERIT_DEFAULT);
774*d4514f0bSApple OSS Distributions 	deallocate_if_not_fixed_overwrite(kr, map, out_addr, size, flags);
775*d4514f0bSApple OSS Distributions 	(void)mach_port_deallocate(mach_task_self(), memobject);
776*d4514f0bSApple OSS Distributions 	return kr;
777*d4514f0bSApple OSS Distributions }
778*d4514f0bSApple OSS Distributions 
779*d4514f0bSApple OSS Distributions static kern_return_t
call_map_fn__memobject_fixed__start_size_offset_object(map_fn_t fn,MAP_T map,mach_vm_address_t start,mach_vm_size_t size,vm_object_offset_t offset,mach_vm_size_t obj_size)780*d4514f0bSApple OSS Distributions call_map_fn__memobject_fixed__start_size_offset_object(map_fn_t fn, MAP_T map, mach_vm_address_t start, mach_vm_size_t size, vm_object_offset_t offset, mach_vm_size_t obj_size)
781*d4514f0bSApple OSS Distributions {
782*d4514f0bSApple OSS Distributions 	return helper_call_map_fn__memobject__ssoo(fn, map, VM_FLAGS_FIXED | VM_FLAGS_OVERWRITE, false, start, size, offset, obj_size);
783*d4514f0bSApple OSS Distributions }
784*d4514f0bSApple OSS Distributions 
785*d4514f0bSApple OSS Distributions static kern_return_t
call_map_fn__memobject_fixed_copy__start_size_offset_object(map_fn_t fn,MAP_T map,mach_vm_address_t start,mach_vm_size_t size,vm_object_offset_t offset,mach_vm_size_t obj_size)786*d4514f0bSApple OSS Distributions call_map_fn__memobject_fixed_copy__start_size_offset_object(map_fn_t fn, MAP_T map, mach_vm_address_t start, mach_vm_size_t size, vm_object_offset_t offset, mach_vm_size_t obj_size)
787*d4514f0bSApple OSS Distributions {
788*d4514f0bSApple OSS Distributions 	return helper_call_map_fn__memobject__ssoo(fn, map, VM_FLAGS_FIXED | VM_FLAGS_OVERWRITE, true, start, size, offset, obj_size);
789*d4514f0bSApple OSS Distributions }
790*d4514f0bSApple OSS Distributions 
791*d4514f0bSApple OSS Distributions static kern_return_t
call_map_fn__memobject_anywhere__start_size_offset_object(map_fn_t fn,MAP_T map,mach_vm_address_t start,mach_vm_size_t size,vm_object_offset_t offset,mach_vm_size_t obj_size)792*d4514f0bSApple OSS Distributions call_map_fn__memobject_anywhere__start_size_offset_object(map_fn_t fn, MAP_T map, mach_vm_address_t start, mach_vm_size_t size, vm_object_offset_t offset, mach_vm_size_t obj_size)
793*d4514f0bSApple OSS Distributions {
794*d4514f0bSApple OSS Distributions 	return helper_call_map_fn__memobject__ssoo(fn, map, VM_FLAGS_ANYWHERE, false, start, size, offset, obj_size);
795*d4514f0bSApple OSS Distributions }
796*d4514f0bSApple OSS Distributions 
797*d4514f0bSApple OSS Distributions static kern_return_t
help_call_map_fn__allocate__inherit(map_fn_t fn,MAP_T map,int flags,bool copy,mach_vm_address_t start,mach_vm_size_t size,vm_inherit_t inherit)798*d4514f0bSApple OSS Distributions help_call_map_fn__allocate__inherit(map_fn_t fn, MAP_T map, int flags, bool copy, mach_vm_address_t start, mach_vm_size_t size, vm_inherit_t inherit)
799*d4514f0bSApple OSS Distributions {
800*d4514f0bSApple OSS Distributions 	mach_vm_address_t out_addr = start;
801*d4514f0bSApple OSS Distributions 	kern_return_t kr = fn(map, &out_addr, size, 0, flags,
802*d4514f0bSApple OSS Distributions 	    0, KB16, copy, VM_PROT_DEFAULT, VM_PROT_DEFAULT, inherit);
803*d4514f0bSApple OSS Distributions 	deallocate_if_not_fixed_overwrite(kr, map, out_addr, size, flags);
804*d4514f0bSApple OSS Distributions 	return kr;
805*d4514f0bSApple OSS Distributions }
806*d4514f0bSApple OSS Distributions 
807*d4514f0bSApple OSS Distributions static kern_return_t
call_map_fn__allocate_fixed__inherit(map_fn_t fn,MAP_T map,mach_vm_address_t start,mach_vm_size_t size,vm_inherit_t inherit)808*d4514f0bSApple OSS Distributions call_map_fn__allocate_fixed__inherit(map_fn_t fn, MAP_T map, mach_vm_address_t start, mach_vm_size_t size, vm_inherit_t inherit)
809*d4514f0bSApple OSS Distributions {
810*d4514f0bSApple OSS Distributions 	return help_call_map_fn__allocate__inherit(fn, map, VM_FLAGS_FIXED | VM_FLAGS_OVERWRITE, false, start, size, inherit);
811*d4514f0bSApple OSS Distributions }
812*d4514f0bSApple OSS Distributions 
813*d4514f0bSApple OSS Distributions static kern_return_t
call_map_fn__allocate_fixed_copy__inherit(map_fn_t fn,MAP_T map,mach_vm_address_t start,mach_vm_size_t size,vm_inherit_t inherit)814*d4514f0bSApple OSS Distributions call_map_fn__allocate_fixed_copy__inherit(map_fn_t fn, MAP_T map, mach_vm_address_t start, mach_vm_size_t size, vm_inherit_t inherit)
815*d4514f0bSApple OSS Distributions {
816*d4514f0bSApple OSS Distributions 	return help_call_map_fn__allocate__inherit(fn, map, VM_FLAGS_FIXED | VM_FLAGS_OVERWRITE, true, start, size, inherit);
817*d4514f0bSApple OSS Distributions }
818*d4514f0bSApple OSS Distributions 
819*d4514f0bSApple OSS Distributions static kern_return_t
call_map_fn__allocate_anywhere__inherit(map_fn_t fn,MAP_T map,mach_vm_address_t start,mach_vm_size_t size,vm_inherit_t inherit)820*d4514f0bSApple OSS Distributions call_map_fn__allocate_anywhere__inherit(map_fn_t fn, MAP_T map, mach_vm_address_t start, mach_vm_size_t size, vm_inherit_t inherit)
821*d4514f0bSApple OSS Distributions {
822*d4514f0bSApple OSS Distributions 	return help_call_map_fn__allocate__inherit(fn, map, VM_FLAGS_ANYWHERE, false, start, size, inherit);
823*d4514f0bSApple OSS Distributions }
824*d4514f0bSApple OSS Distributions 
825*d4514f0bSApple OSS Distributions static kern_return_t
help_call_map_fn__memobject__inherit(map_fn_t fn,MAP_T map,int flags,bool copy,mach_vm_address_t start,mach_vm_size_t size,vm_inherit_t inherit)826*d4514f0bSApple OSS Distributions help_call_map_fn__memobject__inherit(map_fn_t fn, MAP_T map, int flags, bool copy, mach_vm_address_t start, mach_vm_size_t size, vm_inherit_t inherit)
827*d4514f0bSApple OSS Distributions {
828*d4514f0bSApple OSS Distributions 	mach_port_t memobject = make_a_mem_object(TEST_ALLOC_SIZE + 1);
829*d4514f0bSApple OSS Distributions 	mach_vm_address_t out_addr = start;
830*d4514f0bSApple OSS Distributions 	kern_return_t kr = fn(map, &out_addr, size, 0, flags,
831*d4514f0bSApple OSS Distributions 	    memobject, KB16, copy, VM_PROT_DEFAULT, VM_PROT_DEFAULT, inherit);
832*d4514f0bSApple OSS Distributions 	deallocate_if_not_fixed_overwrite(kr, map, out_addr, size, flags);
833*d4514f0bSApple OSS Distributions 	(void)mach_port_deallocate(mach_task_self(), memobject);
834*d4514f0bSApple OSS Distributions 	return kr;
835*d4514f0bSApple OSS Distributions }
836*d4514f0bSApple OSS Distributions 
837*d4514f0bSApple OSS Distributions static kern_return_t
call_map_fn__memobject_fixed__inherit(map_fn_t fn,MAP_T map,mach_vm_address_t start,mach_vm_size_t size,vm_inherit_t inherit)838*d4514f0bSApple OSS Distributions call_map_fn__memobject_fixed__inherit(map_fn_t fn, MAP_T map, mach_vm_address_t start, mach_vm_size_t size, vm_inherit_t inherit)
839*d4514f0bSApple OSS Distributions {
840*d4514f0bSApple OSS Distributions 	return help_call_map_fn__memobject__inherit(fn, map, VM_FLAGS_FIXED | VM_FLAGS_OVERWRITE, false, start, size, inherit);
841*d4514f0bSApple OSS Distributions }
842*d4514f0bSApple OSS Distributions 
843*d4514f0bSApple OSS Distributions static kern_return_t
call_map_fn__memobject_fixed_copy__inherit(map_fn_t fn,MAP_T map,mach_vm_address_t start,mach_vm_size_t size,vm_inherit_t inherit)844*d4514f0bSApple OSS Distributions call_map_fn__memobject_fixed_copy__inherit(map_fn_t fn, MAP_T map, mach_vm_address_t start, mach_vm_size_t size, vm_inherit_t inherit)
845*d4514f0bSApple OSS Distributions {
846*d4514f0bSApple OSS Distributions 	return help_call_map_fn__memobject__inherit(fn, map, VM_FLAGS_FIXED | VM_FLAGS_OVERWRITE, true, start, size, inherit);
847*d4514f0bSApple OSS Distributions }
848*d4514f0bSApple OSS Distributions 
849*d4514f0bSApple OSS Distributions static kern_return_t
call_map_fn__memobject_anywhere__inherit(map_fn_t fn,MAP_T map,mach_vm_address_t start,mach_vm_size_t size,vm_inherit_t inherit)850*d4514f0bSApple OSS Distributions call_map_fn__memobject_anywhere__inherit(map_fn_t fn, MAP_T map, mach_vm_address_t start, mach_vm_size_t size, vm_inherit_t inherit)
851*d4514f0bSApple OSS Distributions {
852*d4514f0bSApple OSS Distributions 	return help_call_map_fn__memobject__inherit(fn, map, VM_FLAGS_ANYWHERE, false, start, size, inherit);
853*d4514f0bSApple OSS Distributions }
854*d4514f0bSApple OSS Distributions 
855*d4514f0bSApple OSS Distributions static kern_return_t
call_map_fn__allocate__flags(map_fn_t fn,MAP_T map,mach_vm_address_t * start,mach_vm_size_t size,int flags)856*d4514f0bSApple OSS Distributions call_map_fn__allocate__flags(map_fn_t fn, MAP_T map, mach_vm_address_t * start, mach_vm_size_t size, int flags)
857*d4514f0bSApple OSS Distributions {
858*d4514f0bSApple OSS Distributions 	kern_return_t kr = fn(map, start, size, 0, flags,
859*d4514f0bSApple OSS Distributions 	    0, KB16, false, VM_PROT_DEFAULT, VM_PROT_DEFAULT, VM_INHERIT_DEFAULT);
860*d4514f0bSApple OSS Distributions 	deallocate_if_not_fixed_overwrite(kr, map, *start, size, flags);
861*d4514f0bSApple OSS Distributions 	return kr;
862*d4514f0bSApple OSS Distributions }
863*d4514f0bSApple OSS Distributions 
864*d4514f0bSApple OSS Distributions static kern_return_t
call_map_fn__allocate_copy__flags(map_fn_t fn,MAP_T map,mach_vm_address_t * start,mach_vm_size_t size,int flags)865*d4514f0bSApple OSS Distributions call_map_fn__allocate_copy__flags(map_fn_t fn, MAP_T map, mach_vm_address_t * start, mach_vm_size_t size, int flags)
866*d4514f0bSApple OSS Distributions {
867*d4514f0bSApple OSS Distributions 	kern_return_t kr = fn(map, start, size, 0, flags,
868*d4514f0bSApple OSS Distributions 	    0, KB16, false, VM_PROT_DEFAULT, VM_PROT_DEFAULT, VM_INHERIT_DEFAULT);
869*d4514f0bSApple OSS Distributions 	deallocate_if_not_fixed_overwrite(kr, map, *start, size, flags);
870*d4514f0bSApple OSS Distributions 	return kr;
871*d4514f0bSApple OSS Distributions }
872*d4514f0bSApple OSS Distributions 
873*d4514f0bSApple OSS Distributions static kern_return_t
call_map_fn__memobject__flags(map_fn_t fn,MAP_T map,mach_vm_address_t * start,mach_vm_size_t size,int flags)874*d4514f0bSApple OSS Distributions call_map_fn__memobject__flags(map_fn_t fn, MAP_T map, mach_vm_address_t * start, mach_vm_size_t size, int flags)
875*d4514f0bSApple OSS Distributions {
876*d4514f0bSApple OSS Distributions 	mach_port_t memobject = make_a_mem_object(TEST_ALLOC_SIZE + 1);
877*d4514f0bSApple OSS Distributions 	kern_return_t kr = fn(map, start, size, 0, flags,
878*d4514f0bSApple OSS Distributions 	    memobject, KB16, false, VM_PROT_DEFAULT, VM_PROT_DEFAULT, VM_INHERIT_DEFAULT);
879*d4514f0bSApple OSS Distributions 	deallocate_if_not_fixed_overwrite(kr, map, *start, size, flags);
880*d4514f0bSApple OSS Distributions 	(void)mach_port_deallocate(mach_task_self(), memobject);
881*d4514f0bSApple OSS Distributions 	return kr;
882*d4514f0bSApple OSS Distributions }
883*d4514f0bSApple OSS Distributions 
884*d4514f0bSApple OSS Distributions static kern_return_t
call_map_fn__memobject_copy__flags(map_fn_t fn,MAP_T map,mach_vm_address_t * start,mach_vm_size_t size,int flags)885*d4514f0bSApple OSS Distributions call_map_fn__memobject_copy__flags(map_fn_t fn, MAP_T map, mach_vm_address_t * start, mach_vm_size_t size, int flags)
886*d4514f0bSApple OSS Distributions {
887*d4514f0bSApple OSS Distributions 	mach_port_t memobject = make_a_mem_object(TEST_ALLOC_SIZE + 1);
888*d4514f0bSApple OSS Distributions 	kern_return_t kr = fn(map, start, size, 0, flags,
889*d4514f0bSApple OSS Distributions 	    memobject, KB16, true, VM_PROT_DEFAULT, VM_PROT_DEFAULT, VM_INHERIT_DEFAULT);
890*d4514f0bSApple OSS Distributions 	deallocate_if_not_fixed_overwrite(kr, map, *start, size, flags);
891*d4514f0bSApple OSS Distributions 	(void)mach_port_deallocate(mach_task_self(), memobject);
892*d4514f0bSApple OSS Distributions 	return kr;
893*d4514f0bSApple OSS Distributions }
894*d4514f0bSApple OSS Distributions 
895*d4514f0bSApple OSS Distributions static kern_return_t
help_call_map_fn__allocate__prot_pairs(map_fn_t fn,MAP_T map,int flags,bool copy,vm_prot_t cur,vm_prot_t max)896*d4514f0bSApple OSS Distributions help_call_map_fn__allocate__prot_pairs(map_fn_t fn, MAP_T map, int flags, bool copy, vm_prot_t cur, vm_prot_t max)
897*d4514f0bSApple OSS Distributions {
898*d4514f0bSApple OSS Distributions 	mach_vm_address_t out_addr = 0;
899*d4514f0bSApple OSS Distributions 	kern_return_t kr = fn(map, &out_addr, KB16, 0, flags,
900*d4514f0bSApple OSS Distributions 	    0, KB16, copy, cur, max, VM_INHERIT_DEFAULT);
901*d4514f0bSApple OSS Distributions 	deallocate_if_not_fixed_overwrite(kr, map, out_addr, KB16, flags);
902*d4514f0bSApple OSS Distributions 	return kr;
903*d4514f0bSApple OSS Distributions }
904*d4514f0bSApple OSS Distributions 
905*d4514f0bSApple OSS Distributions static kern_return_t
call_map_fn__allocate_fixed__prot_pairs(map_fn_t fn,MAP_T map,vm_prot_t cur,vm_prot_t max)906*d4514f0bSApple OSS Distributions call_map_fn__allocate_fixed__prot_pairs(map_fn_t fn, MAP_T map, vm_prot_t cur, vm_prot_t max)
907*d4514f0bSApple OSS Distributions {
908*d4514f0bSApple OSS Distributions 	return help_call_map_fn__allocate__prot_pairs(fn, map, VM_FLAGS_FIXED | VM_FLAGS_OVERWRITE, false, cur, max);
909*d4514f0bSApple OSS Distributions }
910*d4514f0bSApple OSS Distributions 
911*d4514f0bSApple OSS Distributions static kern_return_t
call_map_fn__allocate_fixed_copy__prot_pairs(map_fn_t fn,MAP_T map,vm_prot_t cur,vm_prot_t max)912*d4514f0bSApple OSS Distributions call_map_fn__allocate_fixed_copy__prot_pairs(map_fn_t fn, MAP_T map, vm_prot_t cur, vm_prot_t max)
913*d4514f0bSApple OSS Distributions {
914*d4514f0bSApple OSS Distributions 	return help_call_map_fn__allocate__prot_pairs(fn, map, VM_FLAGS_FIXED | VM_FLAGS_OVERWRITE, true, cur, max);
915*d4514f0bSApple OSS Distributions }
916*d4514f0bSApple OSS Distributions 
917*d4514f0bSApple OSS Distributions static kern_return_t
call_map_fn__allocate_anywhere__prot_pairs(map_fn_t fn,MAP_T map,vm_prot_t cur,vm_prot_t max)918*d4514f0bSApple OSS Distributions call_map_fn__allocate_anywhere__prot_pairs(map_fn_t fn, MAP_T map, vm_prot_t cur, vm_prot_t max)
919*d4514f0bSApple OSS Distributions {
920*d4514f0bSApple OSS Distributions 	return help_call_map_fn__allocate__prot_pairs(fn, map, VM_FLAGS_ANYWHERE, false, cur, max);
921*d4514f0bSApple OSS Distributions }
922*d4514f0bSApple OSS Distributions 
923*d4514f0bSApple OSS Distributions static kern_return_t
help_call_map_fn__memobject__prot_pairs(map_fn_t fn,MAP_T map,int flags,bool copy,vm_prot_t cur,vm_prot_t max)924*d4514f0bSApple OSS Distributions help_call_map_fn__memobject__prot_pairs(map_fn_t fn, MAP_T map, int flags, bool copy, vm_prot_t cur, vm_prot_t max)
925*d4514f0bSApple OSS Distributions {
926*d4514f0bSApple OSS Distributions 	mach_port_t memobject = make_a_mem_object(TEST_ALLOC_SIZE + 1);
927*d4514f0bSApple OSS Distributions 	mach_vm_address_t out_addr = 0;
928*d4514f0bSApple OSS Distributions 	kern_return_t kr = fn(map, &out_addr, KB16, 0, flags,
929*d4514f0bSApple OSS Distributions 	    memobject, KB16, copy, cur, max, VM_INHERIT_DEFAULT);
930*d4514f0bSApple OSS Distributions 	deallocate_if_not_fixed_overwrite(kr, map, out_addr, KB16, flags);
931*d4514f0bSApple OSS Distributions 	(void)mach_port_deallocate(mach_task_self(), memobject);
932*d4514f0bSApple OSS Distributions 	return kr;
933*d4514f0bSApple OSS Distributions }
934*d4514f0bSApple OSS Distributions 
935*d4514f0bSApple OSS Distributions static kern_return_t
call_map_fn__memobject_fixed__prot_pairs(map_fn_t fn,MAP_T map,vm_prot_t cur,vm_prot_t max)936*d4514f0bSApple OSS Distributions call_map_fn__memobject_fixed__prot_pairs(map_fn_t fn, MAP_T map, vm_prot_t cur, vm_prot_t max)
937*d4514f0bSApple OSS Distributions {
938*d4514f0bSApple OSS Distributions 	return help_call_map_fn__memobject__prot_pairs(fn, map, VM_FLAGS_FIXED | VM_FLAGS_OVERWRITE, false, cur, max);
939*d4514f0bSApple OSS Distributions }
940*d4514f0bSApple OSS Distributions 
941*d4514f0bSApple OSS Distributions static kern_return_t
call_map_fn__memobject_fixed_copy__prot_pairs(map_fn_t fn,MAP_T map,vm_prot_t cur,vm_prot_t max)942*d4514f0bSApple OSS Distributions call_map_fn__memobject_fixed_copy__prot_pairs(map_fn_t fn, MAP_T map, vm_prot_t cur, vm_prot_t max)
943*d4514f0bSApple OSS Distributions {
944*d4514f0bSApple OSS Distributions 	return help_call_map_fn__memobject__prot_pairs(fn, map, VM_FLAGS_FIXED | VM_FLAGS_OVERWRITE, true, cur, max);
945*d4514f0bSApple OSS Distributions }
946*d4514f0bSApple OSS Distributions 
947*d4514f0bSApple OSS Distributions static kern_return_t
call_map_fn__memobject_anywhere__prot_pairs(map_fn_t fn,MAP_T map,vm_prot_t cur,vm_prot_t max)948*d4514f0bSApple OSS Distributions call_map_fn__memobject_anywhere__prot_pairs(map_fn_t fn, MAP_T map, vm_prot_t cur, vm_prot_t max)
949*d4514f0bSApple OSS Distributions {
950*d4514f0bSApple OSS Distributions 	return help_call_map_fn__memobject__prot_pairs(fn, map, VM_FLAGS_ANYWHERE, false, cur, max);
951*d4514f0bSApple OSS Distributions }
952*d4514f0bSApple OSS Distributions 
953*d4514f0bSApple OSS Distributions // implementations
954*d4514f0bSApple OSS Distributions 
955*d4514f0bSApple OSS Distributions #define IMPL_MAP_FN_START_SIZE(map_fn, instance)                                                \
956*d4514f0bSApple OSS Distributions     static kern_return_t                                                                        \
957*d4514f0bSApple OSS Distributions     call_ ## map_fn ## __ ## instance (MAP_T map, mach_vm_address_t start, mach_vm_size_t size) \
958*d4514f0bSApple OSS Distributions     {                                                                                           \
959*d4514f0bSApple OSS Distributions 	return call_map_fn__ ## instance(map_fn, map, start, size);                             \
960*d4514f0bSApple OSS Distributions     }
961*d4514f0bSApple OSS Distributions 
962*d4514f0bSApple OSS Distributions #define IMPL_MAP_FN_HINT_SIZE(map_fn, instance)                                                      \
963*d4514f0bSApple OSS Distributions     static kern_return_t                                                                             \
964*d4514f0bSApple OSS Distributions     call_ ## map_fn ## __ ## instance (MAP_T map, mach_vm_address_t start_hint, mach_vm_size_t size) \
965*d4514f0bSApple OSS Distributions     {                                                                                                \
966*d4514f0bSApple OSS Distributions 	return call_map_fn__ ## instance(map_fn, map, start_hint, size);                             \
967*d4514f0bSApple OSS Distributions     }
968*d4514f0bSApple OSS Distributions 
969*d4514f0bSApple OSS Distributions #define IMPL_MAP_FN_START_SIZE_OFFSET_OBJECT(map_fn, instance)                                                                                                                   \
970*d4514f0bSApple OSS Distributions     static kern_return_t                                                                                                                                                         \
971*d4514f0bSApple OSS Distributions     call_ ## map_fn ## __ ## instance ## __start_size_offset_object(MAP_T map, mach_vm_address_t start, mach_vm_size_t size, vm_object_offset_t offset, mach_vm_size_t obj_size) \
972*d4514f0bSApple OSS Distributions     {                                                                                                                                                                            \
973*d4514f0bSApple OSS Distributions 	return call_map_fn__ ## instance ## __start_size_offset_object(map_fn, map, start, size, offset, obj_size);                                                              \
974*d4514f0bSApple OSS Distributions     }
975*d4514f0bSApple OSS Distributions 
976*d4514f0bSApple OSS Distributions #define IMPL_MAP_FN_START_SIZE_INHERIT(map_fn, instance)                                                                          \
977*d4514f0bSApple OSS Distributions     static kern_return_t                                                                                                          \
978*d4514f0bSApple OSS Distributions     call_ ## map_fn ## __ ## instance ## __inherit(MAP_T map, mach_vm_address_t start, mach_vm_size_t size, vm_inherit_t inherit) \
979*d4514f0bSApple OSS Distributions     {                                                                                                                             \
980*d4514f0bSApple OSS Distributions 	return call_map_fn__ ## instance ## __inherit(map_fn, map, start, size, inherit);                                         \
981*d4514f0bSApple OSS Distributions     }
982*d4514f0bSApple OSS Distributions 
983*d4514f0bSApple OSS Distributions #define IMPL_MAP_FN_START_SIZE_FLAGS(map_fn, instance)                                                                 \
984*d4514f0bSApple OSS Distributions     static kern_return_t                                                                                               \
985*d4514f0bSApple OSS Distributions     call_ ## map_fn ## __ ## instance ## __flags(MAP_T map, mach_vm_address_t * start, mach_vm_size_t size, int flags) \
986*d4514f0bSApple OSS Distributions     {                                                                                                                  \
987*d4514f0bSApple OSS Distributions 	return call_map_fn__ ## instance ## __flags(map_fn, map, start, size, flags);                                  \
988*d4514f0bSApple OSS Distributions     }
989*d4514f0bSApple OSS Distributions 
990*d4514f0bSApple OSS Distributions #define IMPL_MAP_FN_PROT_PAIRS(map_fn, instance)                                               \
991*d4514f0bSApple OSS Distributions     static kern_return_t                                                                       \
992*d4514f0bSApple OSS Distributions     call_ ## map_fn ## __ ## instance ## __prot_pairs(MAP_T map, vm_prot_t cur, vm_prot_t max) \
993*d4514f0bSApple OSS Distributions     {                                                                                          \
994*d4514f0bSApple OSS Distributions 	return call_map_fn__ ## instance ## __prot_pairs(map_fn, map, cur, max);               \
995*d4514f0bSApple OSS Distributions     }
996*d4514f0bSApple OSS Distributions 
997*d4514f0bSApple OSS Distributions #define IMPL(map_fn)                                                       \
998*d4514f0bSApple OSS Distributions 	IMPL_MAP_FN_START_SIZE(map_fn, allocate_fixed)                     \
999*d4514f0bSApple OSS Distributions 	IMPL_MAP_FN_START_SIZE(map_fn, allocate_fixed_copy)                \
1000*d4514f0bSApple OSS Distributions 	IMPL_MAP_FN_START_SIZE(map_fn, memobject_fixed)                    \
1001*d4514f0bSApple OSS Distributions 	IMPL_MAP_FN_START_SIZE(map_fn, memobject_fixed_copy)               \
1002*d4514f0bSApple OSS Distributions 	IMPL_MAP_FN_HINT_SIZE(map_fn, allocate_anywhere)                   \
1003*d4514f0bSApple OSS Distributions 	IMPL_MAP_FN_HINT_SIZE(map_fn, memobject_anywhere)                  \
1004*d4514f0bSApple OSS Distributions 	IMPL_MAP_FN_START_SIZE_OFFSET_OBJECT(map_fn, memobject_fixed)      \
1005*d4514f0bSApple OSS Distributions 	IMPL_MAP_FN_START_SIZE_OFFSET_OBJECT(map_fn, memobject_fixed_copy) \
1006*d4514f0bSApple OSS Distributions 	IMPL_MAP_FN_START_SIZE_OFFSET_OBJECT(map_fn, memobject_anywhere)   \
1007*d4514f0bSApple OSS Distributions 	IMPL_MAP_FN_START_SIZE_INHERIT(map_fn, allocate_fixed)             \
1008*d4514f0bSApple OSS Distributions 	IMPL_MAP_FN_START_SIZE_INHERIT(map_fn, allocate_fixed_copy)        \
1009*d4514f0bSApple OSS Distributions 	IMPL_MAP_FN_START_SIZE_INHERIT(map_fn, allocate_anywhere)          \
1010*d4514f0bSApple OSS Distributions 	IMPL_MAP_FN_START_SIZE_INHERIT(map_fn, memobject_fixed)            \
1011*d4514f0bSApple OSS Distributions 	IMPL_MAP_FN_START_SIZE_INHERIT(map_fn, memobject_fixed_copy)       \
1012*d4514f0bSApple OSS Distributions 	IMPL_MAP_FN_START_SIZE_INHERIT(map_fn, memobject_anywhere)         \
1013*d4514f0bSApple OSS Distributions 	IMPL_MAP_FN_START_SIZE_FLAGS(map_fn, allocate)                     \
1014*d4514f0bSApple OSS Distributions 	IMPL_MAP_FN_START_SIZE_FLAGS(map_fn, allocate_copy)                \
1015*d4514f0bSApple OSS Distributions 	IMPL_MAP_FN_START_SIZE_FLAGS(map_fn, memobject)                    \
1016*d4514f0bSApple OSS Distributions 	IMPL_MAP_FN_START_SIZE_FLAGS(map_fn, memobject_copy)               \
1017*d4514f0bSApple OSS Distributions 	IMPL_MAP_FN_PROT_PAIRS(map_fn, allocate_fixed)                     \
1018*d4514f0bSApple OSS Distributions 	IMPL_MAP_FN_PROT_PAIRS(map_fn, allocate_fixed_copy)                \
1019*d4514f0bSApple OSS Distributions 	IMPL_MAP_FN_PROT_PAIRS(map_fn, allocate_anywhere)                  \
1020*d4514f0bSApple OSS Distributions 	IMPL_MAP_FN_PROT_PAIRS(map_fn, memobject_fixed)                    \
1021*d4514f0bSApple OSS Distributions 	IMPL_MAP_FN_PROT_PAIRS(map_fn, memobject_fixed_copy)               \
1022*d4514f0bSApple OSS Distributions 	IMPL_MAP_FN_PROT_PAIRS(map_fn, memobject_anywhere)                 \
1023*d4514f0bSApple OSS Distributions 
1024*d4514f0bSApple OSS Distributions static kern_return_t
mach_vm_map_wrapped(vm_map_t target_task,mach_vm_address_t * address,mach_vm_size_t size,mach_vm_offset_t mask,int flags,mem_entry_name_port_t object,memory_object_offset_t offset,boolean_t copy,vm_prot_t cur_protection,vm_prot_t max_protection,vm_inherit_t inheritance)1025*d4514f0bSApple OSS Distributions mach_vm_map_wrapped(vm_map_t target_task,
1026*d4514f0bSApple OSS Distributions     mach_vm_address_t *address,
1027*d4514f0bSApple OSS Distributions     mach_vm_size_t size,
1028*d4514f0bSApple OSS Distributions     mach_vm_offset_t mask,
1029*d4514f0bSApple OSS Distributions     int flags,
1030*d4514f0bSApple OSS Distributions     mem_entry_name_port_t object,
1031*d4514f0bSApple OSS Distributions     memory_object_offset_t offset,
1032*d4514f0bSApple OSS Distributions     boolean_t copy,
1033*d4514f0bSApple OSS Distributions     vm_prot_t cur_protection,
1034*d4514f0bSApple OSS Distributions     vm_prot_t max_protection,
1035*d4514f0bSApple OSS Distributions     vm_inherit_t inheritance)
1036*d4514f0bSApple OSS Distributions {
1037*d4514f0bSApple OSS Distributions 	mach_vm_address_t addr = *address;
1038*d4514f0bSApple OSS Distributions 	kern_return_t kr = mach_vm_map(target_task, &addr, size, mask, flags, object, offset, copy, cur_protection, max_protection, inheritance);
1039*d4514f0bSApple OSS Distributions 	check_mach_vm_map_outparam_changes(&kr, addr, *address, flags, target_task);
1040*d4514f0bSApple OSS Distributions 	*address = addr;
1041*d4514f0bSApple OSS Distributions 	return kr;
1042*d4514f0bSApple OSS Distributions }
IMPL(mach_vm_map_wrapped)1043*d4514f0bSApple OSS Distributions IMPL(mach_vm_map_wrapped)
1044*d4514f0bSApple OSS Distributions 
1045*d4514f0bSApple OSS Distributions #if TEST_OLD_STYLE_MACH
1046*d4514f0bSApple OSS Distributions static kern_return_t
1047*d4514f0bSApple OSS Distributions vm_map_64_retyped(vm_map_t target_task,
1048*d4514f0bSApple OSS Distributions     mach_vm_address_t *address,
1049*d4514f0bSApple OSS Distributions     mach_vm_size_t size,
1050*d4514f0bSApple OSS Distributions     mach_vm_offset_t mask,
1051*d4514f0bSApple OSS Distributions     int flags,
1052*d4514f0bSApple OSS Distributions     mem_entry_name_port_t object,
1053*d4514f0bSApple OSS Distributions     memory_object_offset_t offset,
1054*d4514f0bSApple OSS Distributions     boolean_t copy,
1055*d4514f0bSApple OSS Distributions     vm_prot_t cur_protection,
1056*d4514f0bSApple OSS Distributions     vm_prot_t max_protection,
1057*d4514f0bSApple OSS Distributions     vm_inherit_t inheritance)
1058*d4514f0bSApple OSS Distributions {
1059*d4514f0bSApple OSS Distributions 	vm_address_t addr = (vm_address_t)*address;
1060*d4514f0bSApple OSS Distributions 	kern_return_t kr = vm_map_64(target_task, &addr, (vm_size_t)size, (vm_address_t)mask, flags, object, (vm_offset_t)offset, copy, cur_protection, max_protection, inheritance);
1061*d4514f0bSApple OSS Distributions 	check_mach_vm_map_outparam_changes(&kr, addr, (vm_address_t)*address, flags, target_task);
1062*d4514f0bSApple OSS Distributions 	*address = addr;
1063*d4514f0bSApple OSS Distributions 	return kr;
1064*d4514f0bSApple OSS Distributions }
IMPL(vm_map_64_retyped)1065*d4514f0bSApple OSS Distributions IMPL(vm_map_64_retyped)
1066*d4514f0bSApple OSS Distributions 
1067*d4514f0bSApple OSS Distributions static kern_return_t
1068*d4514f0bSApple OSS Distributions vm_map_retyped(vm_map_t target_task,
1069*d4514f0bSApple OSS Distributions     mach_vm_address_t *address,
1070*d4514f0bSApple OSS Distributions     mach_vm_size_t size,
1071*d4514f0bSApple OSS Distributions     mach_vm_offset_t mask,
1072*d4514f0bSApple OSS Distributions     int flags,
1073*d4514f0bSApple OSS Distributions     mem_entry_name_port_t object,
1074*d4514f0bSApple OSS Distributions     memory_object_offset_t offset,
1075*d4514f0bSApple OSS Distributions     boolean_t copy,
1076*d4514f0bSApple OSS Distributions     vm_prot_t cur_protection,
1077*d4514f0bSApple OSS Distributions     vm_prot_t max_protection,
1078*d4514f0bSApple OSS Distributions     vm_inherit_t inheritance)
1079*d4514f0bSApple OSS Distributions {
1080*d4514f0bSApple OSS Distributions 	vm_address_t addr = (vm_address_t)*address;
1081*d4514f0bSApple OSS Distributions 	kern_return_t kr = vm_map(target_task, &addr, (vm_size_t)size, (vm_address_t)mask, flags, object, (vm_offset_t)offset, copy, cur_protection, max_protection, inheritance);
1082*d4514f0bSApple OSS Distributions 	check_mach_vm_map_outparam_changes(&kr, addr, (vm_address_t)*address, flags, target_task);
1083*d4514f0bSApple OSS Distributions 	*address = addr;
1084*d4514f0bSApple OSS Distributions 	return kr;
1085*d4514f0bSApple OSS Distributions }
1086*d4514f0bSApple OSS Distributions IMPL(vm_map_retyped)
1087*d4514f0bSApple OSS Distributions #endif
1088*d4514f0bSApple OSS Distributions 
1089*d4514f0bSApple OSS Distributions #undef IMPL_MAP_FN_START_SIZE
1090*d4514f0bSApple OSS Distributions #undef IMPL_MAP_FN_SIZE
1091*d4514f0bSApple OSS Distributions #undef IMPL_MAP_FN_START_SIZE_OFFSET_OBJECT
1092*d4514f0bSApple OSS Distributions #undef IMPL_MAP_FN_START_SIZE_INHERIT
1093*d4514f0bSApple OSS Distributions #undef IMPL_MAP_FN_START_SIZE_FLAGS
1094*d4514f0bSApple OSS Distributions #undef IMPL_MAP_FN_PROT_PAIRS
1095*d4514f0bSApple OSS Distributions #undef IMPL
1096*d4514f0bSApple OSS Distributions 
1097*d4514f0bSApple OSS Distributions 
1098*d4514f0bSApple OSS Distributions // mmap
1099*d4514f0bSApple OSS Distributions // Directly calling this symbol lets us hit the syscall directly instead of the libsyscall wrapper.
1100*d4514f0bSApple OSS Distributions void *__mmap(void *addr, size_t len, int prot, int flags, int fildes, off_t off);
1101*d4514f0bSApple OSS Distributions 
1102*d4514f0bSApple OSS Distributions // We invert MAP_UNIX03 in the flags. This is because by default libsyscall intercepts calls to mmap and adds MAP_UNIX03.
1103*d4514f0bSApple OSS Distributions // That means MAP_UNIX03 should be the default for most of our tests, and we should only test without MAP_UNIX03 when we explicitly want to.
1104*d4514f0bSApple OSS Distributions void *
mmap_wrapper(void * addr,size_t len,int prot,int flags,int fildes,off_t off)1105*d4514f0bSApple OSS Distributions mmap_wrapper(void *addr, size_t len, int prot, int flags, int fildes, off_t off)
1106*d4514f0bSApple OSS Distributions {
1107*d4514f0bSApple OSS Distributions 	flags ^= MAP_UNIX03;
1108*d4514f0bSApple OSS Distributions 	return __mmap(addr, len, prot, flags, fildes, off);
1109*d4514f0bSApple OSS Distributions }
1110*d4514f0bSApple OSS Distributions 
1111*d4514f0bSApple OSS Distributions // Rename the UNIX03 flag for the code below since we're inverting its meaning.
1112*d4514f0bSApple OSS Distributions #define MAP_NOT_UNIX03 0x40000
1113*d4514f0bSApple OSS Distributions static_assert(MAP_NOT_UNIX03 == MAP_UNIX03, "MAP_UNIX03 value changed");
1114*d4514f0bSApple OSS Distributions #undef MAP_UNIX03
1115*d4514f0bSApple OSS Distributions #define MAP_UNIX03 dont_use_MAP_UNIX03
1116*d4514f0bSApple OSS Distributions 
1117*d4514f0bSApple OSS Distributions // helpers
1118*d4514f0bSApple OSS Distributions 
1119*d4514f0bSApple OSS Distributions // Return true if security policy disallows unsigned code.
1120*d4514f0bSApple OSS Distributions // Some test results are expected to change with this set.
1121*d4514f0bSApple OSS Distributions static bool
unsigned_code_is_disallowed(void)1122*d4514f0bSApple OSS Distributions unsigned_code_is_disallowed(void)
1123*d4514f0bSApple OSS Distributions {
1124*d4514f0bSApple OSS Distributions 	if (isRosetta()) {
1125*d4514f0bSApple OSS Distributions 		return false;
1126*d4514f0bSApple OSS Distributions 	}
1127*d4514f0bSApple OSS Distributions 
1128*d4514f0bSApple OSS Distributions 	int out_value = 0;
1129*d4514f0bSApple OSS Distributions 	size_t io_size = sizeof(out_value);
1130*d4514f0bSApple OSS Distributions 	if (0 == sysctlbyname("security.mac.amfi.unsigned_code_policy",
1131*d4514f0bSApple OSS Distributions 	    &out_value, &io_size, NULL, 0)) {
1132*d4514f0bSApple OSS Distributions 		return out_value;
1133*d4514f0bSApple OSS Distributions 	}
1134*d4514f0bSApple OSS Distributions 
1135*d4514f0bSApple OSS Distributions 	// sysctl not present, assume unsigned code is okay
1136*d4514f0bSApple OSS Distributions 	return false;
1137*d4514f0bSApple OSS Distributions }
1138*d4514f0bSApple OSS Distributions 
1139*d4514f0bSApple OSS Distributions static int
maybe_hide_mmap_failure(int ret,int prot,int fd)1140*d4514f0bSApple OSS Distributions maybe_hide_mmap_failure(int ret, int prot, int fd)
1141*d4514f0bSApple OSS Distributions {
1142*d4514f0bSApple OSS Distributions 	// Special case for mmap(PROT_EXEC, fd).
1143*d4514f0bSApple OSS Distributions 	// When SIP is enabled these get EPERM from mac_file_check_mmap().
1144*d4514f0bSApple OSS Distributions 	// The golden files record the SIP-disabled values.
1145*d4514f0bSApple OSS Distributions 	// This special case also allows the test to succeed when SIP
1146*d4514f0bSApple OSS Distributions 	// is enabled even though the return value isn't the golden one.
1147*d4514f0bSApple OSS Distributions 	if (ret == EPERM && fd != -1 && (prot & PROT_EXEC) &&
1148*d4514f0bSApple OSS Distributions 	    unsigned_code_is_disallowed()) {
1149*d4514f0bSApple OSS Distributions 		return ACCEPTABLE;
1150*d4514f0bSApple OSS Distributions 	}
1151*d4514f0bSApple OSS Distributions 	return ret;
1152*d4514f0bSApple OSS Distributions }
1153*d4514f0bSApple OSS Distributions 
1154*d4514f0bSApple OSS Distributions static kern_return_t
help_call_mmap__vm_prot(MAP_T map __unused,int flags,mach_vm_address_t start,mach_vm_size_t size,vm_prot_t prot)1155*d4514f0bSApple OSS Distributions help_call_mmap__vm_prot(MAP_T map __unused, int flags, mach_vm_address_t start, mach_vm_size_t size, vm_prot_t prot)
1156*d4514f0bSApple OSS Distributions {
1157*d4514f0bSApple OSS Distributions 	int fd = -1;
1158*d4514f0bSApple OSS Distributions 	if (!(flags & MAP_ANON)) {
1159*d4514f0bSApple OSS Distributions 		fd = get_fd();
1160*d4514f0bSApple OSS Distributions 	}
1161*d4514f0bSApple OSS Distributions 	void *rv = mmap_wrapper((void *)start, (size_t) size, prot, flags, fd, 0);
1162*d4514f0bSApple OSS Distributions 	if (rv == MAP_FAILED) {
1163*d4514f0bSApple OSS Distributions 		return maybe_hide_mmap_failure(errno, prot, fd);
1164*d4514f0bSApple OSS Distributions 	} else {
1165*d4514f0bSApple OSS Distributions 		assert(0 == munmap_helper(rv, size));
1166*d4514f0bSApple OSS Distributions 		return 0;
1167*d4514f0bSApple OSS Distributions 	}
1168*d4514f0bSApple OSS Distributions }
1169*d4514f0bSApple OSS Distributions 
1170*d4514f0bSApple OSS Distributions static kern_return_t
help_call_mmap__kernel_flags(MAP_T map __unused,int mmap_flags,mach_vm_address_t start,mach_vm_size_t size,int kernel_flags)1171*d4514f0bSApple OSS Distributions help_call_mmap__kernel_flags(MAP_T map __unused, int mmap_flags, mach_vm_address_t start, mach_vm_size_t size, int kernel_flags)
1172*d4514f0bSApple OSS Distributions {
1173*d4514f0bSApple OSS Distributions 	void *rv = mmap_wrapper((void *)start, (size_t) size, VM_PROT_DEFAULT, mmap_flags, kernel_flags, 0);
1174*d4514f0bSApple OSS Distributions 	if (rv == MAP_FAILED) {
1175*d4514f0bSApple OSS Distributions 		return errno;
1176*d4514f0bSApple OSS Distributions 	} else {
1177*d4514f0bSApple OSS Distributions 		assert(0 == munmap_helper(rv, size));
1178*d4514f0bSApple OSS Distributions 		return 0;
1179*d4514f0bSApple OSS Distributions 	}
1180*d4514f0bSApple OSS Distributions }
1181*d4514f0bSApple OSS Distributions 
1182*d4514f0bSApple OSS Distributions static kern_return_t
help_call_mmap__dst_size_fileoff(MAP_T map __unused,int flags,mach_vm_address_t dst,mach_vm_size_t size,mach_vm_address_t fileoff)1183*d4514f0bSApple OSS Distributions help_call_mmap__dst_size_fileoff(MAP_T map __unused, int flags, mach_vm_address_t dst, mach_vm_size_t size, mach_vm_address_t fileoff)
1184*d4514f0bSApple OSS Distributions {
1185*d4514f0bSApple OSS Distributions 	int fd = -1;
1186*d4514f0bSApple OSS Distributions 	if (!(flags & MAP_ANON)) {
1187*d4514f0bSApple OSS Distributions 		fd = get_fd();
1188*d4514f0bSApple OSS Distributions 	}
1189*d4514f0bSApple OSS Distributions 	void *rv = mmap_wrapper((void *)dst, (size_t) size, VM_PROT_DEFAULT, flags, fd, (off_t)fileoff);
1190*d4514f0bSApple OSS Distributions 	if (rv == MAP_FAILED) {
1191*d4514f0bSApple OSS Distributions 		return errno;
1192*d4514f0bSApple OSS Distributions 	} else {
1193*d4514f0bSApple OSS Distributions 		assert(0 == munmap_helper(rv, size));
1194*d4514f0bSApple OSS Distributions 		return 0;
1195*d4514f0bSApple OSS Distributions 	}
1196*d4514f0bSApple OSS Distributions }
1197*d4514f0bSApple OSS Distributions 
1198*d4514f0bSApple OSS Distributions static kern_return_t
help_call_mmap__start_size(MAP_T map __unused,int flags,mach_vm_address_t start,mach_vm_size_t size)1199*d4514f0bSApple OSS Distributions help_call_mmap__start_size(MAP_T map __unused, int flags, mach_vm_address_t start, mach_vm_size_t size)
1200*d4514f0bSApple OSS Distributions {
1201*d4514f0bSApple OSS Distributions 	int fd = -1;
1202*d4514f0bSApple OSS Distributions 	if (!(flags & MAP_ANON)) {
1203*d4514f0bSApple OSS Distributions 		fd = get_fd();
1204*d4514f0bSApple OSS Distributions 	}
1205*d4514f0bSApple OSS Distributions 	void *rv = mmap_wrapper((void *)start, (size_t) size, VM_PROT_DEFAULT, flags, fd, 0);
1206*d4514f0bSApple OSS Distributions 	if (rv == MAP_FAILED) {
1207*d4514f0bSApple OSS Distributions 		return errno;
1208*d4514f0bSApple OSS Distributions 	} else {
1209*d4514f0bSApple OSS Distributions 		assert(0 == munmap_helper(rv, size));
1210*d4514f0bSApple OSS Distributions 		return 0;
1211*d4514f0bSApple OSS Distributions 	}
1212*d4514f0bSApple OSS Distributions }
1213*d4514f0bSApple OSS Distributions 
1214*d4514f0bSApple OSS Distributions static kern_return_t
help_call_mmap__offset_size(MAP_T map __unused,int flags,mach_vm_address_t offset,mach_vm_size_t size)1215*d4514f0bSApple OSS Distributions help_call_mmap__offset_size(MAP_T map __unused, int flags, mach_vm_address_t offset, mach_vm_size_t size)
1216*d4514f0bSApple OSS Distributions {
1217*d4514f0bSApple OSS Distributions 	int fd = -1;
1218*d4514f0bSApple OSS Distributions 	if (!(flags & MAP_ANON)) {
1219*d4514f0bSApple OSS Distributions 		fd = get_fd();
1220*d4514f0bSApple OSS Distributions 	}
1221*d4514f0bSApple OSS Distributions 	void *rv = mmap_wrapper((void *)0, (size_t) size, VM_PROT_DEFAULT, flags, fd, (off_t)offset);
1222*d4514f0bSApple OSS Distributions 	if (rv == MAP_FAILED) {
1223*d4514f0bSApple OSS Distributions 		return errno;
1224*d4514f0bSApple OSS Distributions 	} else {
1225*d4514f0bSApple OSS Distributions 		assert(0 == munmap_helper(rv, size));
1226*d4514f0bSApple OSS Distributions 		return 0;
1227*d4514f0bSApple OSS Distributions 	}
1228*d4514f0bSApple OSS Distributions }
1229*d4514f0bSApple OSS Distributions 
1230*d4514f0bSApple OSS Distributions #define IMPL_ONE_FROM_HELPER(type, variant, flags, ...)                                                                                 \
1231*d4514f0bSApple OSS Distributions 	static kern_return_t                                                                                                            \
1232*d4514f0bSApple OSS Distributions 	__attribute__((used))                                                                                                           \
1233*d4514f0bSApple OSS Distributions 	call_mmap ## __ ## variant ## __ ## type(MAP_T map, mach_vm_address_t start, mach_vm_size_t size DROP_COMMAS(__VA_ARGS__)) {    \
1234*d4514f0bSApple OSS Distributions 	        return help_call_mmap__ ## type(map, flags, start, size DROP_TYPES(__VA_ARGS__));                                       \
1235*d4514f0bSApple OSS Distributions 	}
1236*d4514f0bSApple OSS Distributions 
1237*d4514f0bSApple OSS Distributions // call functions
1238*d4514f0bSApple OSS Distributions 
1239*d4514f0bSApple OSS Distributions #define IMPL_FROM_HELPER(type, ...) \
1240*d4514f0bSApple OSS Distributions 	IMPL_ONE_FROM_HELPER(type, file_private,          MAP_FILE | MAP_PRIVATE,                          ##__VA_ARGS__)  \
1241*d4514f0bSApple OSS Distributions 	IMPL_ONE_FROM_HELPER(type, anon_private,          MAP_ANON | MAP_PRIVATE,                          ##__VA_ARGS__)  \
1242*d4514f0bSApple OSS Distributions 	IMPL_ONE_FROM_HELPER(type, file_shared,           MAP_FILE | MAP_SHARED,                           ##__VA_ARGS__)  \
1243*d4514f0bSApple OSS Distributions 	IMPL_ONE_FROM_HELPER(type, anon_shared,           MAP_ANON | MAP_SHARED,                           ##__VA_ARGS__)  \
1244*d4514f0bSApple OSS Distributions 	IMPL_ONE_FROM_HELPER(type, file_private_codesign, MAP_FILE | MAP_PRIVATE | MAP_RESILIENT_CODESIGN, ##__VA_ARGS__)  \
1245*d4514f0bSApple OSS Distributions 	IMPL_ONE_FROM_HELPER(type, file_private_media,    MAP_FILE | MAP_PRIVATE | MAP_RESILIENT_MEDIA,    ##__VA_ARGS__)  \
1246*d4514f0bSApple OSS Distributions 	IMPL_ONE_FROM_HELPER(type, nounix03_private,      MAP_FILE | MAP_PRIVATE | MAP_NOT_UNIX03,         ##__VA_ARGS__)  \
1247*d4514f0bSApple OSS Distributions 	IMPL_ONE_FROM_HELPER(type, fixed_private,         MAP_FILE | MAP_PRIVATE | MAP_FIXED,              ##__VA_ARGS__)  \
1248*d4514f0bSApple OSS Distributions 
IMPL_FROM_HELPER(vm_prot,vm_prot_t,prot)1249*d4514f0bSApple OSS Distributions IMPL_FROM_HELPER(vm_prot, vm_prot_t, prot)
1250*d4514f0bSApple OSS Distributions IMPL_FROM_HELPER(dst_size_fileoff, mach_vm_address_t, fileoff)
1251*d4514f0bSApple OSS Distributions IMPL_FROM_HELPER(start_size)
1252*d4514f0bSApple OSS Distributions IMPL_FROM_HELPER(offset_size)
1253*d4514f0bSApple OSS Distributions 
1254*d4514f0bSApple OSS Distributions IMPL_ONE_FROM_HELPER(kernel_flags, anon_private, MAP_ANON | MAP_PRIVATE, int, kernel_flags)
1255*d4514f0bSApple OSS Distributions IMPL_ONE_FROM_HELPER(kernel_flags, anon_shared, MAP_ANON | MAP_SHARED, int, kernel_flags)
1256*d4514f0bSApple OSS Distributions 
1257*d4514f0bSApple OSS Distributions static kern_return_t
1258*d4514f0bSApple OSS Distributions call_mmap__mmap_flags(MAP_T map __unused, mach_vm_address_t start, mach_vm_size_t size, int mmap_flags)
1259*d4514f0bSApple OSS Distributions {
1260*d4514f0bSApple OSS Distributions 	int fd = -1;
1261*d4514f0bSApple OSS Distributions 	if (!(mmap_flags & MAP_ANON)) {
1262*d4514f0bSApple OSS Distributions 		fd = get_fd();
1263*d4514f0bSApple OSS Distributions 	}
1264*d4514f0bSApple OSS Distributions 	void *rv = mmap_wrapper((void *)start, (size_t) size, VM_PROT_DEFAULT, mmap_flags, fd, 0);
1265*d4514f0bSApple OSS Distributions 	if (rv == MAP_FAILED) {
1266*d4514f0bSApple OSS Distributions 		return errno;
1267*d4514f0bSApple OSS Distributions 	} else {
1268*d4514f0bSApple OSS Distributions 		assert(0 == munmap(rv, (size_t) size));
1269*d4514f0bSApple OSS Distributions 		return 0;
1270*d4514f0bSApple OSS Distributions 	}
1271*d4514f0bSApple OSS Distributions }
1272*d4514f0bSApple OSS Distributions 
1273*d4514f0bSApple OSS Distributions // Mach memory entry ownership
1274*d4514f0bSApple OSS Distributions 
1275*d4514f0bSApple OSS Distributions static kern_return_t
call_mach_memory_entry_ownership__ledger_tag(MAP_T map __unused,int ledger_tag)1276*d4514f0bSApple OSS Distributions call_mach_memory_entry_ownership__ledger_tag(MAP_T map __unused, int ledger_tag)
1277*d4514f0bSApple OSS Distributions {
1278*d4514f0bSApple OSS Distributions 	mach_port_t mementry = make_a_mem_entry(TEST_ALLOC_SIZE + 1);
1279*d4514f0bSApple OSS Distributions 	kern_return_t kr = mach_memory_entry_ownership(mementry, mach_task_self(), ledger_tag, 0);
1280*d4514f0bSApple OSS Distributions 	(void)mach_port_deallocate(mach_task_self(), mementry);
1281*d4514f0bSApple OSS Distributions 	return kr;
1282*d4514f0bSApple OSS Distributions }
1283*d4514f0bSApple OSS Distributions 
1284*d4514f0bSApple OSS Distributions static kern_return_t
call_mach_memory_entry_ownership__ledger_flag(MAP_T map __unused,int ledger_flag)1285*d4514f0bSApple OSS Distributions call_mach_memory_entry_ownership__ledger_flag(MAP_T map __unused, int ledger_flag)
1286*d4514f0bSApple OSS Distributions {
1287*d4514f0bSApple OSS Distributions 	mach_port_t mementry = make_a_mem_entry(TEST_ALLOC_SIZE + 1);
1288*d4514f0bSApple OSS Distributions 	kern_return_t kr = mach_memory_entry_ownership(mementry, mach_task_self(), VM_LEDGER_TAG_DEFAULT, ledger_flag);
1289*d4514f0bSApple OSS Distributions 	(void)mach_port_deallocate(mach_task_self(), mementry);
1290*d4514f0bSApple OSS Distributions 	return kr;
1291*d4514f0bSApple OSS Distributions }
1292*d4514f0bSApple OSS Distributions 
1293*d4514f0bSApple OSS Distributions 
1294*d4514f0bSApple OSS Distributions // For deallocators like munmap and vm_deallocate.
1295*d4514f0bSApple OSS Distributions // Return a non-zero error code if we should avoid performing this trial.
1296*d4514f0bSApple OSS Distributions kern_return_t
short_circuit_deallocator(MAP_T map,start_size_trial_t trial)1297*d4514f0bSApple OSS Distributions short_circuit_deallocator(MAP_T map, start_size_trial_t trial)
1298*d4514f0bSApple OSS Distributions {
1299*d4514f0bSApple OSS Distributions 	// mach_vm_deallocate(size == 0) is safe
1300*d4514f0bSApple OSS Distributions 	if (trial.size == 0) {
1301*d4514f0bSApple OSS Distributions 		return 0;
1302*d4514f0bSApple OSS Distributions 	}
1303*d4514f0bSApple OSS Distributions 
1304*d4514f0bSApple OSS Distributions 	// Allow deallocation attempts based on a valid allocation
1305*d4514f0bSApple OSS Distributions 	// (assumes the test loop will slide this trial to a valid allocation)
1306*d4514f0bSApple OSS Distributions 	if (!trial.start_is_absolute && trial.size_is_absolute) {
1307*d4514f0bSApple OSS Distributions 		return 0;
1308*d4514f0bSApple OSS Distributions 	}
1309*d4514f0bSApple OSS Distributions 
1310*d4514f0bSApple OSS Distributions 	// Avoid overwriting random live memory.
1311*d4514f0bSApple OSS Distributions 	if (!vm_sanitize_range_overflows_strict_zero(trial.start, trial.size, VM_MAP_PAGE_MASK(map))) {
1312*d4514f0bSApple OSS Distributions 		return IGNORED;
1313*d4514f0bSApple OSS Distributions 	}
1314*d4514f0bSApple OSS Distributions 
1315*d4514f0bSApple OSS Distributions 	// Avoid EXC_GUARD if it is still enabled.
1316*d4514f0bSApple OSS Distributions 	mach_vm_address_t sum;
1317*d4514f0bSApple OSS Distributions 	if (!__builtin_add_overflow(trial.start, trial.size, &sum) &&
1318*d4514f0bSApple OSS Distributions 	    trial.start + trial.size != 0 &&
1319*d4514f0bSApple OSS Distributions 	    round_up_page(trial.start + trial.size, PAGE_SIZE) == 0) {
1320*d4514f0bSApple OSS Distributions 		// this case provokes EXC_GUARD
1321*d4514f0bSApple OSS Distributions 		if (EXC_GUARD_ENABLED) {
1322*d4514f0bSApple OSS Distributions 			return GUARD;
1323*d4514f0bSApple OSS Distributions 		}
1324*d4514f0bSApple OSS Distributions 	}
1325*d4514f0bSApple OSS Distributions 
1326*d4514f0bSApple OSS Distributions 	// Allow.
1327*d4514f0bSApple OSS Distributions 	return 0;
1328*d4514f0bSApple OSS Distributions }
1329*d4514f0bSApple OSS Distributions 
1330*d4514f0bSApple OSS Distributions static kern_return_t
call_mach_vm_deallocate(MAP_T map,mach_vm_address_t start,mach_vm_size_t size)1331*d4514f0bSApple OSS Distributions call_mach_vm_deallocate(MAP_T map, mach_vm_address_t start, mach_vm_size_t size)
1332*d4514f0bSApple OSS Distributions {
1333*d4514f0bSApple OSS Distributions 	kern_return_t kr = mach_vm_deallocate(map, start, size);
1334*d4514f0bSApple OSS Distributions 	return kr;
1335*d4514f0bSApple OSS Distributions }
1336*d4514f0bSApple OSS Distributions 
1337*d4514f0bSApple OSS Distributions #if TEST_OLD_STYLE_MACH
1338*d4514f0bSApple OSS Distributions static kern_return_t
call_vm_deallocate(MAP_T map,mach_vm_address_t start,mach_vm_size_t size)1339*d4514f0bSApple OSS Distributions call_vm_deallocate(MAP_T map, mach_vm_address_t start, mach_vm_size_t size)
1340*d4514f0bSApple OSS Distributions {
1341*d4514f0bSApple OSS Distributions 	kern_return_t kr = vm_deallocate(map, (vm_address_t) start, (vm_size_t) size);
1342*d4514f0bSApple OSS Distributions 	return kr;
1343*d4514f0bSApple OSS Distributions }
1344*d4514f0bSApple OSS Distributions #endif
1345*d4514f0bSApple OSS Distributions 
1346*d4514f0bSApple OSS Distributions static kern_return_t
call_mach_vm_allocate__flags(MAP_T map,mach_vm_address_t * start,mach_vm_size_t size,int flags)1347*d4514f0bSApple OSS Distributions call_mach_vm_allocate__flags(MAP_T map, mach_vm_address_t * start, mach_vm_size_t size, int flags)
1348*d4514f0bSApple OSS Distributions {
1349*d4514f0bSApple OSS Distributions 	mach_vm_address_t saved_start = *start;
1350*d4514f0bSApple OSS Distributions 	kern_return_t kr = mach_vm_allocate(map, start, size, flags);
1351*d4514f0bSApple OSS Distributions 	check_mach_vm_allocate_outparam_changes(&kr, *start, size, saved_start, flags, map);
1352*d4514f0bSApple OSS Distributions 	return kr;
1353*d4514f0bSApple OSS Distributions }
1354*d4514f0bSApple OSS Distributions 
1355*d4514f0bSApple OSS Distributions 
1356*d4514f0bSApple OSS Distributions static kern_return_t
call_mach_vm_allocate__start_size_fixed(MAP_T map,mach_vm_address_t * start,mach_vm_size_t size)1357*d4514f0bSApple OSS Distributions call_mach_vm_allocate__start_size_fixed(MAP_T map, mach_vm_address_t * start, mach_vm_size_t size)
1358*d4514f0bSApple OSS Distributions {
1359*d4514f0bSApple OSS Distributions 	mach_vm_address_t saved_start = *start;
1360*d4514f0bSApple OSS Distributions 	kern_return_t kr = mach_vm_allocate(map, start, size, VM_FLAGS_FIXED);
1361*d4514f0bSApple OSS Distributions 	check_mach_vm_allocate_outparam_changes(&kr, *start, size, saved_start, VM_FLAGS_FIXED, map);
1362*d4514f0bSApple OSS Distributions 	return kr;
1363*d4514f0bSApple OSS Distributions }
1364*d4514f0bSApple OSS Distributions 
1365*d4514f0bSApple OSS Distributions static kern_return_t
call_mach_vm_allocate__start_size_anywhere(MAP_T map,mach_vm_address_t * start,mach_vm_size_t size)1366*d4514f0bSApple OSS Distributions call_mach_vm_allocate__start_size_anywhere(MAP_T map, mach_vm_address_t * start, mach_vm_size_t size)
1367*d4514f0bSApple OSS Distributions {
1368*d4514f0bSApple OSS Distributions 	mach_vm_address_t saved_start = *start;
1369*d4514f0bSApple OSS Distributions 	kern_return_t kr = mach_vm_allocate(map, start, size, VM_FLAGS_ANYWHERE);
1370*d4514f0bSApple OSS Distributions 	check_mach_vm_allocate_outparam_changes(&kr, *start, size, saved_start, VM_FLAGS_ANYWHERE, map);
1371*d4514f0bSApple OSS Distributions 	return kr;
1372*d4514f0bSApple OSS Distributions }
1373*d4514f0bSApple OSS Distributions 
1374*d4514f0bSApple OSS Distributions static kern_return_t
call_mach_vm_inherit(MAP_T map,mach_vm_address_t start,mach_vm_size_t size)1375*d4514f0bSApple OSS Distributions call_mach_vm_inherit(MAP_T map, mach_vm_address_t start, mach_vm_size_t size)
1376*d4514f0bSApple OSS Distributions {
1377*d4514f0bSApple OSS Distributions 	kern_return_t kr = mach_vm_inherit(map, start, size, VM_INHERIT_NONE);
1378*d4514f0bSApple OSS Distributions 	return kr;
1379*d4514f0bSApple OSS Distributions }
1380*d4514f0bSApple OSS Distributions #if TEST_OLD_STYLE_MACH
1381*d4514f0bSApple OSS Distributions static kern_return_t
call_vm_inherit(MAP_T map,vm_address_t start,vm_size_t size)1382*d4514f0bSApple OSS Distributions call_vm_inherit(MAP_T map, vm_address_t start, vm_size_t size)
1383*d4514f0bSApple OSS Distributions {
1384*d4514f0bSApple OSS Distributions 	kern_return_t kr = vm_inherit(map, start, size, VM_INHERIT_NONE);
1385*d4514f0bSApple OSS Distributions 	return kr;
1386*d4514f0bSApple OSS Distributions }
1387*d4514f0bSApple OSS Distributions #endif
1388*d4514f0bSApple OSS Distributions 
1389*d4514f0bSApple OSS Distributions static int
call_minherit(void * start,size_t size)1390*d4514f0bSApple OSS Distributions call_minherit(void *start, size_t size)
1391*d4514f0bSApple OSS Distributions {
1392*d4514f0bSApple OSS Distributions 	int err = minherit(start, size, VM_INHERIT_SHARE);
1393*d4514f0bSApple OSS Distributions 	return err ? errno : 0;
1394*d4514f0bSApple OSS Distributions }
1395*d4514f0bSApple OSS Distributions 
1396*d4514f0bSApple OSS Distributions static kern_return_t
call_mach_vm_inherit__inherit(MAP_T map,mach_vm_address_t start,mach_vm_size_t size,vm_inherit_t value)1397*d4514f0bSApple OSS Distributions call_mach_vm_inherit__inherit(MAP_T map, mach_vm_address_t start, mach_vm_size_t size, vm_inherit_t value)
1398*d4514f0bSApple OSS Distributions {
1399*d4514f0bSApple OSS Distributions 	kern_return_t kr = mach_vm_inherit(map, start, size, value);
1400*d4514f0bSApple OSS Distributions 	return kr;
1401*d4514f0bSApple OSS Distributions }
1402*d4514f0bSApple OSS Distributions 
1403*d4514f0bSApple OSS Distributions static int
call_minherit__inherit(void * start,size_t size,int value)1404*d4514f0bSApple OSS Distributions call_minherit__inherit(void * start, size_t size, int value)
1405*d4514f0bSApple OSS Distributions {
1406*d4514f0bSApple OSS Distributions 	int err = minherit(start, size, value);
1407*d4514f0bSApple OSS Distributions 	return err ? errno : 0;
1408*d4514f0bSApple OSS Distributions }
1409*d4514f0bSApple OSS Distributions 
1410*d4514f0bSApple OSS Distributions static kern_return_t
call_mach_vm_protect__start_size(MAP_T map,mach_vm_address_t start,mach_vm_size_t size)1411*d4514f0bSApple OSS Distributions call_mach_vm_protect__start_size(MAP_T map, mach_vm_address_t start, mach_vm_size_t size)
1412*d4514f0bSApple OSS Distributions {
1413*d4514f0bSApple OSS Distributions 	kern_return_t kr = mach_vm_protect(map, start, size, 0, VM_PROT_READ | VM_PROT_WRITE);
1414*d4514f0bSApple OSS Distributions 	return kr;
1415*d4514f0bSApple OSS Distributions }
1416*d4514f0bSApple OSS Distributions static kern_return_t
call_mach_vm_protect__vm_prot(MAP_T map,mach_vm_address_t start,mach_vm_size_t size,vm_prot_t prot)1417*d4514f0bSApple OSS Distributions call_mach_vm_protect__vm_prot(MAP_T map, mach_vm_address_t start, mach_vm_size_t size, vm_prot_t prot)
1418*d4514f0bSApple OSS Distributions {
1419*d4514f0bSApple OSS Distributions 	kern_return_t kr = mach_vm_protect(map, start, size, 0, prot);
1420*d4514f0bSApple OSS Distributions 	return kr;
1421*d4514f0bSApple OSS Distributions }
1422*d4514f0bSApple OSS Distributions #if TEST_OLD_STYLE_MACH
1423*d4514f0bSApple OSS Distributions static kern_return_t
call_vm_protect__start_size(MAP_T map,vm_address_t start,vm_size_t size)1424*d4514f0bSApple OSS Distributions call_vm_protect__start_size(MAP_T map, vm_address_t start, vm_size_t size)
1425*d4514f0bSApple OSS Distributions {
1426*d4514f0bSApple OSS Distributions 	kern_return_t kr = vm_protect(map, start, size, 0, VM_PROT_READ | VM_PROT_WRITE);
1427*d4514f0bSApple OSS Distributions 	return kr;
1428*d4514f0bSApple OSS Distributions }
1429*d4514f0bSApple OSS Distributions static kern_return_t
call_vm_protect__vm_prot(MAP_T map,vm_address_t start,vm_size_t size,vm_prot_t prot)1430*d4514f0bSApple OSS Distributions call_vm_protect__vm_prot(MAP_T map, vm_address_t start, vm_size_t size, vm_prot_t prot)
1431*d4514f0bSApple OSS Distributions {
1432*d4514f0bSApple OSS Distributions 	kern_return_t kr = vm_protect(map, start, size, 0, prot);
1433*d4514f0bSApple OSS Distributions 	return kr;
1434*d4514f0bSApple OSS Distributions }
1435*d4514f0bSApple OSS Distributions #endif
1436*d4514f0bSApple OSS Distributions 
1437*d4514f0bSApple OSS Distributions extern int __mprotect(void *, size_t, int);
1438*d4514f0bSApple OSS Distributions 
1439*d4514f0bSApple OSS Distributions static int
call_mprotect__start_size(void * start,size_t size)1440*d4514f0bSApple OSS Distributions call_mprotect__start_size(void *start, size_t size)
1441*d4514f0bSApple OSS Distributions {
1442*d4514f0bSApple OSS Distributions 	int err = __mprotect(start, size, PROT_READ | PROT_WRITE);
1443*d4514f0bSApple OSS Distributions 	return err ? errno : 0;
1444*d4514f0bSApple OSS Distributions }
1445*d4514f0bSApple OSS Distributions 
1446*d4514f0bSApple OSS Distributions static int
call_mprotect__vm_prot(void * start,size_t size,int prot)1447*d4514f0bSApple OSS Distributions call_mprotect__vm_prot(void *start, size_t size, int prot)
1448*d4514f0bSApple OSS Distributions {
1449*d4514f0bSApple OSS Distributions 	int err = __mprotect(start, size, prot);
1450*d4514f0bSApple OSS Distributions 	return err ? errno : 0;
1451*d4514f0bSApple OSS Distributions }
1452*d4514f0bSApple OSS Distributions 
1453*d4514f0bSApple OSS Distributions #if TEST_OLD_STYLE_MACH
1454*d4514f0bSApple OSS Distributions static kern_return_t
call_vm_behavior_set__start_size__default(MAP_T map,vm_address_t start,vm_size_t size)1455*d4514f0bSApple OSS Distributions call_vm_behavior_set__start_size__default(MAP_T map, vm_address_t start, vm_size_t size)
1456*d4514f0bSApple OSS Distributions {
1457*d4514f0bSApple OSS Distributions 	kern_return_t kr = vm_behavior_set(map, start, size, VM_BEHAVIOR_DEFAULT);
1458*d4514f0bSApple OSS Distributions 	return kr;
1459*d4514f0bSApple OSS Distributions }
1460*d4514f0bSApple OSS Distributions 
1461*d4514f0bSApple OSS Distributions static kern_return_t
call_vm_behavior_set__start_size__can_reuse(MAP_T map,vm_address_t start,vm_size_t size)1462*d4514f0bSApple OSS Distributions call_vm_behavior_set__start_size__can_reuse(MAP_T map, vm_address_t start, vm_size_t size)
1463*d4514f0bSApple OSS Distributions {
1464*d4514f0bSApple OSS Distributions 	kern_return_t kr = vm_behavior_set(map, start, size, VM_BEHAVIOR_CAN_REUSE);
1465*d4514f0bSApple OSS Distributions 	return kr;
1466*d4514f0bSApple OSS Distributions }
1467*d4514f0bSApple OSS Distributions 
1468*d4514f0bSApple OSS Distributions static kern_return_t
call_vm_behavior_set__vm_behavior(MAP_T map,vm_address_t start,vm_size_t size,vm_behavior_t behavior)1469*d4514f0bSApple OSS Distributions call_vm_behavior_set__vm_behavior(MAP_T map, vm_address_t start, vm_size_t size, vm_behavior_t behavior)
1470*d4514f0bSApple OSS Distributions {
1471*d4514f0bSApple OSS Distributions 	kern_return_t kr = vm_behavior_set(map, start, size, behavior);
1472*d4514f0bSApple OSS Distributions 	return kr;
1473*d4514f0bSApple OSS Distributions }
1474*d4514f0bSApple OSS Distributions #endif /* TEST_OLD_STYLE_MACH */
1475*d4514f0bSApple OSS Distributions 
1476*d4514f0bSApple OSS Distributions extern int __shared_region_map_and_slide_2_np(uint32_t files_count,
1477*d4514f0bSApple OSS Distributions     const struct shared_file_np *files,
1478*d4514f0bSApple OSS Distributions     uint32_t mappings_count,
1479*d4514f0bSApple OSS Distributions     const struct shared_file_mapping_slide_np *mappings);
1480*d4514f0bSApple OSS Distributions 
1481*d4514f0bSApple OSS Distributions static int
maybe_hide_shared_region_map_failure(int ret,uint32_t files_count,const struct shared_file_np * files,uint32_t mappings_count)1482*d4514f0bSApple OSS Distributions maybe_hide_shared_region_map_failure(int ret,
1483*d4514f0bSApple OSS Distributions     uint32_t files_count, const struct shared_file_np *files,
1484*d4514f0bSApple OSS Distributions     uint32_t mappings_count)
1485*d4514f0bSApple OSS Distributions {
1486*d4514f0bSApple OSS Distributions 	// Special case for __shared_region_map_and_slide_2_np().
1487*d4514f0bSApple OSS Distributions 	// When SIP is enabled this case gets EPERM instead of EINVAL due to
1488*d4514f0bSApple OSS Distributions 	// vm_shared_region_map_file returning KERN_PROTECTION_FAILURE instead of
1489*d4514f0bSApple OSS Distributions 	// KERN_INVALID_ARGUMENT.
1490*d4514f0bSApple OSS Distributions 	if (ret == EPERM && files_count == 1 && mappings_count == 1 &&
1491*d4514f0bSApple OSS Distributions 	    files->sf_fd == get_fd() && files->sf_mappings_count == 1 &&
1492*d4514f0bSApple OSS Distributions 	    unsigned_code_is_disallowed()) {
1493*d4514f0bSApple OSS Distributions 		return ACCEPTABLE;
1494*d4514f0bSApple OSS Distributions 	}
1495*d4514f0bSApple OSS Distributions 	return ret;
1496*d4514f0bSApple OSS Distributions }
1497*d4514f0bSApple OSS Distributions 
1498*d4514f0bSApple OSS Distributions static int
call_shared_region_map_and_slide_2_np_child(uint32_t files_count,const struct shared_file_np * files,uint32_t mappings_count,const struct shared_file_mapping_slide_np * mappings)1499*d4514f0bSApple OSS Distributions call_shared_region_map_and_slide_2_np_child(uint32_t files_count, const struct shared_file_np *files,
1500*d4514f0bSApple OSS Distributions     uint32_t mappings_count, const struct shared_file_mapping_slide_np *mappings)
1501*d4514f0bSApple OSS Distributions {
1502*d4514f0bSApple OSS Distributions 	int err = __shared_region_map_and_slide_2_np(files_count, files, mappings_count, mappings);
1503*d4514f0bSApple OSS Distributions 	return err ? maybe_hide_shared_region_map_failure(errno, files_count, files, mappings_count) : 0;
1504*d4514f0bSApple OSS Distributions }
1505*d4514f0bSApple OSS Distributions 
1506*d4514f0bSApple OSS Distributions typedef struct {
1507*d4514f0bSApple OSS Distributions 	uint32_t files_count;
1508*d4514f0bSApple OSS Distributions 	const struct shared_file_np *files;
1509*d4514f0bSApple OSS Distributions 	uint32_t mappings_count;
1510*d4514f0bSApple OSS Distributions 	const struct shared_file_mapping_slide_np *mappings;
1511*d4514f0bSApple OSS Distributions } map_n_slice_thread_args;
1512*d4514f0bSApple OSS Distributions 
1513*d4514f0bSApple OSS Distributions void*
thread_func(void * args)1514*d4514f0bSApple OSS Distributions thread_func(void* args)
1515*d4514f0bSApple OSS Distributions {
1516*d4514f0bSApple OSS Distributions 	map_n_slice_thread_args *thread_args = (map_n_slice_thread_args *)args;
1517*d4514f0bSApple OSS Distributions 	uint32_t files_count = thread_args->files_count;
1518*d4514f0bSApple OSS Distributions 	const struct shared_file_np *files = thread_args->files;
1519*d4514f0bSApple OSS Distributions 	uint32_t mappings_count = thread_args->mappings_count;
1520*d4514f0bSApple OSS Distributions 	const struct shared_file_mapping_slide_np *mappings = thread_args->mappings;
1521*d4514f0bSApple OSS Distributions 
1522*d4514f0bSApple OSS Distributions 	int err = call_shared_region_map_and_slide_2_np_child(files_count, files, mappings_count, mappings);
1523*d4514f0bSApple OSS Distributions 
1524*d4514f0bSApple OSS Distributions 	int *result = malloc(sizeof(int));
1525*d4514f0bSApple OSS Distributions 	assert(result != NULL);
1526*d4514f0bSApple OSS Distributions 	*result = err;
1527*d4514f0bSApple OSS Distributions 	return result;
1528*d4514f0bSApple OSS Distributions }
1529*d4514f0bSApple OSS Distributions 
1530*d4514f0bSApple OSS Distributions static int
call_shared_region_map_and_slide_2_np_in_thread(uint32_t files_count,const struct shared_file_np * files,uint32_t mappings_count,const struct shared_file_mapping_slide_np * mappings)1531*d4514f0bSApple OSS Distributions call_shared_region_map_and_slide_2_np_in_thread(uint32_t files_count, const struct shared_file_np *files,
1532*d4514f0bSApple OSS Distributions     uint32_t mappings_count, const struct shared_file_mapping_slide_np *mappings)
1533*d4514f0bSApple OSS Distributions {
1534*d4514f0bSApple OSS Distributions 	// From vm/vm_shared_region.c: After a chroot(), the calling process keeps using its original shared region [...]
1535*d4514f0bSApple OSS Distributions 	// But its children will use a different shared region [...]
1536*d4514f0bSApple OSS Distributions 	if (chroot(".") < 0) {
1537*d4514f0bSApple OSS Distributions 		return BUSTED;
1538*d4514f0bSApple OSS Distributions 	}
1539*d4514f0bSApple OSS Distributions 
1540*d4514f0bSApple OSS Distributions 	map_n_slice_thread_args args = {files_count, files, mappings_count, mappings};
1541*d4514f0bSApple OSS Distributions 	pthread_t thread;
1542*d4514f0bSApple OSS Distributions 	if (pthread_create(&thread, NULL, thread_func, (void *)&args) < 0) {
1543*d4514f0bSApple OSS Distributions 		return -91;
1544*d4514f0bSApple OSS Distributions 	}
1545*d4514f0bSApple OSS Distributions 
1546*d4514f0bSApple OSS Distributions 	int *err;
1547*d4514f0bSApple OSS Distributions 	if (pthread_join(thread, (void**)&err) < 0) {
1548*d4514f0bSApple OSS Distributions 		return BUSTED;
1549*d4514f0bSApple OSS Distributions 	}
1550*d4514f0bSApple OSS Distributions 
1551*d4514f0bSApple OSS Distributions 	if (chroot("/") < 0) {
1552*d4514f0bSApple OSS Distributions 		return BUSTED;
1553*d4514f0bSApple OSS Distributions 	}
1554*d4514f0bSApple OSS Distributions 
1555*d4514f0bSApple OSS Distributions 	return *err;
1556*d4514f0bSApple OSS Distributions }
1557*d4514f0bSApple OSS Distributions 
1558*d4514f0bSApple OSS Distributions static int
call_madvise__start_size(void * start,size_t size)1559*d4514f0bSApple OSS Distributions call_madvise__start_size(void *start, size_t size)
1560*d4514f0bSApple OSS Distributions {
1561*d4514f0bSApple OSS Distributions 	int err = madvise(start, size, MADV_NORMAL);
1562*d4514f0bSApple OSS Distributions 	return err ? errno : 0;
1563*d4514f0bSApple OSS Distributions }
1564*d4514f0bSApple OSS Distributions 
1565*d4514f0bSApple OSS Distributions static int
call_madvise__vm_advise(void * start,size_t size,int advise)1566*d4514f0bSApple OSS Distributions call_madvise__vm_advise(void *start, size_t size, int advise)
1567*d4514f0bSApple OSS Distributions {
1568*d4514f0bSApple OSS Distributions 	int err = madvise(start, size, advise);
1569*d4514f0bSApple OSS Distributions 	return err ? errno : 0;
1570*d4514f0bSApple OSS Distributions }
1571*d4514f0bSApple OSS Distributions 
1572*d4514f0bSApple OSS Distributions static int
call_mach_vm_msync__start_size(MAP_T map,mach_vm_address_t start,mach_vm_size_t size)1573*d4514f0bSApple OSS Distributions call_mach_vm_msync__start_size(MAP_T map, mach_vm_address_t start, mach_vm_size_t size)
1574*d4514f0bSApple OSS Distributions {
1575*d4514f0bSApple OSS Distributions 	kern_return_t kr = mach_vm_msync(map, start, size, VM_SYNC_ASYNCHRONOUS);
1576*d4514f0bSApple OSS Distributions 	return kr;
1577*d4514f0bSApple OSS Distributions }
1578*d4514f0bSApple OSS Distributions 
1579*d4514f0bSApple OSS Distributions static int
call_mach_vm_msync__vm_sync(MAP_T map,mach_vm_address_t start,mach_vm_size_t size,vm_sync_t sync)1580*d4514f0bSApple OSS Distributions call_mach_vm_msync__vm_sync(MAP_T map, mach_vm_address_t start, mach_vm_size_t size, vm_sync_t sync)
1581*d4514f0bSApple OSS Distributions {
1582*d4514f0bSApple OSS Distributions 	kern_return_t kr = mach_vm_msync(map, start, size, sync);
1583*d4514f0bSApple OSS Distributions 	return kr;
1584*d4514f0bSApple OSS Distributions }
1585*d4514f0bSApple OSS Distributions 
1586*d4514f0bSApple OSS Distributions #if TEST_OLD_STYLE_MACH
1587*d4514f0bSApple OSS Distributions static int
call_vm_msync__start_size(MAP_T map,vm_address_t start,vm_size_t size)1588*d4514f0bSApple OSS Distributions call_vm_msync__start_size(MAP_T map, vm_address_t start, vm_size_t size)
1589*d4514f0bSApple OSS Distributions {
1590*d4514f0bSApple OSS Distributions 	kern_return_t kr = vm_msync(map, start, size, VM_SYNC_ASYNCHRONOUS);
1591*d4514f0bSApple OSS Distributions 	return kr;
1592*d4514f0bSApple OSS Distributions }
1593*d4514f0bSApple OSS Distributions 
1594*d4514f0bSApple OSS Distributions static int
call_vm_msync__vm_sync(MAP_T map,vm_address_t start,vm_size_t size,vm_sync_t sync)1595*d4514f0bSApple OSS Distributions call_vm_msync__vm_sync(MAP_T map, vm_address_t start, vm_size_t size, vm_sync_t sync)
1596*d4514f0bSApple OSS Distributions {
1597*d4514f0bSApple OSS Distributions 	kern_return_t kr = vm_msync(map, start, size, sync);
1598*d4514f0bSApple OSS Distributions 	return kr;
1599*d4514f0bSApple OSS Distributions }
1600*d4514f0bSApple OSS Distributions #endif /* TEST_OLD_STYLE_MACH */
1601*d4514f0bSApple OSS Distributions 
1602*d4514f0bSApple OSS Distributions // msync has a libsyscall wrapper that does alignment. We want the raw syscall.
1603*d4514f0bSApple OSS Distributions int __msync(void *, size_t, int);
1604*d4514f0bSApple OSS Distributions 
1605*d4514f0bSApple OSS Distributions static int
call_msync__start_size(void * start,size_t size)1606*d4514f0bSApple OSS Distributions call_msync__start_size(void *start, size_t size)
1607*d4514f0bSApple OSS Distributions {
1608*d4514f0bSApple OSS Distributions 	int err = __msync(start, size, MS_SYNC);
1609*d4514f0bSApple OSS Distributions 	return err ? errno : 0;
1610*d4514f0bSApple OSS Distributions }
1611*d4514f0bSApple OSS Distributions 
1612*d4514f0bSApple OSS Distributions static int
call_msync__vm_msync(void * start,size_t size,int msync_value)1613*d4514f0bSApple OSS Distributions call_msync__vm_msync(void *start, size_t size, int msync_value)
1614*d4514f0bSApple OSS Distributions {
1615*d4514f0bSApple OSS Distributions 	int err = __msync(start, size, msync_value);
1616*d4514f0bSApple OSS Distributions 	return err ? errno : 0;
1617*d4514f0bSApple OSS Distributions }
1618*d4514f0bSApple OSS Distributions 
1619*d4514f0bSApple OSS Distributions // msync nocancel isn't declared, but we want to directly hit the syscall
1620*d4514f0bSApple OSS Distributions int __msync_nocancel(void *, size_t, int);
1621*d4514f0bSApple OSS Distributions 
1622*d4514f0bSApple OSS Distributions static int
call_msync_nocancel__start_size(void * start,size_t size)1623*d4514f0bSApple OSS Distributions call_msync_nocancel__start_size(void *start, size_t size)
1624*d4514f0bSApple OSS Distributions {
1625*d4514f0bSApple OSS Distributions 	int err = __msync_nocancel(start, size, MS_SYNC);
1626*d4514f0bSApple OSS Distributions 	return err ? errno : 0;
1627*d4514f0bSApple OSS Distributions }
1628*d4514f0bSApple OSS Distributions 
1629*d4514f0bSApple OSS Distributions static int
call_msync_nocancel__vm_msync(void * start,size_t size,int msync_value)1630*d4514f0bSApple OSS Distributions call_msync_nocancel__vm_msync(void *start, size_t size, int msync_value)
1631*d4514f0bSApple OSS Distributions {
1632*d4514f0bSApple OSS Distributions 	int err = __msync_nocancel(start, size, msync_value);
1633*d4514f0bSApple OSS Distributions 	return err ? errno : 0;
1634*d4514f0bSApple OSS Distributions }
1635*d4514f0bSApple OSS Distributions 
1636*d4514f0bSApple OSS Distributions static void
check_mach_vm_machine_attribute_outparam_changes(kern_return_t * kr,vm_machine_attribute_val_t value,vm_machine_attribute_val_t saved_value)1637*d4514f0bSApple OSS Distributions check_mach_vm_machine_attribute_outparam_changes(kern_return_t * kr, vm_machine_attribute_val_t value, vm_machine_attribute_val_t saved_value)
1638*d4514f0bSApple OSS Distributions {
1639*d4514f0bSApple OSS Distributions 	if (value != saved_value) {
1640*d4514f0bSApple OSS Distributions 		*kr = OUT_PARAM_BAD;
1641*d4514f0bSApple OSS Distributions 	}
1642*d4514f0bSApple OSS Distributions }
1643*d4514f0bSApple OSS Distributions 
1644*d4514f0bSApple OSS Distributions static int
call_mach_vm_machine_attribute__start_size(MAP_T map,mach_vm_address_t start,mach_vm_size_t size)1645*d4514f0bSApple OSS Distributions call_mach_vm_machine_attribute__start_size(MAP_T map, mach_vm_address_t start, mach_vm_size_t size)
1646*d4514f0bSApple OSS Distributions {
1647*d4514f0bSApple OSS Distributions 	vm_machine_attribute_val_t value = MATTR_VAL_GET;
1648*d4514f0bSApple OSS Distributions 	vm_machine_attribute_val_t initial_value = value;
1649*d4514f0bSApple OSS Distributions 	kern_return_t kr = mach_vm_machine_attribute(map, start, size, MATTR_CACHE, &value);
1650*d4514f0bSApple OSS Distributions 	check_mach_vm_machine_attribute_outparam_changes(&kr, value, initial_value);
1651*d4514f0bSApple OSS Distributions 	return kr;
1652*d4514f0bSApple OSS Distributions }
1653*d4514f0bSApple OSS Distributions 
1654*d4514f0bSApple OSS Distributions 
1655*d4514f0bSApple OSS Distributions static int
call_mach_vm_machine_attribute__machine_attribute(MAP_T map,mach_vm_address_t start,mach_vm_size_t size,vm_machine_attribute_t attr)1656*d4514f0bSApple OSS Distributions call_mach_vm_machine_attribute__machine_attribute(MAP_T map, mach_vm_address_t start, mach_vm_size_t size, vm_machine_attribute_t attr)
1657*d4514f0bSApple OSS Distributions {
1658*d4514f0bSApple OSS Distributions 	vm_machine_attribute_val_t value = MATTR_VAL_GET;
1659*d4514f0bSApple OSS Distributions 	vm_machine_attribute_val_t initial_value = value;
1660*d4514f0bSApple OSS Distributions 	kern_return_t kr = mach_vm_machine_attribute(map, start, size, attr, &value);
1661*d4514f0bSApple OSS Distributions 	check_mach_vm_machine_attribute_outparam_changes(&kr, value, initial_value);
1662*d4514f0bSApple OSS Distributions 	return kr;
1663*d4514f0bSApple OSS Distributions }
1664*d4514f0bSApple OSS Distributions 
1665*d4514f0bSApple OSS Distributions #if TEST_OLD_STYLE_MACH
1666*d4514f0bSApple OSS Distributions static int
call_vm_machine_attribute__start_size(MAP_T map,vm_address_t start,vm_size_t size)1667*d4514f0bSApple OSS Distributions call_vm_machine_attribute__start_size(MAP_T map, vm_address_t start, vm_size_t size)
1668*d4514f0bSApple OSS Distributions {
1669*d4514f0bSApple OSS Distributions 	vm_machine_attribute_val_t value = MATTR_VAL_GET;
1670*d4514f0bSApple OSS Distributions 	vm_machine_attribute_val_t initial_value = value;
1671*d4514f0bSApple OSS Distributions 	kern_return_t kr = vm_machine_attribute(map, start, size, MATTR_CACHE, &value);
1672*d4514f0bSApple OSS Distributions 	check_mach_vm_machine_attribute_outparam_changes(&kr, value, initial_value);
1673*d4514f0bSApple OSS Distributions 	return kr;
1674*d4514f0bSApple OSS Distributions }
1675*d4514f0bSApple OSS Distributions 
1676*d4514f0bSApple OSS Distributions static int
call_vm_machine_attribute__machine_attribute(MAP_T map,vm_address_t start,vm_size_t size,vm_machine_attribute_t attr)1677*d4514f0bSApple OSS Distributions call_vm_machine_attribute__machine_attribute(MAP_T map, vm_address_t start, vm_size_t size, vm_machine_attribute_t attr)
1678*d4514f0bSApple OSS Distributions {
1679*d4514f0bSApple OSS Distributions 	vm_machine_attribute_val_t value = MATTR_VAL_GET;
1680*d4514f0bSApple OSS Distributions 	vm_machine_attribute_val_t initial_value = value;
1681*d4514f0bSApple OSS Distributions 	kern_return_t kr = vm_machine_attribute(map, start, size, attr, &value);
1682*d4514f0bSApple OSS Distributions 	check_mach_vm_machine_attribute_outparam_changes(&kr, value, initial_value);
1683*d4514f0bSApple OSS Distributions 	return kr;
1684*d4514f0bSApple OSS Distributions }
1685*d4514f0bSApple OSS Distributions #endif /* TEST_OLD_STYLE_MACH */
1686*d4514f0bSApple OSS Distributions 
1687*d4514f0bSApple OSS Distributions static int
call_mach_vm_purgable_control__address__get(MAP_T map,mach_vm_address_t addr)1688*d4514f0bSApple OSS Distributions call_mach_vm_purgable_control__address__get(MAP_T map, mach_vm_address_t addr)
1689*d4514f0bSApple OSS Distributions {
1690*d4514f0bSApple OSS Distributions 	int state = INVALID_PURGABLE_STATE;
1691*d4514f0bSApple OSS Distributions 	int initial_state = state;
1692*d4514f0bSApple OSS Distributions 	kern_return_t kr = mach_vm_purgable_control(map, addr, VM_PURGABLE_GET_STATE, &state);
1693*d4514f0bSApple OSS Distributions 	check_mach_vm_purgable_control_outparam_changes(&kr, state, initial_state, VM_PURGABLE_GET_STATE);
1694*d4514f0bSApple OSS Distributions 	return kr;
1695*d4514f0bSApple OSS Distributions }
1696*d4514f0bSApple OSS Distributions 
1697*d4514f0bSApple OSS Distributions 
1698*d4514f0bSApple OSS Distributions static int
call_mach_vm_purgable_control__address__purge_all(MAP_T map,mach_vm_address_t addr)1699*d4514f0bSApple OSS Distributions call_mach_vm_purgable_control__address__purge_all(MAP_T map, mach_vm_address_t addr)
1700*d4514f0bSApple OSS Distributions {
1701*d4514f0bSApple OSS Distributions 	int state = INVALID_PURGABLE_STATE;
1702*d4514f0bSApple OSS Distributions 	int initial_state = state;
1703*d4514f0bSApple OSS Distributions 	kern_return_t kr = mach_vm_purgable_control(map, addr, VM_PURGABLE_PURGE_ALL, &state);
1704*d4514f0bSApple OSS Distributions 	check_mach_vm_purgable_control_outparam_changes(&kr, state, initial_state, VM_PURGABLE_PURGE_ALL);
1705*d4514f0bSApple OSS Distributions 	return kr;
1706*d4514f0bSApple OSS Distributions }
1707*d4514f0bSApple OSS Distributions 
1708*d4514f0bSApple OSS Distributions static int
call_mach_vm_purgable_control__purgeable_state(MAP_T map,mach_vm_address_t addr,vm_purgable_t control,int state)1709*d4514f0bSApple OSS Distributions call_mach_vm_purgable_control__purgeable_state(MAP_T map, mach_vm_address_t addr, vm_purgable_t control, int state)
1710*d4514f0bSApple OSS Distributions {
1711*d4514f0bSApple OSS Distributions 	int initial_state = state;
1712*d4514f0bSApple OSS Distributions 	kern_return_t kr = mach_vm_purgable_control(map, addr, control, &state);
1713*d4514f0bSApple OSS Distributions 	check_mach_vm_purgable_control_outparam_changes(&kr, state, initial_state, control);
1714*d4514f0bSApple OSS Distributions 	return kr;
1715*d4514f0bSApple OSS Distributions }
1716*d4514f0bSApple OSS Distributions 
1717*d4514f0bSApple OSS Distributions #if TEST_OLD_STYLE_MACH
1718*d4514f0bSApple OSS Distributions static int
call_vm_purgable_control__address__get(MAP_T map,vm_address_t addr)1719*d4514f0bSApple OSS Distributions call_vm_purgable_control__address__get(MAP_T map, vm_address_t addr)
1720*d4514f0bSApple OSS Distributions {
1721*d4514f0bSApple OSS Distributions 	int state = INVALID_PURGABLE_STATE;
1722*d4514f0bSApple OSS Distributions 	int initial_state = state;
1723*d4514f0bSApple OSS Distributions 	kern_return_t kr = vm_purgable_control(map, addr, VM_PURGABLE_GET_STATE, &state);
1724*d4514f0bSApple OSS Distributions 	check_mach_vm_purgable_control_outparam_changes(&kr, state, initial_state, VM_PURGABLE_GET_STATE);
1725*d4514f0bSApple OSS Distributions 	return kr;
1726*d4514f0bSApple OSS Distributions }
1727*d4514f0bSApple OSS Distributions 
1728*d4514f0bSApple OSS Distributions static int
call_vm_purgable_control__address__purge_all(MAP_T map,vm_address_t addr)1729*d4514f0bSApple OSS Distributions call_vm_purgable_control__address__purge_all(MAP_T map, vm_address_t addr)
1730*d4514f0bSApple OSS Distributions {
1731*d4514f0bSApple OSS Distributions 	int state = INVALID_PURGABLE_STATE;
1732*d4514f0bSApple OSS Distributions 	int initial_state = state;
1733*d4514f0bSApple OSS Distributions 	kern_return_t kr = vm_purgable_control(map, addr, VM_PURGABLE_PURGE_ALL, &state);
1734*d4514f0bSApple OSS Distributions 	check_mach_vm_purgable_control_outparam_changes(&kr, state, initial_state, VM_PURGABLE_PURGE_ALL);
1735*d4514f0bSApple OSS Distributions 	return kr;
1736*d4514f0bSApple OSS Distributions }
1737*d4514f0bSApple OSS Distributions 
1738*d4514f0bSApple OSS Distributions static int
call_vm_purgable_control__purgeable_state(MAP_T map,vm_address_t addr,vm_purgable_t control,int state)1739*d4514f0bSApple OSS Distributions call_vm_purgable_control__purgeable_state(MAP_T map, vm_address_t addr, vm_purgable_t control, int state)
1740*d4514f0bSApple OSS Distributions {
1741*d4514f0bSApple OSS Distributions 	int initial_state = state;
1742*d4514f0bSApple OSS Distributions 	kern_return_t kr = vm_purgable_control(map, addr, control, &state);
1743*d4514f0bSApple OSS Distributions 	check_mach_vm_purgable_control_outparam_changes(&kr, state, initial_state, control);
1744*d4514f0bSApple OSS Distributions 	return kr;
1745*d4514f0bSApple OSS Distributions }
1746*d4514f0bSApple OSS Distributions #endif /* TEST_OLD_STYLE_MACH */
1747*d4514f0bSApple OSS Distributions 
1748*d4514f0bSApple OSS Distributions static void
check_mach_vm_region_recurse_outparam_changes(kern_return_t * kr,void * info,void * saved_info,size_t info_size,natural_t depth,natural_t saved_depth,mach_vm_address_t addr,mach_vm_address_t saved_addr,mach_vm_size_t size,mach_vm_size_t saved_size)1749*d4514f0bSApple OSS Distributions check_mach_vm_region_recurse_outparam_changes(kern_return_t * kr, void * info, void * saved_info, size_t info_size,
1750*d4514f0bSApple OSS Distributions     natural_t depth, natural_t saved_depth, mach_vm_address_t addr, mach_vm_address_t saved_addr,
1751*d4514f0bSApple OSS Distributions     mach_vm_size_t size, mach_vm_size_t saved_size)
1752*d4514f0bSApple OSS Distributions {
1753*d4514f0bSApple OSS Distributions 	if (*kr == KERN_SUCCESS) {
1754*d4514f0bSApple OSS Distributions 		if (depth == saved_depth) {
1755*d4514f0bSApple OSS Distributions 			*kr = OUT_PARAM_BAD;
1756*d4514f0bSApple OSS Distributions 		}
1757*d4514f0bSApple OSS Distributions 		if (size == saved_size) {
1758*d4514f0bSApple OSS Distributions 			*kr = OUT_PARAM_BAD;
1759*d4514f0bSApple OSS Distributions 		}
1760*d4514f0bSApple OSS Distributions 		if (memcmp(info, saved_info, info_size) == 0) {
1761*d4514f0bSApple OSS Distributions 			*kr = OUT_PARAM_BAD;
1762*d4514f0bSApple OSS Distributions 		}
1763*d4514f0bSApple OSS Distributions 	} else {
1764*d4514f0bSApple OSS Distributions 		if (depth != saved_depth || addr != saved_addr || size != saved_size || memcmp(info, saved_info, info_size) != 0) {
1765*d4514f0bSApple OSS Distributions 			*kr = OUT_PARAM_BAD;
1766*d4514f0bSApple OSS Distributions 		}
1767*d4514f0bSApple OSS Distributions 	}
1768*d4514f0bSApple OSS Distributions }
1769*d4514f0bSApple OSS Distributions 
1770*d4514f0bSApple OSS Distributions static kern_return_t
call_mach_vm_region_recurse(MAP_T map,mach_vm_address_t addr)1771*d4514f0bSApple OSS Distributions call_mach_vm_region_recurse(MAP_T map, mach_vm_address_t addr)
1772*d4514f0bSApple OSS Distributions {
1773*d4514f0bSApple OSS Distributions 	vm_region_submap_info_data_64_t info;
1774*d4514f0bSApple OSS Distributions 	info.inheritance = INVALID_INHERIT;
1775*d4514f0bSApple OSS Distributions 	vm_region_submap_info_data_64_t saved_info = info;
1776*d4514f0bSApple OSS Distributions 	mach_vm_size_t size_out = UNLIKELY_INITIAL_SIZE;
1777*d4514f0bSApple OSS Distributions 	mach_vm_size_t saved_size = size_out;
1778*d4514f0bSApple OSS Distributions 	natural_t depth = 10;
1779*d4514f0bSApple OSS Distributions 	natural_t saved_depth = depth;
1780*d4514f0bSApple OSS Distributions 	mach_msg_type_number_t count = VM_REGION_SUBMAP_INFO_COUNT_64;
1781*d4514f0bSApple OSS Distributions 	mach_vm_address_t addr_cpy = addr;
1782*d4514f0bSApple OSS Distributions 
1783*d4514f0bSApple OSS Distributions 	kern_return_t kr = mach_vm_region_recurse(map,
1784*d4514f0bSApple OSS Distributions 	    &addr_cpy,
1785*d4514f0bSApple OSS Distributions 	    &size_out,
1786*d4514f0bSApple OSS Distributions 	    &depth,
1787*d4514f0bSApple OSS Distributions 	    (vm_region_recurse_info_t)&info,
1788*d4514f0bSApple OSS Distributions 	    &count);
1789*d4514f0bSApple OSS Distributions 	check_mach_vm_region_recurse_outparam_changes(&kr, &info, &saved_info, sizeof(info), depth, saved_depth,
1790*d4514f0bSApple OSS Distributions 	    addr, addr_cpy, size_out, saved_size);
1791*d4514f0bSApple OSS Distributions 
1792*d4514f0bSApple OSS Distributions 	return kr;
1793*d4514f0bSApple OSS Distributions }
1794*d4514f0bSApple OSS Distributions 
1795*d4514f0bSApple OSS Distributions #if TEST_OLD_STYLE_MACH
1796*d4514f0bSApple OSS Distributions static kern_return_t
call_vm_region_recurse(MAP_T map,vm_address_t addr)1797*d4514f0bSApple OSS Distributions call_vm_region_recurse(MAP_T map, vm_address_t addr)
1798*d4514f0bSApple OSS Distributions {
1799*d4514f0bSApple OSS Distributions 	vm_region_submap_info_data_t info;
1800*d4514f0bSApple OSS Distributions 	info.inheritance = INVALID_INHERIT;
1801*d4514f0bSApple OSS Distributions 	vm_region_submap_info_data_t saved_info = info;
1802*d4514f0bSApple OSS Distributions 
1803*d4514f0bSApple OSS Distributions 	vm_size_t size_out = UNLIKELY_INITIAL_SIZE;
1804*d4514f0bSApple OSS Distributions 	vm_size_t saved_size = size_out;
1805*d4514f0bSApple OSS Distributions 
1806*d4514f0bSApple OSS Distributions 	natural_t depth = 10;
1807*d4514f0bSApple OSS Distributions 	natural_t saved_depth = depth;
1808*d4514f0bSApple OSS Distributions 
1809*d4514f0bSApple OSS Distributions 	mach_msg_type_number_t count = VM_REGION_SUBMAP_INFO_COUNT;
1810*d4514f0bSApple OSS Distributions 	vm_address_t addr_cpy = addr;
1811*d4514f0bSApple OSS Distributions 
1812*d4514f0bSApple OSS Distributions 	kern_return_t kr = vm_region_recurse(map,
1813*d4514f0bSApple OSS Distributions 	    &addr_cpy,
1814*d4514f0bSApple OSS Distributions 	    &size_out,
1815*d4514f0bSApple OSS Distributions 	    &depth,
1816*d4514f0bSApple OSS Distributions 	    (vm_region_recurse_info_t)&info,
1817*d4514f0bSApple OSS Distributions 	    &count);
1818*d4514f0bSApple OSS Distributions 
1819*d4514f0bSApple OSS Distributions 	check_mach_vm_region_recurse_outparam_changes(&kr, &info, &saved_info, sizeof(info), depth, saved_depth,
1820*d4514f0bSApple OSS Distributions 	    addr_cpy, addr, size_out, saved_size);
1821*d4514f0bSApple OSS Distributions 
1822*d4514f0bSApple OSS Distributions 	return kr;
1823*d4514f0bSApple OSS Distributions }
1824*d4514f0bSApple OSS Distributions 
1825*d4514f0bSApple OSS Distributions static kern_return_t
call_vm_region_recurse_64(MAP_T map,vm_address_t addr)1826*d4514f0bSApple OSS Distributions call_vm_region_recurse_64(MAP_T map, vm_address_t addr)
1827*d4514f0bSApple OSS Distributions {
1828*d4514f0bSApple OSS Distributions 	vm_region_submap_info_data_64_t info;
1829*d4514f0bSApple OSS Distributions 	info.inheritance = INVALID_INHERIT;
1830*d4514f0bSApple OSS Distributions 	vm_region_submap_info_data_64_t saved_info = info;
1831*d4514f0bSApple OSS Distributions 
1832*d4514f0bSApple OSS Distributions 	vm_size_t size_out = UNLIKELY_INITIAL_SIZE;
1833*d4514f0bSApple OSS Distributions 	vm_size_t saved_size = size_out;
1834*d4514f0bSApple OSS Distributions 
1835*d4514f0bSApple OSS Distributions 	natural_t depth = 10;
1836*d4514f0bSApple OSS Distributions 	natural_t saved_depth = depth;
1837*d4514f0bSApple OSS Distributions 
1838*d4514f0bSApple OSS Distributions 	mach_msg_type_number_t count = VM_REGION_SUBMAP_INFO_COUNT_64;
1839*d4514f0bSApple OSS Distributions 	vm_address_t addr_cpy = addr;
1840*d4514f0bSApple OSS Distributions 
1841*d4514f0bSApple OSS Distributions 	kern_return_t kr = vm_region_recurse_64(map,
1842*d4514f0bSApple OSS Distributions 	    &addr_cpy,
1843*d4514f0bSApple OSS Distributions 	    &size_out,
1844*d4514f0bSApple OSS Distributions 	    &depth,
1845*d4514f0bSApple OSS Distributions 	    (vm_region_recurse_info_t)&info,
1846*d4514f0bSApple OSS Distributions 	    &count);
1847*d4514f0bSApple OSS Distributions 
1848*d4514f0bSApple OSS Distributions 	check_mach_vm_region_recurse_outparam_changes(&kr, &info, &saved_info, sizeof(info), depth, saved_depth,
1849*d4514f0bSApple OSS Distributions 	    addr_cpy, addr, size_out, saved_size);
1850*d4514f0bSApple OSS Distributions 
1851*d4514f0bSApple OSS Distributions 	return kr;
1852*d4514f0bSApple OSS Distributions }
1853*d4514f0bSApple OSS Distributions #endif /* TEST_OLD_STYLE_MACH */
1854*d4514f0bSApple OSS Distributions 
1855*d4514f0bSApple OSS Distributions static kern_return_t
call_mach_vm_page_info(MAP_T map,mach_vm_address_t addr)1856*d4514f0bSApple OSS Distributions call_mach_vm_page_info(MAP_T map, mach_vm_address_t addr)
1857*d4514f0bSApple OSS Distributions {
1858*d4514f0bSApple OSS Distributions 	vm_page_info_flavor_t flavor = VM_PAGE_INFO_BASIC;
1859*d4514f0bSApple OSS Distributions 	mach_msg_type_number_t count = VM_PAGE_INFO_BASIC_COUNT;
1860*d4514f0bSApple OSS Distributions 	mach_msg_type_number_t saved_count = count;
1861*d4514f0bSApple OSS Distributions 	vm_page_info_basic_data_t info = {0};
1862*d4514f0bSApple OSS Distributions 	info.depth = -1;
1863*d4514f0bSApple OSS Distributions 	vm_page_info_basic_data_t saved_info = info;
1864*d4514f0bSApple OSS Distributions 
1865*d4514f0bSApple OSS Distributions 	kern_return_t kr = mach_vm_page_info(map, addr, flavor, (vm_page_info_t)&info, &count);
1866*d4514f0bSApple OSS Distributions 	check_mach_vm_page_info_outparam_changes(&kr, info, saved_info, count, saved_count);
1867*d4514f0bSApple OSS Distributions 	return kr;
1868*d4514f0bSApple OSS Distributions }
1869*d4514f0bSApple OSS Distributions 
1870*d4514f0bSApple OSS Distributions static void
check_mach_vm_page_query_outparam_changes(kern_return_t * kr,int disposition,int saved_disposition,int ref_count)1871*d4514f0bSApple OSS Distributions check_mach_vm_page_query_outparam_changes(kern_return_t * kr, int disposition, int saved_disposition, int ref_count)
1872*d4514f0bSApple OSS Distributions {
1873*d4514f0bSApple OSS Distributions 	if (*kr == KERN_SUCCESS) {
1874*d4514f0bSApple OSS Distributions 		/*
1875*d4514f0bSApple OSS Distributions 		 * There should be no outside references to the memory created for this test
1876*d4514f0bSApple OSS Distributions 		 */
1877*d4514f0bSApple OSS Distributions 		if (ref_count != 0) {
1878*d4514f0bSApple OSS Distributions 			*kr = OUT_PARAM_BAD;
1879*d4514f0bSApple OSS Distributions 		}
1880*d4514f0bSApple OSS Distributions 		if (disposition == saved_disposition) {
1881*d4514f0bSApple OSS Distributions 			*kr = OUT_PARAM_BAD;
1882*d4514f0bSApple OSS Distributions 		}
1883*d4514f0bSApple OSS Distributions 	}
1884*d4514f0bSApple OSS Distributions }
1885*d4514f0bSApple OSS Distributions 
1886*d4514f0bSApple OSS Distributions static kern_return_t
call_mach_vm_page_query(MAP_T map,mach_vm_address_t addr)1887*d4514f0bSApple OSS Distributions call_mach_vm_page_query(MAP_T map, mach_vm_address_t addr)
1888*d4514f0bSApple OSS Distributions {
1889*d4514f0bSApple OSS Distributions 	int disp = INVALID_DISPOSITION_VALUE, ref = 0;
1890*d4514f0bSApple OSS Distributions 	int saved_disposition = disp;
1891*d4514f0bSApple OSS Distributions 	kern_return_t kr = mach_vm_page_query(map, addr, &disp, &ref);
1892*d4514f0bSApple OSS Distributions 	check_mach_vm_page_query_outparam_changes(&kr, disp, saved_disposition, ref);
1893*d4514f0bSApple OSS Distributions 	return kr;
1894*d4514f0bSApple OSS Distributions }
1895*d4514f0bSApple OSS Distributions 
1896*d4514f0bSApple OSS Distributions #if TEST_OLD_STYLE_MACH
1897*d4514f0bSApple OSS Distributions static kern_return_t
call_vm_map_page_query(MAP_T map,vm_address_t addr)1898*d4514f0bSApple OSS Distributions call_vm_map_page_query(MAP_T map, vm_address_t addr)
1899*d4514f0bSApple OSS Distributions {
1900*d4514f0bSApple OSS Distributions 	int disp = INVALID_DISPOSITION_VALUE, ref = 0;
1901*d4514f0bSApple OSS Distributions 	int saved_disposition = disp;
1902*d4514f0bSApple OSS Distributions 	kern_return_t kr = vm_map_page_query(map, addr, &disp, &ref);
1903*d4514f0bSApple OSS Distributions 	check_mach_vm_page_query_outparam_changes(&kr, disp, saved_disposition, ref);
1904*d4514f0bSApple OSS Distributions 	return kr;
1905*d4514f0bSApple OSS Distributions }
1906*d4514f0bSApple OSS Distributions #endif /* TEST_OLD_STYLE_MACH */
1907*d4514f0bSApple OSS Distributions 
1908*d4514f0bSApple OSS Distributions static void
check_mach_vm_page_range_query_outparam_changes(kern_return_t * kr,mach_vm_size_t out_count,mach_vm_size_t in_count)1909*d4514f0bSApple OSS Distributions check_mach_vm_page_range_query_outparam_changes(kern_return_t * kr, mach_vm_size_t out_count, mach_vm_size_t in_count)
1910*d4514f0bSApple OSS Distributions {
1911*d4514f0bSApple OSS Distributions 	if (out_count != in_count) {
1912*d4514f0bSApple OSS Distributions 		*kr = OUT_PARAM_BAD;
1913*d4514f0bSApple OSS Distributions 	}
1914*d4514f0bSApple OSS Distributions }
1915*d4514f0bSApple OSS Distributions 
1916*d4514f0bSApple OSS Distributions static kern_return_t
call_mach_vm_page_range_query(MAP_T map,mach_vm_address_t start,mach_vm_size_t size)1917*d4514f0bSApple OSS Distributions call_mach_vm_page_range_query(MAP_T map, mach_vm_address_t start, mach_vm_size_t size)
1918*d4514f0bSApple OSS Distributions {
1919*d4514f0bSApple OSS Distributions 	// mach_vm_page_range_query writes one int per page output
1920*d4514f0bSApple OSS Distributions 	// and can accept any address range as input
1921*d4514f0bSApple OSS Distributions 	// We can't provide that much storage for very large lengths.
1922*d4514f0bSApple OSS Distributions 	// Instead we provide a limited output buffer,
1923*d4514f0bSApple OSS Distributions 	// write-protect the page after it, and "succeed" if the kernel
1924*d4514f0bSApple OSS Distributions 	// fills the buffer and then returns EFAULT.
1925*d4514f0bSApple OSS Distributions 
1926*d4514f0bSApple OSS Distributions 	// enough space for MAX_PAGE_RANGE_QUERY with 4KB pages, twice
1927*d4514f0bSApple OSS Distributions 	mach_vm_size_t prq_buf_size = 2 * 262144 * sizeof(int);
1928*d4514f0bSApple OSS Distributions 	mach_vm_address_t prq_buf = 0;
1929*d4514f0bSApple OSS Distributions 	kern_return_t kr = mach_vm_allocate(map, &prq_buf,
1930*d4514f0bSApple OSS Distributions 	    prq_buf_size + KB16, VM_FLAGS_ANYWHERE);
1931*d4514f0bSApple OSS Distributions 	assert(kr == 0);
1932*d4514f0bSApple OSS Distributions 
1933*d4514f0bSApple OSS Distributions 	// protect the guard page
1934*d4514f0bSApple OSS Distributions 	mach_vm_address_t prq_guard = prq_buf + prq_buf_size;
1935*d4514f0bSApple OSS Distributions 	kr = mach_vm_protect(map, prq_guard, KB16, 0, VM_PROT_NONE);
1936*d4514f0bSApple OSS Distributions 	assert(kr == 0);
1937*d4514f0bSApple OSS Distributions 
1938*d4514f0bSApple OSS Distributions 	// pre-fill the output buffer with an invalid value
1939*d4514f0bSApple OSS Distributions 	memset((char *)prq_buf, 0xff, prq_buf_size);
1940*d4514f0bSApple OSS Distributions 
1941*d4514f0bSApple OSS Distributions 	mach_vm_size_t in_count = size / KB16 + (size % KB16 ? 1 : 0);
1942*d4514f0bSApple OSS Distributions 	mach_vm_size_t out_count = in_count;
1943*d4514f0bSApple OSS Distributions 	kr = mach_vm_page_range_query(map, start, size, prq_buf, &out_count);
1944*d4514f0bSApple OSS Distributions 
1945*d4514f0bSApple OSS Distributions 	// yes, EFAULT as a kern_return_t because mach_vm_page_range_query returns copyio's error
1946*d4514f0bSApple OSS Distributions 	if (kr == EFAULT) {
1947*d4514f0bSApple OSS Distributions 		bool bad = false;
1948*d4514f0bSApple OSS Distributions 		for (unsigned i = 0; i < prq_buf_size / sizeof(uint32_t); i++) {
1949*d4514f0bSApple OSS Distributions 			if (((uint32_t *)prq_buf)[i] == 0xffffffff) {
1950*d4514f0bSApple OSS Distributions 				// kernel didn't fill the entire writeable buffer, that's bad
1951*d4514f0bSApple OSS Distributions 				bad = true;
1952*d4514f0bSApple OSS Distributions 				break;
1953*d4514f0bSApple OSS Distributions 			}
1954*d4514f0bSApple OSS Distributions 		}
1955*d4514f0bSApple OSS Distributions 		if (!bad) {
1956*d4514f0bSApple OSS Distributions 			// kernel filled our buffer and then hit our fault page
1957*d4514f0bSApple OSS Distributions 			// we'll allow it
1958*d4514f0bSApple OSS Distributions 			kr = 0;
1959*d4514f0bSApple OSS Distributions 		}
1960*d4514f0bSApple OSS Distributions 	}
1961*d4514f0bSApple OSS Distributions 
1962*d4514f0bSApple OSS Distributions 	check_mach_vm_page_range_query_outparam_changes(&kr, out_count, in_count);
1963*d4514f0bSApple OSS Distributions 	(void)mach_vm_deallocate(map, prq_buf, prq_buf_size + KB16);
1964*d4514f0bSApple OSS Distributions 
1965*d4514f0bSApple OSS Distributions 	return kr;
1966*d4514f0bSApple OSS Distributions }
1967*d4514f0bSApple OSS Distributions 
1968*d4514f0bSApple OSS Distributions static int
call_mincore(void * start,size_t size)1969*d4514f0bSApple OSS Distributions call_mincore(void *start, size_t size)
1970*d4514f0bSApple OSS Distributions {
1971*d4514f0bSApple OSS Distributions 	// mincore writes one byte per page output
1972*d4514f0bSApple OSS Distributions 	// and can accept any address range as input
1973*d4514f0bSApple OSS Distributions 	// We can't provide that much storage for very large lengths.
1974*d4514f0bSApple OSS Distributions 	// Instead we provide a limited output buffer,
1975*d4514f0bSApple OSS Distributions 	// write-protect the page after it, and "succeed" if the kernel
1976*d4514f0bSApple OSS Distributions 	// fills the buffer and then returns EFAULT.
1977*d4514f0bSApple OSS Distributions 
1978*d4514f0bSApple OSS Distributions 	// enough space for MAX_PAGE_RANGE_QUERY with 4KB pages, twice
1979*d4514f0bSApple OSS Distributions 	size_t mincore_buf_size = 2 * 262144;
1980*d4514f0bSApple OSS Distributions 	char *mincore_buf = 0;
1981*d4514f0bSApple OSS Distributions 	mincore_buf = mmap(NULL, mincore_buf_size + KB16, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0);
1982*d4514f0bSApple OSS Distributions 	assert(mincore_buf != MAP_FAILED);
1983*d4514f0bSApple OSS Distributions 
1984*d4514f0bSApple OSS Distributions 	// protect the guard page
1985*d4514f0bSApple OSS Distributions 	char *mincore_guard = mincore_buf + mincore_buf_size;
1986*d4514f0bSApple OSS Distributions 	int err = mprotect(mincore_guard, KB16, PROT_NONE);
1987*d4514f0bSApple OSS Distributions 	assert(err == 0);
1988*d4514f0bSApple OSS Distributions 
1989*d4514f0bSApple OSS Distributions 	// pre-fill the output buffer with an invalid value
1990*d4514f0bSApple OSS Distributions 	memset(mincore_buf, 0xff, mincore_buf_size);
1991*d4514f0bSApple OSS Distributions 
1992*d4514f0bSApple OSS Distributions 	int ret;
1993*d4514f0bSApple OSS Distributions 	err = mincore(start, size, mincore_buf);
1994*d4514f0bSApple OSS Distributions 	if (err == 0) {
1995*d4514f0bSApple OSS Distributions 		ret = 0;
1996*d4514f0bSApple OSS Distributions 	} else if (errno != EFAULT) {
1997*d4514f0bSApple OSS Distributions 		ret = errno;
1998*d4514f0bSApple OSS Distributions 	} else {
1999*d4514f0bSApple OSS Distributions 		// EFAULT - check if kernel hit our guard page
2000*d4514f0bSApple OSS Distributions 		bool bad = false;
2001*d4514f0bSApple OSS Distributions 		for (unsigned i = 0; i < mincore_buf_size; i++) {
2002*d4514f0bSApple OSS Distributions 			if (mincore_buf[i] == (char)0xff) {
2003*d4514f0bSApple OSS Distributions 				// kernel didn't fill the entire writeable buffer, that's bad
2004*d4514f0bSApple OSS Distributions 				bad = true;
2005*d4514f0bSApple OSS Distributions 				break;
2006*d4514f0bSApple OSS Distributions 			}
2007*d4514f0bSApple OSS Distributions 		}
2008*d4514f0bSApple OSS Distributions 		if (!bad) {
2009*d4514f0bSApple OSS Distributions 			// kernel filled our buffer and then hit our guard page
2010*d4514f0bSApple OSS Distributions 			// we'll allow it
2011*d4514f0bSApple OSS Distributions 			ret = 0;
2012*d4514f0bSApple OSS Distributions 		} else {
2013*d4514f0bSApple OSS Distributions 			ret = errno;
2014*d4514f0bSApple OSS Distributions 		}
2015*d4514f0bSApple OSS Distributions 	}
2016*d4514f0bSApple OSS Distributions 
2017*d4514f0bSApple OSS Distributions 	(void)munmap(mincore_buf, mincore_buf_size + PAGE_SIZE);
2018*d4514f0bSApple OSS Distributions 
2019*d4514f0bSApple OSS Distributions 	return ret;
2020*d4514f0bSApple OSS Distributions }
2021*d4514f0bSApple OSS Distributions 
2022*d4514f0bSApple OSS Distributions 
2023*d4514f0bSApple OSS Distributions typedef kern_return_t (*fn_mach_vm_deferred_reclamation_buffer_init)(task_t task, mach_vm_address_t address, mach_vm_size_t size);
2024*d4514f0bSApple OSS Distributions 
2025*d4514f0bSApple OSS Distributions static results_t *
test_mach_vm_deferred_reclamation_buffer_init(fn_mach_vm_deferred_reclamation_buffer_init func,const char * testname)2026*d4514f0bSApple OSS Distributions test_mach_vm_deferred_reclamation_buffer_init(fn_mach_vm_deferred_reclamation_buffer_init func,
2027*d4514f0bSApple OSS Distributions     const char * testname)
2028*d4514f0bSApple OSS Distributions {
2029*d4514f0bSApple OSS Distributions 	int ret = 0;
2030*d4514f0bSApple OSS Distributions 	// Set vm.reclaim_max_threshold to non-zero
2031*d4514f0bSApple OSS Distributions 	int orig_reclaim_max_threshold = 0;
2032*d4514f0bSApple OSS Distributions 	int new_reclaim_max_threshold = 1;
2033*d4514f0bSApple OSS Distributions 	size_t size = sizeof(orig_reclaim_max_threshold);
2034*d4514f0bSApple OSS Distributions 	int sysctl_res = sysctlbyname("vm.reclaim_max_threshold", &orig_reclaim_max_threshold, &size, NULL, 0);
2035*d4514f0bSApple OSS Distributions 	assert(sysctl_res == 0);
2036*d4514f0bSApple OSS Distributions 	sysctl_res = sysctlbyname("vm.reclaim_max_threshold", NULL, 0, &new_reclaim_max_threshold, size);
2037*d4514f0bSApple OSS Distributions 	assert(sysctl_res == 0);
2038*d4514f0bSApple OSS Distributions 
2039*d4514f0bSApple OSS Distributions 	reclamation_buffer_init_trials_t *trials SMART_RECLAMATION_BUFFER_INIT_TRIALS();
2040*d4514f0bSApple OSS Distributions 	results_t *results = alloc_results(testname, eSMART_RECLAMATION_BUFFER_INIT_TRIALS, trials->count);
2041*d4514f0bSApple OSS Distributions 
2042*d4514f0bSApple OSS Distributions 	// reserve last trial to run without modified sysctl
2043*d4514f0bSApple OSS Distributions 	for (unsigned i = 0; i < trials->count - 1; i++) {
2044*d4514f0bSApple OSS Distributions 		reclamation_buffer_init_trial_t trial = trials->list[i];
2045*d4514f0bSApple OSS Distributions 		ret = func(trial.task, trial.address, trial.size);
2046*d4514f0bSApple OSS Distributions 		append_result(results, ret, trial.name);
2047*d4514f0bSApple OSS Distributions 	}
2048*d4514f0bSApple OSS Distributions 
2049*d4514f0bSApple OSS Distributions 	// run with vm.reclaim_max_threshold = 0 and exercise KERN_NOT_SUPPORTED path
2050*d4514f0bSApple OSS Distributions 	new_reclaim_max_threshold = 0;
2051*d4514f0bSApple OSS Distributions 	reclamation_buffer_init_trial_t last_trial = trials->list[trials->count - 1];
2052*d4514f0bSApple OSS Distributions 
2053*d4514f0bSApple OSS Distributions 	sysctl_res = sysctlbyname("vm.reclaim_max_threshold", NULL, 0, &new_reclaim_max_threshold, size);
2054*d4514f0bSApple OSS Distributions 	assert(sysctl_res == 0);
2055*d4514f0bSApple OSS Distributions 
2056*d4514f0bSApple OSS Distributions 	ret = func(last_trial.task, last_trial.address, last_trial.size);
2057*d4514f0bSApple OSS Distributions 	if (__improbable(ret == KERN_INVALID_ARGUMENT)) {
2058*d4514f0bSApple OSS Distributions 		// Unlikely case when args are rejected before sysctl check.
2059*d4514f0bSApple OSS Distributions 		// When this happens during test run, return acceptable, but if this happens
2060*d4514f0bSApple OSS Distributions 		// during golden file generation, record the expected value.
2061*d4514f0bSApple OSS Distributions 		ret = generate_golden ? KERN_NOT_SUPPORTED : ACCEPTABLE;
2062*d4514f0bSApple OSS Distributions 	}
2063*d4514f0bSApple OSS Distributions 	append_result(results, ret, last_trial.name);
2064*d4514f0bSApple OSS Distributions 
2065*d4514f0bSApple OSS Distributions 	// Revert vm.reclaim_max_threshold to how we found it
2066*d4514f0bSApple OSS Distributions 	sysctl_res = sysctlbyname("vm.reclaim_max_threshold", NULL, 0, &orig_reclaim_max_threshold, size);
2067*d4514f0bSApple OSS Distributions 	assert(sysctl_res == 0);
2068*d4514f0bSApple OSS Distributions 
2069*d4514f0bSApple OSS Distributions 	return results;
2070*d4514f0bSApple OSS Distributions }
2071*d4514f0bSApple OSS Distributions 
2072*d4514f0bSApple OSS Distributions 
2073*d4514f0bSApple OSS Distributions static vm_map_kernel_flags_trials_t *
generate_mmap_kernel_flags_trials()2074*d4514f0bSApple OSS Distributions generate_mmap_kernel_flags_trials()
2075*d4514f0bSApple OSS Distributions {
2076*d4514f0bSApple OSS Distributions 	// mmap rejects both ANYWHERE and FIXED | OVERWRITE
2077*d4514f0bSApple OSS Distributions 	// so don't set any prefix flags.
2078*d4514f0bSApple OSS Distributions 	return generate_prefixed_vm_map_kernel_flags_trials(0, "");
2079*d4514f0bSApple OSS Distributions }
2080*d4514f0bSApple OSS Distributions 
2081*d4514f0bSApple OSS Distributions 
2082*d4514f0bSApple OSS Distributions #define SMART_MMAP_KERNEL_FLAGS_TRIALS()                                \
2083*d4514f0bSApple OSS Distributions 	__attribute__((cleanup(cleanup_vm_map_kernel_flags_trials)))    \
2084*d4514f0bSApple OSS Distributions 	= generate_mmap_kernel_flags_trials()
2085*d4514f0bSApple OSS Distributions 
2086*d4514f0bSApple OSS Distributions static results_t *
test_mmap_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)2087*d4514f0bSApple OSS Distributions test_mmap_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)
2088*d4514f0bSApple OSS Distributions {
2089*d4514f0bSApple OSS Distributions 	MAP_T map SMART_MAP;
2090*d4514f0bSApple OSS Distributions 
2091*d4514f0bSApple OSS Distributions 	allocation_t base SMART_ALLOCATE_VM(map, TEST_ALLOC_SIZE, VM_PROT_DEFAULT);
2092*d4514f0bSApple OSS Distributions 	vm_map_kernel_flags_trials_t * trials SMART_MMAP_KERNEL_FLAGS_TRIALS();
2093*d4514f0bSApple OSS Distributions 	results_t *results = alloc_results(testname, eSMART_MMAP_KERNEL_FLAGS_TRIALS, trials->count);
2094*d4514f0bSApple OSS Distributions 
2095*d4514f0bSApple OSS Distributions 	for (unsigned i = 0; i < trials->count; i++) {
2096*d4514f0bSApple OSS Distributions 		kern_return_t ret = func(map, base.addr, base.size, trials->list[i].flags);
2097*d4514f0bSApple OSS Distributions 		append_result(results, ret, trials->list[i].name);
2098*d4514f0bSApple OSS Distributions 	}
2099*d4514f0bSApple OSS Distributions 	return results;
2100*d4514f0bSApple OSS Distributions }
2101*d4514f0bSApple OSS Distributions 
2102*d4514f0bSApple OSS Distributions // Test a Unix function.
2103*d4514f0bSApple OSS Distributions // Run each trial with an allocated vm region and a vm_inherit_t
2104*d4514f0bSApple OSS Distributions typedef int (*unix_with_inherit_fn)(void *start, size_t size, int inherit);
2105*d4514f0bSApple OSS Distributions 
2106*d4514f0bSApple OSS Distributions static results_t *
test_unix_with_allocated_vm_inherit_t(unix_with_inherit_fn fn,const char * testname)2107*d4514f0bSApple OSS Distributions test_unix_with_allocated_vm_inherit_t(unix_with_inherit_fn fn, const char * testname)
2108*d4514f0bSApple OSS Distributions {
2109*d4514f0bSApple OSS Distributions 	MAP_T map SMART_MAP;
2110*d4514f0bSApple OSS Distributions 	allocation_t base SMART_ALLOCATE_VM(map, TEST_ALLOC_SIZE, VM_PROT_DEFAULT);
2111*d4514f0bSApple OSS Distributions 	vm_inherit_trials_t *trials SMART_VM_INHERIT_TRIALS();
2112*d4514f0bSApple OSS Distributions 	results_t *results = alloc_results(testname, eSMART_VM_INHERIT_TRIALS, trials->count);
2113*d4514f0bSApple OSS Distributions 
2114*d4514f0bSApple OSS Distributions 	for (unsigned i = 0; i < trials->count; i++) {
2115*d4514f0bSApple OSS Distributions 		vm_inherit_trial_t trial = trials->list[i];
2116*d4514f0bSApple OSS Distributions 		int ret = fn((void*)(uintptr_t)base.addr, (size_t)base.size, (int)trial.value);
2117*d4514f0bSApple OSS Distributions 		append_result(results, ret, trial.name);
2118*d4514f0bSApple OSS Distributions 	}
2119*d4514f0bSApple OSS Distributions 	return results;
2120*d4514f0bSApple OSS Distributions }
2121*d4514f0bSApple OSS Distributions 
2122*d4514f0bSApple OSS Distributions // Test a Unix function.
2123*d4514f0bSApple OSS Distributions // Run each trial with an allocated vm region and a vm_msync_t
2124*d4514f0bSApple OSS Distributions typedef int (*unix_with_msync_fn)(void *start, size_t size, int msync_value);
2125*d4514f0bSApple OSS Distributions 
2126*d4514f0bSApple OSS Distributions static results_t *
test_unix_with_allocated_vm_msync_t(unix_with_msync_fn fn,const char * testname)2127*d4514f0bSApple OSS Distributions test_unix_with_allocated_vm_msync_t(unix_with_msync_fn fn, const char * testname)
2128*d4514f0bSApple OSS Distributions {
2129*d4514f0bSApple OSS Distributions 	MAP_T map SMART_MAP;
2130*d4514f0bSApple OSS Distributions 	allocation_t base SMART_ALLOCATE_VM(map, TEST_ALLOC_SIZE, VM_PROT_DEFAULT);
2131*d4514f0bSApple OSS Distributions 	vm_msync_trials_t *trials SMART_VM_MSYNC_TRIALS();
2132*d4514f0bSApple OSS Distributions 	results_t *results = alloc_results(testname, eSMART_VM_MSYNC_TRIALS, trials->count);
2133*d4514f0bSApple OSS Distributions 
2134*d4514f0bSApple OSS Distributions 	for (unsigned i = 0; i < trials->count; i++) {
2135*d4514f0bSApple OSS Distributions 		vm_msync_trial_t trial = trials->list[i];
2136*d4514f0bSApple OSS Distributions 		int ret = fn((void*)(uintptr_t)base.addr, (size_t)base.size, (int)trial.value);
2137*d4514f0bSApple OSS Distributions 		append_result(results, ret, trial.name);
2138*d4514f0bSApple OSS Distributions 	}
2139*d4514f0bSApple OSS Distributions 	return results;
2140*d4514f0bSApple OSS Distributions }
2141*d4514f0bSApple OSS Distributions 
2142*d4514f0bSApple OSS Distributions // Test a Unix function.
2143*d4514f0bSApple OSS Distributions // Run each trial with an allocated vm region and an advise
2144*d4514f0bSApple OSS Distributions typedef int (*unix_with_advise_fn)(void *start, size_t size, int advise);
2145*d4514f0bSApple OSS Distributions 
2146*d4514f0bSApple OSS Distributions static results_t *
test_unix_with_allocated_aligned_vm_advise_t(unix_with_advise_fn fn,mach_vm_size_t align_mask,const char * testname)2147*d4514f0bSApple OSS Distributions test_unix_with_allocated_aligned_vm_advise_t(unix_with_advise_fn fn, mach_vm_size_t align_mask, const char * testname)
2148*d4514f0bSApple OSS Distributions {
2149*d4514f0bSApple OSS Distributions 	MAP_T map SMART_MAP;
2150*d4514f0bSApple OSS Distributions 	allocation_t base SMART_ALLOCATE_ALIGNED_VM(map, TEST_ALLOC_SIZE, align_mask, VM_PROT_DEFAULT);
2151*d4514f0bSApple OSS Distributions 	vm_advise_trials_t *trials SMART_VM_ADVISE_TRIALS();
2152*d4514f0bSApple OSS Distributions 	results_t *results = alloc_results(testname, eSMART_VM_ADVISE_TRIALS, trials->count);
2153*d4514f0bSApple OSS Distributions 
2154*d4514f0bSApple OSS Distributions 	for (unsigned i = 0; i < trials->count; i++) {
2155*d4514f0bSApple OSS Distributions 		vm_advise_trial_t trial = trials->list[i];
2156*d4514f0bSApple OSS Distributions 		int ret = fn((void*)(uintptr_t)base.addr, (size_t)base.size, (int)trial.value);
2157*d4514f0bSApple OSS Distributions 		append_result(results, ret, trial.name);
2158*d4514f0bSApple OSS Distributions 	}
2159*d4514f0bSApple OSS Distributions 	return results;
2160*d4514f0bSApple OSS Distributions }
2161*d4514f0bSApple OSS Distributions 
2162*d4514f0bSApple OSS Distributions // Rosetta userspace intercepts shared_region_map_and_slide_2_np calls and this Rosetta wrapper
2163*d4514f0bSApple OSS Distributions // function doesn't have the necessary checks to support invalid input arguments. Skip these trials
2164*d4514f0bSApple OSS Distributions // intead of crashing the test.
2165*d4514f0bSApple OSS Distributions static bool
shared_region_map_and_slide_would_crash(shared_region_map_and_slide_2_trial_t * trial)2166*d4514f0bSApple OSS Distributions shared_region_map_and_slide_would_crash(shared_region_map_and_slide_2_trial_t *trial)
2167*d4514f0bSApple OSS Distributions {
2168*d4514f0bSApple OSS Distributions 	uint32_t files_count = trial->files_count;
2169*d4514f0bSApple OSS Distributions 	struct shared_file_np *files = trial->files;
2170*d4514f0bSApple OSS Distributions 	uint32_t mappings_count = trial->mappings_count;
2171*d4514f0bSApple OSS Distributions 	struct shared_file_mapping_slide_np *mappings = trial->mappings;
2172*d4514f0bSApple OSS Distributions 
2173*d4514f0bSApple OSS Distributions 	if (files_count == 0 || files_count == 1 || files_count > _SR_FILE_MAPPINGS_MAX_FILES) {
2174*d4514f0bSApple OSS Distributions 		return true;
2175*d4514f0bSApple OSS Distributions 	}
2176*d4514f0bSApple OSS Distributions 	if (mappings_count == 0 || mappings_count > SFM_MAX) {
2177*d4514f0bSApple OSS Distributions 		return true;
2178*d4514f0bSApple OSS Distributions 	}
2179*d4514f0bSApple OSS Distributions 	if (!files) {
2180*d4514f0bSApple OSS Distributions 		return true;
2181*d4514f0bSApple OSS Distributions 	}
2182*d4514f0bSApple OSS Distributions 	if (!mappings) {
2183*d4514f0bSApple OSS Distributions 		return true;
2184*d4514f0bSApple OSS Distributions 	}
2185*d4514f0bSApple OSS Distributions 	if (mappings_count != (((files_count - 1) * kNumSharedCacheMappings) + 1) &&
2186*d4514f0bSApple OSS Distributions 	    mappings_count != (files_count * kNumSharedCacheMappings)) {
2187*d4514f0bSApple OSS Distributions 		return true;
2188*d4514f0bSApple OSS Distributions 	}
2189*d4514f0bSApple OSS Distributions 	if (files_count >= kMaxSubcaches) {
2190*d4514f0bSApple OSS Distributions 		return true;
2191*d4514f0bSApple OSS Distributions 	}
2192*d4514f0bSApple OSS Distributions 	return false;
2193*d4514f0bSApple OSS Distributions }
2194*d4514f0bSApple OSS Distributions 
2195*d4514f0bSApple OSS Distributions typedef int (*unix_shared_region_map_and_slide_2_np)(uint32_t files_coun, const struct shared_file_np *files, uint32_t mappings_count, const struct shared_file_mapping_slide_np *mappings);
2196*d4514f0bSApple OSS Distributions 
2197*d4514f0bSApple OSS Distributions static results_t *
test_unix_shared_region_map_and_slide_2_np(unix_shared_region_map_and_slide_2_np func,const char * testname)2198*d4514f0bSApple OSS Distributions test_unix_shared_region_map_and_slide_2_np(unix_shared_region_map_and_slide_2_np func, const char *testname)
2199*d4514f0bSApple OSS Distributions {
2200*d4514f0bSApple OSS Distributions 	uint64_t dyld_fp = (uint64_t)get_dyld_fd();
2201*d4514f0bSApple OSS Distributions 	shared_region_map_and_slide_2_trials_t *trials SMART_SHARED_REGION_MAP_AND_SLIDE_2_TRIALS(dyld_fp);
2202*d4514f0bSApple OSS Distributions 	results_t *results = alloc_results(testname, eSMART_SHARED_REGION_MAP_AND_SLIDE_2_TRIALS, dyld_fp, trials->count);
2203*d4514f0bSApple OSS Distributions 
2204*d4514f0bSApple OSS Distributions 	for (unsigned i = 0; i < trials->count; i++) {
2205*d4514f0bSApple OSS Distributions 		int ret;
2206*d4514f0bSApple OSS Distributions 		shared_region_map_and_slide_2_trial_t trial = trials->list[i];
2207*d4514f0bSApple OSS Distributions 		if (isRosetta() && shared_region_map_and_slide_would_crash(&trial)) {
2208*d4514f0bSApple OSS Distributions 			ret = IGNORED;
2209*d4514f0bSApple OSS Distributions 		} else {
2210*d4514f0bSApple OSS Distributions 			ret = func(trial.files_count, trial.files, trial.mappings_count, trial.mappings);
2211*d4514f0bSApple OSS Distributions 		}
2212*d4514f0bSApple OSS Distributions 		append_result(results, ret, trial.name);
2213*d4514f0bSApple OSS Distributions 	}
2214*d4514f0bSApple OSS Distributions 
2215*d4514f0bSApple OSS Distributions 	close_dyld_fd();
2216*d4514f0bSApple OSS Distributions 	return results;
2217*d4514f0bSApple OSS Distributions }
2218*d4514f0bSApple OSS Distributions 
2219*d4514f0bSApple OSS Distributions static results_t *
test_dst_size_fileoff(kern_return_t (* func)(MAP_T map,mach_vm_address_t dst,mach_vm_size_t size,mach_vm_address_t fileoff),const char * testname)2220*d4514f0bSApple OSS Distributions test_dst_size_fileoff(kern_return_t (*func)(MAP_T map, mach_vm_address_t dst, mach_vm_size_t size, mach_vm_address_t fileoff), const char * testname)
2221*d4514f0bSApple OSS Distributions {
2222*d4514f0bSApple OSS Distributions 	MAP_T map SMART_MAP;
2223*d4514f0bSApple OSS Distributions 	src_dst_size_trials_t * trials SMART_FILEOFF_DST_SIZE_TRIALS();
2224*d4514f0bSApple OSS Distributions 	results_t *results = alloc_results(testname, eSMART_FILEOFF_DST_SIZE_TRIALS, trials->count);
2225*d4514f0bSApple OSS Distributions 
2226*d4514f0bSApple OSS Distributions 	for (unsigned i = 0; i < trials->count; i++) {
2227*d4514f0bSApple OSS Distributions 		src_dst_size_trial_t trial = trials->list[i];
2228*d4514f0bSApple OSS Distributions 		unallocation_t dst_base SMART_UNALLOCATE_VM(map, TEST_ALLOC_SIZE);
2229*d4514f0bSApple OSS Distributions 		// src a.k.a. mmap fileoff doesn't slide
2230*d4514f0bSApple OSS Distributions 		trial = slide_trial_dst(trial, dst_base.addr);
2231*d4514f0bSApple OSS Distributions 		int ret = func(map, trial.dst, trial.size, trial.src);
2232*d4514f0bSApple OSS Distributions 		append_result(results, ret, trial.name);
2233*d4514f0bSApple OSS Distributions 	}
2234*d4514f0bSApple OSS Distributions 	return results;
2235*d4514f0bSApple OSS Distributions }
2236*d4514f0bSApple OSS Distributions 
2237*d4514f0bSApple OSS Distributions // Try to allocate a destination for mmap(MAP_FIXED) to overwrite.
2238*d4514f0bSApple OSS Distributions // On exit:
2239*d4514f0bSApple OSS Distributions // *out_dst *out_size are the allocation, or 0
2240*d4514f0bSApple OSS Distributions // *out_panic is true if the trial should stop and record PANIC
2241*d4514f0bSApple OSS Distributions // (because the trial specifies an absolute address that is already occupied)
2242*d4514f0bSApple OSS Distributions // *out_slide is true if the trial should slide by *out_dst
2243*d4514f0bSApple OSS Distributions static __attribute__((overloadable)) void
allocate_for_mmap_fixed(MAP_T map,mach_vm_address_t trial_dst,mach_vm_size_t trial_size,bool trial_dst_is_absolute,bool trial_size_is_absolute,mach_vm_address_t * out_dst,mach_vm_size_t * out_size,bool * out_panic,bool * out_slide)2244*d4514f0bSApple OSS Distributions allocate_for_mmap_fixed(MAP_T map, mach_vm_address_t trial_dst, mach_vm_size_t trial_size, bool trial_dst_is_absolute, bool trial_size_is_absolute, mach_vm_address_t *out_dst, mach_vm_size_t *out_size, bool *out_panic, bool *out_slide)
2245*d4514f0bSApple OSS Distributions {
2246*d4514f0bSApple OSS Distributions 	*out_panic = false;
2247*d4514f0bSApple OSS Distributions 	*out_slide = false;
2248*d4514f0bSApple OSS Distributions 
2249*d4514f0bSApple OSS Distributions 	if (trial_dst_is_absolute && trial_size_is_absolute) {
2250*d4514f0bSApple OSS Distributions 		// known dst addr, known size
2251*d4514f0bSApple OSS Distributions 		*out_dst = trial_dst;
2252*d4514f0bSApple OSS Distributions 		*out_size = trial_size;
2253*d4514f0bSApple OSS Distributions 		kern_return_t kr = mach_vm_allocate(map, out_dst, *out_size, VM_FLAGS_FIXED);
2254*d4514f0bSApple OSS Distributions 		if (kr == KERN_NO_SPACE) {
2255*d4514f0bSApple OSS Distributions 			// this space is in use, we can't allow mmap to try to overwrite it
2256*d4514f0bSApple OSS Distributions 			*out_panic = true;
2257*d4514f0bSApple OSS Distributions 			*out_dst = 0;
2258*d4514f0bSApple OSS Distributions 			*out_size = 0;
2259*d4514f0bSApple OSS Distributions 		} else if (kr != 0) {
2260*d4514f0bSApple OSS Distributions 			// some other error, assume mmap will also fail
2261*d4514f0bSApple OSS Distributions 			*out_dst = 0;
2262*d4514f0bSApple OSS Distributions 			*out_size = 0;
2263*d4514f0bSApple OSS Distributions 		}
2264*d4514f0bSApple OSS Distributions 		// no slide, trial and allocation are already at the same place
2265*d4514f0bSApple OSS Distributions 		*out_slide = false;
2266*d4514f0bSApple OSS Distributions 	} else {
2267*d4514f0bSApple OSS Distributions 		// other cases either fit in a small allocation or fail
2268*d4514f0bSApple OSS Distributions 		*out_dst = 0;
2269*d4514f0bSApple OSS Distributions 		*out_size = TEST_ALLOC_SIZE;
2270*d4514f0bSApple OSS Distributions 		kern_return_t kr = mach_vm_allocate(map, out_dst, *out_size, VM_FLAGS_ANYWHERE);
2271*d4514f0bSApple OSS Distributions 		if (kr != 0) {
2272*d4514f0bSApple OSS Distributions 			// allocation error, assume mmap will also fail
2273*d4514f0bSApple OSS Distributions 			*out_dst = 0;
2274*d4514f0bSApple OSS Distributions 			*out_size = 0;
2275*d4514f0bSApple OSS Distributions 		}
2276*d4514f0bSApple OSS Distributions 		*out_slide = true;
2277*d4514f0bSApple OSS Distributions 	}
2278*d4514f0bSApple OSS Distributions }
2279*d4514f0bSApple OSS Distributions 
2280*d4514f0bSApple OSS Distributions static __attribute__((overloadable)) void
allocate_for_mmap_fixed(MAP_T map,start_size_trial_t trial,mach_vm_address_t * out_dst,mach_vm_size_t * out_size,bool * out_panic,bool * out_slide)2281*d4514f0bSApple OSS Distributions allocate_for_mmap_fixed(MAP_T map, start_size_trial_t trial, mach_vm_address_t *out_dst, mach_vm_size_t *out_size, bool *out_panic, bool *out_slide)
2282*d4514f0bSApple OSS Distributions {
2283*d4514f0bSApple OSS Distributions 	allocate_for_mmap_fixed(map, trial.start, trial.size, trial.start_is_absolute, trial.size_is_absolute,
2284*d4514f0bSApple OSS Distributions 	    out_dst, out_size, out_panic, out_slide);
2285*d4514f0bSApple OSS Distributions }
2286*d4514f0bSApple OSS Distributions static __attribute__((overloadable)) void
allocate_for_mmap_fixed(MAP_T map,src_dst_size_trial_t trial,mach_vm_address_t * out_dst,mach_vm_size_t * out_size,bool * out_panic,bool * out_slide)2287*d4514f0bSApple OSS Distributions allocate_for_mmap_fixed(MAP_T map, src_dst_size_trial_t trial, mach_vm_address_t *out_dst, mach_vm_size_t *out_size, bool *out_panic, bool *out_slide)
2288*d4514f0bSApple OSS Distributions {
2289*d4514f0bSApple OSS Distributions 	allocate_for_mmap_fixed(map, trial.dst, trial.size, trial.dst_is_absolute, !trial.size_is_dst_relative,
2290*d4514f0bSApple OSS Distributions 	    out_dst, out_size, out_panic, out_slide);
2291*d4514f0bSApple OSS Distributions }
2292*d4514f0bSApple OSS Distributions 
2293*d4514f0bSApple OSS Distributions // Like test_dst_size_fileoff, but specialized for mmap(MAP_FIXED).
2294*d4514f0bSApple OSS Distributions // mmap(MAP_FIXED) is destructive, forcibly unmapping anything
2295*d4514f0bSApple OSS Distributions // already at that address.
2296*d4514f0bSApple OSS Distributions // We must ensure that each trial is either obviously invalid and caught
2297*d4514f0bSApple OSS Distributions // by the sanitizers, or is valid and overwrites an allocation we control.
2298*d4514f0bSApple OSS Distributions static results_t *
test_fixed_dst_size_fileoff(kern_return_t (* func)(MAP_T map,mach_vm_address_t dst,mach_vm_size_t size,mach_vm_address_t fileoff),const char * testname)2299*d4514f0bSApple OSS Distributions test_fixed_dst_size_fileoff(kern_return_t (*func)(MAP_T map, mach_vm_address_t dst, mach_vm_size_t size, mach_vm_address_t fileoff), const char * testname)
2300*d4514f0bSApple OSS Distributions {
2301*d4514f0bSApple OSS Distributions 	MAP_T map SMART_MAP;
2302*d4514f0bSApple OSS Distributions 	src_dst_size_trials_t * trials SMART_FILEOFF_DST_SIZE_TRIALS();
2303*d4514f0bSApple OSS Distributions 	results_t *results = alloc_results(testname, eSMART_FILEOFF_DST_SIZE_TRIALS, trials->count);
2304*d4514f0bSApple OSS Distributions 	for (unsigned i = 0; i < trials->count; i++) {
2305*d4514f0bSApple OSS Distributions 		src_dst_size_trial_t trial = trials->list[i];
2306*d4514f0bSApple OSS Distributions 		// Try to create an allocation for mmap to overwrite.
2307*d4514f0bSApple OSS Distributions 		mach_vm_address_t dst_alloc;
2308*d4514f0bSApple OSS Distributions 		mach_vm_size_t dst_size;
2309*d4514f0bSApple OSS Distributions 		bool should_panic;
2310*d4514f0bSApple OSS Distributions 		bool should_slide_trial;
2311*d4514f0bSApple OSS Distributions 		allocate_for_mmap_fixed(map, trial, &dst_alloc, &dst_size, &should_panic, &should_slide_trial);
2312*d4514f0bSApple OSS Distributions 		if (should_panic) {
2313*d4514f0bSApple OSS Distributions 			append_result(results, PANIC, trial.name);
2314*d4514f0bSApple OSS Distributions 			continue;
2315*d4514f0bSApple OSS Distributions 		}
2316*d4514f0bSApple OSS Distributions 		if (should_slide_trial) {
2317*d4514f0bSApple OSS Distributions 			// src a.k.a. mmap fileoff doesn't slide
2318*d4514f0bSApple OSS Distributions 			trial = slide_trial_dst(trial, dst_alloc);
2319*d4514f0bSApple OSS Distributions 		}
2320*d4514f0bSApple OSS Distributions 
2321*d4514f0bSApple OSS Distributions 		kern_return_t ret = func(map, trial.dst, trial.size, trial.src);
2322*d4514f0bSApple OSS Distributions 
2323*d4514f0bSApple OSS Distributions 		if (dst_alloc != 0) {
2324*d4514f0bSApple OSS Distributions 			(void)mach_vm_deallocate(map, dst_alloc, dst_size);
2325*d4514f0bSApple OSS Distributions 		}
2326*d4514f0bSApple OSS Distributions 		append_result(results, ret, trial.name);
2327*d4514f0bSApple OSS Distributions 	}
2328*d4514f0bSApple OSS Distributions 	return results;
2329*d4514f0bSApple OSS Distributions }
2330*d4514f0bSApple OSS Distributions 
2331*d4514f0bSApple OSS Distributions // Like test_mach_with_allocated_start_size, but specialized for mmap(MAP_FIXED).
2332*d4514f0bSApple OSS Distributions // See test_fixed_dst_size_fileoff for more.
2333*d4514f0bSApple OSS Distributions static results_t *
test_fixed_dst_size(kern_return_t (* func)(MAP_T map,mach_vm_address_t dst,mach_vm_size_t size),const char * testname)2334*d4514f0bSApple OSS Distributions test_fixed_dst_size(kern_return_t (*func)(MAP_T map, mach_vm_address_t dst, mach_vm_size_t size), const char *testname)
2335*d4514f0bSApple OSS Distributions {
2336*d4514f0bSApple OSS Distributions 	MAP_T map SMART_MAP;
2337*d4514f0bSApple OSS Distributions 	start_size_trials_t *trials SMART_START_SIZE_TRIALS(0);  // no base addr
2338*d4514f0bSApple OSS Distributions 	results_t *results = alloc_results(testname, eSMART_START_SIZE_TRIALS, 0, trials->count);
2339*d4514f0bSApple OSS Distributions 	for (unsigned i = 0; i < trials->count; i++) {
2340*d4514f0bSApple OSS Distributions 		start_size_trial_t trial = trials->list[i];
2341*d4514f0bSApple OSS Distributions 		// Try to create an allocation for mmap to overwrite.
2342*d4514f0bSApple OSS Distributions 		mach_vm_address_t dst_alloc;
2343*d4514f0bSApple OSS Distributions 		mach_vm_size_t dst_size;
2344*d4514f0bSApple OSS Distributions 		bool should_panic;
2345*d4514f0bSApple OSS Distributions 		bool should_slide_trial;
2346*d4514f0bSApple OSS Distributions 		allocate_for_mmap_fixed(map, trial, &dst_alloc, &dst_size, &should_panic, &should_slide_trial);
2347*d4514f0bSApple OSS Distributions 		if (should_panic) {
2348*d4514f0bSApple OSS Distributions 			append_result(results, PANIC, trial.name);
2349*d4514f0bSApple OSS Distributions 			continue;
2350*d4514f0bSApple OSS Distributions 		}
2351*d4514f0bSApple OSS Distributions 		if (should_slide_trial) {
2352*d4514f0bSApple OSS Distributions 			trial = slide_trial(trial, dst_alloc);
2353*d4514f0bSApple OSS Distributions 		}
2354*d4514f0bSApple OSS Distributions 
2355*d4514f0bSApple OSS Distributions 		kern_return_t ret = func(map, trial.start, trial.size);
2356*d4514f0bSApple OSS Distributions 
2357*d4514f0bSApple OSS Distributions 		if (dst_alloc != 0) {
2358*d4514f0bSApple OSS Distributions 			(void)mach_vm_deallocate(map, dst_alloc, dst_size);
2359*d4514f0bSApple OSS Distributions 		}
2360*d4514f0bSApple OSS Distributions 		append_result(results, ret, trial.name);
2361*d4514f0bSApple OSS Distributions 	}
2362*d4514f0bSApple OSS Distributions 	return results;
2363*d4514f0bSApple OSS Distributions }
2364*d4514f0bSApple OSS Distributions 
2365*d4514f0bSApple OSS Distributions static results_t *
test_allocated_src_allocated_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)2366*d4514f0bSApple OSS Distributions test_allocated_src_allocated_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)
2367*d4514f0bSApple OSS Distributions {
2368*d4514f0bSApple OSS Distributions 	MAP_T map SMART_MAP;
2369*d4514f0bSApple OSS Distributions 	allocation_t src_base SMART_ALLOCATE_VM(map, TEST_ALLOC_SIZE, VM_PROT_DEFAULT);
2370*d4514f0bSApple OSS Distributions 	allocation_t dst_base SMART_ALLOCATE_VM(map, TEST_ALLOC_SIZE, VM_PROT_DEFAULT);
2371*d4514f0bSApple OSS Distributions 	src_dst_size_trials_t * trials SMART_SRC_DST_SIZE_TRIALS();
2372*d4514f0bSApple OSS Distributions 	results_t *results = alloc_results(testname, eSMART_SRC_DST_SIZE_TRIALS, trials->count);
2373*d4514f0bSApple OSS Distributions 
2374*d4514f0bSApple OSS Distributions 	for (unsigned i = 0; i < trials->count; i++) {
2375*d4514f0bSApple OSS Distributions 		src_dst_size_trial_t trial = trials->list[i];
2376*d4514f0bSApple OSS Distributions 		trial = slide_trial_src(trial, src_base.addr);
2377*d4514f0bSApple OSS Distributions 		trial = slide_trial_dst(trial, dst_base.addr);
2378*d4514f0bSApple OSS Distributions 		int ret = func(map, trial.src, trial.size, trial.dst);
2379*d4514f0bSApple OSS Distributions 		// func should be fixed-overwrite, nothing new to deallocate
2380*d4514f0bSApple OSS Distributions 		append_result(results, ret, trial.name);
2381*d4514f0bSApple OSS Distributions 	}
2382*d4514f0bSApple OSS Distributions 	return results;
2383*d4514f0bSApple OSS Distributions }
2384*d4514f0bSApple OSS Distributions 
2385*d4514f0bSApple OSS Distributions static task_exc_guard_behavior_t saved_exc_guard_behavior;
2386*d4514f0bSApple OSS Distributions 
2387*d4514f0bSApple OSS Distributions static void
disable_exc_guard()2388*d4514f0bSApple OSS Distributions disable_exc_guard()
2389*d4514f0bSApple OSS Distributions {
2390*d4514f0bSApple OSS Distributions 	T_SETUPBEGIN;
2391*d4514f0bSApple OSS Distributions 
2392*d4514f0bSApple OSS Distributions 	// Disable EXC_GUARD for the duration of the test.
2393*d4514f0bSApple OSS Distributions 	// We restore it at the end.
2394*d4514f0bSApple OSS Distributions 	kern_return_t kr = task_get_exc_guard_behavior(mach_task_self(), &saved_exc_guard_behavior);
2395*d4514f0bSApple OSS Distributions 	assert(kr == 0);
2396*d4514f0bSApple OSS Distributions 
2397*d4514f0bSApple OSS Distributions 	kr = task_set_exc_guard_behavior(mach_task_self(), TASK_EXC_GUARD_NONE);
2398*d4514f0bSApple OSS Distributions 	if (kr) {
2399*d4514f0bSApple OSS Distributions 		T_LOG("warning, couldn't disable EXC_GUARD; some tests are disabled");
2400*d4514f0bSApple OSS Distributions 		EXC_GUARD_ENABLED = true;
2401*d4514f0bSApple OSS Distributions 	} else {
2402*d4514f0bSApple OSS Distributions 		EXC_GUARD_ENABLED = false;
2403*d4514f0bSApple OSS Distributions 	}
2404*d4514f0bSApple OSS Distributions 
2405*d4514f0bSApple OSS Distributions 	T_SETUPEND;
2406*d4514f0bSApple OSS Distributions }
2407*d4514f0bSApple OSS Distributions 
2408*d4514f0bSApple OSS Distributions static void
restore_exc_guard()2409*d4514f0bSApple OSS Distributions restore_exc_guard()
2410*d4514f0bSApple OSS Distributions {
2411*d4514f0bSApple OSS Distributions 	// restore process's EXC_GUARD handling
2412*d4514f0bSApple OSS Distributions 	(void)task_set_exc_guard_behavior(mach_task_self(), saved_exc_guard_behavior);
2413*d4514f0bSApple OSS Distributions }
2414*d4514f0bSApple OSS Distributions 
2415*d4514f0bSApple OSS Distributions static int
set_disable_vm_sanitize_telemetry_via_sysctl(uint32_t val)2416*d4514f0bSApple OSS Distributions set_disable_vm_sanitize_telemetry_via_sysctl(uint32_t val)
2417*d4514f0bSApple OSS Distributions {
2418*d4514f0bSApple OSS Distributions 	int ret = sysctlbyname("debug.disable_vm_sanitize_telemetry", NULL, NULL, &val, sizeof(uint32_t));
2419*d4514f0bSApple OSS Distributions 	if (ret != 0) {
2420*d4514f0bSApple OSS Distributions 		printf("sysctl failed with errno %d.\n", errno);
2421*d4514f0bSApple OSS Distributions 	}
2422*d4514f0bSApple OSS Distributions 	return ret;
2423*d4514f0bSApple OSS Distributions }
2424*d4514f0bSApple OSS Distributions 
2425*d4514f0bSApple OSS Distributions static int
disable_vm_sanitize_telemetry(void)2426*d4514f0bSApple OSS Distributions disable_vm_sanitize_telemetry(void)
2427*d4514f0bSApple OSS Distributions {
2428*d4514f0bSApple OSS Distributions 	return set_disable_vm_sanitize_telemetry_via_sysctl(1);
2429*d4514f0bSApple OSS Distributions }
2430*d4514f0bSApple OSS Distributions 
2431*d4514f0bSApple OSS Distributions static int
reenable_vm_sanitize_telemetry(void)2432*d4514f0bSApple OSS Distributions reenable_vm_sanitize_telemetry(void)
2433*d4514f0bSApple OSS Distributions {
2434*d4514f0bSApple OSS Distributions 	return set_disable_vm_sanitize_telemetry_via_sysctl(0);
2435*d4514f0bSApple OSS Distributions }
2436*d4514f0bSApple OSS Distributions 
2437*d4514f0bSApple OSS Distributions #define MAX_LINE_LENGTH 100
2438*d4514f0bSApple OSS Distributions #define MAX_NUM_TESTS 350
2439*d4514f0bSApple OSS Distributions #define TMP_DIR "/tmp/"
2440*d4514f0bSApple OSS Distributions #define ASSETS_DIR "../assets/vm_parameter_validation/"
2441*d4514f0bSApple OSS Distributions #define DECOMPRESS ASSETS_DIR "decompress.sh"
2442*d4514f0bSApple OSS Distributions #define GOLDEN_FILE TMP_DIR "user_golden_image.log"
2443*d4514f0bSApple OSS Distributions 
2444*d4514f0bSApple OSS Distributions #define KERN_GOLDEN_FILE TMP_DIR "kern_golden_image.log"
2445*d4514f0bSApple OSS Distributions 
2446*d4514f0bSApple OSS Distributions results_t *golden_list[MAX_NUM_TESTS];
2447*d4514f0bSApple OSS Distributions results_t *kern_list[MAX_NUM_TESTS];
2448*d4514f0bSApple OSS Distributions 
2449*d4514f0bSApple OSS Distributions #define FILL_TRIALS_NAMES_AND_CONTINUE(results, trials, t_count) { \
2450*d4514f0bSApple OSS Distributions 	for (unsigned i = 0; i < t_count; i++) { \
2451*d4514f0bSApple OSS Distributions 	/* trials names are free'd in dealloc_results() */ \
2452*d4514f0bSApple OSS Distributions 	        (results)->list[i].name = kstrdup((trials)->list[i].name); \
2453*d4514f0bSApple OSS Distributions 	} \
2454*d4514f0bSApple OSS Distributions }
2455*d4514f0bSApple OSS Distributions 
2456*d4514f0bSApple OSS Distributions #define FILL_TRIALS_NAMES(results, trials) { \
2457*d4514f0bSApple OSS Distributions 	unsigned t_count = ((trials)->count < (results)->count) ? (trials)->count : (results)->count; \
2458*d4514f0bSApple OSS Distributions 	if ((trials)->count != (results)->count) { \
2459*d4514f0bSApple OSS Distributions 	        T_LOG("%s:%d Trials count mismatch, expected %u, golden file %u\n", \
2460*d4514f0bSApple OSS Distributions 	                __func__, __LINE__, (trials)->count, (results)->count); \
2461*d4514f0bSApple OSS Distributions 	}\
2462*d4514f0bSApple OSS Distributions 	FILL_TRIALS_NAMES_AND_CONTINUE((results), (trials), (t_count)) \
2463*d4514f0bSApple OSS Distributions 	break; \
2464*d4514f0bSApple OSS Distributions }
2465*d4514f0bSApple OSS Distributions 
2466*d4514f0bSApple OSS Distributions static void
fill_golden_trials(uint64_t trialsargs[static TRIALSARGUMENTS_SIZE],results_t * results)2467*d4514f0bSApple OSS Distributions fill_golden_trials(uint64_t trialsargs[static TRIALSARGUMENTS_SIZE],
2468*d4514f0bSApple OSS Distributions     results_t *results)
2469*d4514f0bSApple OSS Distributions {
2470*d4514f0bSApple OSS Distributions 	trialsformula_t formula = results->trialsformula;
2471*d4514f0bSApple OSS Distributions 	uint64_t trialsargs0 = trialsargs[0];
2472*d4514f0bSApple OSS Distributions 	uint64_t trialsargs1 = trialsargs[1];
2473*d4514f0bSApple OSS Distributions 	switch (formula) {
2474*d4514f0bSApple OSS Distributions 	case eUNKNOWN_TRIALS:
2475*d4514f0bSApple OSS Distributions 		// Leave them empty
2476*d4514f0bSApple OSS Distributions 		T_FAIL("Golden file with unknown trials, testname: %s\n", results->testname);
2477*d4514f0bSApple OSS Distributions 		break;
2478*d4514f0bSApple OSS Distributions 	case eSMART_VM_MAP_KERNEL_FLAGS_TRIALS: {
2479*d4514f0bSApple OSS Distributions 		vm_map_kernel_flags_trials_t * trials SMART_VM_MAP_KERNEL_FLAGS_TRIALS();
2480*d4514f0bSApple OSS Distributions 		FILL_TRIALS_NAMES(results, trials);
2481*d4514f0bSApple OSS Distributions 	}
2482*d4514f0bSApple OSS Distributions 	case eSMART_VM_INHERIT_TRIALS: {
2483*d4514f0bSApple OSS Distributions 		vm_inherit_trials_t *trials SMART_VM_INHERIT_TRIALS();
2484*d4514f0bSApple OSS Distributions 		FILL_TRIALS_NAMES(results, trials);
2485*d4514f0bSApple OSS Distributions 	}
2486*d4514f0bSApple OSS Distributions 	case eSMART_MMAP_KERNEL_FLAGS_TRIALS: {
2487*d4514f0bSApple OSS Distributions 		vm_map_kernel_flags_trials_t * trials SMART_MMAP_KERNEL_FLAGS_TRIALS();
2488*d4514f0bSApple OSS Distributions 		FILL_TRIALS_NAMES(results, trials);
2489*d4514f0bSApple OSS Distributions 	}
2490*d4514f0bSApple OSS Distributions 	case eSMART_MMAP_FLAGS_TRIALS: {
2491*d4514f0bSApple OSS Distributions 		mmap_flags_trials_t *trials SMART_MMAP_FLAGS_TRIALS();
2492*d4514f0bSApple OSS Distributions 		FILL_TRIALS_NAMES(results, trials);
2493*d4514f0bSApple OSS Distributions 	}
2494*d4514f0bSApple OSS Distributions 	case eSMART_GENERIC_FLAG_TRIALS: {
2495*d4514f0bSApple OSS Distributions 		generic_flag_trials_t *trials SMART_GENERIC_FLAG_TRIALS();
2496*d4514f0bSApple OSS Distributions 		FILL_TRIALS_NAMES(results, trials);
2497*d4514f0bSApple OSS Distributions 	}
2498*d4514f0bSApple OSS Distributions 	case eSMART_VM_TAG_TRIALS: {
2499*d4514f0bSApple OSS Distributions 		// special case, trails (vm_tag_trials_values) depend on data only available on KERNEL
2500*d4514f0bSApple OSS Distributions 		vm_tag_trials_t *trials SMART_VM_TAG_TRIALS();
2501*d4514f0bSApple OSS Distributions 		FILL_TRIALS_NAMES(results, trials);
2502*d4514f0bSApple OSS Distributions 	}
2503*d4514f0bSApple OSS Distributions 	case eSMART_VM_PROT_TRIALS: {
2504*d4514f0bSApple OSS Distributions 		vm_prot_trials_t *trials SMART_VM_PROT_TRIALS();
2505*d4514f0bSApple OSS Distributions 		FILL_TRIALS_NAMES(results, trials);
2506*d4514f0bSApple OSS Distributions 	}
2507*d4514f0bSApple OSS Distributions 	case eSMART_VM_PROT_PAIR_TRIALS: {
2508*d4514f0bSApple OSS Distributions 		vm_prot_pair_trials_t *trials SMART_VM_PROT_PAIR_TRIALS();
2509*d4514f0bSApple OSS Distributions 		FILL_TRIALS_NAMES(results, trials);
2510*d4514f0bSApple OSS Distributions 	}
2511*d4514f0bSApple OSS Distributions 	case eSMART_LEDGER_TAG_TRIALS: {
2512*d4514f0bSApple OSS Distributions 		ledger_tag_trials_t *trials SMART_LEDGER_TAG_TRIALS();
2513*d4514f0bSApple OSS Distributions 		FILL_TRIALS_NAMES(results, trials);
2514*d4514f0bSApple OSS Distributions 	}
2515*d4514f0bSApple OSS Distributions 	case eSMART_LEDGER_FLAG_TRIALS: {
2516*d4514f0bSApple OSS Distributions 		ledger_flag_trials_t *trials SMART_LEDGER_FLAG_TRIALS();
2517*d4514f0bSApple OSS Distributions 		FILL_TRIALS_NAMES(results, trials);
2518*d4514f0bSApple OSS Distributions 	}
2519*d4514f0bSApple OSS Distributions 	case eSMART_ADDR_TRIALS: {
2520*d4514f0bSApple OSS Distributions 		addr_trials_t *trials SMART_ADDR_TRIALS(trialsargs0);
2521*d4514f0bSApple OSS Distributions 		if (trialsargs1) {
2522*d4514f0bSApple OSS Distributions 			// Special case with an additional trial such that obj_size + addr == 0
2523*d4514f0bSApple OSS Distributions 			FILL_TRIALS_NAMES_AND_CONTINUE(results, trials, trials->count);
2524*d4514f0bSApple OSS Distributions 			assert(trials->count + 1 == results->count);
2525*d4514f0bSApple OSS Distributions 			char *trial_desc;
2526*d4514f0bSApple OSS Distributions 			kasprintf(&trial_desc, "addr: -0x%llx", trialsargs1);
2527*d4514f0bSApple OSS Distributions 			results->list[results->count - 1].name = kstrdup(trial_desc);
2528*d4514f0bSApple OSS Distributions 			kfree_str(trial_desc);
2529*d4514f0bSApple OSS Distributions 			break;
2530*d4514f0bSApple OSS Distributions 		} else {
2531*d4514f0bSApple OSS Distributions 			FILL_TRIALS_NAMES(results, trials);
2532*d4514f0bSApple OSS Distributions 		}
2533*d4514f0bSApple OSS Distributions 	}
2534*d4514f0bSApple OSS Distributions 	case eSMART_SIZE_TRIALS: {
2535*d4514f0bSApple OSS Distributions 		size_trials_t *trials SMART_SIZE_TRIALS();
2536*d4514f0bSApple OSS Distributions 		FILL_TRIALS_NAMES(results, trials);
2537*d4514f0bSApple OSS Distributions 	}
2538*d4514f0bSApple OSS Distributions 	case eSMART_START_SIZE_TRIALS: {
2539*d4514f0bSApple OSS Distributions 		// NB: base.addr is not constant between runs but doesn't affect trial name
2540*d4514f0bSApple OSS Distributions 		start_size_trials_t *trials SMART_START_SIZE_TRIALS(trialsargs0);
2541*d4514f0bSApple OSS Distributions 		FILL_TRIALS_NAMES(results, trials);
2542*d4514f0bSApple OSS Distributions 	}
2543*d4514f0bSApple OSS Distributions 	case eSMART_START_SIZE_OFFSET_OBJECT_TRIALS: {
2544*d4514f0bSApple OSS Distributions 		start_size_offset_object_trials_t *trials SMART_START_SIZE_OFFSET_OBJECT_TRIALS();
2545*d4514f0bSApple OSS Distributions 		FILL_TRIALS_NAMES(results, trials);
2546*d4514f0bSApple OSS Distributions 	}
2547*d4514f0bSApple OSS Distributions 	case eSMART_START_SIZE_OFFSET_TRIALS: {
2548*d4514f0bSApple OSS Distributions 		start_size_offset_trials_t *trials SMART_START_SIZE_OFFSET_TRIALS();
2549*d4514f0bSApple OSS Distributions 		FILL_TRIALS_NAMES(results, trials);
2550*d4514f0bSApple OSS Distributions 	}
2551*d4514f0bSApple OSS Distributions 	case eSMART_SIZE_SIZE_TRIALS: {
2552*d4514f0bSApple OSS Distributions 		T_FAIL("SIZE_SIZE_TRIALS not used\n");
2553*d4514f0bSApple OSS Distributions 		break;
2554*d4514f0bSApple OSS Distributions 	}
2555*d4514f0bSApple OSS Distributions 	case eSMART_SRC_DST_SIZE_TRIALS: {
2556*d4514f0bSApple OSS Distributions 		src_dst_size_trials_t * trials SMART_SRC_DST_SIZE_TRIALS();
2557*d4514f0bSApple OSS Distributions 		FILL_TRIALS_NAMES(results, trials);
2558*d4514f0bSApple OSS Distributions 	}
2559*d4514f0bSApple OSS Distributions 	case eSMART_FILEOFF_DST_SIZE_TRIALS: {
2560*d4514f0bSApple OSS Distributions 		src_dst_size_trials_t * trials SMART_FILEOFF_DST_SIZE_TRIALS();
2561*d4514f0bSApple OSS Distributions 		FILL_TRIALS_NAMES(results, trials);
2562*d4514f0bSApple OSS Distributions 	}
2563*d4514f0bSApple OSS Distributions 	case eSMART_VM_BEHAVIOR_TRIALS: {
2564*d4514f0bSApple OSS Distributions 		vm_behavior_trials_t *trials SMART_VM_BEHAVIOR_TRIALS();
2565*d4514f0bSApple OSS Distributions 		FILL_TRIALS_NAMES(results, trials);
2566*d4514f0bSApple OSS Distributions 	}
2567*d4514f0bSApple OSS Distributions 	case eSMART_VM_ADVISE_TRIALS: {
2568*d4514f0bSApple OSS Distributions 		vm_advise_trials_t *trials SMART_VM_ADVISE_TRIALS();
2569*d4514f0bSApple OSS Distributions 		FILL_TRIALS_NAMES(results, trials);
2570*d4514f0bSApple OSS Distributions 	}
2571*d4514f0bSApple OSS Distributions 	case eSMART_VM_SYNC_TRIALS: {
2572*d4514f0bSApple OSS Distributions 		vm_sync_trials_t *trials SMART_VM_SYNC_TRIALS();
2573*d4514f0bSApple OSS Distributions 		FILL_TRIALS_NAMES(results, trials);
2574*d4514f0bSApple OSS Distributions 	}
2575*d4514f0bSApple OSS Distributions 	case eSMART_VM_MSYNC_TRIALS: {
2576*d4514f0bSApple OSS Distributions 		vm_msync_trials_t *trials SMART_VM_MSYNC_TRIALS();
2577*d4514f0bSApple OSS Distributions 		FILL_TRIALS_NAMES(results, trials);
2578*d4514f0bSApple OSS Distributions 	}
2579*d4514f0bSApple OSS Distributions 	case eSMART_VM_MACHINE_ATTRIBUTE_TRIALS: {
2580*d4514f0bSApple OSS Distributions 		vm_machine_attribute_trials_t *trials SMART_VM_MACHINE_ATTRIBUTE_TRIALS();
2581*d4514f0bSApple OSS Distributions 		FILL_TRIALS_NAMES(results, trials);
2582*d4514f0bSApple OSS Distributions 	}
2583*d4514f0bSApple OSS Distributions 	case eSMART_VM_PURGEABLE_AND_STATE_TRIALS: {
2584*d4514f0bSApple OSS Distributions 		vm_purgeable_and_state_trials_t *trials SMART_VM_PURGEABLE_AND_STATE_TRIALS();
2585*d4514f0bSApple OSS Distributions 		FILL_TRIALS_NAMES(results, trials);
2586*d4514f0bSApple OSS Distributions 	}
2587*d4514f0bSApple OSS Distributions 	case eSMART_START_SIZE_START_SIZE_TRIALS: {
2588*d4514f0bSApple OSS Distributions 		start_size_start_size_trials_t *trials SMART_START_SIZE_START_SIZE_TRIALS();
2589*d4514f0bSApple OSS Distributions 		FILL_TRIALS_NAMES(results, trials);
2590*d4514f0bSApple OSS Distributions 	}
2591*d4514f0bSApple OSS Distributions 	case eSMART_SHARED_REGION_MAP_AND_SLIDE_2_TRIALS: {
2592*d4514f0bSApple OSS Distributions 		shared_region_map_and_slide_2_trials_t *trials SMART_SHARED_REGION_MAP_AND_SLIDE_2_TRIALS(trialsargs0);
2593*d4514f0bSApple OSS Distributions 		FILL_TRIALS_NAMES(results, trials);
2594*d4514f0bSApple OSS Distributions 	}
2595*d4514f0bSApple OSS Distributions 	case eSMART_RECLAMATION_BUFFER_INIT_TRIALS: {
2596*d4514f0bSApple OSS Distributions 		reclamation_buffer_init_trials_t *trials SMART_RECLAMATION_BUFFER_INIT_TRIALS();
2597*d4514f0bSApple OSS Distributions 		FILL_TRIALS_NAMES(results, trials);
2598*d4514f0bSApple OSS Distributions 	}
2599*d4514f0bSApple OSS Distributions 	default:
2600*d4514f0bSApple OSS Distributions 		T_FAIL("New formula %u, args %llu %llu, update fill_golden_trials, testname: %s\n",
2601*d4514f0bSApple OSS Distributions 		    formula, trialsargs[0], trialsargs[1], results->testname);
2602*d4514f0bSApple OSS Distributions 	}
2603*d4514f0bSApple OSS Distributions }
2604*d4514f0bSApple OSS Distributions 
2605*d4514f0bSApple OSS Distributions // Number of test trials with ret == OUT_PARAM_BAD
2606*d4514f0bSApple OSS Distributions int out_param_bad_count = 0;
2607*d4514f0bSApple OSS Distributions 
2608*d4514f0bSApple OSS Distributions static results_t *
test_name_to_golden_results(const char * testname)2609*d4514f0bSApple OSS Distributions test_name_to_golden_results(const char* testname)
2610*d4514f0bSApple OSS Distributions {
2611*d4514f0bSApple OSS Distributions 	results_t *golden_results = NULL;
2612*d4514f0bSApple OSS Distributions 	results_t *golden_results_found = NULL;
2613*d4514f0bSApple OSS Distributions 
2614*d4514f0bSApple OSS Distributions 	for (uint32_t x = 0; x < num_tests; x++) {
2615*d4514f0bSApple OSS Distributions 		golden_results = golden_list[x];
2616*d4514f0bSApple OSS Distributions 		if (strncmp(golden_results->testname, testname, strlen(testname)) == 0) {
2617*d4514f0bSApple OSS Distributions 			golden_results->tested_count += 1;
2618*d4514f0bSApple OSS Distributions 			golden_results_found = golden_results;
2619*d4514f0bSApple OSS Distributions 			break;
2620*d4514f0bSApple OSS Distributions 		}
2621*d4514f0bSApple OSS Distributions 	}
2622*d4514f0bSApple OSS Distributions 
2623*d4514f0bSApple OSS Distributions 	return golden_results_found;
2624*d4514f0bSApple OSS Distributions }
2625*d4514f0bSApple OSS Distributions 
2626*d4514f0bSApple OSS Distributions static void
dump_results_list(results_t * res_list[],uint32_t res_num_tests)2627*d4514f0bSApple OSS Distributions dump_results_list(results_t *res_list[], uint32_t res_num_tests)
2628*d4514f0bSApple OSS Distributions {
2629*d4514f0bSApple OSS Distributions 	for (uint32_t x = 0; x < res_num_tests; x++) {
2630*d4514f0bSApple OSS Distributions 		results_t *results = res_list[x];
2631*d4514f0bSApple OSS Distributions 		testprintf("\t[%u] %s (%u)\n", x, results->testname, results->count);
2632*d4514f0bSApple OSS Distributions 	}
2633*d4514f0bSApple OSS Distributions }
2634*d4514f0bSApple OSS Distributions 
2635*d4514f0bSApple OSS Distributions static void
dump_golden_list()2636*d4514f0bSApple OSS Distributions dump_golden_list()
2637*d4514f0bSApple OSS Distributions {
2638*d4514f0bSApple OSS Distributions 	testprintf("======\n");
2639*d4514f0bSApple OSS Distributions 	testprintf("golden_list %p, num_tests %u\n", golden_list, num_tests);
2640*d4514f0bSApple OSS Distributions 	dump_results_list(golden_list, num_tests);
2641*d4514f0bSApple OSS Distributions 	testprintf("======\n");
2642*d4514f0bSApple OSS Distributions }
2643*d4514f0bSApple OSS Distributions 
2644*d4514f0bSApple OSS Distributions static void
dump_kernel_results_list()2645*d4514f0bSApple OSS Distributions dump_kernel_results_list()
2646*d4514f0bSApple OSS Distributions {
2647*d4514f0bSApple OSS Distributions 	testprintf("======\n");
2648*d4514f0bSApple OSS Distributions 	testprintf("kernel_results_list %p, num_tests %u\n", kern_list, num_kern_tests);
2649*d4514f0bSApple OSS Distributions 	dump_results_list(kern_list, num_kern_tests);
2650*d4514f0bSApple OSS Distributions 	testprintf("======\n");
2651*d4514f0bSApple OSS Distributions }
2652*d4514f0bSApple OSS Distributions 
2653*d4514f0bSApple OSS Distributions // Read results written by dump_golden_results().
2654*d4514f0bSApple OSS Distributions static int
populate_golden_results(const char * filename)2655*d4514f0bSApple OSS Distributions populate_golden_results(const char *filename)
2656*d4514f0bSApple OSS Distributions {
2657*d4514f0bSApple OSS Distributions 	FILE *file;
2658*d4514f0bSApple OSS Distributions 	char line[MAX_LINE_LENGTH];
2659*d4514f0bSApple OSS Distributions 	char trial_formula[20];
2660*d4514f0bSApple OSS Distributions 	results_t *results = NULL;
2661*d4514f0bSApple OSS Distributions 	trialsformula_t formula = eUNKNOWN_TRIALS;
2662*d4514f0bSApple OSS Distributions 	uint64_t trial_args[TRIALSARGUMENTS_SIZE] = {0, 0};
2663*d4514f0bSApple OSS Distributions 	uint32_t num_results = 0;
2664*d4514f0bSApple OSS Distributions 	uint32_t result_number = 0;
2665*d4514f0bSApple OSS Distributions 	int result_ret = 0;
2666*d4514f0bSApple OSS Distributions 	char *test_name = NULL;
2667*d4514f0bSApple OSS Distributions 	char *sub_line = NULL;
2668*d4514f0bSApple OSS Distributions 	char *s_num_results = NULL;
2669*d4514f0bSApple OSS Distributions 	bool in_test = FALSE;
2670*d4514f0bSApple OSS Distributions 	out_param_bad_count = 0;
2671*d4514f0bSApple OSS Distributions 	kern_trialname_generation = strnstr(filename, "kern_golden_image", strlen(filename)) != NULL;
2672*d4514f0bSApple OSS Distributions 
2673*d4514f0bSApple OSS Distributions 	// cd to the directory containing this executable
2674*d4514f0bSApple OSS Distributions 	// Test files are located relative to there.
2675*d4514f0bSApple OSS Distributions 	uint32_t exesize = 0;
2676*d4514f0bSApple OSS Distributions 	_NSGetExecutablePath(NULL, &exesize);
2677*d4514f0bSApple OSS Distributions 	char *exe = malloc(exesize);
2678*d4514f0bSApple OSS Distributions 	assert(exe != NULL);
2679*d4514f0bSApple OSS Distributions 	_NSGetExecutablePath(exe, &exesize);
2680*d4514f0bSApple OSS Distributions 	char *dir = dirname(exe);
2681*d4514f0bSApple OSS Distributions 	chdir(dir);
2682*d4514f0bSApple OSS Distributions 	free(exe);
2683*d4514f0bSApple OSS Distributions 
2684*d4514f0bSApple OSS Distributions 	file = fopen(filename, "r");
2685*d4514f0bSApple OSS Distributions 	if (file == NULL) {
2686*d4514f0bSApple OSS Distributions 		T_FAIL("Could not open file %s\n", filename);
2687*d4514f0bSApple OSS Distributions 		return 1;
2688*d4514f0bSApple OSS Distributions 	}
2689*d4514f0bSApple OSS Distributions 
2690*d4514f0bSApple OSS Distributions 	// Read file line by line
2691*d4514f0bSApple OSS Distributions 	while (fgets(line, MAX_LINE_LENGTH, file) != NULL) {
2692*d4514f0bSApple OSS Distributions 		// Check if the line starts with "TESTNAME" or "RESULT COUNT"
2693*d4514f0bSApple OSS Distributions 		if (strncmp(line, TESTNAME_DELIMITER, strlen(TESTNAME_DELIMITER)) == 0) {
2694*d4514f0bSApple OSS Distributions 			// remove the newline char
2695*d4514f0bSApple OSS Distributions 			line[strcspn(line, "\n")] = 0;
2696*d4514f0bSApple OSS Distributions 			sub_line = line + strlen(TESTNAME_DELIMITER);
2697*d4514f0bSApple OSS Distributions 			test_name = strdup(sub_line);
2698*d4514f0bSApple OSS Distributions 			formula = eUNKNOWN_TRIALS;
2699*d4514f0bSApple OSS Distributions 			trial_args[0] = TRIALSARGUMENTS_NONE;
2700*d4514f0bSApple OSS Distributions 			trial_args[1] = TRIALSARGUMENTS_NONE;
2701*d4514f0bSApple OSS Distributions 			// T_LOG("TESTNAME %u : %s", num_tests, test_name);
2702*d4514f0bSApple OSS Distributions 			in_test = TRUE;
2703*d4514f0bSApple OSS Distributions 		} else if (in_test && strncmp(line, TRIALSFORMULA_DELIMITER, strlen(TRIALSFORMULA_DELIMITER)) == 0) {
2704*d4514f0bSApple OSS Distributions 			sscanf(line, "%*s %s %*s %llu,%llu,%llu", trial_formula, &trial_args[0], &trial_args[1], &trial_page_size);
2705*d4514f0bSApple OSS Distributions 			formula = trialsformula_from_string(trial_formula);
2706*d4514f0bSApple OSS Distributions 		} else if (in_test && strncmp(line, RESULTCOUNT_DELIMITER, strlen(RESULTCOUNT_DELIMITER)) == 0) {
2707*d4514f0bSApple OSS Distributions 			assert(num_tests < MAX_NUM_TESTS);
2708*d4514f0bSApple OSS Distributions 			s_num_results = line + strlen(RESULTCOUNT_DELIMITER);
2709*d4514f0bSApple OSS Distributions 			num_results = (uint32_t)strtoul(s_num_results, NULL, 10);
2710*d4514f0bSApple OSS Distributions 			results = alloc_results(test_name, formula, trial_args, TRIALSARGUMENTS_SIZE, num_results);
2711*d4514f0bSApple OSS Distributions 			assert(results);
2712*d4514f0bSApple OSS Distributions 			results->count = num_results;
2713*d4514f0bSApple OSS Distributions 			fill_golden_trials(trial_args, results);
2714*d4514f0bSApple OSS Distributions 			golden_list[num_tests++] = results;
2715*d4514f0bSApple OSS Distributions 			// T_LOG("num_tests %u, testname %s, count: %u", num_tests, results->testname, results->count);
2716*d4514f0bSApple OSS Distributions 		} else if (in_test && strncmp(line, TESTRESULT_DELIMITER, strlen(TESTRESULT_DELIMITER)) == 0) {
2717*d4514f0bSApple OSS Distributions 			sscanf(line, "%d: %d", &result_number, &result_ret);
2718*d4514f0bSApple OSS Distributions 			assert(result_number < num_results);
2719*d4514f0bSApple OSS Distributions 			// T_LOG("\tresult #%u: %d\n", result_number, result_ret);
2720*d4514f0bSApple OSS Distributions 			results->list[result_number].ret = result_ret;
2721*d4514f0bSApple OSS Distributions 			if (result_ret == OUT_PARAM_BAD) {
2722*d4514f0bSApple OSS Distributions 				out_param_bad_count += 1;
2723*d4514f0bSApple OSS Distributions 				T_FAIL("Out parameter violation in test %s - %s\n", results->testname, results->list[result_number].name);
2724*d4514f0bSApple OSS Distributions 			}
2725*d4514f0bSApple OSS Distributions 		} else {
2726*d4514f0bSApple OSS Distributions 			// T_LOG("Unknown line: %s\n", line);
2727*d4514f0bSApple OSS Distributions 			in_test = FALSE;
2728*d4514f0bSApple OSS Distributions 		}
2729*d4514f0bSApple OSS Distributions 	}
2730*d4514f0bSApple OSS Distributions 
2731*d4514f0bSApple OSS Distributions 	fclose(file);
2732*d4514f0bSApple OSS Distributions 
2733*d4514f0bSApple OSS Distributions 	if (!out_param_bad_count) {
2734*d4514f0bSApple OSS Distributions 		dump_golden_list();
2735*d4514f0bSApple OSS Distributions 	}
2736*d4514f0bSApple OSS Distributions 	kern_trialname_generation = FALSE;
2737*d4514f0bSApple OSS Distributions 
2738*d4514f0bSApple OSS Distributions 	return out_param_bad_count;
2739*d4514f0bSApple OSS Distributions }
2740*d4514f0bSApple OSS Distributions 
2741*d4514f0bSApple OSS Distributions static void
clean_golden_results()2742*d4514f0bSApple OSS Distributions clean_golden_results()
2743*d4514f0bSApple OSS Distributions {
2744*d4514f0bSApple OSS Distributions 	for (uint32_t x = 0; x < num_tests; ++x) {
2745*d4514f0bSApple OSS Distributions 		if (golden_list[x]->tested_count == 0) {
2746*d4514f0bSApple OSS Distributions 			T_LOG("WARN: Test %s found in golden file but no test with that name was run\n",
2747*d4514f0bSApple OSS Distributions 			    golden_list[x]->testname);
2748*d4514f0bSApple OSS Distributions 		}
2749*d4514f0bSApple OSS Distributions 		if (golden_list[x]->tested_count > 1) {
2750*d4514f0bSApple OSS Distributions 			T_LOG("WARN: Test %s found in golden file with %d runs\n",
2751*d4514f0bSApple OSS Distributions 			    golden_list[x]->testname, golden_list[x]->tested_count);
2752*d4514f0bSApple OSS Distributions 		}
2753*d4514f0bSApple OSS Distributions 		dealloc_results(golden_list[x]);
2754*d4514f0bSApple OSS Distributions 		golden_list[x] = NULL;
2755*d4514f0bSApple OSS Distributions 	}
2756*d4514f0bSApple OSS Distributions }
2757*d4514f0bSApple OSS Distributions 
2758*d4514f0bSApple OSS Distributions static void
clean_kernel_results()2759*d4514f0bSApple OSS Distributions clean_kernel_results()
2760*d4514f0bSApple OSS Distributions {
2761*d4514f0bSApple OSS Distributions 	for (uint32_t x = 0; x < num_kern_tests; ++x) {
2762*d4514f0bSApple OSS Distributions 		dealloc_results(kern_list[x]);
2763*d4514f0bSApple OSS Distributions 		kern_list[x] = NULL;
2764*d4514f0bSApple OSS Distributions 	}
2765*d4514f0bSApple OSS Distributions }
2766*d4514f0bSApple OSS Distributions 
2767*d4514f0bSApple OSS Distributions // buffer to output userspace golden file results (using same size as the kern buffer)
2768*d4514f0bSApple OSS Distributions static const int64_t GOLDEN_OUTPUT_BUFFER_SIZE = SYSCTL_OUTPUT_BUFFER_SIZE;
2769*d4514f0bSApple OSS Distributions static char* GOLDEN_OUTPUT_START;
2770*d4514f0bSApple OSS Distributions static char* GOLDEN_OUTPUT_BUF;
2771*d4514f0bSApple OSS Distributions static char* GOLDEN_OUTPUT_END;
2772*d4514f0bSApple OSS Distributions 
2773*d4514f0bSApple OSS Distributions void
goldenprintf(const char * format,...)2774*d4514f0bSApple OSS Distributions goldenprintf(const char *format, ...)
2775*d4514f0bSApple OSS Distributions {
2776*d4514f0bSApple OSS Distributions 	if (!GOLDEN_OUTPUT_START) {
2777*d4514f0bSApple OSS Distributions 		GOLDEN_OUTPUT_START = calloc(GOLDEN_OUTPUT_BUFFER_SIZE, 1);
2778*d4514f0bSApple OSS Distributions 		GOLDEN_OUTPUT_BUF = GOLDEN_OUTPUT_START;
2779*d4514f0bSApple OSS Distributions 		GOLDEN_OUTPUT_END = GOLDEN_OUTPUT_BUF + GOLDEN_OUTPUT_BUFFER_SIZE;
2780*d4514f0bSApple OSS Distributions 	}
2781*d4514f0bSApple OSS Distributions 
2782*d4514f0bSApple OSS Distributions 	int printed;
2783*d4514f0bSApple OSS Distributions 	ssize_t s_buffer_size = GOLDEN_OUTPUT_END - GOLDEN_OUTPUT_BUF;
2784*d4514f0bSApple OSS Distributions 	assert(s_buffer_size > 0 && s_buffer_size <= GOLDEN_OUTPUT_BUFFER_SIZE);
2785*d4514f0bSApple OSS Distributions 	size_t buffer_size = (size_t)s_buffer_size;
2786*d4514f0bSApple OSS Distributions 	va_list args;
2787*d4514f0bSApple OSS Distributions 	va_start(args, format);
2788*d4514f0bSApple OSS Distributions 	printed = vsnprintf(GOLDEN_OUTPUT_BUF, buffer_size, format, args);
2789*d4514f0bSApple OSS Distributions 	va_end(args);
2790*d4514f0bSApple OSS Distributions 	assert(printed >= 0);
2791*d4514f0bSApple OSS Distributions 	assert((unsigned)printed < buffer_size - 1);
2792*d4514f0bSApple OSS Distributions 	assert(GOLDEN_OUTPUT_BUF + printed + 1 < GOLDEN_OUTPUT_END);
2793*d4514f0bSApple OSS Distributions 	GOLDEN_OUTPUT_BUF += printed;
2794*d4514f0bSApple OSS Distributions }
2795*d4514f0bSApple OSS Distributions 
2796*d4514f0bSApple OSS Distributions // Verbose output in dump_results, controlled by DUMP_RESULTS env.
2797*d4514f0bSApple OSS Distributions bool dump = FALSE;
2798*d4514f0bSApple OSS Distributions // Output to create a golden test result, controlled by GENERATE_GOLDEN_IMAGE.
2799*d4514f0bSApple OSS Distributions bool generate_golden = FALSE;
2800*d4514f0bSApple OSS Distributions // Read existing golden file and print its contents in verbose format (like dump_results). Controlled by DUMP_GOLDEN_IMAGE.
2801*d4514f0bSApple OSS Distributions bool dump_golden = FALSE;
2802*d4514f0bSApple OSS Distributions // Run tests as tests (i.e. emit TS_{PASS/FAIL}), enabled unless golden image generation is true.
2803*d4514f0bSApple OSS Distributions bool should_test_results =  TRUE;
2804*d4514f0bSApple OSS Distributions 
2805*d4514f0bSApple OSS Distributions T_DECL(vm_parameter_validation_user,
2806*d4514f0bSApple OSS Distributions     "parameter validation for userspace calls",
2807*d4514f0bSApple OSS Distributions     T_META_SPAWN_TOOL(DECOMPRESS),
2808*d4514f0bSApple OSS Distributions     T_META_SPAWN_TOOL_ARG("user"),
2809*d4514f0bSApple OSS Distributions     T_META_SPAWN_TOOL_ARG(TMP_DIR),
2810*d4514f0bSApple OSS Distributions     T_META_SPAWN_TOOL_ARG(GOLDEN_FILES_VERSION)
2811*d4514f0bSApple OSS Distributions     )
2812*d4514f0bSApple OSS Distributions {
2813*d4514f0bSApple OSS Distributions 	if (disable_vm_sanitize_telemetry() != 0) {
2814*d4514f0bSApple OSS Distributions 		T_FAIL("Could not disable VM API telemetry. Bailing out early.");
2815*d4514f0bSApple OSS Distributions 		return;
2816*d4514f0bSApple OSS Distributions 	}
2817*d4514f0bSApple OSS Distributions 
2818*d4514f0bSApple OSS Distributions 	read_env();
2819*d4514f0bSApple OSS Distributions 
2820*d4514f0bSApple OSS Distributions 	T_LOG("dump %d, golden %d, dump_golden %d, test %d\n", dump, generate_golden, dump_golden, should_test_results);
2821*d4514f0bSApple OSS Distributions 
2822*d4514f0bSApple OSS Distributions 	if (generate_golden && unsigned_code_is_disallowed()) {
2823*d4514f0bSApple OSS Distributions 		// Some test results change when SIP is enabled.
2824*d4514f0bSApple OSS Distributions 		// Golden files must record the SIP-disabled values.
2825*d4514f0bSApple OSS Distributions 		T_FAIL("Can't generate golden files with SIP enabled. Disable SIP and try again.\n");
2826*d4514f0bSApple OSS Distributions 		return;
2827*d4514f0bSApple OSS Distributions 	}
2828*d4514f0bSApple OSS Distributions 
2829*d4514f0bSApple OSS Distributions 	if ((dump_golden || should_test_results) && populate_golden_results(GOLDEN_FILE)) {
2830*d4514f0bSApple OSS Distributions 		// bail out early, problem loading golden test results
2831*d4514f0bSApple OSS Distributions 		T_FAIL("Could not load golden file '%s'\n", GOLDEN_FILE);
2832*d4514f0bSApple OSS Distributions 		return;
2833*d4514f0bSApple OSS Distributions 	}
2834*d4514f0bSApple OSS Distributions 
2835*d4514f0bSApple OSS Distributions 	set_up_guard_page();
2836*d4514f0bSApple OSS Distributions 
2837*d4514f0bSApple OSS Distributions 	disable_exc_guard();
2838*d4514f0bSApple OSS Distributions 
2839*d4514f0bSApple OSS Distributions 	if (dump_golden) {
2840*d4514f0bSApple OSS Distributions 		// just print the parsed golden file
2841*d4514f0bSApple OSS Distributions 		for (uint32_t x = 0; x < num_tests; ++x) {
2842*d4514f0bSApple OSS Distributions 			__dump_results(golden_list[x]);
2843*d4514f0bSApple OSS Distributions 		}
2844*d4514f0bSApple OSS Distributions 		goto out;
2845*d4514f0bSApple OSS Distributions 	}
2846*d4514f0bSApple OSS Distributions 
2847*d4514f0bSApple OSS Distributions 	/*
2848*d4514f0bSApple OSS Distributions 	 * -- memory entry functions --
2849*d4514f0bSApple OSS Distributions 	 * The memory entry test functions use macros to generate each flavor of memory entry function.
2850*d4514f0bSApple OSS Distributions 	 * This is partially becauseof many entrypoints (mach_make_memory_entry/mach_make_memory_entry_64/mach_make_memory_entry)
2851*d4514f0bSApple OSS Distributions 	 * and partially because many flavors of each function are called (copy/memonly/share/...).
2852*d4514f0bSApple OSS Distributions 	 */
2853*d4514f0bSApple OSS Distributions 
2854*d4514f0bSApple OSS Distributions 	// Mach start/size with both old-style and new-style types
2855*d4514f0bSApple OSS Distributions 	// (co-located so old and new can be compared more easily)
2856*d4514f0bSApple OSS Distributions #define RUN_NEW(fn, name) dealloc_results(process_results(test_mach_with_allocated_start_size(fn, name " (start/size)")))
2857*d4514f0bSApple OSS Distributions #if TEST_OLD_STYLE_MACH
2858*d4514f0bSApple OSS Distributions #define RUN_OLD(fn, name) dealloc_results(process_results(test_oldmach_with_allocated_start_size(fn, name " (start/size)")))
2859*d4514f0bSApple OSS Distributions #define RUN_OLD64(fn, name) RUN_NEW(fn, name)
2860*d4514f0bSApple OSS Distributions #else
2861*d4514f0bSApple OSS Distributions #define RUN_OLD(fn, name) do {} while (0)
2862*d4514f0bSApple OSS Distributions #define RUN_OLD64(fn, name) do {} while (0)
2863*d4514f0bSApple OSS Distributions #endif
2864*d4514f0bSApple OSS Distributions 	// mach_make_memory_entry has up to three entry points on U32, unlike other functions that have two
2865*d4514f0bSApple OSS Distributions 	RUN_NEW(call_mach_make_memory_entry_64__start_size__copy, "mach_make_memory_entry_64 (copy)");
2866*d4514f0bSApple OSS Distributions 	RUN_OLD(call_mach_make_memory_entry__start_size__copy, "mach_make_memory_entry (copy)");
2867*d4514f0bSApple OSS Distributions 	RUN_OLD64(call__mach_make_memory_entry__start_size__copy, "_mach_make_memory_entry (copy)");
2868*d4514f0bSApple OSS Distributions 	RUN_NEW(call_mach_make_memory_entry_64__start_size__memonly, "mach_make_memory_entry_64 (mem_only)");
2869*d4514f0bSApple OSS Distributions 	RUN_OLD(call_mach_make_memory_entry__start_size__memonly, "mach_make_memory_entry (mem_only)");
2870*d4514f0bSApple OSS Distributions 	RUN_OLD64(call__mach_make_memory_entry__start_size__memonly, "_mach_make_memory_entry (mem_only)");
2871*d4514f0bSApple OSS Distributions 	RUN_NEW(call_mach_make_memory_entry_64__start_size__namedcreate, "mach_make_memory_entry_64 (named_create)");
2872*d4514f0bSApple OSS Distributions 	RUN_OLD(call_mach_make_memory_entry__start_size__namedcreate, "mach_make_memory_entry (named_create)");
2873*d4514f0bSApple OSS Distributions 	RUN_OLD64(call__mach_make_memory_entry__start_size__namedcreate, "_mach_make_memory_entry (named_create)");
2874*d4514f0bSApple OSS Distributions 	RUN_NEW(call_mach_make_memory_entry_64__start_size__share, "mach_make_memory_entry_64 (share)");
2875*d4514f0bSApple OSS Distributions 	RUN_OLD(call_mach_make_memory_entry__start_size__share, "mach_make_memory_entry (share)");
2876*d4514f0bSApple OSS Distributions 	RUN_OLD64(call__mach_make_memory_entry__start_size__share, "_mach_make_memory_entry (share)");
2877*d4514f0bSApple OSS Distributions 	RUN_NEW(call_mach_make_memory_entry_64__start_size__namedreuse, "mach_make_memory_entry_64 (named_reuse)");
2878*d4514f0bSApple OSS Distributions 	RUN_OLD(call_mach_make_memory_entry__start_size__namedreuse, "mach_make_memory_entry (named_reuse)");
2879*d4514f0bSApple OSS Distributions 	RUN_OLD64(call__mach_make_memory_entry__start_size__namedreuse, "_mach_make_memory_entry (named_reuse)");
2880*d4514f0bSApple OSS Distributions #undef RUN_NEW
2881*d4514f0bSApple OSS Distributions #undef RUN_OLD
2882*d4514f0bSApple OSS Distributions #undef RUN_OLD64
2883*d4514f0bSApple OSS Distributions 
2884*d4514f0bSApple OSS Distributions #define RUN(fn, name) dealloc_results(process_results(test_mach_with_size(fn, name " (size)")))
2885*d4514f0bSApple OSS Distributions 	RUN(call_mach_memory_object_memory_entry_64__size, "mach_memory_object_memory_entry_64");
2886*d4514f0bSApple OSS Distributions 	RUN(call_replacement_mach_memory_object_memory_entry__size, "mach_memory_object_memory_entry");
2887*d4514f0bSApple OSS Distributions #undef RUN
2888*d4514f0bSApple OSS Distributions 
2889*d4514f0bSApple OSS Distributions #define RUN_NEW(fn, name) dealloc_results(process_results(test_mach_with_allocated_vm_prot_t(fn, name " (vm_prot_t)")))
2890*d4514f0bSApple OSS Distributions #define RUN_OLD(fn, name) dealloc_results(process_results(test_oldmach_with_allocated_vm_prot_t(fn, name " (vm_prot_t)")))
2891*d4514f0bSApple OSS Distributions #define RUN_OLD64(fn, name) RUN_NEW(fn, name)
2892*d4514f0bSApple OSS Distributions 
2893*d4514f0bSApple OSS Distributions 	RUN_NEW(call_mach_make_memory_entry_64__vm_prot, "mach_make_memory_entry_64");
2894*d4514f0bSApple OSS Distributions #if TEST_OLD_STYLE_MACH
2895*d4514f0bSApple OSS Distributions 	RUN_OLD(call_mach_make_memory_entry__vm_prot, "mach_make_memory_entry");
2896*d4514f0bSApple OSS Distributions 	RUN_OLD64(call__mach_make_memory_entry__vm_prot, "_mach_make_memory_entry");
2897*d4514f0bSApple OSS Distributions #endif
2898*d4514f0bSApple OSS Distributions 
2899*d4514f0bSApple OSS Distributions #undef RUN_NEW
2900*d4514f0bSApple OSS Distributions #undef RUN_OLD
2901*d4514f0bSApple OSS Distributions #undef RUN_OLD64
2902*d4514f0bSApple OSS Distributions 
2903*d4514f0bSApple OSS Distributions #define RUN(fn, name) dealloc_results(process_results(test_mach_vm_prot(fn, name " (vm_prot_t)")))
2904*d4514f0bSApple OSS Distributions 	RUN(call_mach_memory_object_memory_entry_64__vm_prot, "mach_memory_object_memory_entry_64");
2905*d4514f0bSApple OSS Distributions 	RUN(call_replacement_mach_memory_object_memory_entry__vm_prot, "mach_memory_object_memory_entry");
2906*d4514f0bSApple OSS Distributions #undef RUN
2907*d4514f0bSApple OSS Distributions 
2908*d4514f0bSApple OSS Distributions #define RUN(fn, name) dealloc_results(process_results(test_mach_with_ledger_tag(fn, name " (ledger tag)")))
2909*d4514f0bSApple OSS Distributions 	RUN(call_mach_memory_entry_ownership__ledger_tag, "mach_memory_entry_ownership");
2910*d4514f0bSApple OSS Distributions #undef RUN
2911*d4514f0bSApple OSS Distributions 
2912*d4514f0bSApple OSS Distributions #define RUN(fn, name) dealloc_results(process_results(test_mach_with_ledger_flag(fn, name " (ledger flag)")))
2913*d4514f0bSApple OSS Distributions 	RUN(call_mach_memory_entry_ownership__ledger_flag, "mach_memory_entry_ownership");
2914*d4514f0bSApple OSS Distributions #undef RUN
2915*d4514f0bSApple OSS Distributions 
2916*d4514f0bSApple OSS Distributions 	/*
2917*d4514f0bSApple OSS Distributions 	 * -- allocate/deallocate functions --
2918*d4514f0bSApple OSS Distributions 	 */
2919*d4514f0bSApple OSS Distributions 
2920*d4514f0bSApple OSS Distributions #define RUN(fn, name) dealloc_results(process_results(test_mach_allocation_func_with_start_size(fn, name)))
2921*d4514f0bSApple OSS Distributions 	RUN(call_mach_vm_allocate__start_size_fixed, "mach_vm_allocate (fixed) (realigned start/size)");
2922*d4514f0bSApple OSS Distributions 	RUN(call_mach_vm_allocate__start_size_anywhere, "mach_vm_allocate (anywhere) (hint/size)");
2923*d4514f0bSApple OSS Distributions #undef RUN
2924*d4514f0bSApple OSS Distributions 
2925*d4514f0bSApple OSS Distributions #define RUN(fn, name) dealloc_results(process_results(test_mach_allocation_func_with_vm_map_kernel_flags_t(fn, name " (vm_map_kernel_flags_t)")))
2926*d4514f0bSApple OSS Distributions 	RUN(call_mach_vm_allocate__flags, "mach_vm_allocate");
2927*d4514f0bSApple OSS Distributions #undef RUN
2928*d4514f0bSApple OSS Distributions 
2929*d4514f0bSApple OSS Distributions 	dealloc_results(process_results(test_deallocator(call_mach_vm_deallocate, "mach_vm_deallocate (start/size)")));
2930*d4514f0bSApple OSS Distributions #if TEST_OLD_STYLE_MACH
2931*d4514f0bSApple OSS Distributions 	dealloc_results(process_results(test_deallocator(call_vm_deallocate, "vm_deallocate (start/size)")));
2932*d4514f0bSApple OSS Distributions #endif
2933*d4514f0bSApple OSS Distributions 
2934*d4514f0bSApple OSS Distributions #define RUN(fn, name) dealloc_results(process_results(test_deallocator(fn, name " (start/size)")))
2935*d4514f0bSApple OSS Distributions 	RUN(call_munmap, "munmap");
2936*d4514f0bSApple OSS Distributions #undef RUN
2937*d4514f0bSApple OSS Distributions 
2938*d4514f0bSApple OSS Distributions 	/*
2939*d4514f0bSApple OSS Distributions 	 * -- map/unmap functions --
2940*d4514f0bSApple OSS Distributions 	 * The map/unmap functions use multiple layers of macros.
2941*d4514f0bSApple OSS Distributions 	 * The macros are used both for function generation (see IMPL_ONE_FROM_HELPER) and to call all of those.
2942*d4514f0bSApple OSS Distributions 	 * This was written this way to further avoid lots of code duplication, as the map/remap functions
2943*d4514f0bSApple OSS Distributions 	 * have many different parameter combinations we want to test.
2944*d4514f0bSApple OSS Distributions 	 */
2945*d4514f0bSApple OSS Distributions 
2946*d4514f0bSApple OSS Distributions 	// map tests
2947*d4514f0bSApple OSS Distributions 
2948*d4514f0bSApple OSS Distributions #define RUN_START_SIZE(fn, name) dealloc_results(process_results(test_mach_with_allocated_start_size(fn, name " (realigned start/size)")))
2949*d4514f0bSApple OSS Distributions #define RUN_HINT_SIZE(fn, name) dealloc_results(process_results(test_mach_with_allocated_start_size(fn, name " (hint/size)")))
2950*d4514f0bSApple OSS Distributions #define RUN_PROT_PAIR(fn, name) dealloc_results(process_results(test_mach_vm_prot_pair(fn, name " (prot_pairs)")))
2951*d4514f0bSApple OSS Distributions #define RUN_INHERIT(fn, name) dealloc_results(process_results(test_mach_with_allocated_vm_inherit_t(fn, name " (vm_inherit_t)")))
2952*d4514f0bSApple OSS Distributions #define RUN_FLAGS(fn, name) dealloc_results(process_results(test_mach_allocation_func_with_vm_map_kernel_flags_t(fn, name " (vm_map_kernel_flags_t)")))
2953*d4514f0bSApple OSS Distributions #define RUN_SSOO(fn, name) dealloc_results(process_results(test_mach_with_allocated_start_size_offset_object(fn, name " (start/size/offset/object)")))
2954*d4514f0bSApple OSS Distributions 
2955*d4514f0bSApple OSS Distributions #define RUN_ALL(fn, name)     \
2956*d4514f0bSApple OSS Distributions 	RUN_START_SIZE(call_ ## fn ## __allocate_fixed, #name " (allocate fixed overwrite)");   \
2957*d4514f0bSApple OSS Distributions 	RUN_START_SIZE(call_ ## fn ## __allocate_fixed_copy, #name " (allocate fixed overwrite copy)");  \
2958*d4514f0bSApple OSS Distributions 	RUN_START_SIZE(call_ ## fn ## __memobject_fixed, #name " (memobject fixed overwrite)");  \
2959*d4514f0bSApple OSS Distributions 	RUN_START_SIZE(call_ ## fn ## __memobject_fixed_copy, #name " (memobject fixed overwrite copy)"); \
2960*d4514f0bSApple OSS Distributions 	RUN_HINT_SIZE(call_ ## fn ## __allocate_anywhere, #name " (allocate anywhere)");  \
2961*d4514f0bSApple OSS Distributions 	RUN_HINT_SIZE(call_ ## fn ## __memobject_anywhere, #name " (memobject anywhere)");  \
2962*d4514f0bSApple OSS Distributions 	RUN_PROT_PAIR(call_ ## fn ## __allocate_fixed__prot_pairs, #name " (allocate fixed overwrite)");  \
2963*d4514f0bSApple OSS Distributions 	RUN_PROT_PAIR(call_ ## fn ## __allocate_fixed_copy__prot_pairs, #name " (allocate fixed overwrite copy)");  \
2964*d4514f0bSApple OSS Distributions 	RUN_PROT_PAIR(call_ ## fn ## __allocate_anywhere__prot_pairs, #name " (allocate anywhere)");  \
2965*d4514f0bSApple OSS Distributions 	RUN_PROT_PAIR(call_ ## fn ## __memobject_fixed__prot_pairs, #name " (memobject fixed overwrite)");  \
2966*d4514f0bSApple OSS Distributions 	RUN_PROT_PAIR(call_ ## fn ## __memobject_fixed_copy__prot_pairs, #name " (memobject fixed overwrite copy)");  \
2967*d4514f0bSApple OSS Distributions 	RUN_PROT_PAIR(call_ ## fn ## __memobject_anywhere__prot_pairs, #name " (memobject anywhere)");  \
2968*d4514f0bSApple OSS Distributions 	RUN_INHERIT(call_ ## fn ## __allocate_fixed__inherit, #name " (allocate fixed overwrite)");  \
2969*d4514f0bSApple OSS Distributions 	RUN_INHERIT(call_ ## fn ## __allocate_fixed_copy__inherit, #name " (allocate fixed overwrite copy)");  \
2970*d4514f0bSApple OSS Distributions 	RUN_INHERIT(call_ ## fn ## __allocate_anywhere__inherit, #name " (allocate anywhere)");  \
2971*d4514f0bSApple OSS Distributions 	RUN_INHERIT(call_ ## fn ## __memobject_fixed__inherit, #name " (memobject fixed overwrite)");  \
2972*d4514f0bSApple OSS Distributions 	RUN_INHERIT(call_ ## fn ## __memobject_fixed_copy__inherit, #name " (memobject fixed overwrite copy)");  \
2973*d4514f0bSApple OSS Distributions 	RUN_INHERIT(call_ ## fn ## __memobject_anywhere__inherit, #name " (memobject anywhere)");  \
2974*d4514f0bSApple OSS Distributions 	RUN_FLAGS(call_ ## fn ## __allocate__flags, #name " (allocate)");  \
2975*d4514f0bSApple OSS Distributions 	RUN_FLAGS(call_ ## fn ## __allocate_copy__flags, #name " (allocate copy)");  \
2976*d4514f0bSApple OSS Distributions 	RUN_FLAGS(call_ ## fn ## __memobject__flags, #name " (memobject)");  \
2977*d4514f0bSApple OSS Distributions 	RUN_FLAGS(call_ ## fn ## __memobject_copy__flags, #name " (memobject copy)");  \
2978*d4514f0bSApple OSS Distributions 	RUN_SSOO(call_ ## fn ## __memobject_fixed__start_size_offset_object, #name " (memobject fixed overwrite)");  \
2979*d4514f0bSApple OSS Distributions 	RUN_SSOO(call_ ## fn ## __memobject_fixed_copy__start_size_offset_object, #name " (memobject fixed overwrite copy)");  \
2980*d4514f0bSApple OSS Distributions 	RUN_SSOO(call_ ## fn ## __memobject_anywhere__start_size_offset_object, #name " (memobject anywhere)");  \
2981*d4514f0bSApple OSS Distributions 
2982*d4514f0bSApple OSS Distributions 	RUN_ALL(mach_vm_map_wrapped, mach_vm_map);
2983*d4514f0bSApple OSS Distributions #if TEST_OLD_STYLE_MACH
2984*d4514f0bSApple OSS Distributions 	RUN_ALL(vm_map_64_retyped, vm_map_64);
2985*d4514f0bSApple OSS Distributions 	RUN_ALL(vm_map_retyped, vm_map);
2986*d4514f0bSApple OSS Distributions #endif
2987*d4514f0bSApple OSS Distributions 
2988*d4514f0bSApple OSS Distributions #undef RUN_ALL
2989*d4514f0bSApple OSS Distributions #undef RUN_START_SIZE
2990*d4514f0bSApple OSS Distributions #undef RUN_HINT_SIZE
2991*d4514f0bSApple OSS Distributions #undef RUN_PROT_PAIR
2992*d4514f0bSApple OSS Distributions #undef RUN_INHERIT
2993*d4514f0bSApple OSS Distributions #undef RUN_FLAGS
2994*d4514f0bSApple OSS Distributions #undef RUN_SSOO
2995*d4514f0bSApple OSS Distributions 
2996*d4514f0bSApple OSS Distributions 	// remap tests
2997*d4514f0bSApple OSS Distributions 
2998*d4514f0bSApple OSS Distributions #define FN_NAME(fn, variant, type) call_ ## fn ## __  ## variant ## __ ## type
2999*d4514f0bSApple OSS Distributions #define RUN_HELPER(harness, fn, variant, type, type_name, name) dealloc_results(process_results(harness(FN_NAME(fn, variant, type), #name " (" #variant ") (" type_name ")")))
3000*d4514f0bSApple OSS Distributions #define RUN_SRC_SIZE(fn, variant, type_name, name) RUN_HELPER(test_mach_with_allocated_start_size, fn, variant, src_size, type_name, name)
3001*d4514f0bSApple OSS Distributions #define RUN_DST_SIZE(fn, variant, type_name, name) RUN_HELPER(test_mach_with_allocated_start_size, fn, variant, dst_size, type_name, name)
3002*d4514f0bSApple OSS Distributions #define RUN_PROT_PAIRS(fn, variant, name) RUN_HELPER(test_mach_with_allocated_vm_prot_pair, fn, variant, prot_pairs, "prot_pairs", name)
3003*d4514f0bSApple OSS Distributions #define RUN_INHERIT(fn, variant, name) RUN_HELPER(test_mach_with_allocated_vm_inherit_t, fn, variant, inherit, "inherit", name)
3004*d4514f0bSApple OSS Distributions #define RUN_FLAGS(fn, variant, name) RUN_HELPER(test_mach_with_allocated_vm_map_kernel_flags_t, fn, variant, flags, "flags", name)
3005*d4514f0bSApple OSS Distributions #define RUN_SRC_DST_SIZE(fn, dst, variant, type_name, name) RUN_HELPER(test_allocated_src_##dst##_dst_size, fn, variant, src_dst_size, type_name, name)
3006*d4514f0bSApple OSS Distributions 
3007*d4514f0bSApple OSS Distributions #define RUN_ALL(fn, realigned, name)                                    \
3008*d4514f0bSApple OSS Distributions 	RUN_SRC_SIZE(fn, copy, realigned "src/size", name);             \
3009*d4514f0bSApple OSS Distributions 	RUN_SRC_SIZE(fn, nocopy, realigned "src/size", name);           \
3010*d4514f0bSApple OSS Distributions 	RUN_DST_SIZE(fn, fixed, "realigned dst/size", name);            \
3011*d4514f0bSApple OSS Distributions 	RUN_DST_SIZE(fn, fixed_copy, "realigned dst/size", name);       \
3012*d4514f0bSApple OSS Distributions 	RUN_DST_SIZE(fn, anywhere, "hint/size", name);                  \
3013*d4514f0bSApple OSS Distributions 	RUN_INHERIT(fn, fixed, name);                                   \
3014*d4514f0bSApple OSS Distributions 	RUN_INHERIT(fn, fixed_copy, name);                              \
3015*d4514f0bSApple OSS Distributions 	RUN_INHERIT(fn, anywhere, name);                                \
3016*d4514f0bSApple OSS Distributions 	RUN_FLAGS(fn, nocopy, name);                                    \
3017*d4514f0bSApple OSS Distributions 	RUN_FLAGS(fn, copy, name);                                      \
3018*d4514f0bSApple OSS Distributions 	RUN_PROT_PAIRS(fn, fixed, name);                                \
3019*d4514f0bSApple OSS Distributions 	RUN_PROT_PAIRS(fn, fixed_copy, name);                           \
3020*d4514f0bSApple OSS Distributions 	RUN_PROT_PAIRS(fn, anywhere, name);                             \
3021*d4514f0bSApple OSS Distributions 	RUN_SRC_DST_SIZE(fn, allocated, fixed, "src/dst/size", name);   \
3022*d4514f0bSApple OSS Distributions 	RUN_SRC_DST_SIZE(fn, allocated, fixed_copy, "src/dst/size", name); \
3023*d4514f0bSApple OSS Distributions 	RUN_SRC_DST_SIZE(fn, unallocated, anywhere, "src/dst/size", name); \
3024*d4514f0bSApple OSS Distributions 
3025*d4514f0bSApple OSS Distributions 	RUN_ALL(mach_vm_remap_user, "realigned ", mach_vm_remap);
3026*d4514f0bSApple OSS Distributions 	RUN_ALL(mach_vm_remap_new_user, , mach_vm_remap_new);
3027*d4514f0bSApple OSS Distributions 
3028*d4514f0bSApple OSS Distributions #if TEST_OLD_STYLE_MACH
3029*d4514f0bSApple OSS Distributions 	RUN_ALL(vm_remap_retyped, "realigned ", vm_remap);
3030*d4514f0bSApple OSS Distributions #endif
3031*d4514f0bSApple OSS Distributions 
3032*d4514f0bSApple OSS Distributions #undef RUN_ALL
3033*d4514f0bSApple OSS Distributions #undef RUN_HELPER
3034*d4514f0bSApple OSS Distributions #undef RUN_SRC_SIZE
3035*d4514f0bSApple OSS Distributions #undef RUN_DST_SIZE
3036*d4514f0bSApple OSS Distributions #undef RUN_PROT_PAIRS
3037*d4514f0bSApple OSS Distributions #undef RUN_INHERIT
3038*d4514f0bSApple OSS Distributions #undef RUN_FLAGS
3039*d4514f0bSApple OSS Distributions #undef RUN_SRC_DST_SIZE
3040*d4514f0bSApple OSS Distributions 
3041*d4514f0bSApple OSS Distributions 	// mmap tests
3042*d4514f0bSApple OSS Distributions 
3043*d4514f0bSApple OSS Distributions #define RUN(fn, name) dealloc_results(process_results(test_mmap_with_allocated_vm_map_kernel_flags_t(fn, name " (kernel flags)")))
3044*d4514f0bSApple OSS Distributions 	RUN(call_mmap__anon_private__kernel_flags, "mmap (anon private)");
3045*d4514f0bSApple OSS Distributions 	RUN(call_mmap__anon_shared__kernel_flags, "mmap (anon shared)");
3046*d4514f0bSApple OSS Distributions #undef RUN
3047*d4514f0bSApple OSS Distributions 
3048*d4514f0bSApple OSS Distributions #define RUN(fn, name) dealloc_results(process_results(test_mach_with_allocated_mmap_flags(fn, name " (mmap flags)")))
3049*d4514f0bSApple OSS Distributions 	RUN(call_mmap__mmap_flags, "mmap");
3050*d4514f0bSApple OSS Distributions #undef RUN
3051*d4514f0bSApple OSS Distributions 
3052*d4514f0bSApple OSS Distributions #define RUN(fn, name) dealloc_results(process_results(test_mach_with_allocated_start_size(fn, name " (hint/size)")))
3053*d4514f0bSApple OSS Distributions 	RUN(call_mmap__file_private__start_size, "mmap (file private)");
3054*d4514f0bSApple OSS Distributions 	RUN(call_mmap__anon_private__start_size, "mmap (anon private)");
3055*d4514f0bSApple OSS Distributions 	RUN(call_mmap__file_shared__start_size, "mmap (file shared)");
3056*d4514f0bSApple OSS Distributions 	RUN(call_mmap__anon_shared__start_size, "mmap (anon shared)");
3057*d4514f0bSApple OSS Distributions 	RUN(call_mmap__file_private_codesign__start_size, "mmap (file private codesign)");
3058*d4514f0bSApple OSS Distributions 	RUN(call_mmap__file_private_media__start_size, "mmap (file private media)");
3059*d4514f0bSApple OSS Distributions 	RUN(call_mmap__nounix03_private__start_size, "mmap (no unix03)");
3060*d4514f0bSApple OSS Distributions #undef RUN
3061*d4514f0bSApple OSS Distributions 
3062*d4514f0bSApple OSS Distributions #define RUN(fn, name) dealloc_results(process_results(test_fixed_dst_size(fn, name " (dst/size)")))
3063*d4514f0bSApple OSS Distributions 	RUN(call_mmap__fixed_private__start_size, "mmap (fixed)");
3064*d4514f0bSApple OSS Distributions #undef RUN
3065*d4514f0bSApple OSS Distributions 
3066*d4514f0bSApple OSS Distributions #define RUN(fn, name) dealloc_results(process_results(test_mach_with_allocated_start_size(fn, name " (offset/size)")))
3067*d4514f0bSApple OSS Distributions 	RUN(call_mmap__file_private__offset_size, "mmap (file private)");
3068*d4514f0bSApple OSS Distributions 	RUN(call_mmap__anon_private__offset_size, "mmap (anon private)");
3069*d4514f0bSApple OSS Distributions 	RUN(call_mmap__file_shared__offset_size, "mmap (file shared)");
3070*d4514f0bSApple OSS Distributions 	RUN(call_mmap__anon_shared__offset_size, "mmap (anon shared)");
3071*d4514f0bSApple OSS Distributions 	RUN(call_mmap__file_private_codesign__offset_size, "mmap (file private codesign)");
3072*d4514f0bSApple OSS Distributions 	RUN(call_mmap__file_private_media__offset_size, "mmap (file private media)");
3073*d4514f0bSApple OSS Distributions 	RUN(call_mmap__nounix03_private__offset_size, "mmap (no unix03)");
3074*d4514f0bSApple OSS Distributions #undef RUN
3075*d4514f0bSApple OSS Distributions 
3076*d4514f0bSApple OSS Distributions #define RUN(fn, name) dealloc_results(process_results(test_dst_size_fileoff(fn, name " (hint/size/fileoff)")))
3077*d4514f0bSApple OSS Distributions 	RUN(call_mmap__file_private__dst_size_fileoff, "mmap (file private)");
3078*d4514f0bSApple OSS Distributions 	RUN(call_mmap__anon_private__dst_size_fileoff, "mmap (anon private)");
3079*d4514f0bSApple OSS Distributions 	RUN(call_mmap__file_shared__dst_size_fileoff, "mmap (file shared)");
3080*d4514f0bSApple OSS Distributions 	RUN(call_mmap__anon_shared__dst_size_fileoff, "mmap (anon shared)");
3081*d4514f0bSApple OSS Distributions 	RUN(call_mmap__file_private_codesign__dst_size_fileoff, "mmap (file private codesign)");
3082*d4514f0bSApple OSS Distributions 	RUN(call_mmap__file_private_media__dst_size_fileoff, "mmap (file private media)");
3083*d4514f0bSApple OSS Distributions 	RUN(call_mmap__nounix03_private__dst_size_fileoff, "mmap (no unix03)");
3084*d4514f0bSApple OSS Distributions #undef RUN
3085*d4514f0bSApple OSS Distributions 
3086*d4514f0bSApple OSS Distributions #define RUN(fn, name) dealloc_results(process_results(test_fixed_dst_size_fileoff(fn, name " (dst/size/fileoff)")))
3087*d4514f0bSApple OSS Distributions 	RUN(call_mmap__fixed_private__dst_size_fileoff, "mmap (fixed)");
3088*d4514f0bSApple OSS Distributions #undef RUN
3089*d4514f0bSApple OSS Distributions 
3090*d4514f0bSApple OSS Distributions #define RUN(fn, name) dealloc_results(process_results(test_mach_with_allocated_vm_prot_t(fn, name " (vm_prot_t)")))
3091*d4514f0bSApple OSS Distributions 	RUN(call_mmap__file_private__vm_prot, "mmap (file private)");
3092*d4514f0bSApple OSS Distributions 	RUN(call_mmap__anon_private__vm_prot, "mmap (anon private)");
3093*d4514f0bSApple OSS Distributions 	RUN(call_mmap__file_shared__vm_prot, "mmap (file shared)");
3094*d4514f0bSApple OSS Distributions 	RUN(call_mmap__anon_shared__vm_prot, "mmap (anon shared)");
3095*d4514f0bSApple OSS Distributions 	RUN(call_mmap__file_private_codesign__vm_prot, "mmap (file private codesign)");
3096*d4514f0bSApple OSS Distributions 	RUN(call_mmap__file_private_media__vm_prot, "mmap (file private media)");
3097*d4514f0bSApple OSS Distributions 	RUN(call_mmap__nounix03_private__vm_prot, "mmap (no unix03)");
3098*d4514f0bSApple OSS Distributions 	RUN(call_mmap__fixed_private__vm_prot, "mmap (fixed)");
3099*d4514f0bSApple OSS Distributions #undef RUN
3100*d4514f0bSApple OSS Distributions 
3101*d4514f0bSApple OSS Distributions #define RUN(fn, name) dealloc_results(process_results(test_unix_with_allocated_start_size(fn, name " (start/size)")))
3102*d4514f0bSApple OSS Distributions 	RUN(call_mremap_encrypted, "mremap_encrypted");
3103*d4514f0bSApple OSS Distributions #undef RUN
3104*d4514f0bSApple OSS Distributions 
3105*d4514f0bSApple OSS Distributions 	/*
3106*d4514f0bSApple OSS Distributions 	 * -- wire/unwire functions --
3107*d4514f0bSApple OSS Distributions 	 */
3108*d4514f0bSApple OSS Distributions 
3109*d4514f0bSApple OSS Distributions #define RUN(fn, name) dealloc_results(process_results(test_unix_with_allocated_start_size(fn, name " (start/size)")))
3110*d4514f0bSApple OSS Distributions 	RUN(call_mlock, "mlock");
3111*d4514f0bSApple OSS Distributions 	RUN(call_munlock, "munlock");
3112*d4514f0bSApple OSS Distributions #undef RUN
3113*d4514f0bSApple OSS Distributions 
3114*d4514f0bSApple OSS Distributions #define RUN(fn, name) dealloc_results(process_results(test_mach_with_allocated_start_size(fn, name " (start/size)")))
3115*d4514f0bSApple OSS Distributions 	RUN(call_mach_vm_wire__wire, "mach_vm_wire (wire)");
3116*d4514f0bSApple OSS Distributions 	RUN(call_replacement_vm_wire__wire, "vm_wire (wire)");
3117*d4514f0bSApple OSS Distributions 	RUN(call_mach_vm_wire__unwire, "mach_vm_wire (unwire)");
3118*d4514f0bSApple OSS Distributions 	RUN(call_replacement_vm_wire__unwire, "vm_wire (unwire)");
3119*d4514f0bSApple OSS Distributions #undef RUN
3120*d4514f0bSApple OSS Distributions 
3121*d4514f0bSApple OSS Distributions #define RUN(fn, name) dealloc_results(process_results(test_mach_with_allocated_vm_prot_t(fn, name " (vm_prot_t)")))
3122*d4514f0bSApple OSS Distributions 	RUN(call_mach_vm_wire__vm_prot, "mach_vm_wire");
3123*d4514f0bSApple OSS Distributions 	RUN(call_replacement_vm_wire__vm_prot, "vm_wire");
3124*d4514f0bSApple OSS Distributions #undef RUN
3125*d4514f0bSApple OSS Distributions 
3126*d4514f0bSApple OSS Distributions 	/*
3127*d4514f0bSApple OSS Distributions 	 * -- copyin/copyout functions --
3128*d4514f0bSApple OSS Distributions 	 */
3129*d4514f0bSApple OSS Distributions 
3130*d4514f0bSApple OSS Distributions #define RUN_NEW(fn, name) dealloc_results(process_results(test_mach_with_allocated_start_size(fn, name " (start/size)")))
3131*d4514f0bSApple OSS Distributions #if TEST_OLD_STYLE_MACH
3132*d4514f0bSApple OSS Distributions #define RUN_OLD(fn, name) dealloc_results(process_results(test_oldmach_with_allocated_start_size(fn, name " (start/size)")))
3133*d4514f0bSApple OSS Distributions #else
3134*d4514f0bSApple OSS Distributions #define RUN_OLD(fn, name) do {} while (0)
3135*d4514f0bSApple OSS Distributions #endif
3136*d4514f0bSApple OSS Distributions 	RUN_NEW(call_mach_vm_read, "mach_vm_read");
3137*d4514f0bSApple OSS Distributions 	RUN_OLD(call_vm_read, "vm_read");
3138*d4514f0bSApple OSS Distributions 	RUN_NEW(call_mach_vm_read_list, "mach_vm_read_list");
3139*d4514f0bSApple OSS Distributions 	RUN_OLD(call_vm_read_list, "vm_read_list");
3140*d4514f0bSApple OSS Distributions 
3141*d4514f0bSApple OSS Distributions 	RUN_NEW(call_mach_vm_read_overwrite__src, "mach_vm_read_overwrite (src)");
3142*d4514f0bSApple OSS Distributions 	RUN_NEW(call_mach_vm_read_overwrite__dst, "mach_vm_read_overwrite (dst)");
3143*d4514f0bSApple OSS Distributions 	RUN_OLD(call_vm_read_overwrite__src, "vm_read_overwrite (src)");
3144*d4514f0bSApple OSS Distributions 	RUN_OLD(call_vm_read_overwrite__dst, "vm_read_overwrite (dst)");
3145*d4514f0bSApple OSS Distributions 
3146*d4514f0bSApple OSS Distributions 	RUN_NEW(call_mach_vm_write__src, "mach_vm_write (src)");
3147*d4514f0bSApple OSS Distributions 	RUN_NEW(call_mach_vm_write__dst, "mach_vm_write (dst)");
3148*d4514f0bSApple OSS Distributions 	RUN_OLD(call_vm_write__src, "vm_write (src)");
3149*d4514f0bSApple OSS Distributions 	RUN_OLD(call_vm_write__dst, "vm_write (dst)");
3150*d4514f0bSApple OSS Distributions 
3151*d4514f0bSApple OSS Distributions 	RUN_NEW(call_mach_vm_copy__src, "mach_vm_copy (src)");
3152*d4514f0bSApple OSS Distributions 	RUN_NEW(call_mach_vm_copy__dst, "mach_vm_copy (dst)");
3153*d4514f0bSApple OSS Distributions 	RUN_OLD(call_vm_copy__src, "vm_copy (src)");
3154*d4514f0bSApple OSS Distributions 	RUN_OLD(call_vm_copy__dst, "vm_copy (dst)");
3155*d4514f0bSApple OSS Distributions #undef RUN_NEW
3156*d4514f0bSApple OSS Distributions #undef RUN_OLD
3157*d4514f0bSApple OSS Distributions 
3158*d4514f0bSApple OSS Distributions 	/*
3159*d4514f0bSApple OSS Distributions 	 * -- inherit functions --
3160*d4514f0bSApple OSS Distributions 	 */
3161*d4514f0bSApple OSS Distributions 
3162*d4514f0bSApple OSS Distributions #define RUN_NEW(fn, name) dealloc_results(process_results(test_mach_with_allocated_start_size(fn, name " (start/size)")))
3163*d4514f0bSApple OSS Distributions #if TEST_OLD_STYLE_MACH
3164*d4514f0bSApple OSS Distributions #define RUN_OLD(fn, name) dealloc_results(process_results(test_oldmach_with_allocated_start_size(fn, name " (start/size)")))
3165*d4514f0bSApple OSS Distributions #else
3166*d4514f0bSApple OSS Distributions #define RUN_OLD(fn, name) do {} while (0)
3167*d4514f0bSApple OSS Distributions #endif
3168*d4514f0bSApple OSS Distributions 	RUN_NEW(call_mach_vm_inherit, "mach_vm_inherit");
3169*d4514f0bSApple OSS Distributions 	RUN_OLD(call_vm_inherit, "vm_inherit");
3170*d4514f0bSApple OSS Distributions #undef RUN_OLD
3171*d4514f0bSApple OSS Distributions #undef RUN_NEW
3172*d4514f0bSApple OSS Distributions 
3173*d4514f0bSApple OSS Distributions #define RUN(fn, name) dealloc_results(process_results(test_unix_with_allocated_start_size(fn, name " (start/size)")))
3174*d4514f0bSApple OSS Distributions 	RUN(call_minherit, "minherit");
3175*d4514f0bSApple OSS Distributions #undef RUN
3176*d4514f0bSApple OSS Distributions 
3177*d4514f0bSApple OSS Distributions #define RUN(fn, name) dealloc_results(process_results(test_mach_with_allocated_vm_inherit_t(fn, name " (vm_inherit_t)")))
3178*d4514f0bSApple OSS Distributions 	RUN(call_mach_vm_inherit__inherit, "mach_vm_inherit");
3179*d4514f0bSApple OSS Distributions #undef RUN
3180*d4514f0bSApple OSS Distributions #define RUN(fn, name) dealloc_results(process_results(test_unix_with_allocated_vm_inherit_t(fn, name " (vm_inherit_t)")))
3181*d4514f0bSApple OSS Distributions 	RUN(call_minherit__inherit, "minherit");
3182*d4514f0bSApple OSS Distributions #undef RUN
3183*d4514f0bSApple OSS Distributions 
3184*d4514f0bSApple OSS Distributions 	/*
3185*d4514f0bSApple OSS Distributions 	 * -- protection functions --
3186*d4514f0bSApple OSS Distributions 	 */
3187*d4514f0bSApple OSS Distributions 
3188*d4514f0bSApple OSS Distributions #define RUN_NEW(fn, name) dealloc_results(process_results(test_mach_with_allocated_start_size(fn, name " (start/size)")))
3189*d4514f0bSApple OSS Distributions #if TEST_OLD_STYLE_MACH
3190*d4514f0bSApple OSS Distributions #define RUN_OLD(fn, name) dealloc_results(process_results(test_oldmach_with_allocated_start_size(fn, name " (start/size)")))
3191*d4514f0bSApple OSS Distributions #else
3192*d4514f0bSApple OSS Distributions #define RUN_OLD(fn, name) do {} while (0)
3193*d4514f0bSApple OSS Distributions #endif
3194*d4514f0bSApple OSS Distributions 	RUN_NEW(call_mach_vm_protect__start_size, "mach_vm_protect");
3195*d4514f0bSApple OSS Distributions 	RUN_OLD(call_vm_protect__start_size, "vm_protect");
3196*d4514f0bSApple OSS Distributions #undef RUN_NEW
3197*d4514f0bSApple OSS Distributions #undef RUN_OLD
3198*d4514f0bSApple OSS Distributions #define RUN_NEW(fn, name) dealloc_results(process_results(test_mach_with_allocated_vm_prot_t(fn, name " (vm_prot_t)")))
3199*d4514f0bSApple OSS Distributions #if TEST_OLD_STYLE_MACH
3200*d4514f0bSApple OSS Distributions #define RUN_OLD(fn, name) dealloc_results(process_results(test_oldmach_with_allocated_vm_prot_t(fn, name " (vm_prot_t)")))
3201*d4514f0bSApple OSS Distributions #else
3202*d4514f0bSApple OSS Distributions #define RUN_OLD(fn, name) do {} while (0)
3203*d4514f0bSApple OSS Distributions #endif
3204*d4514f0bSApple OSS Distributions 	RUN_NEW(call_mach_vm_protect__vm_prot, "mach_vm_protect");
3205*d4514f0bSApple OSS Distributions 	RUN_OLD(call_vm_protect__vm_prot, "vm_protect");
3206*d4514f0bSApple OSS Distributions #undef RUN_NEW
3207*d4514f0bSApple OSS Distributions #undef RUN_OLD
3208*d4514f0bSApple OSS Distributions #define RUN(fn, name) dealloc_results(process_results(test_unix_with_allocated_start_size(fn, name " (start/size)")))
3209*d4514f0bSApple OSS Distributions 	RUN(call_mprotect__start_size, "mprotect");
3210*d4514f0bSApple OSS Distributions #undef RUN
3211*d4514f0bSApple OSS Distributions #define RUN(fn, name) dealloc_results(process_results(test_unix_with_allocated_vm_prot_t(fn, name " (vm_prot_t)")))
3212*d4514f0bSApple OSS Distributions 	RUN(call_mprotect__vm_prot, "mprotect");
3213*d4514f0bSApple OSS Distributions #undef RUN
3214*d4514f0bSApple OSS Distributions 
3215*d4514f0bSApple OSS Distributions 	/*
3216*d4514f0bSApple OSS Distributions 	 * -- madvise/behavior functions --
3217*d4514f0bSApple OSS Distributions 	 */
3218*d4514f0bSApple OSS Distributions 
3219*d4514f0bSApple OSS Distributions 	unsigned alignment_for_can_reuse;
3220*d4514f0bSApple OSS Distributions 	if (isRosetta()) {
3221*d4514f0bSApple OSS Distributions 		/*
3222*d4514f0bSApple OSS Distributions 		 * VM_BEHAVIOR_CAN_REUSE and MADV_CAN_REUSE get different errors
3223*d4514f0bSApple OSS Distributions 		 * on Rosetta when the allocation happens to be 4K vs 16K aligned.
3224*d4514f0bSApple OSS Distributions 		 * Force 16K alignment for consistent results.
3225*d4514f0bSApple OSS Distributions 		 */
3226*d4514f0bSApple OSS Distributions 		alignment_for_can_reuse = KB16 - 1;
3227*d4514f0bSApple OSS Distributions 	} else {
3228*d4514f0bSApple OSS Distributions 		/* Use default alignment everywhere else. */
3229*d4514f0bSApple OSS Distributions 		alignment_for_can_reuse = 0;
3230*d4514f0bSApple OSS Distributions 	}
3231*d4514f0bSApple OSS Distributions 
3232*d4514f0bSApple OSS Distributions #define RUN_NEW(fn, name) dealloc_results(process_results(test_mach_with_allocated_start_size(fn, name " (start/size)")))
3233*d4514f0bSApple OSS Distributions #if TEST_OLD_STYLE_MACH
3234*d4514f0bSApple OSS Distributions #define RUN_OLD(fn, name) dealloc_results(process_results(test_oldmach_with_allocated_start_size(fn, name " (start/size)")))
3235*d4514f0bSApple OSS Distributions #else
3236*d4514f0bSApple OSS Distributions #define RUN_OLD(fn, name) do {} while (0)
3237*d4514f0bSApple OSS Distributions #endif
3238*d4514f0bSApple OSS Distributions 	RUN_NEW(call_mach_vm_behavior_set__start_size__default, "mach_vm_behavior_set (VM_BEHAVIOR_DEFAULT)");
3239*d4514f0bSApple OSS Distributions 	RUN_OLD(call_vm_behavior_set__start_size__default, "vm_behavior_set (VM_BEHAVIOR_DEFAULT)");
3240*d4514f0bSApple OSS Distributions #undef RUN_NEW
3241*d4514f0bSApple OSS Distributions #undef RUN_OLD
3242*d4514f0bSApple OSS Distributions 
3243*d4514f0bSApple OSS Distributions #define RUN_NEW(fn, name) dealloc_results(process_results(test_mach_with_allocated_aligned_start_size(fn, alignment_for_can_reuse, name " (start/size)")))
3244*d4514f0bSApple OSS Distributions #if TEST_OLD_STYLE_MACH
3245*d4514f0bSApple OSS Distributions #define RUN_OLD(fn, name) dealloc_results(process_results(test_oldmach_with_allocated_aligned_start_size(fn, alignment_for_can_reuse, name " (start/size)")))
3246*d4514f0bSApple OSS Distributions #else
3247*d4514f0bSApple OSS Distributions #define RUN_OLD(fn, name) do {} while (0)
3248*d4514f0bSApple OSS Distributions #endif
3249*d4514f0bSApple OSS Distributions 	RUN_NEW(call_mach_vm_behavior_set__start_size__can_reuse, "mach_vm_behavior_set (VM_BEHAVIOR_CAN_REUSE)");
3250*d4514f0bSApple OSS Distributions 	RUN_OLD(call_vm_behavior_set__start_size__can_reuse, "vm_behavior_set (VM_BEHAVIOR_CAN_REUSE)");
3251*d4514f0bSApple OSS Distributions #undef RUN_NEW
3252*d4514f0bSApple OSS Distributions #undef RUN_OLD
3253*d4514f0bSApple OSS Distributions 
3254*d4514f0bSApple OSS Distributions #define RUN_NEW(fn, name) dealloc_results(process_results(test_mach_with_allocated_aligned_vm_behavior_t(fn, alignment_for_can_reuse, name " (vm_behavior_t)")))
3255*d4514f0bSApple OSS Distributions #if TEST_OLD_STYLE_MACH
3256*d4514f0bSApple OSS Distributions #define RUN_OLD(fn, name) dealloc_results(process_results(test_oldmach_with_allocated_aligned_vm_behavior_t(fn, alignment_for_can_reuse, name " (vm_behavior_t)")))
3257*d4514f0bSApple OSS Distributions #else
3258*d4514f0bSApple OSS Distributions #define RUN_OLD(fn, name) do {} while (0)
3259*d4514f0bSApple OSS Distributions #endif
3260*d4514f0bSApple OSS Distributions 	RUN_NEW(call_mach_vm_behavior_set__vm_behavior, "mach_vm_behavior_set");
3261*d4514f0bSApple OSS Distributions 	RUN_OLD(call_vm_behavior_set__vm_behavior, "vm_behavior_set");
3262*d4514f0bSApple OSS Distributions #undef RUN_NEW
3263*d4514f0bSApple OSS Distributions #undef RUN_OLD
3264*d4514f0bSApple OSS Distributions 
3265*d4514f0bSApple OSS Distributions #define RUN(fn, name) dealloc_results(process_results(test_unix_with_allocated_start_size(fn, name " (start/size)")))
3266*d4514f0bSApple OSS Distributions 	RUN(call_madvise__start_size, "madvise");
3267*d4514f0bSApple OSS Distributions #undef RUN
3268*d4514f0bSApple OSS Distributions 
3269*d4514f0bSApple OSS Distributions #define RUN(fn, name) dealloc_results(process_results(test_unix_with_allocated_aligned_vm_advise_t(fn, alignment_for_can_reuse, name " (vm_advise_t)")))
3270*d4514f0bSApple OSS Distributions 	RUN(call_madvise__vm_advise, "madvise");
3271*d4514f0bSApple OSS Distributions #undef RUN
3272*d4514f0bSApple OSS Distributions 
3273*d4514f0bSApple OSS Distributions 	/*
3274*d4514f0bSApple OSS Distributions 	 * -- msync functions --
3275*d4514f0bSApple OSS Distributions 	 */
3276*d4514f0bSApple OSS Distributions 
3277*d4514f0bSApple OSS Distributions #define RUN_NEW(fn, name) dealloc_results(process_results(test_mach_with_allocated_start_size(fn, name " (start/size)")))
3278*d4514f0bSApple OSS Distributions #if TEST_OLD_STYLE_MACH
3279*d4514f0bSApple OSS Distributions #define RUN_OLD(fn, name) dealloc_results(process_results(test_oldmach_with_allocated_start_size(fn, name " (start/size)")))
3280*d4514f0bSApple OSS Distributions #else
3281*d4514f0bSApple OSS Distributions #define RUN_OLD(fn, name) do {} while (0)
3282*d4514f0bSApple OSS Distributions #endif
3283*d4514f0bSApple OSS Distributions 	RUN_NEW(call_mach_vm_msync__start_size, "mach_vm_msync");
3284*d4514f0bSApple OSS Distributions 	RUN_OLD(call_vm_msync__start_size, "vm_msync");
3285*d4514f0bSApple OSS Distributions #undef RUN_NEW
3286*d4514f0bSApple OSS Distributions #undef RUN_OLD
3287*d4514f0bSApple OSS Distributions #define RUN_NEW(fn, name) dealloc_results(process_results(test_mach_with_allocated_vm_sync_t(fn, name " (vm_sync_t)")))
3288*d4514f0bSApple OSS Distributions #if TEST_OLD_STYLE_MACH
3289*d4514f0bSApple OSS Distributions #define RUN_OLD(fn, name) dealloc_results(process_results(test_oldmach_with_allocated_vm_sync_t(fn, name " (vm_sync_t)")))
3290*d4514f0bSApple OSS Distributions #else
3291*d4514f0bSApple OSS Distributions #define RUN_OLD(fn, name) do {} while (0)
3292*d4514f0bSApple OSS Distributions #endif
3293*d4514f0bSApple OSS Distributions 	RUN_NEW(call_mach_vm_msync__vm_sync, "mach_vm_msync");
3294*d4514f0bSApple OSS Distributions 	RUN_OLD(call_vm_msync__vm_sync, "vm_msync");
3295*d4514f0bSApple OSS Distributions #undef RUN_NEW
3296*d4514f0bSApple OSS Distributions #undef RUN_OLD
3297*d4514f0bSApple OSS Distributions #define RUN(fn, name) dealloc_results(process_results(test_unix_with_allocated_start_size(fn, name " (start/size)")))
3298*d4514f0bSApple OSS Distributions 	RUN(call_msync__start_size, "msync");
3299*d4514f0bSApple OSS Distributions 	RUN(call_msync_nocancel__start_size, "msync_nocancel");
3300*d4514f0bSApple OSS Distributions #undef RUN
3301*d4514f0bSApple OSS Distributions #define RUN(fn, name) dealloc_results(process_results(test_unix_with_allocated_vm_msync_t(fn, name " (msync flags)")))
3302*d4514f0bSApple OSS Distributions 	RUN(call_msync__vm_msync, "msync");
3303*d4514f0bSApple OSS Distributions 	RUN(call_msync_nocancel__vm_msync, "msync_nocancel");
3304*d4514f0bSApple OSS Distributions #undef RUN
3305*d4514f0bSApple OSS Distributions 
3306*d4514f0bSApple OSS Distributions 	/*
3307*d4514f0bSApple OSS Distributions 	 * -- machine attribute functions --
3308*d4514f0bSApple OSS Distributions 	 */
3309*d4514f0bSApple OSS Distributions 
3310*d4514f0bSApple OSS Distributions #define RUN_NEW(fn, name) dealloc_results(process_results(test_mach_with_allocated_start_size(fn, name " (start/size)")))
3311*d4514f0bSApple OSS Distributions #if TEST_OLD_STYLE_MACH
3312*d4514f0bSApple OSS Distributions #define RUN_OLD(fn, name) dealloc_results(process_results(test_oldmach_with_allocated_start_size(fn, name " (start/size)")))
3313*d4514f0bSApple OSS Distributions #else
3314*d4514f0bSApple OSS Distributions #define RUN_OLD(fn, name) do {} while (0)
3315*d4514f0bSApple OSS Distributions #endif
3316*d4514f0bSApple OSS Distributions 	RUN_NEW(call_mach_vm_machine_attribute__start_size, "mach_vm_machine_attribute");
3317*d4514f0bSApple OSS Distributions 	RUN_OLD(call_vm_machine_attribute__start_size, "vm_machine_attribute");
3318*d4514f0bSApple OSS Distributions #undef RUN_NEW
3319*d4514f0bSApple OSS Distributions #undef RUN_OLD
3320*d4514f0bSApple OSS Distributions #define RUN_NEW(fn, name) dealloc_results(process_results(test_mach_with_allocated_vm_machine_attribute_t(fn, name " (machine_attribute_t)")))
3321*d4514f0bSApple OSS Distributions #if TEST_OLD_STYLE_MACH
3322*d4514f0bSApple OSS Distributions #define RUN_OLD(fn, name) dealloc_results(process_results(test_oldmach_with_allocated_vm_machine_attribute_t(fn, name " (machine_attribute_t)")))
3323*d4514f0bSApple OSS Distributions #else
3324*d4514f0bSApple OSS Distributions #define RUN_OLD(fn, name) do {} while (0)
3325*d4514f0bSApple OSS Distributions #endif
3326*d4514f0bSApple OSS Distributions 	RUN_NEW(call_mach_vm_machine_attribute__machine_attribute, "mach_vm_machine_attribute");
3327*d4514f0bSApple OSS Distributions 	RUN_OLD(call_vm_machine_attribute__machine_attribute, "vm_machine_attribute");
3328*d4514f0bSApple OSS Distributions #undef RUN_NEW
3329*d4514f0bSApple OSS Distributions #undef RUN_OLD
3330*d4514f0bSApple OSS Distributions 
3331*d4514f0bSApple OSS Distributions 	/*
3332*d4514f0bSApple OSS Distributions 	 * -- purgability/purgeability functions --
3333*d4514f0bSApple OSS Distributions 	 */
3334*d4514f0bSApple OSS Distributions 
3335*d4514f0bSApple OSS Distributions #define RUN_NEW(fn, name) dealloc_results(process_results(test_mach_with_allocated_purgeable_addr(fn, name " (addr)")))
3336*d4514f0bSApple OSS Distributions #if TEST_OLD_STYLE_MACH
3337*d4514f0bSApple OSS Distributions #define RUN_OLD(fn, name) dealloc_results(process_results(test_oldmach_with_allocated_purgeable_addr(fn, name " (addr)")))
3338*d4514f0bSApple OSS Distributions #else
3339*d4514f0bSApple OSS Distributions #define RUN_OLD(fn, name) do {} while (0)
3340*d4514f0bSApple OSS Distributions #endif
3341*d4514f0bSApple OSS Distributions 	RUN_NEW(call_mach_vm_purgable_control__address__get, "mach_vm_purgable_control (get)");
3342*d4514f0bSApple OSS Distributions 	RUN_OLD(call_vm_purgable_control__address__get, "vm_purgable_control (get)");
3343*d4514f0bSApple OSS Distributions 
3344*d4514f0bSApple OSS Distributions 	RUN_NEW(call_mach_vm_purgable_control__address__purge_all, "mach_vm_purgable_control (purge all)");
3345*d4514f0bSApple OSS Distributions 	RUN_OLD(call_vm_purgable_control__address__purge_all, "vm_purgable_control (purge all)");
3346*d4514f0bSApple OSS Distributions #undef RUN_NEW
3347*d4514f0bSApple OSS Distributions #undef RUN_OLD
3348*d4514f0bSApple OSS Distributions #define RUN_NEW(fn, name) dealloc_results(process_results(test_mach_with_allocated_purgeable_and_state(fn, name " (purgeable and state)")))
3349*d4514f0bSApple OSS Distributions #if TEST_OLD_STYLE_MACH
3350*d4514f0bSApple OSS Distributions #define RUN_OLD(fn, name) dealloc_results(process_results(test_oldmach_with_allocated_purgeable_and_state(fn, name " (purgeable and state)")))
3351*d4514f0bSApple OSS Distributions #else
3352*d4514f0bSApple OSS Distributions #define RUN_OLD(fn, name) do {} while (0)
3353*d4514f0bSApple OSS Distributions #endif
3354*d4514f0bSApple OSS Distributions 	RUN_NEW(call_mach_vm_purgable_control__purgeable_state, "mach_vm_purgable_control");
3355*d4514f0bSApple OSS Distributions 	RUN_OLD(call_vm_purgable_control__purgeable_state, "vm_purgable_control");
3356*d4514f0bSApple OSS Distributions #undef RUN_NEW
3357*d4514f0bSApple OSS Distributions #undef RUN_OLD
3358*d4514f0bSApple OSS Distributions 
3359*d4514f0bSApple OSS Distributions 	/*
3360*d4514f0bSApple OSS Distributions 	 * -- region info functions --
3361*d4514f0bSApple OSS Distributions 	 */
3362*d4514f0bSApple OSS Distributions 
3363*d4514f0bSApple OSS Distributions #define RUN_NEW(fn, name) dealloc_results(process_results(test_mach_with_allocated_addr(fn, name " (addr)")))
3364*d4514f0bSApple OSS Distributions #if TEST_OLD_STYLE_MACH
3365*d4514f0bSApple OSS Distributions #define RUN_OLD(fn, name) dealloc_results(process_results(test_oldmach_with_allocated_addr(fn, name " (addr)")))
3366*d4514f0bSApple OSS Distributions #else
3367*d4514f0bSApple OSS Distributions #define RUN_OLD(fn, name) do {} while (0)
3368*d4514f0bSApple OSS Distributions #endif
3369*d4514f0bSApple OSS Distributions 	RUN_NEW(call_mach_vm_region, "mach_vm_region");
3370*d4514f0bSApple OSS Distributions 	RUN_OLD(call_vm_region, "vm_region");
3371*d4514f0bSApple OSS Distributions 	RUN_NEW(call_mach_vm_region_recurse, "mach_vm_region_recurse");
3372*d4514f0bSApple OSS Distributions 	RUN_OLD(call_vm_region_recurse, "vm_region_recurse");
3373*d4514f0bSApple OSS Distributions 	RUN_OLD(call_vm_region_recurse_64, "vm_region_recurse_64");
3374*d4514f0bSApple OSS Distributions #undef RUN_NEW
3375*d4514f0bSApple OSS Distributions #undef RUN_OLD
3376*d4514f0bSApple OSS Distributions 
3377*d4514f0bSApple OSS Distributions 	/*
3378*d4514f0bSApple OSS Distributions 	 * -- page info functions --
3379*d4514f0bSApple OSS Distributions 	 */
3380*d4514f0bSApple OSS Distributions 
3381*d4514f0bSApple OSS Distributions #define RUN_NEW(fn, name) dealloc_results(process_results(test_mach_with_allocated_addr(fn, name " (addr)")))
3382*d4514f0bSApple OSS Distributions #if TEST_OLD_STYLE_MACH
3383*d4514f0bSApple OSS Distributions #define RUN_OLD(fn, name) dealloc_results(process_results(test_oldmach_with_allocated_addr(fn, name " (addr)")))
3384*d4514f0bSApple OSS Distributions #else
3385*d4514f0bSApple OSS Distributions #define RUN_OLD(fn, name) do {} while (0)
3386*d4514f0bSApple OSS Distributions #endif
3387*d4514f0bSApple OSS Distributions 	RUN_NEW(call_mach_vm_page_info, "mach_vm_page_info");
3388*d4514f0bSApple OSS Distributions 	RUN_NEW(call_mach_vm_page_query, "mach_vm_page_query");
3389*d4514f0bSApple OSS Distributions 	RUN_OLD(call_vm_map_page_query, "vm_map_page_query");
3390*d4514f0bSApple OSS Distributions #undef RUN_NEW
3391*d4514f0bSApple OSS Distributions #undef RUN_OLD
3392*d4514f0bSApple OSS Distributions 
3393*d4514f0bSApple OSS Distributions #define RUN_NEW(fn, name) dealloc_results(process_results(test_mach_with_allocated_start_size(fn, name " (start/size)")))
3394*d4514f0bSApple OSS Distributions 	RUN_NEW(call_mach_vm_page_range_query, "mach_vm_page_range_query");
3395*d4514f0bSApple OSS Distributions #undef RUN_NEW
3396*d4514f0bSApple OSS Distributions 
3397*d4514f0bSApple OSS Distributions #define RUN(fn, name) dealloc_results(process_results(test_unix_with_allocated_start_size(fn, name " (start/size)")))
3398*d4514f0bSApple OSS Distributions 	RUN(call_mincore, "mincore");
3399*d4514f0bSApple OSS Distributions #undef RUN
3400*d4514f0bSApple OSS Distributions 
3401*d4514f0bSApple OSS Distributions 	/*
3402*d4514f0bSApple OSS Distributions 	 * -- miscellaneous functions --
3403*d4514f0bSApple OSS Distributions 	 */
3404*d4514f0bSApple OSS Distributions 
3405*d4514f0bSApple OSS Distributions #define RUN(fn, name) dealloc_results(process_results(test_unix_shared_region_map_and_slide_2_np(fn, name " (files/mappings)")))
3406*d4514f0bSApple OSS Distributions 	RUN(call_shared_region_map_and_slide_2_np_child, "shared_region_map_and_slide_2_np");
3407*d4514f0bSApple OSS Distributions 	RUN(call_shared_region_map_and_slide_2_np_in_thread, "different thread shared_region_map_and_slide_2_np");
3408*d4514f0bSApple OSS Distributions #undef RUN
3409*d4514f0bSApple OSS Distributions 
3410*d4514f0bSApple OSS Distributions #define RUN(fn, name) dealloc_results(process_results(test_mach_vm_deferred_reclamation_buffer_init(fn, name)))
3411*d4514f0bSApple OSS Distributions 	RUN(call_mach_vm_deferred_reclamation_buffer_init, "mach_vm_deferred_reclamation_buffer_init");
3412*d4514f0bSApple OSS Distributions #undef RUN
3413*d4514f0bSApple OSS Distributions 
3414*d4514f0bSApple OSS Distributions out:
3415*d4514f0bSApple OSS Distributions 	restore_exc_guard();
3416*d4514f0bSApple OSS Distributions 
3417*d4514f0bSApple OSS Distributions 	if (generate_golden) {
3418*d4514f0bSApple OSS Distributions 		if (!out_param_bad_count || (dump && !should_test_results)) {
3419*d4514f0bSApple OSS Distributions 			// Print after verified there is not OUT_PARAM_BAD results before printing,
3420*d4514f0bSApple OSS Distributions 			// or user explicitly set DUMP_RESULTS=1 GENERATE_GOLDEN_IMAGE=1
3421*d4514f0bSApple OSS Distributions 			printf("%s", GOLDEN_OUTPUT_START);
3422*d4514f0bSApple OSS Distributions 		}
3423*d4514f0bSApple OSS Distributions 	}
3424*d4514f0bSApple OSS Distributions 	free(GOLDEN_OUTPUT_START);
3425*d4514f0bSApple OSS Distributions 
3426*d4514f0bSApple OSS Distributions 	if (dump_golden || should_test_results) {
3427*d4514f0bSApple OSS Distributions 		clean_golden_results();
3428*d4514f0bSApple OSS Distributions 	}
3429*d4514f0bSApple OSS Distributions 
3430*d4514f0bSApple OSS Distributions 	if (reenable_vm_sanitize_telemetry() != 0) {
3431*d4514f0bSApple OSS Distributions 		T_FAIL("Failed to reenable VM API telemetry.");
3432*d4514f0bSApple OSS Distributions 		return;
3433*d4514f0bSApple OSS Distributions 	}
3434*d4514f0bSApple OSS Distributions 
3435*d4514f0bSApple OSS Distributions 	T_PASS("vm parameter validation userspace");
3436*d4514f0bSApple OSS Distributions }
3437*d4514f0bSApple OSS Distributions 
3438*d4514f0bSApple OSS Distributions 
3439*d4514f0bSApple OSS Distributions /////////////////////////////////////////////////////
3440*d4514f0bSApple OSS Distributions // Kernel test invocation.
3441*d4514f0bSApple OSS Distributions // The actual test code is in:
3442*d4514f0bSApple OSS Distributions // osfmk/tests/vm_parameter_validation_kern.c
3443*d4514f0bSApple OSS Distributions 
3444*d4514f0bSApple OSS Distributions #define KERN_RESULT_DELIMITER "\n"
3445*d4514f0bSApple OSS Distributions 
3446*d4514f0bSApple OSS Distributions #ifndef STRINGIFY
3447*d4514f0bSApple OSS Distributions #define __STR(x)        #x
3448*d4514f0bSApple OSS Distributions #define STRINGIFY(x)    __STR(x)
3449*d4514f0bSApple OSS Distributions #endif
3450*d4514f0bSApple OSS Distributions 
3451*d4514f0bSApple OSS Distributions // Verify golden list being generated doesn't contain OUT_BAD_PARAM
3452*d4514f0bSApple OSS Distributions static int
out_bad_param_in_kern_golden_results(char * kern_buffer)3453*d4514f0bSApple OSS Distributions out_bad_param_in_kern_golden_results(char *kern_buffer)
3454*d4514f0bSApple OSS Distributions {
3455*d4514f0bSApple OSS Distributions 	const char *out_param_bad_str = STRINGIFY(OUT_PARAM_BAD);
3456*d4514f0bSApple OSS Distributions 	char *out_param_bad_match = strstr(kern_buffer, out_param_bad_str);
3457*d4514f0bSApple OSS Distributions 	if (out_param_bad_match) {
3458*d4514f0bSApple OSS Distributions 		T_FAIL("Out parameter violation return code (%s) found in results, aborting.\n", out_param_bad_str);
3459*d4514f0bSApple OSS Distributions 		return 1;
3460*d4514f0bSApple OSS Distributions 	}
3461*d4514f0bSApple OSS Distributions 	return 0;
3462*d4514f0bSApple OSS Distributions }
3463*d4514f0bSApple OSS Distributions 
3464*d4514f0bSApple OSS Distributions 
3465*d4514f0bSApple OSS Distributions // Read results written by __dump_results()
3466*d4514f0bSApple OSS Distributions static int
populate_kernel_results(char * kern_buffer)3467*d4514f0bSApple OSS Distributions populate_kernel_results(char *kern_buffer)
3468*d4514f0bSApple OSS Distributions {
3469*d4514f0bSApple OSS Distributions 	char *line = NULL;
3470*d4514f0bSApple OSS Distributions 	char *sub_line = NULL;
3471*d4514f0bSApple OSS Distributions 	char *test_name = NULL;
3472*d4514f0bSApple OSS Distributions 	char *result_name = NULL;
3473*d4514f0bSApple OSS Distributions 	char *token = NULL;
3474*d4514f0bSApple OSS Distributions 	char *s_num_kern_results = NULL;
3475*d4514f0bSApple OSS Distributions 	results_t *kern_results = NULL;
3476*d4514f0bSApple OSS Distributions 	uint32_t num_kern_results = 0;
3477*d4514f0bSApple OSS Distributions 	uint32_t result_number = 0;
3478*d4514f0bSApple OSS Distributions 	int result_ret = 0;
3479*d4514f0bSApple OSS Distributions 	bool in_test = FALSE;
3480*d4514f0bSApple OSS Distributions 
3481*d4514f0bSApple OSS Distributions 	line = strtok(kern_buffer, KERN_RESULT_DELIMITER);
3482*d4514f0bSApple OSS Distributions 	while (line != NULL) {
3483*d4514f0bSApple OSS Distributions 		if (strncmp(line, TESTNAME_DELIMITER, strlen(TESTNAME_DELIMITER)) == 0) {
3484*d4514f0bSApple OSS Distributions 			sub_line = line + strlen(TESTNAME_DELIMITER);
3485*d4514f0bSApple OSS Distributions 			test_name = strdup(sub_line);
3486*d4514f0bSApple OSS Distributions 			result_number = 0;
3487*d4514f0bSApple OSS Distributions 			in_test = TRUE;
3488*d4514f0bSApple OSS Distributions 		} else if (in_test && strncmp(line, RESULTCOUNT_DELIMITER, strlen(RESULTCOUNT_DELIMITER)) == 0) {
3489*d4514f0bSApple OSS Distributions 			s_num_kern_results = line + strlen(RESULTCOUNT_DELIMITER);
3490*d4514f0bSApple OSS Distributions 			num_kern_results = (uint32_t)strtoul(s_num_kern_results, NULL, 10);
3491*d4514f0bSApple OSS Distributions 			kern_results = alloc_results(test_name, eUNKNOWN_TRIALS, num_kern_results);
3492*d4514f0bSApple OSS Distributions 			kern_results->count = num_kern_results;
3493*d4514f0bSApple OSS Distributions 			kern_list[num_kern_tests++] = kern_results;
3494*d4514f0bSApple OSS Distributions 		} else if (in_test && strncmp(line, TESTCONFIG_DELIMITER, strlen(TESTCONFIG_DELIMITER)) == 0) {
3495*d4514f0bSApple OSS Distributions 			sub_line = line + strlen(TESTCONFIG_DELIMITER);
3496*d4514f0bSApple OSS Distributions 			kern_results->testconfig = strdup(sub_line);
3497*d4514f0bSApple OSS Distributions 		} else if (in_test && strstr(line, KERN_TESTRESULT_DELIMITER)) {
3498*d4514f0bSApple OSS Distributions 			// should have found TESTCONFIG already
3499*d4514f0bSApple OSS Distributions 			assert(kern_results->testconfig != NULL);
3500*d4514f0bSApple OSS Distributions 			sscanf(line, KERN_TESTRESULT_DELIMITER "%d", &result_ret);
3501*d4514f0bSApple OSS Distributions 			// get result name (comes after the first ,)
3502*d4514f0bSApple OSS Distributions 			token = strchr(line, ',');
3503*d4514f0bSApple OSS Distributions 			if (token) {
3504*d4514f0bSApple OSS Distributions 				token = token + 2; // skip the , and the extra space
3505*d4514f0bSApple OSS Distributions 				result_name = strdup(token);
3506*d4514f0bSApple OSS Distributions 				if (result_number >= num_kern_results) {
3507*d4514f0bSApple OSS Distributions 					T_LOG("\tKERN Invalid output in test %s, seeing more results (%u) than expected (%u), ignoring trial RESULT %d, %s\n",
3508*d4514f0bSApple OSS Distributions 					    test_name, result_number, num_kern_results, result_ret, result_name);
3509*d4514f0bSApple OSS Distributions 					free(result_name);
3510*d4514f0bSApple OSS Distributions 				} else {
3511*d4514f0bSApple OSS Distributions 					kern_results->list[result_number++] = (result_t){.ret = result_ret, .name = result_name};
3512*d4514f0bSApple OSS Distributions 				}
3513*d4514f0bSApple OSS Distributions 			}
3514*d4514f0bSApple OSS Distributions 		} else {
3515*d4514f0bSApple OSS Distributions 			// T_LOG("Unknown kernel result line: %s\n", line);
3516*d4514f0bSApple OSS Distributions 			//in_test = FALSE;
3517*d4514f0bSApple OSS Distributions 		}
3518*d4514f0bSApple OSS Distributions 
3519*d4514f0bSApple OSS Distributions 		line = strtok(NULL, KERN_RESULT_DELIMITER);
3520*d4514f0bSApple OSS Distributions 	}
3521*d4514f0bSApple OSS Distributions 
3522*d4514f0bSApple OSS Distributions 	dump_kernel_results_list();
3523*d4514f0bSApple OSS Distributions 
3524*d4514f0bSApple OSS Distributions 	return 0;
3525*d4514f0bSApple OSS Distributions }
3526*d4514f0bSApple OSS Distributions 
3527*d4514f0bSApple OSS Distributions static int64_t
run_sysctl_test(const char * t,int64_t value)3528*d4514f0bSApple OSS Distributions run_sysctl_test(const char *t, int64_t value)
3529*d4514f0bSApple OSS Distributions {
3530*d4514f0bSApple OSS Distributions 	char name[1024];
3531*d4514f0bSApple OSS Distributions 	int64_t result = 0;
3532*d4514f0bSApple OSS Distributions 	size_t s = sizeof(value);
3533*d4514f0bSApple OSS Distributions 	int rc;
3534*d4514f0bSApple OSS Distributions 
3535*d4514f0bSApple OSS Distributions 	snprintf(name, sizeof(name), "debug.test.%s", t);
3536*d4514f0bSApple OSS Distributions 	rc = sysctlbyname(name, &result, &s, &value, s);
3537*d4514f0bSApple OSS Distributions 	T_QUIET; T_ASSERT_POSIX_SUCCESS(rc, "sysctlbyname(%s)", t);
3538*d4514f0bSApple OSS Distributions 	return result;
3539*d4514f0bSApple OSS Distributions }
3540*d4514f0bSApple OSS Distributions 
3541*d4514f0bSApple OSS Distributions T_DECL(vm_parameter_validation_kern,
3542*d4514f0bSApple OSS Distributions     "parameter validation for kext/xnu calls",
3543*d4514f0bSApple OSS Distributions     T_META_SPAWN_TOOL(DECOMPRESS),
3544*d4514f0bSApple OSS Distributions     T_META_SPAWN_TOOL_ARG("kern"),
3545*d4514f0bSApple OSS Distributions     T_META_SPAWN_TOOL_ARG(TMP_DIR),
3546*d4514f0bSApple OSS Distributions     T_META_SPAWN_TOOL_ARG(GOLDEN_FILES_VERSION)
3547*d4514f0bSApple OSS Distributions     )
3548*d4514f0bSApple OSS Distributions {
3549*d4514f0bSApple OSS Distributions 	if (disable_vm_sanitize_telemetry() != 0) {
3550*d4514f0bSApple OSS Distributions 		T_FAIL("Could not disable VM API telemetry. Bailing out early.");
3551*d4514f0bSApple OSS Distributions 		return;
3552*d4514f0bSApple OSS Distributions 	}
3553*d4514f0bSApple OSS Distributions 
3554*d4514f0bSApple OSS Distributions 	read_env();
3555*d4514f0bSApple OSS Distributions 
3556*d4514f0bSApple OSS Distributions 	T_LOG("dump %d, golden %d, dump_golden %d, test %d\n", dump, generate_golden, dump_golden, should_test_results);
3557*d4514f0bSApple OSS Distributions 
3558*d4514f0bSApple OSS Distributions 	disable_exc_guard();
3559*d4514f0bSApple OSS Distributions 
3560*d4514f0bSApple OSS Distributions 	if (dump_golden) {
3561*d4514f0bSApple OSS Distributions 		if (populate_golden_results(KERN_GOLDEN_FILE)) {
3562*d4514f0bSApple OSS Distributions 			// couldn't load golden test results
3563*d4514f0bSApple OSS Distributions 			T_FAIL("Could not load golden file '%s'\n", KERN_GOLDEN_FILE);
3564*d4514f0bSApple OSS Distributions 			goto out;
3565*d4514f0bSApple OSS Distributions 		}
3566*d4514f0bSApple OSS Distributions 
3567*d4514f0bSApple OSS Distributions 		// just print the parsed golden file
3568*d4514f0bSApple OSS Distributions 		for (uint32_t x = 0; x < num_tests; ++x) {
3569*d4514f0bSApple OSS Distributions 			__dump_results(golden_list[x]);
3570*d4514f0bSApple OSS Distributions 		}
3571*d4514f0bSApple OSS Distributions 		clean_golden_results();
3572*d4514f0bSApple OSS Distributions 		goto out;
3573*d4514f0bSApple OSS Distributions 	}
3574*d4514f0bSApple OSS Distributions 
3575*d4514f0bSApple OSS Distributions 	T_LOG("Running kernel tests\n");
3576*d4514f0bSApple OSS Distributions 
3577*d4514f0bSApple OSS Distributions 	// We allocate a large buffer. The kernel-side code writes output to it.
3578*d4514f0bSApple OSS Distributions 	// Then we print that output. This is faster than making the kernel-side
3579*d4514f0bSApple OSS Distributions 	// code print directly to the serial console, which takes many minutes
3580*d4514f0bSApple OSS Distributions 	// to transfer our test output at 14.4 KB/s.
3581*d4514f0bSApple OSS Distributions 	// We align this buffer to KB16 to allow the lower bits to be used for a fd.
3582*d4514f0bSApple OSS Distributions 	void *output;
3583*d4514f0bSApple OSS Distributions 	int alloc_failed = posix_memalign(&output, KB16, SYSCTL_OUTPUT_BUFFER_SIZE);
3584*d4514f0bSApple OSS Distributions 	assert(alloc_failed == 0);
3585*d4514f0bSApple OSS Distributions 
3586*d4514f0bSApple OSS Distributions 	memset(output, 0, SYSCTL_OUTPUT_BUFFER_SIZE);
3587*d4514f0bSApple OSS Distributions 
3588*d4514f0bSApple OSS Distributions 	int fd = get_fd();
3589*d4514f0bSApple OSS Distributions 	assert((fd & ((int)KB16 - 1)) == fd);
3590*d4514f0bSApple OSS Distributions 	if (generate_golden) {
3591*d4514f0bSApple OSS Distributions 		// pass flag on the msb of the fd
3592*d4514f0bSApple OSS Distributions 		assert((fd & ((int)(KB16 >> 1) - 1)) == fd);
3593*d4514f0bSApple OSS Distributions 		fd |=  KB16 >> 1;
3594*d4514f0bSApple OSS Distributions 	}
3595*d4514f0bSApple OSS Distributions 	int64_t result = run_sysctl_test("vm_parameter_validation_kern", (int64_t)output + fd);
3596*d4514f0bSApple OSS Distributions 
3597*d4514f0bSApple OSS Distributions 	T_QUIET; T_EXPECT_EQ(1ull, result, "vm_parameter_validation_kern");
3598*d4514f0bSApple OSS Distributions 
3599*d4514f0bSApple OSS Distributions 	if (generate_golden) {
3600*d4514f0bSApple OSS Distributions 		if (!out_bad_param_in_kern_golden_results(output) || (dump && !should_test_results)) {
3601*d4514f0bSApple OSS Distributions 			// Print after verified there is not OUT_PARAM_BAD results before printing,
3602*d4514f0bSApple OSS Distributions 			// or user explicitly set DUMP_RESULTS=1 GENERATE_GOLDEN_IMAGE=1
3603*d4514f0bSApple OSS Distributions 			printf("%s", output);
3604*d4514f0bSApple OSS Distributions 		}
3605*d4514f0bSApple OSS Distributions 		free(output);
3606*d4514f0bSApple OSS Distributions 		output = NULL;
3607*d4514f0bSApple OSS Distributions 	} else {
3608*d4514f0bSApple OSS Distributions 		// recreate a results_t to compare against the golden file results
3609*d4514f0bSApple OSS Distributions 		if (populate_kernel_results(output)) {
3610*d4514f0bSApple OSS Distributions 			T_FAIL("Error while parsing results\n");
3611*d4514f0bSApple OSS Distributions 		}
3612*d4514f0bSApple OSS Distributions 		free(output);
3613*d4514f0bSApple OSS Distributions 		output = NULL;
3614*d4514f0bSApple OSS Distributions 
3615*d4514f0bSApple OSS Distributions 		if (should_test_results && populate_golden_results(KERN_GOLDEN_FILE)) {
3616*d4514f0bSApple OSS Distributions 			// couldn't load golden test results
3617*d4514f0bSApple OSS Distributions 			T_FAIL("Could not load golden file '%s'\n", KERN_GOLDEN_FILE);
3618*d4514f0bSApple OSS Distributions 			clean_kernel_results();
3619*d4514f0bSApple OSS Distributions 			goto out;
3620*d4514f0bSApple OSS Distributions 		}
3621*d4514f0bSApple OSS Distributions 
3622*d4514f0bSApple OSS Distributions 		// compare results against values from golden list
3623*d4514f0bSApple OSS Distributions 		for (uint32_t x = 0; x < num_kern_tests; ++x) {
3624*d4514f0bSApple OSS Distributions 			process_results(kern_list[x]);
3625*d4514f0bSApple OSS Distributions 			dealloc_results(kern_list[x]);
3626*d4514f0bSApple OSS Distributions 			kern_list[x] = NULL;
3627*d4514f0bSApple OSS Distributions 		}
3628*d4514f0bSApple OSS Distributions 		clean_golden_results();
3629*d4514f0bSApple OSS Distributions 	}
3630*d4514f0bSApple OSS Distributions 
3631*d4514f0bSApple OSS Distributions out:
3632*d4514f0bSApple OSS Distributions 	restore_exc_guard();
3633*d4514f0bSApple OSS Distributions 
3634*d4514f0bSApple OSS Distributions 	if (reenable_vm_sanitize_telemetry() != 0) {
3635*d4514f0bSApple OSS Distributions 		T_FAIL("Failed to reenable VM API telemetry.");
3636*d4514f0bSApple OSS Distributions 		return;
3637*d4514f0bSApple OSS Distributions 	}
3638*d4514f0bSApple OSS Distributions 
3639*d4514f0bSApple OSS Distributions 	T_PASS("vm parameter validation kern");
3640*d4514f0bSApple OSS Distributions }
3641