linux: Add MMAP_ABOVE4G from Linux 6.6 to sys/mman.h
[glibc.git] / misc / tst-syscalls.c
blob493091ccd44e7722c0d8ec7adfdce6934a46f186
1 /* Test for syscall interfaces.
2 Copyright (C) 2020-2023 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
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.
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.
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/>. */
19 /* This test verifies that the x32 system call handling zero-extends
20 unsigned 32-bit arguments to the 64-bit argument registers for
21 system calls (bug 25810). The bug is specific to x32, but the test
22 should pass on all architectures. */
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <fcntl.h>
27 #include <sys/mman.h>
28 #include <support/check.h>
29 #include <support/xunistd.h>
31 /* On x32, this can be passed in a single 64-bit integer register. */
32 struct Array
34 size_t length;
35 void *ptr;
38 static int error_count;
40 __attribute__ ((noclone, noinline))
41 struct Array
42 allocate (size_t bytes)
44 if (!bytes)
45 return __extension__ (struct Array) {0, 0};
47 void *p = mmap (0x0, bytes, PROT_READ | PROT_WRITE,
48 MAP_PRIVATE | MAP_ANON, -1, 0);
49 if (p == MAP_FAILED)
50 return __extension__ (struct Array) {0, 0};
52 return __extension__ (struct Array) {bytes, p};
55 __attribute__ ((noclone, noinline))
56 void
57 deallocate (struct Array b)
59 /* On x32, the 64-bit integer register containing `b' may be copied
60 to another 64-bit integer register to pass the second argument to
61 munmap. */
62 if (b.length && munmap (b.ptr, b.length))
64 printf ("munmap error: %m\n");
65 error_count++;
69 __attribute__ ((noclone, noinline))
70 void *
71 do_mmap (void *addr, size_t length)
73 return mmap (addr, length, PROT_READ | PROT_WRITE,
74 MAP_PRIVATE | MAP_ANON, -1, 0);
77 __attribute__ ((noclone, noinline))
78 void *
79 reallocate (struct Array b)
81 /* On x32, the 64-bit integer register containing `b' may be copied
82 to another 64-bit integer register to pass the second argument to
83 do_mmap. */
84 if (b.length)
85 return do_mmap (b.ptr, b.length);
86 return NULL;
89 __attribute__ ((noclone, noinline))
90 void
91 protect (struct Array b)
93 if (b.length)
95 /* On x32, the 64-bit integer register containing `b' may be copied
96 to another 64-bit integer register to pass the second argument
97 to mprotect. */
98 if (mprotect (b.ptr, b.length,
99 PROT_READ | PROT_WRITE | PROT_EXEC))
101 printf ("mprotect error: %m\n");
102 error_count++;
107 __attribute__ ((noclone, noinline))
108 ssize_t
109 do_read (int fd, void *ptr, struct Array b)
111 /* On x32, the 64-bit integer register containing `b' may be copied
112 to another 64-bit integer register to pass the second argument to
113 read. */
114 if (b.length)
115 return read (fd, ptr, b.length);
116 return 0;
119 __attribute__ ((noclone, noinline))
120 ssize_t
121 do_write (int fd, void *ptr, struct Array b)
123 /* On x32, the 64-bit integer register containing `b' may be copied
124 to another 64-bit integer register to pass the second argument to
125 write. */
126 if (b.length)
127 return write (fd, ptr, b.length);
128 return 0;
131 static int
132 do_test (void)
134 struct Array array;
136 array = allocate (1);
137 protect (array);
138 deallocate (array);
139 void *p = reallocate (array);
140 if (p == MAP_FAILED)
142 printf ("mmap error: %m\n");
143 error_count++;
145 array.ptr = p;
146 protect (array);
147 deallocate (array);
149 int fd = xopen ("/dev/null", O_RDWR, 0);
150 char buf[2];
151 array.ptr = buf;
152 if (do_read (fd, array.ptr, array) == -1)
154 printf ("read error: %m\n");
155 error_count++;
157 if (do_write (fd, array.ptr, array) == -1)
159 printf ("write error: %m\n");
160 error_count++;
162 xclose (fd);
164 return error_count ? EXIT_FAILURE : EXIT_SUCCESS;
167 #include <support/test-driver.c>