18 const long configured_page_size = sysconf(_SC_PAGESIZE);
19 if (configured_page_size <= 0)
21 const size_t page_size = (size_t)configured_page_size;
23 printf(
"Testing mmap(2) placement semantics...\n");
24 unsigned char* original =
25 mmap(0, page_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0);
26 if (original == MAP_FAILED)
31 void* no_replace = mmap(original, page_size, PROT_READ | PROT_WRITE,
32 MAP_PRIVATE | MAP_ANON | MAP_FIXED_NOREPLACE, -1, 0);
33 if (no_replace != MAP_FAILED || errno != EEXIST || *original != 0x5A)
37 if (munmap(original, SIZE_MAX) != -1 || errno != EINVAL || *original != 0x5A)
40 const size_t replacement_size = page_size * 3;
41 void* replacement = mmap(original, replacement_size, PROT_READ | PROT_WRITE,
42 MAP_PRIVATE | MAP_ANON | MAP_FIXED, -1, 0);
43 if (replacement != original || *original != 0)
47 void* follower = mmap(0, page_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0);
48 if (follower == MAP_FAILED || ((uintptr_t)follower >= (uintptr_t)original &&
49 (uintptr_t)follower < (uintptr_t)original + replacement_size))
53 mmap(original + 17, page_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0);
54 if (hinted == MAP_FAILED || hinted == original || ((uintptr_t)hinted & (page_size - 1)) ||
58 if (munmap(hinted, page_size) || munmap(follower, page_size) ||
59 munmap(replacement, replacement_size))
62 void* reclaimed = mmap(replacement, replacement_size, PROT_READ | PROT_WRITE,
63 MAP_PRIVATE | MAP_ANON | MAP_FIXED_NOREPLACE, -1, 0);
64 if (reclaimed != replacement || munmap(reclaimed, replacement_size))
67 unsigned char* split =
68 mmap(0, replacement_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0);
69 if (split == MAP_FAILED || munmap(split + page_size, page_size))
72 void* middle = mmap(split + page_size, page_size, PROT_READ | PROT_WRITE,
73 MAP_PRIVATE | MAP_ANON | MAP_FIXED_NOREPLACE, -1, 0);
74 if (middle != split + page_size)
78 void* prefix = mmap(split, page_size, PROT_READ | PROT_WRITE,
79 MAP_PRIVATE | MAP_ANON | MAP_FIXED_NOREPLACE, -1, 0);
80 if (prefix != MAP_FAILED || errno != EEXIST || munmap(split, replacement_size))
83 void* split_reclaimed = mmap(split, replacement_size, PROT_READ | PROT_WRITE,
84 MAP_PRIVATE | MAP_ANON | MAP_FIXED_NOREPLACE, -1, 0);
85 if (split_reclaimed != split || munmap(split_reclaimed, replacement_size))
87 printf(
"mmap(2) placement semantics were successful!\n");