1 /* Memory allocation next to an unmapped page.
2 Copyright (C) 2017-2022 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
4
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
9
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, see
17 <https://www.gnu.org/licenses/>. */
18
19 #include <support/check.h>
20 #include <support/next_to_fault.h>
21 #include <support/xunistd.h>
22 #include <sys/mman.h>
23 #include <sys/param.h>
24
25 struct support_next_to_fault
support_next_to_fault_allocate(size_t size)26 support_next_to_fault_allocate (size_t size)
27 {
28 long page_size = sysconf (_SC_PAGE_SIZE);
29 TEST_VERIFY_EXIT (page_size > 0);
30 struct support_next_to_fault result;
31 result.region_size = roundup (size, page_size) + page_size;
32 if (size + page_size <= size || result.region_size <= size)
33 FAIL_EXIT1 ("support_next_to_fault_allocate (%zu): overflow", size);
34 result.region_start
35 = xmmap (NULL, result.region_size, PROT_READ | PROT_WRITE,
36 MAP_PRIVATE | MAP_ANONYMOUS, -1);
37 /* Unmap the page after the allocation. */
38 xmprotect (result.region_start + (result.region_size - page_size),
39 page_size, PROT_NONE);
40 /* Align the allocation within the region so that it ends just
41 before the PROT_NONE page. */
42 result.buffer = result.region_start + result.region_size - page_size - size;
43 result.length = size;
44 return result;
45 }
46
47 void
support_next_to_fault_free(struct support_next_to_fault * ntf)48 support_next_to_fault_free (struct support_next_to_fault *ntf)
49 {
50 xmunmap (ntf->region_start, ntf->region_size);
51 *ntf = (struct support_next_to_fault) { NULL, };
52 }
53