1 /*
2 * Copyright (c) 2024 Apple Inc. All rights reserved.
3 *
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
14 *
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
17 *
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
25 *
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27 */
28
29 /*
30 * vm/configurator_vm_allocate.c
31 *
32 * Test vm_allocate(FIXED and FIXED|OVERWRITE) with many different VM states.
33 */
34
35 #include "configurator/vm_configurator_tests.h"
36 #include "configurator/vm_configurator_helpers.h"
37 #include "exc_guard_helper.h"
38 #include <sys/mman.h>
39
40 T_GLOBAL_META(
41 T_META_NAMESPACE("xnu.vm.configurator"),
42 T_META_RADAR_COMPONENT_NAME("xnu"),
43 T_META_RADAR_COMPONENT_VERSION("VM"),
44 T_META_RUN_CONCURRENTLY(true),
45 T_META_ASROOT(true), /* required for vm submap sysctls */
46 T_META_ALL_VALID_ARCHS(true)
47 );
48
49 /*
50 * rdar://143341561 mmap(FIXED) overwrite sometimes provokes EXC_GUARD
51 * Remove this when that bug is fixed.
52 *
53 * normal workaround: run mmap(FIXED) with the EXC_GUARD catcher in place
54 * when the test is expected to hit rdar://143341561
55 * Rosetta workaround: EXC_GUARD catcher doesn't work on Rosetta, so don't run
56 * mmap(FIXED) when the test is expected to hit rdar://143341561
57 */
58 #define workaround_rdar_143341561 1
59
60 static void
checker_perform_successful_mmap_anon(checker_list_t * checker_list,mach_vm_address_t start,mach_vm_size_t size,uint16_t user_tag)61 checker_perform_successful_mmap_anon(
62 checker_list_t *checker_list,
63 mach_vm_address_t start,
64 mach_vm_size_t size,
65 uint16_t user_tag)
66 {
67 /* Make a new checker for the allocation. */
68 vm_entry_checker_t *new_checker = make_checker_for_vm_allocate(
69 checker_list, start, size, VM_MAKE_TAG(user_tag));
70 entry_checker_range_t new_range = { new_checker, new_checker };
71
72 /* Find existing checkers in the address range. */
73 entry_checker_range_t old_range =
74 checker_list_find_and_clip_including_holes(checker_list, start, size);
75
76 /* Free the old checkers and insert the new checker. */
77 checker_list_replace_range(checker_list, old_range, new_range);
78 }
79
80 static test_result_t
successful_mmap_anon_fixed(checker_list_t * checker_list,mach_vm_address_t start,mach_vm_size_t size)81 successful_mmap_anon_fixed(
82 checker_list_t *checker_list,
83 mach_vm_address_t start,
84 mach_vm_size_t size)
85 {
86 void *ret = mmap((void *)start, size, PROT_READ | PROT_WRITE,
87 MAP_PRIVATE | MAP_ANON | MAP_FIXED, -1, 0);
88 mach_vm_address_t allocated = (mach_vm_address_t)ret;
89 if (ret == MAP_FAILED) {
90 T_EXPECT_POSIX_SUCCESS(ret, "mmap(ANON | FIXED)");
91 return TestFailed;
92 }
93 if (allocated != start) {
94 T_FAIL("mmap(ANON | FIXED) returned address 0x%llx (expected 0x%llx)", allocated, start);
95 return TestFailed;
96 }
97 checker_perform_successful_mmap_anon(checker_list, start, size, 0);
98
99 return verify_vm_state(checker_list, "after mmap(ANON | FIXED)");
100 }
101
102
103 static test_result_t
successful_mmap_anon_fixed_with_tag(checker_list_t * checker_list,mach_vm_address_t start,mach_vm_size_t size,uint16_t tag)104 successful_mmap_anon_fixed_with_tag(
105 checker_list_t *checker_list,
106 mach_vm_address_t start,
107 mach_vm_size_t size,
108 uint16_t tag)
109 {
110 void *ret = mmap((void *)start, size, PROT_READ | PROT_WRITE,
111 MAP_PRIVATE | MAP_ANON | MAP_FIXED, VM_MAKE_TAG(tag), 0);
112 mach_vm_address_t allocated = (mach_vm_address_t)ret;
113 if (ret == MAP_FAILED) {
114 T_EXPECT_POSIX_SUCCESS(ret, "mmap(ANON | FIXED, tag)");
115 return TestFailed;
116 }
117 if (allocated != start) {
118 T_FAIL("mmap(ANON | FIXED, tag) returned address 0x%llx (expected 0x%llx)", allocated, start);
119 return TestFailed;
120 }
121 checker_perform_successful_mmap_anon(checker_list, start, size, tag);
122
123 return verify_vm_state(checker_list, "after mmap(ANON | FIXED, tag)");
124 }
125
126 static test_result_t
successful_mmap_anon_fixed_with_neighbor_tags(checker_list_t * checker_list,mach_vm_address_t start,mach_vm_size_t size)127 successful_mmap_anon_fixed_with_neighbor_tags(
128 checker_list_t *checker_list,
129 mach_vm_address_t start,
130 mach_vm_size_t size)
131 {
132 uint16_t tag;
133
134 /*
135 * Allocate with a tag matching the entry to the left,
136 * to probe simplify behavior.
137 */
138 tag = get_app_specific_user_tag_for_address(start - 1);
139 if (TestFailed == successful_mmap_anon_fixed_with_tag(
140 checker_list, start, size, tag)) {
141 return TestFailed;
142 }
143
144 /*
145 * Allocate again, with a tag matching the entry to the right,
146 * to probe simplify behavior.
147 */
148 tag = get_app_specific_user_tag_for_address(start + size);
149 if (TestFailed == successful_mmap_anon_fixed_with_tag(
150 checker_list, start, size, tag)) {
151 return TestFailed;
152 }
153
154 return TestSucceeded;
155 }
156
157 static bool
call_mmap_anon_fixed_and_expect_ENOMEM(mach_vm_address_t start,mach_vm_size_t size,uint16_t tag)158 call_mmap_anon_fixed_and_expect_ENOMEM(
159 mach_vm_address_t start,
160 mach_vm_size_t size,
161 uint16_t tag)
162 {
163 #if workaround_rdar_143341561
164 __block void *ret;
165 exc_guard_helper_info_t exc_info;
166 bool caught_exception =
167 block_raised_exc_guard_of_type(GUARD_TYPE_VIRT_MEMORY, &exc_info, ^{
168 ret = mmap((void *)start, size, PROT_READ | PROT_WRITE,
169 MAP_PRIVATE | MAP_ANON | MAP_FIXED, VM_MAKE_TAG(tag), 0);
170 });
171 if (caught_exception) {
172 T_LOG("warning: rdar://143341561 mmap(fixed) should work "
173 "regardless of whether a mapping exists at the addr");
174 }
175 #else /* not workaround_rdar_143341561 */
176 void *ret = mmap((void *)start, size, PROT_READ | PROT_WRITE,
177 MAP_PRIVATE | MAP_ANON | MAP_FIXED, VM_MAKE_TAG(tag), 0);
178 #endif /* not workaround_rdar_143341561 */
179
180 if (ret != MAP_FAILED) {
181 T_EXPECT_POSIX_ERROR(ret, ENOMEM, "mmap(ANON | FIXED, tag)");
182 return false;
183 }
184 return true;
185 }
186
187
188 static test_result_t
test_permanent_entry_fixed(checker_list_t * checker_list,mach_vm_address_t start,mach_vm_size_t size)189 test_permanent_entry_fixed(
190 checker_list_t *checker_list,
191 mach_vm_address_t start,
192 mach_vm_size_t size)
193 {
194 #if workaround_rdar_143341561
195 if (isRosetta()) {
196 T_LOG("warning: can't work around rdar://143341561 on Rosetta; just passing instead");
197 return TestSucceeded;
198 }
199 #endif
200
201 if (!call_mmap_anon_fixed_and_expect_ENOMEM(start, size, 0)) {
202 return TestFailed;
203 }
204
205 /* one permanent entry, it becomes inaccessible */
206 checker_perform_vm_deallocate_permanent(checker_list, start, size);
207
208 return verify_vm_state(checker_list, "after mmap(ANON | FIXED)");
209 }
210
211 static test_result_t
test_permanent_before_permanent_fixed(checker_list_t * checker_list,mach_vm_address_t start,mach_vm_size_t size)212 test_permanent_before_permanent_fixed(
213 checker_list_t *checker_list,
214 mach_vm_address_t start,
215 mach_vm_size_t size)
216 {
217 #if workaround_rdar_143341561
218 if (isRosetta()) {
219 T_LOG("warning: can't work around rdar://143341561 on Rosetta; just passing instead");
220 return TestSucceeded;
221 }
222 #endif
223
224 if (!call_mmap_anon_fixed_and_expect_ENOMEM(start, size, 0)) {
225 return TestFailed;
226 }
227
228 /* two permanent entries, both become inaccessible */
229 checker_perform_vm_deallocate_permanent(checker_list, start, size / 2);
230 checker_perform_vm_deallocate_permanent(checker_list, start + size / 2, size / 2);
231
232 return verify_vm_state(checker_list, "after mmap(ANON | FIXED)");
233 }
234
235 static test_result_t
test_permanent_before_allocation_fixed(checker_list_t * checker_list,mach_vm_address_t start,mach_vm_size_t size)236 test_permanent_before_allocation_fixed(
237 checker_list_t *checker_list,
238 mach_vm_address_t start,
239 mach_vm_size_t size)
240 {
241 #if workaround_rdar_143341561
242 if (isRosetta()) {
243 T_LOG("warning: can't work around rdar://143341561 on Rosetta; just passing instead");
244 return TestSucceeded;
245 }
246 #endif
247
248 if (!call_mmap_anon_fixed_and_expect_ENOMEM(start, size, 0)) {
249 return TestFailed;
250 }
251
252 /*
253 * one permanent entry, becomes inaccessible
254 * one nonpermanent allocation, unchanged
255 */
256 checker_perform_vm_deallocate_permanent(checker_list, start, size / 2);
257 /* [start + size/2, start + size) unchanged */
258
259 return verify_vm_state(checker_list, "after mmap(ANON | FIXED)");
260 }
261
262 static test_result_t
test_permanent_before_allocation_fixed_rdar144128567(checker_list_t * checker_list,mach_vm_address_t start,mach_vm_size_t size)263 test_permanent_before_allocation_fixed_rdar144128567(
264 checker_list_t *checker_list,
265 mach_vm_address_t start,
266 mach_vm_size_t size)
267 {
268 #if workaround_rdar_143341561
269 if (isRosetta()) {
270 T_LOG("warning: can't work around rdar://143341561 on Rosetta; just passing instead");
271 return TestSucceeded;
272 }
273 #endif
274
275 if (!call_mmap_anon_fixed_and_expect_ENOMEM(start, size, 0)) {
276 return TestFailed;
277 }
278
279 /*
280 * one permanent entry, becomes inaccessible
281 * one nonpermanent allocation, becomes deallocated (rdar://144128567)
282 */
283 checker_perform_vm_deallocate_permanent(checker_list, start, size / 2);
284 checker_perform_successful_vm_deallocate(checker_list, start + size / 2, size / 2);
285
286 return verify_vm_state(checker_list, "after mmap(ANON | FIXED)");
287 }
288
289 static test_result_t
test_permanent_before_hole_fixed(checker_list_t * checker_list,mach_vm_address_t start,mach_vm_size_t size)290 test_permanent_before_hole_fixed(
291 checker_list_t *checker_list,
292 mach_vm_address_t start,
293 mach_vm_size_t size)
294 {
295 #if workaround_rdar_143341561
296 if (isRosetta()) {
297 T_LOG("warning: can't work around rdar://143341561 on Rosetta; just passing instead");
298 return TestSucceeded;
299 }
300 #endif
301
302 if (!call_mmap_anon_fixed_and_expect_ENOMEM(start, size, 0)) {
303 return TestFailed;
304 }
305
306 /*
307 * one permanent entry, becomes inaccessible
308 * one hole, unchanged
309 */
310 checker_perform_vm_deallocate_permanent(checker_list, start, size / 2);
311 /* no change for addresses [start + size / 2, start + size) */
312
313 return verify_vm_state(checker_list, "after mmap(ANON | FIXED)");
314 }
315
316 static test_result_t
test_permanent_after_allocation_fixed(checker_list_t * checker_list,mach_vm_address_t start,mach_vm_size_t size)317 test_permanent_after_allocation_fixed(
318 checker_list_t *checker_list,
319 mach_vm_address_t start,
320 mach_vm_size_t size)
321 {
322 #if workaround_rdar_143341561
323 if (isRosetta()) {
324 T_LOG("warning: can't work around rdar://143341561 on Rosetta; just passing instead");
325 return TestSucceeded;
326 }
327 #endif
328
329 if (!call_mmap_anon_fixed_and_expect_ENOMEM(start, size, 0)) {
330 return TestFailed;
331 }
332
333 /*
334 * one nonpermanent allocation, becomes deallocated
335 * one permanent entry, becomes inaccessible
336 */
337 checker_perform_successful_vm_deallocate(checker_list, start, size / 2);
338 checker_perform_vm_deallocate_permanent(checker_list, start + size / 2, size / 2);
339
340 return verify_vm_state(checker_list, "after mmap(ANON | FIXED)");
341 }
342
343 static test_result_t
test_permanent_after_hole_fixed(checker_list_t * checker_list,mach_vm_address_t start,mach_vm_size_t size)344 test_permanent_after_hole_fixed(
345 checker_list_t *checker_list,
346 mach_vm_address_t start,
347 mach_vm_size_t size)
348 {
349 #if workaround_rdar_143341561
350 if (isRosetta()) {
351 T_LOG("warning: can't work around rdar://143341561 on Rosetta; just passing instead");
352 return TestSucceeded;
353 }
354 #endif
355
356 if (!call_mmap_anon_fixed_and_expect_ENOMEM(start, size, 0)) {
357 return TestFailed;
358 }
359
360 /*
361 * one hole, unchanged
362 * one permanent entry, becomes inaccessible
363 */
364 /* no change for addresses [start, start + size / 2) */
365 checker_perform_vm_deallocate_permanent(checker_list, start + size / 2, size / 2);
366
367 return verify_vm_state(checker_list, "after mmap(ANON | FIXED)");
368 }
369
370
371 static test_result_t
test_permanent_entry_fixed_with_neighbor_tags(checker_list_t * checker_list,mach_vm_address_t start,mach_vm_size_t size)372 test_permanent_entry_fixed_with_neighbor_tags(
373 checker_list_t *checker_list,
374 mach_vm_address_t start,
375 mach_vm_size_t size)
376 {
377 #if workaround_rdar_143341561
378 if (isRosetta()) {
379 T_LOG("warning: can't work around rdar://143341561 on Rosetta; just passing instead");
380 return TestSucceeded;
381 }
382 #endif
383
384 uint16_t tag;
385
386 /*
387 * Allocate with a tag matching the entry to the left,
388 */
389 tag = get_app_specific_user_tag_for_address(start - 1);
390 if (!call_mmap_anon_fixed_and_expect_ENOMEM(start, size, tag)) {
391 return TestFailed;
392 }
393
394 /* one permanent entry, it becomes inaccessible */
395 checker_perform_vm_deallocate_permanent(checker_list, start, size);
396
397 return verify_vm_state(checker_list, "after mmap(ANON | FIXED)");
398 }
399
400 static test_result_t
test_permanent_before_permanent_fixed_with_neighbor_tags(checker_list_t * checker_list,mach_vm_address_t start,mach_vm_size_t size)401 test_permanent_before_permanent_fixed_with_neighbor_tags(
402 checker_list_t *checker_list,
403 mach_vm_address_t start,
404 mach_vm_size_t size)
405 {
406 #if workaround_rdar_143341561
407 if (isRosetta()) {
408 T_LOG("warning: can't work around rdar://143341561 on Rosetta; just passing instead");
409 return TestSucceeded;
410 }
411 #endif
412
413 uint16_t tag;
414
415 /*
416 * Allocate with a tag matching the entry to the left,
417 */
418 tag = get_app_specific_user_tag_for_address(start - 1);
419 if (!call_mmap_anon_fixed_and_expect_ENOMEM(start, size, tag)) {
420 return TestFailed;
421 }
422
423 /* two permanent entries, both become inaccessible */
424 checker_perform_vm_deallocate_permanent(checker_list, start, size / 2);
425 checker_perform_vm_deallocate_permanent(checker_list, start + size / 2, size / 2);
426
427 return verify_vm_state(checker_list, "after mmap(ANON | FIXED)");
428 }
429
430 static test_result_t
test_permanent_before_allocation_fixed_with_neighbor_tags(checker_list_t * checker_list,mach_vm_address_t start,mach_vm_size_t size)431 test_permanent_before_allocation_fixed_with_neighbor_tags(
432 checker_list_t *checker_list,
433 mach_vm_address_t start,
434 mach_vm_size_t size)
435 {
436 #if workaround_rdar_143341561
437 if (isRosetta()) {
438 T_LOG("warning: can't work around rdar://143341561 on Rosetta; just passing instead");
439 return TestSucceeded;
440 }
441 #endif
442
443 uint16_t tag;
444
445 /*
446 * Allocate with a tag matching the entry to the left,
447 */
448 tag = get_app_specific_user_tag_for_address(start - 1);
449 if (!call_mmap_anon_fixed_and_expect_ENOMEM(start, size, tag)) {
450 return TestFailed;
451 }
452
453 /*
454 * one permanent entry, becomes inaccessible
455 * one nonpermanent allocation, unchanged
456 */
457 checker_perform_vm_deallocate_permanent(checker_list, start, size / 2);
458 /* [start + size/2, start + size) unchanged */
459
460 return verify_vm_state(checker_list, "after mmap(ANON | FIXED)");
461 }
462
463 static test_result_t
test_permanent_before_allocation_fixed_with_neighbor_tags_rdar144128567(checker_list_t * checker_list,mach_vm_address_t start,mach_vm_size_t size)464 test_permanent_before_allocation_fixed_with_neighbor_tags_rdar144128567(
465 checker_list_t *checker_list,
466 mach_vm_address_t start,
467 mach_vm_size_t size)
468 {
469 #if workaround_rdar_143341561
470 if (isRosetta()) {
471 T_LOG("warning: can't work around rdar://143341561 on Rosetta; just passing instead");
472 return TestSucceeded;
473 }
474 #endif
475
476 uint16_t tag;
477
478 /*
479 * Allocate with a tag matching the entry to the left,
480 */
481 tag = get_app_specific_user_tag_for_address(start - 1);
482 if (!call_mmap_anon_fixed_and_expect_ENOMEM(start, size, tag)) {
483 return TestFailed;
484 }
485
486 /*
487 * one permanent entry, becomes inaccessible
488 * one nonpermanent allocation, becomes deallocated (rdar://144128567)
489 */
490 checker_perform_vm_deallocate_permanent(checker_list, start, size / 2);
491 checker_perform_successful_vm_deallocate(checker_list, start + size / 2, size / 2);
492
493 return verify_vm_state(checker_list, "after mmap(ANON | FIXED)");
494 }
495
496 static test_result_t
test_permanent_before_hole_fixed_with_neighbor_tags(checker_list_t * checker_list,mach_vm_address_t start,mach_vm_size_t size)497 test_permanent_before_hole_fixed_with_neighbor_tags(
498 checker_list_t *checker_list,
499 mach_vm_address_t start,
500 mach_vm_size_t size)
501 {
502 #if workaround_rdar_143341561
503 if (isRosetta()) {
504 T_LOG("warning: can't work around rdar://143341561 on Rosetta; just passing instead");
505 return TestSucceeded;
506 }
507 #endif
508
509 uint16_t tag;
510
511 /*
512 * Allocate with a tag matching the entry to the left,
513 */
514 tag = get_app_specific_user_tag_for_address(start - 1);
515 if (!call_mmap_anon_fixed_and_expect_ENOMEM(start, size, tag)) {
516 return TestFailed;
517 }
518
519 /*
520 * one permanent entry, becomes inaccessible
521 * one hole, unchanged
522 */
523 checker_perform_vm_deallocate_permanent(checker_list, start, size / 2);
524 /* no change for addresses [start + size / 2, start + size) */
525
526 return verify_vm_state(checker_list, "after mmap(ANON | FIXED)");
527 }
528
529 static test_result_t
test_permanent_after_allocation_fixed_with_neighbor_tags(checker_list_t * checker_list,mach_vm_address_t start,mach_vm_size_t size)530 test_permanent_after_allocation_fixed_with_neighbor_tags(
531 checker_list_t *checker_list,
532 mach_vm_address_t start,
533 mach_vm_size_t size)
534 {
535 #if workaround_rdar_143341561
536 if (isRosetta()) {
537 T_LOG("warning: can't work around rdar://143341561 on Rosetta; just passing instead");
538 return TestSucceeded;
539 }
540 #endif
541
542 uint16_t tag;
543
544 /*
545 * Allocate with a tag matching the entry to the left,
546 */
547 tag = get_app_specific_user_tag_for_address(start - 1);
548 if (!call_mmap_anon_fixed_and_expect_ENOMEM(start, size, tag)) {
549 return TestFailed;
550 }
551
552 /*
553 * one nonpermanent allocation, becomes deallocated
554 * one permanent entry, becomes inaccessible
555 */
556 checker_perform_successful_vm_deallocate(checker_list, start, size / 2);
557 checker_perform_vm_deallocate_permanent(checker_list, start + size / 2, size / 2);
558
559 return verify_vm_state(checker_list, "after mmap(ANON | FIXED)");
560 }
561
562 static test_result_t
test_permanent_after_hole_fixed_with_neighbor_tags(checker_list_t * checker_list,mach_vm_address_t start,mach_vm_size_t size)563 test_permanent_after_hole_fixed_with_neighbor_tags(
564 checker_list_t *checker_list,
565 mach_vm_address_t start,
566 mach_vm_size_t size)
567 {
568 #if workaround_rdar_143341561
569 if (isRosetta()) {
570 T_LOG("warning: can't work around rdar://143341561 on Rosetta; just passing instead");
571 return TestSucceeded;
572 }
573 #endif
574
575 uint16_t tag;
576
577 /*
578 * Allocate with a tag matching the entry to the left,
579 */
580 tag = get_app_specific_user_tag_for_address(start - 1);
581 if (!call_mmap_anon_fixed_and_expect_ENOMEM(start, size, tag)) {
582 return TestFailed;
583 }
584
585 /*
586 * one hole, unchanged
587 * one permanent entry, becomes inaccessible
588 */
589 /* no change for addresses [start, start + size / 2) */
590 checker_perform_vm_deallocate_permanent(checker_list, start + size / 2, size / 2);
591
592 return verify_vm_state(checker_list, "after mmap(ANON | FIXED)");
593 }
594
595
596 T_DECL(mmap_anon_fixed,
597 "run mmap(ANON | FIXED) with various vm configurations")
598 {
599 #if workaround_rdar_143341561
600 enable_non_fatal_vm_exc_guard();
601 #endif
602
603 vm_tests_t tests = {
604 .single_entry_1 = successful_mmap_anon_fixed,
605 .single_entry_2 = successful_mmap_anon_fixed,
606 .single_entry_3 = successful_mmap_anon_fixed,
607 .single_entry_4 = successful_mmap_anon_fixed,
608
609 .multiple_entries_1 = successful_mmap_anon_fixed,
610 .multiple_entries_2 = successful_mmap_anon_fixed,
611 .multiple_entries_3 = successful_mmap_anon_fixed,
612 .multiple_entries_4 = successful_mmap_anon_fixed,
613 .multiple_entries_5 = successful_mmap_anon_fixed,
614 .multiple_entries_6 = successful_mmap_anon_fixed,
615
616 .some_holes_1 = successful_mmap_anon_fixed,
617 .some_holes_2 = successful_mmap_anon_fixed,
618 .some_holes_3 = successful_mmap_anon_fixed,
619 .some_holes_4 = successful_mmap_anon_fixed,
620 .some_holes_5 = successful_mmap_anon_fixed,
621 .some_holes_6 = successful_mmap_anon_fixed,
622 .some_holes_7 = successful_mmap_anon_fixed,
623 .some_holes_8 = successful_mmap_anon_fixed,
624 .some_holes_9 = successful_mmap_anon_fixed,
625 .some_holes_10 = successful_mmap_anon_fixed,
626 .some_holes_11 = successful_mmap_anon_fixed,
627 .some_holes_12 = successful_mmap_anon_fixed,
628
629 .all_holes_1 = successful_mmap_anon_fixed,
630 .all_holes_2 = successful_mmap_anon_fixed,
631 .all_holes_3 = successful_mmap_anon_fixed,
632 .all_holes_4 = successful_mmap_anon_fixed,
633
634 .null_entry = successful_mmap_anon_fixed,
635 .nonresident_entry = successful_mmap_anon_fixed,
636 .resident_entry = successful_mmap_anon_fixed,
637
638 .shared_entry = successful_mmap_anon_fixed,
639 .shared_entry_discontiguous = successful_mmap_anon_fixed,
640 .shared_entry_partial = successful_mmap_anon_fixed,
641 .shared_entry_pairs = successful_mmap_anon_fixed,
642 .shared_entry_x1000 = successful_mmap_anon_fixed,
643
644 .cow_entry = successful_mmap_anon_fixed,
645 .cow_unreferenced = successful_mmap_anon_fixed,
646 .cow_nocow = successful_mmap_anon_fixed,
647 .nocow_cow = successful_mmap_anon_fixed,
648 .cow_unreadable = successful_mmap_anon_fixed,
649 .cow_unwriteable = successful_mmap_anon_fixed,
650
651 .permanent_entry = test_permanent_entry_fixed,
652 .permanent_before_permanent = test_permanent_before_permanent_fixed,
653 .permanent_before_allocation = test_permanent_before_allocation_fixed,
654 .permanent_before_allocation_2 = test_permanent_before_allocation_fixed_rdar144128567,
655 .permanent_before_hole = test_permanent_before_hole_fixed,
656 .permanent_after_allocation = test_permanent_after_allocation_fixed,
657 .permanent_after_hole = test_permanent_after_hole_fixed,
658
659 .single_submap_single_entry = successful_mmap_anon_fixed,
660 .single_submap_single_entry_first_pages = successful_mmap_anon_fixed,
661 .single_submap_single_entry_last_pages = successful_mmap_anon_fixed,
662 .single_submap_single_entry_middle_pages = successful_mmap_anon_fixed,
663 .single_submap_oversize_entry_at_start = successful_mmap_anon_fixed,
664 .single_submap_oversize_entry_at_end = successful_mmap_anon_fixed,
665 .single_submap_oversize_entry_at_both = successful_mmap_anon_fixed,
666
667 .submap_before_allocation = successful_mmap_anon_fixed,
668 .submap_after_allocation = successful_mmap_anon_fixed,
669 .submap_before_hole = successful_mmap_anon_fixed,
670 .submap_after_hole = successful_mmap_anon_fixed,
671 .submap_allocation_submap_one_entry = successful_mmap_anon_fixed,
672 .submap_allocation_submap_two_entries = successful_mmap_anon_fixed,
673 .submap_allocation_submap_three_entries = successful_mmap_anon_fixed,
674
675 .submap_before_allocation_ro = successful_mmap_anon_fixed,
676 .submap_after_allocation_ro = successful_mmap_anon_fixed,
677 .submap_before_hole_ro = successful_mmap_anon_fixed,
678 .submap_after_hole_ro = successful_mmap_anon_fixed,
679 .submap_allocation_submap_one_entry_ro = successful_mmap_anon_fixed,
680 .submap_allocation_submap_two_entries_ro = successful_mmap_anon_fixed,
681 .submap_allocation_submap_three_entries_ro = successful_mmap_anon_fixed,
682
683 .protection_single_000_000 = successful_mmap_anon_fixed,
684 .protection_single_000_r00 = successful_mmap_anon_fixed,
685 .protection_single_000_0w0 = successful_mmap_anon_fixed,
686 .protection_single_000_rw0 = successful_mmap_anon_fixed,
687 .protection_single_r00_r00 = successful_mmap_anon_fixed,
688 .protection_single_r00_rw0 = successful_mmap_anon_fixed,
689 .protection_single_0w0_0w0 = successful_mmap_anon_fixed,
690 .protection_single_0w0_rw0 = successful_mmap_anon_fixed,
691 .protection_single_rw0_rw0 = successful_mmap_anon_fixed,
692
693 .protection_pairs_000_000 = successful_mmap_anon_fixed,
694 .protection_pairs_000_r00 = successful_mmap_anon_fixed,
695 .protection_pairs_000_0w0 = successful_mmap_anon_fixed,
696 .protection_pairs_000_rw0 = successful_mmap_anon_fixed,
697 .protection_pairs_r00_000 = successful_mmap_anon_fixed,
698 .protection_pairs_r00_r00 = successful_mmap_anon_fixed,
699 .protection_pairs_r00_0w0 = successful_mmap_anon_fixed,
700 .protection_pairs_r00_rw0 = successful_mmap_anon_fixed,
701 .protection_pairs_0w0_000 = successful_mmap_anon_fixed,
702 .protection_pairs_0w0_r00 = successful_mmap_anon_fixed,
703 .protection_pairs_0w0_0w0 = successful_mmap_anon_fixed,
704 .protection_pairs_0w0_rw0 = successful_mmap_anon_fixed,
705 .protection_pairs_rw0_000 = successful_mmap_anon_fixed,
706 .protection_pairs_rw0_r00 = successful_mmap_anon_fixed,
707 .protection_pairs_rw0_0w0 = successful_mmap_anon_fixed,
708 .protection_pairs_rw0_rw0 = successful_mmap_anon_fixed,
709 };
710
711 run_vm_tests("mmap_anon_fixed", __FILE__, &tests, argc, argv);
712 }
713
714
715 T_DECL(mmap_anon_fixed_with_neighbor_tags,
716 "run mmap(ANON | FIXED, tag) with various vm configurations "
717 "and tags copied from neighboring entries")
718 {
719 #if workaround_rdar_143341561
720 enable_non_fatal_vm_exc_guard();
721 #endif
722
723 vm_tests_t tests = {
724 .single_entry_1 = successful_mmap_anon_fixed_with_neighbor_tags,
725 .single_entry_2 = successful_mmap_anon_fixed_with_neighbor_tags,
726 .single_entry_3 = successful_mmap_anon_fixed_with_neighbor_tags,
727 .single_entry_4 = successful_mmap_anon_fixed_with_neighbor_tags,
728
729 .multiple_entries_1 = successful_mmap_anon_fixed_with_neighbor_tags,
730 .multiple_entries_2 = successful_mmap_anon_fixed_with_neighbor_tags,
731 .multiple_entries_3 = successful_mmap_anon_fixed_with_neighbor_tags,
732 .multiple_entries_4 = successful_mmap_anon_fixed_with_neighbor_tags,
733 .multiple_entries_5 = successful_mmap_anon_fixed_with_neighbor_tags,
734 .multiple_entries_6 = successful_mmap_anon_fixed_with_neighbor_tags,
735
736 .some_holes_1 = successful_mmap_anon_fixed_with_neighbor_tags,
737 .some_holes_2 = successful_mmap_anon_fixed_with_neighbor_tags,
738 .some_holes_3 = successful_mmap_anon_fixed_with_neighbor_tags,
739 .some_holes_4 = successful_mmap_anon_fixed_with_neighbor_tags,
740 .some_holes_5 = successful_mmap_anon_fixed_with_neighbor_tags,
741 .some_holes_6 = successful_mmap_anon_fixed_with_neighbor_tags,
742 .some_holes_7 = successful_mmap_anon_fixed_with_neighbor_tags,
743 .some_holes_8 = successful_mmap_anon_fixed_with_neighbor_tags,
744 .some_holes_9 = successful_mmap_anon_fixed_with_neighbor_tags,
745 .some_holes_10 = successful_mmap_anon_fixed_with_neighbor_tags,
746 .some_holes_11 = successful_mmap_anon_fixed_with_neighbor_tags,
747 .some_holes_12 = successful_mmap_anon_fixed_with_neighbor_tags,
748
749 .all_holes_1 = successful_mmap_anon_fixed_with_neighbor_tags,
750 .all_holes_2 = successful_mmap_anon_fixed_with_neighbor_tags,
751 .all_holes_3 = successful_mmap_anon_fixed_with_neighbor_tags,
752 .all_holes_4 = successful_mmap_anon_fixed_with_neighbor_tags,
753
754 .null_entry = successful_mmap_anon_fixed_with_neighbor_tags,
755 .nonresident_entry = successful_mmap_anon_fixed_with_neighbor_tags,
756 .resident_entry = successful_mmap_anon_fixed_with_neighbor_tags,
757
758 .shared_entry = successful_mmap_anon_fixed_with_neighbor_tags,
759 .shared_entry_discontiguous = successful_mmap_anon_fixed_with_neighbor_tags,
760 .shared_entry_partial = successful_mmap_anon_fixed_with_neighbor_tags,
761 .shared_entry_pairs = successful_mmap_anon_fixed_with_neighbor_tags,
762 .shared_entry_x1000 = successful_mmap_anon_fixed_with_neighbor_tags,
763
764 .cow_entry = successful_mmap_anon_fixed_with_neighbor_tags,
765 .cow_unreferenced = successful_mmap_anon_fixed_with_neighbor_tags,
766 .cow_nocow = successful_mmap_anon_fixed_with_neighbor_tags,
767 .nocow_cow = successful_mmap_anon_fixed_with_neighbor_tags,
768 .cow_unreadable = successful_mmap_anon_fixed_with_neighbor_tags,
769 .cow_unwriteable = successful_mmap_anon_fixed_with_neighbor_tags,
770
771 .permanent_entry = test_permanent_entry_fixed_with_neighbor_tags,
772 .permanent_before_permanent = test_permanent_before_permanent_fixed_with_neighbor_tags,
773 .permanent_before_allocation = test_permanent_before_allocation_fixed_with_neighbor_tags,
774 .permanent_before_allocation_2 = test_permanent_before_allocation_fixed_with_neighbor_tags_rdar144128567,
775 .permanent_before_hole = test_permanent_before_hole_fixed_with_neighbor_tags,
776 .permanent_after_allocation = test_permanent_after_allocation_fixed_with_neighbor_tags,
777 .permanent_after_hole = test_permanent_after_hole_fixed_with_neighbor_tags,
778
779 .single_submap_single_entry = successful_mmap_anon_fixed_with_neighbor_tags,
780 .single_submap_single_entry_first_pages = successful_mmap_anon_fixed_with_neighbor_tags,
781 .single_submap_single_entry_last_pages = successful_mmap_anon_fixed_with_neighbor_tags,
782 .single_submap_single_entry_middle_pages = successful_mmap_anon_fixed_with_neighbor_tags,
783 .single_submap_oversize_entry_at_start = successful_mmap_anon_fixed_with_neighbor_tags,
784 .single_submap_oversize_entry_at_end = successful_mmap_anon_fixed_with_neighbor_tags,
785 .single_submap_oversize_entry_at_both = successful_mmap_anon_fixed_with_neighbor_tags,
786
787 .submap_before_allocation = successful_mmap_anon_fixed_with_neighbor_tags,
788 .submap_after_allocation = successful_mmap_anon_fixed_with_neighbor_tags,
789 .submap_before_hole = successful_mmap_anon_fixed_with_neighbor_tags,
790 .submap_after_hole = successful_mmap_anon_fixed_with_neighbor_tags,
791 .submap_allocation_submap_one_entry = successful_mmap_anon_fixed_with_neighbor_tags,
792 .submap_allocation_submap_two_entries = successful_mmap_anon_fixed_with_neighbor_tags,
793 .submap_allocation_submap_three_entries = successful_mmap_anon_fixed_with_neighbor_tags,
794
795 .submap_before_allocation_ro = successful_mmap_anon_fixed_with_neighbor_tags,
796 .submap_after_allocation_ro = successful_mmap_anon_fixed_with_neighbor_tags,
797 .submap_before_hole_ro = successful_mmap_anon_fixed_with_neighbor_tags,
798 .submap_after_hole_ro = successful_mmap_anon_fixed_with_neighbor_tags,
799 .submap_allocation_submap_one_entry_ro = successful_mmap_anon_fixed_with_neighbor_tags,
800 .submap_allocation_submap_two_entries_ro = successful_mmap_anon_fixed_with_neighbor_tags,
801 .submap_allocation_submap_three_entries_ro = successful_mmap_anon_fixed_with_neighbor_tags,
802
803 .protection_single_000_000 = successful_mmap_anon_fixed_with_neighbor_tags,
804 .protection_single_000_r00 = successful_mmap_anon_fixed_with_neighbor_tags,
805 .protection_single_000_0w0 = successful_mmap_anon_fixed_with_neighbor_tags,
806 .protection_single_000_rw0 = successful_mmap_anon_fixed_with_neighbor_tags,
807 .protection_single_r00_r00 = successful_mmap_anon_fixed_with_neighbor_tags,
808 .protection_single_r00_rw0 = successful_mmap_anon_fixed_with_neighbor_tags,
809 .protection_single_0w0_0w0 = successful_mmap_anon_fixed_with_neighbor_tags,
810 .protection_single_0w0_rw0 = successful_mmap_anon_fixed_with_neighbor_tags,
811 .protection_single_rw0_rw0 = successful_mmap_anon_fixed_with_neighbor_tags,
812
813 .protection_pairs_000_000 = successful_mmap_anon_fixed_with_neighbor_tags,
814 .protection_pairs_000_r00 = successful_mmap_anon_fixed_with_neighbor_tags,
815 .protection_pairs_000_0w0 = successful_mmap_anon_fixed_with_neighbor_tags,
816 .protection_pairs_000_rw0 = successful_mmap_anon_fixed_with_neighbor_tags,
817 .protection_pairs_r00_000 = successful_mmap_anon_fixed_with_neighbor_tags,
818 .protection_pairs_r00_r00 = successful_mmap_anon_fixed_with_neighbor_tags,
819 .protection_pairs_r00_0w0 = successful_mmap_anon_fixed_with_neighbor_tags,
820 .protection_pairs_r00_rw0 = successful_mmap_anon_fixed_with_neighbor_tags,
821 .protection_pairs_0w0_000 = successful_mmap_anon_fixed_with_neighbor_tags,
822 .protection_pairs_0w0_r00 = successful_mmap_anon_fixed_with_neighbor_tags,
823 .protection_pairs_0w0_0w0 = successful_mmap_anon_fixed_with_neighbor_tags,
824 .protection_pairs_0w0_rw0 = successful_mmap_anon_fixed_with_neighbor_tags,
825 .protection_pairs_rw0_000 = successful_mmap_anon_fixed_with_neighbor_tags,
826 .protection_pairs_rw0_r00 = successful_mmap_anon_fixed_with_neighbor_tags,
827 .protection_pairs_rw0_0w0 = successful_mmap_anon_fixed_with_neighbor_tags,
828 .protection_pairs_rw0_rw0 = successful_mmap_anon_fixed_with_neighbor_tags,
829 };
830
831 run_vm_tests("mmap_anon_fixed_with_neighbor_tags", __FILE__, &tests, argc, argv);
832 }
833