root / tests / test-mmap.c @ d8bcbabf
History | View | Annotate | Download (12.4 kB)
1 | e1ffb0f1 | edgar_igl | /*
|
---|---|---|---|
2 | e1ffb0f1 | edgar_igl | * Small test program to verify simulated mmap behaviour.
|
3 | e1ffb0f1 | edgar_igl | *
|
4 | e1ffb0f1 | edgar_igl | * When running qemu-linux-user with the -p flag, you may need to tell
|
5 | e1ffb0f1 | edgar_igl | * this test program about the pagesize because getpagesize() will not reflect
|
6 | e1ffb0f1 | edgar_igl | * the -p choice. Simply pass one argument beeing the pagesize.
|
7 | e1ffb0f1 | edgar_igl | *
|
8 | e1ffb0f1 | edgar_igl | * Copyright (c) 2007 AXIS Communications AB
|
9 | e1ffb0f1 | edgar_igl | * Written by Edgar E. Iglesias.
|
10 | e1ffb0f1 | edgar_igl | *
|
11 | e1ffb0f1 | edgar_igl | * This program is free software; you can redistribute it and/or modify
|
12 | e1ffb0f1 | edgar_igl | * it under the terms of the GNU General Public License as published by
|
13 | e1ffb0f1 | edgar_igl | * the Free Software Foundation; either version 2 of the License, or
|
14 | e1ffb0f1 | edgar_igl | * (at your option) any later version.
|
15 | e1ffb0f1 | edgar_igl | *
|
16 | e1ffb0f1 | edgar_igl | * This program is distributed in the hope that it will be useful,
|
17 | e1ffb0f1 | edgar_igl | * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
18 | e1ffb0f1 | edgar_igl | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
19 | e1ffb0f1 | edgar_igl | * GNU General Public License for more details.
|
20 | e1ffb0f1 | edgar_igl | *
|
21 | e1ffb0f1 | edgar_igl | * You should have received a copy of the GNU General Public License
|
22 | 8167ee88 | Blue Swirl | * along with this program; if not, see <http://www.gnu.org/licenses/>.
|
23 | e1ffb0f1 | edgar_igl | */
|
24 | e1ffb0f1 | edgar_igl | |
25 | e1ffb0f1 | edgar_igl | #include <stdio.h> |
26 | e1ffb0f1 | edgar_igl | #include <stdlib.h> |
27 | e1ffb0f1 | edgar_igl | #include <stdint.h> |
28 | e1ffb0f1 | edgar_igl | #include <string.h> |
29 | e1ffb0f1 | edgar_igl | #include <unistd.h> |
30 | e1ffb0f1 | edgar_igl | |
31 | e1ffb0f1 | edgar_igl | #include <sys/mman.h> |
32 | e1ffb0f1 | edgar_igl | |
33 | e1ffb0f1 | edgar_igl | #define D(x)
|
34 | e1ffb0f1 | edgar_igl | |
35 | e1ffb0f1 | edgar_igl | #define fail_unless(x) \
|
36 | e1ffb0f1 | edgar_igl | do \
|
37 | e1ffb0f1 | edgar_igl | { \ |
38 | e1ffb0f1 | edgar_igl | if (!(x)) { \
|
39 | e1ffb0f1 | edgar_igl | fprintf (stderr, "FAILED at %s:%d\n", __FILE__, __LINE__); \
|
40 | e1ffb0f1 | edgar_igl | exit (EXIT_FAILURE); \ |
41 | e1ffb0f1 | edgar_igl | } \ |
42 | e1ffb0f1 | edgar_igl | } while (0); |
43 | e1ffb0f1 | edgar_igl | |
44 | e1ffb0f1 | edgar_igl | unsigned char *dummybuf; |
45 | e1ffb0f1 | edgar_igl | static unsigned int pagesize; |
46 | e1ffb0f1 | edgar_igl | static unsigned int pagemask; |
47 | e1ffb0f1 | edgar_igl | int test_fd;
|
48 | e1ffb0f1 | edgar_igl | size_t test_fsize; |
49 | e1ffb0f1 | edgar_igl | |
50 | e1ffb0f1 | edgar_igl | void check_aligned_anonymous_unfixed_mmaps(void) |
51 | e1ffb0f1 | edgar_igl | { |
52 | e1ffb0f1 | edgar_igl | void *p1;
|
53 | e1ffb0f1 | edgar_igl | void *p2;
|
54 | e1ffb0f1 | edgar_igl | void *p3;
|
55 | e1ffb0f1 | edgar_igl | void *p4;
|
56 | e1ffb0f1 | edgar_igl | void *p5;
|
57 | e1ffb0f1 | edgar_igl | uintptr_t p; |
58 | e1ffb0f1 | edgar_igl | int i;
|
59 | e1ffb0f1 | edgar_igl | |
60 | e1ffb0f1 | edgar_igl | fprintf (stderr, "%s", __func__);
|
61 | e1ffb0f1 | edgar_igl | for (i = 0; i < 0x1fff; i++) |
62 | e1ffb0f1 | edgar_igl | { |
63 | e1ffb0f1 | edgar_igl | size_t len; |
64 | e1ffb0f1 | edgar_igl | |
65 | e1ffb0f1 | edgar_igl | len = pagesize + (pagesize * i & 7);
|
66 | e1ffb0f1 | edgar_igl | p1 = mmap(NULL, len, PROT_READ,
|
67 | e1ffb0f1 | edgar_igl | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); |
68 | e1ffb0f1 | edgar_igl | p2 = mmap(NULL, len, PROT_READ,
|
69 | e1ffb0f1 | edgar_igl | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); |
70 | e1ffb0f1 | edgar_igl | p3 = mmap(NULL, len, PROT_READ,
|
71 | e1ffb0f1 | edgar_igl | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); |
72 | e1ffb0f1 | edgar_igl | p4 = mmap(NULL, len, PROT_READ,
|
73 | e1ffb0f1 | edgar_igl | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); |
74 | e1ffb0f1 | edgar_igl | p5 = mmap(NULL, len, PROT_READ,
|
75 | e1ffb0f1 | edgar_igl | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); |
76 | e1ffb0f1 | edgar_igl | |
77 | e1ffb0f1 | edgar_igl | /* Make sure we get pages aligned with the pagesize. The
|
78 | e1ffb0f1 | edgar_igl | target expects this. */
|
79 | e1ffb0f1 | edgar_igl | fail_unless (p1 != MAP_FAILED); |
80 | e1ffb0f1 | edgar_igl | fail_unless (p2 != MAP_FAILED); |
81 | e1ffb0f1 | edgar_igl | fail_unless (p3 != MAP_FAILED); |
82 | e1ffb0f1 | edgar_igl | fail_unless (p4 != MAP_FAILED); |
83 | e1ffb0f1 | edgar_igl | fail_unless (p5 != MAP_FAILED); |
84 | e1ffb0f1 | edgar_igl | p = (uintptr_t) p1; |
85 | e1ffb0f1 | edgar_igl | D(printf ("p=%x\n", p));
|
86 | e1ffb0f1 | edgar_igl | fail_unless ((p & pagemask) == 0);
|
87 | e1ffb0f1 | edgar_igl | p = (uintptr_t) p2; |
88 | e1ffb0f1 | edgar_igl | fail_unless ((p & pagemask) == 0);
|
89 | e1ffb0f1 | edgar_igl | p = (uintptr_t) p3; |
90 | e1ffb0f1 | edgar_igl | fail_unless ((p & pagemask) == 0);
|
91 | e1ffb0f1 | edgar_igl | p = (uintptr_t) p4; |
92 | e1ffb0f1 | edgar_igl | fail_unless ((p & pagemask) == 0);
|
93 | e1ffb0f1 | edgar_igl | p = (uintptr_t) p5; |
94 | e1ffb0f1 | edgar_igl | fail_unless ((p & pagemask) == 0);
|
95 | e1ffb0f1 | edgar_igl | |
96 | e1ffb0f1 | edgar_igl | /* Make sure we can read from the entire area. */
|
97 | e1ffb0f1 | edgar_igl | memcpy (dummybuf, p1, pagesize); |
98 | e1ffb0f1 | edgar_igl | memcpy (dummybuf, p2, pagesize); |
99 | e1ffb0f1 | edgar_igl | memcpy (dummybuf, p3, pagesize); |
100 | e1ffb0f1 | edgar_igl | memcpy (dummybuf, p4, pagesize); |
101 | e1ffb0f1 | edgar_igl | memcpy (dummybuf, p5, pagesize); |
102 | e1ffb0f1 | edgar_igl | |
103 | e1ffb0f1 | edgar_igl | munmap (p1, len); |
104 | e1ffb0f1 | edgar_igl | munmap (p2, len); |
105 | e1ffb0f1 | edgar_igl | munmap (p3, len); |
106 | e1ffb0f1 | edgar_igl | munmap (p4, len); |
107 | e1ffb0f1 | edgar_igl | munmap (p5, len); |
108 | e1ffb0f1 | edgar_igl | } |
109 | e1ffb0f1 | edgar_igl | fprintf (stderr, " passed\n");
|
110 | e1ffb0f1 | edgar_igl | } |
111 | e1ffb0f1 | edgar_igl | |
112 | e1ffb0f1 | edgar_igl | void check_large_anonymous_unfixed_mmap(void) |
113 | e1ffb0f1 | edgar_igl | { |
114 | e1ffb0f1 | edgar_igl | void *p1;
|
115 | e1ffb0f1 | edgar_igl | uintptr_t p; |
116 | e1ffb0f1 | edgar_igl | size_t len; |
117 | e1ffb0f1 | edgar_igl | |
118 | e1ffb0f1 | edgar_igl | fprintf (stderr, "%s", __func__);
|
119 | e1ffb0f1 | edgar_igl | |
120 | e1ffb0f1 | edgar_igl | len = 0x02000000;
|
121 | e1ffb0f1 | edgar_igl | p1 = mmap(NULL, len, PROT_READ,
|
122 | e1ffb0f1 | edgar_igl | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); |
123 | e1ffb0f1 | edgar_igl | |
124 | e1ffb0f1 | edgar_igl | /* Make sure we get pages aligned with the pagesize. The
|
125 | e1ffb0f1 | edgar_igl | target expects this. */
|
126 | e1ffb0f1 | edgar_igl | fail_unless (p1 != MAP_FAILED); |
127 | e1ffb0f1 | edgar_igl | p = (uintptr_t) p1; |
128 | e1ffb0f1 | edgar_igl | fail_unless ((p & pagemask) == 0);
|
129 | e1ffb0f1 | edgar_igl | |
130 | e1ffb0f1 | edgar_igl | /* Make sure we can read from the entire area. */
|
131 | e1ffb0f1 | edgar_igl | memcpy (dummybuf, p1, pagesize); |
132 | e1ffb0f1 | edgar_igl | munmap (p1, len); |
133 | e1ffb0f1 | edgar_igl | fprintf (stderr, " passed\n");
|
134 | e1ffb0f1 | edgar_igl | } |
135 | e1ffb0f1 | edgar_igl | |
136 | e1ffb0f1 | edgar_igl | void check_aligned_anonymous_unfixed_colliding_mmaps(void) |
137 | e1ffb0f1 | edgar_igl | { |
138 | e1ffb0f1 | edgar_igl | char *p1;
|
139 | e1ffb0f1 | edgar_igl | char *p2;
|
140 | e1ffb0f1 | edgar_igl | char *p3;
|
141 | e1ffb0f1 | edgar_igl | uintptr_t p; |
142 | e1ffb0f1 | edgar_igl | int i;
|
143 | e1ffb0f1 | edgar_igl | |
144 | e1ffb0f1 | edgar_igl | fprintf (stderr, "%s", __func__);
|
145 | e1ffb0f1 | edgar_igl | for (i = 0; i < 0x2fff; i++) |
146 | e1ffb0f1 | edgar_igl | { |
147 | e1ffb0f1 | edgar_igl | int nlen;
|
148 | e1ffb0f1 | edgar_igl | p1 = mmap(NULL, pagesize, PROT_READ,
|
149 | e1ffb0f1 | edgar_igl | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); |
150 | e1ffb0f1 | edgar_igl | fail_unless (p1 != MAP_FAILED); |
151 | e1ffb0f1 | edgar_igl | p = (uintptr_t) p1; |
152 | e1ffb0f1 | edgar_igl | fail_unless ((p & pagemask) == 0);
|
153 | e1ffb0f1 | edgar_igl | memcpy (dummybuf, p1, pagesize); |
154 | e1ffb0f1 | edgar_igl | |
155 | e1ffb0f1 | edgar_igl | p2 = mmap(NULL, pagesize, PROT_READ,
|
156 | e1ffb0f1 | edgar_igl | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); |
157 | e1ffb0f1 | edgar_igl | fail_unless (p2 != MAP_FAILED); |
158 | e1ffb0f1 | edgar_igl | p = (uintptr_t) p2; |
159 | e1ffb0f1 | edgar_igl | fail_unless ((p & pagemask) == 0);
|
160 | e1ffb0f1 | edgar_igl | memcpy (dummybuf, p2, pagesize); |
161 | e1ffb0f1 | edgar_igl | |
162 | e1ffb0f1 | edgar_igl | |
163 | e1ffb0f1 | edgar_igl | munmap (p1, pagesize); |
164 | e1ffb0f1 | edgar_igl | nlen = pagesize * 8;
|
165 | e1ffb0f1 | edgar_igl | p3 = mmap(NULL, nlen, PROT_READ,
|
166 | e1ffb0f1 | edgar_igl | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); |
167 | e1ffb0f1 | edgar_igl | |
168 | e1ffb0f1 | edgar_igl | /* Check if the mmaped areas collide. */
|
169 | e1ffb0f1 | edgar_igl | if (p3 < p2
|
170 | e1ffb0f1 | edgar_igl | && (p3 + nlen) > p2) |
171 | e1ffb0f1 | edgar_igl | fail_unless (0);
|
172 | e1ffb0f1 | edgar_igl | |
173 | e1ffb0f1 | edgar_igl | memcpy (dummybuf, p3, pagesize); |
174 | e1ffb0f1 | edgar_igl | |
175 | e1ffb0f1 | edgar_igl | /* Make sure we get pages aligned with the pagesize. The
|
176 | e1ffb0f1 | edgar_igl | target expects this. */
|
177 | e1ffb0f1 | edgar_igl | fail_unless (p3 != MAP_FAILED); |
178 | e1ffb0f1 | edgar_igl | p = (uintptr_t) p3; |
179 | e1ffb0f1 | edgar_igl | fail_unless ((p & pagemask) == 0);
|
180 | e1ffb0f1 | edgar_igl | munmap (p2, pagesize); |
181 | e1ffb0f1 | edgar_igl | munmap (p3, nlen); |
182 | e1ffb0f1 | edgar_igl | } |
183 | e1ffb0f1 | edgar_igl | fprintf (stderr, " passed\n");
|
184 | e1ffb0f1 | edgar_igl | } |
185 | e1ffb0f1 | edgar_igl | |
186 | e1ffb0f1 | edgar_igl | void check_aligned_anonymous_fixed_mmaps(void) |
187 | e1ffb0f1 | edgar_igl | { |
188 | e1ffb0f1 | edgar_igl | char *addr;
|
189 | e1ffb0f1 | edgar_igl | void *p1;
|
190 | e1ffb0f1 | edgar_igl | uintptr_t p; |
191 | e1ffb0f1 | edgar_igl | int i;
|
192 | e1ffb0f1 | edgar_igl | |
193 | e1ffb0f1 | edgar_igl | /* Find a suitable address to start with. */
|
194 | e1ffb0f1 | edgar_igl | addr = mmap(NULL, pagesize * 40, PROT_READ | PROT_WRITE, |
195 | e1ffb0f1 | edgar_igl | MAP_PRIVATE | MAP_ANONYMOUS, |
196 | e1ffb0f1 | edgar_igl | -1, 0); |
197 | e1ffb0f1 | edgar_igl | fprintf (stderr, "%s addr=%p", __func__, addr);
|
198 | e1ffb0f1 | edgar_igl | fail_unless (addr != MAP_FAILED); |
199 | e1ffb0f1 | edgar_igl | |
200 | e1ffb0f1 | edgar_igl | for (i = 0; i < 40; i++) |
201 | e1ffb0f1 | edgar_igl | { |
202 | e1ffb0f1 | edgar_igl | /* Create submaps within our unfixed map. */
|
203 | e1ffb0f1 | edgar_igl | p1 = mmap(addr, pagesize, PROT_READ, |
204 | e1ffb0f1 | edgar_igl | MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, |
205 | e1ffb0f1 | edgar_igl | -1, 0); |
206 | e1ffb0f1 | edgar_igl | /* Make sure we get pages aligned with the pagesize.
|
207 | e1ffb0f1 | edgar_igl | The target expects this. */
|
208 | e1ffb0f1 | edgar_igl | p = (uintptr_t) p1; |
209 | e1ffb0f1 | edgar_igl | fail_unless (p1 == addr); |
210 | e1ffb0f1 | edgar_igl | fail_unless ((p & pagemask) == 0);
|
211 | e1ffb0f1 | edgar_igl | memcpy (dummybuf, p1, pagesize); |
212 | e1ffb0f1 | edgar_igl | munmap (p1, pagesize); |
213 | e1ffb0f1 | edgar_igl | addr += pagesize; |
214 | e1ffb0f1 | edgar_igl | } |
215 | e1ffb0f1 | edgar_igl | fprintf (stderr, " passed\n");
|
216 | e1ffb0f1 | edgar_igl | } |
217 | e1ffb0f1 | edgar_igl | |
218 | e1ffb0f1 | edgar_igl | void check_aligned_anonymous_fixed_mmaps_collide_with_host(void) |
219 | e1ffb0f1 | edgar_igl | { |
220 | e1ffb0f1 | edgar_igl | char *addr;
|
221 | e1ffb0f1 | edgar_igl | void *p1;
|
222 | e1ffb0f1 | edgar_igl | uintptr_t p; |
223 | e1ffb0f1 | edgar_igl | int i;
|
224 | e1ffb0f1 | edgar_igl | |
225 | e1ffb0f1 | edgar_igl | /* Find a suitable address to start with. Right were the x86 hosts
|
226 | e1ffb0f1 | edgar_igl | stack is. */
|
227 | e1ffb0f1 | edgar_igl | addr = ((void *)0x80000000); |
228 | e1ffb0f1 | edgar_igl | fprintf (stderr, "%s addr=%p", __func__, addr);
|
229 | e1ffb0f1 | edgar_igl | fprintf (stderr, "FIXME: QEMU fails to track pages used by the host.");
|
230 | e1ffb0f1 | edgar_igl | |
231 | e1ffb0f1 | edgar_igl | for (i = 0; i < 20; i++) |
232 | e1ffb0f1 | edgar_igl | { |
233 | e1ffb0f1 | edgar_igl | /* Create submaps within our unfixed map. */
|
234 | e1ffb0f1 | edgar_igl | p1 = mmap(addr, pagesize, PROT_READ | PROT_WRITE, |
235 | e1ffb0f1 | edgar_igl | MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, |
236 | e1ffb0f1 | edgar_igl | -1, 0); |
237 | e1ffb0f1 | edgar_igl | /* Make sure we get pages aligned with the pagesize.
|
238 | e1ffb0f1 | edgar_igl | The target expects this. */
|
239 | e1ffb0f1 | edgar_igl | p = (uintptr_t) p1; |
240 | e1ffb0f1 | edgar_igl | fail_unless (p1 == addr); |
241 | e1ffb0f1 | edgar_igl | fail_unless ((p & pagemask) == 0);
|
242 | e1ffb0f1 | edgar_igl | memcpy (p1, dummybuf, pagesize); |
243 | e1ffb0f1 | edgar_igl | munmap (p1, pagesize); |
244 | e1ffb0f1 | edgar_igl | addr += pagesize; |
245 | e1ffb0f1 | edgar_igl | } |
246 | e1ffb0f1 | edgar_igl | fprintf (stderr, " passed\n");
|
247 | e1ffb0f1 | edgar_igl | } |
248 | e1ffb0f1 | edgar_igl | |
249 | e1ffb0f1 | edgar_igl | void check_file_unfixed_mmaps(void) |
250 | e1ffb0f1 | edgar_igl | { |
251 | e1ffb0f1 | edgar_igl | unsigned int *p1, *p2, *p3; |
252 | e1ffb0f1 | edgar_igl | uintptr_t p; |
253 | e1ffb0f1 | edgar_igl | int i;
|
254 | e1ffb0f1 | edgar_igl | |
255 | e1ffb0f1 | edgar_igl | fprintf (stderr, "%s", __func__);
|
256 | e1ffb0f1 | edgar_igl | for (i = 0; i < 0x10; i++) |
257 | e1ffb0f1 | edgar_igl | { |
258 | e1ffb0f1 | edgar_igl | size_t len; |
259 | e1ffb0f1 | edgar_igl | |
260 | e1ffb0f1 | edgar_igl | len = pagesize; |
261 | e1ffb0f1 | edgar_igl | p1 = mmap(NULL, len, PROT_READ,
|
262 | e1ffb0f1 | edgar_igl | MAP_PRIVATE, |
263 | e1ffb0f1 | edgar_igl | test_fd, 0);
|
264 | e1ffb0f1 | edgar_igl | p2 = mmap(NULL, len, PROT_READ,
|
265 | e1ffb0f1 | edgar_igl | MAP_PRIVATE, |
266 | e1ffb0f1 | edgar_igl | test_fd, pagesize); |
267 | e1ffb0f1 | edgar_igl | p3 = mmap(NULL, len, PROT_READ,
|
268 | e1ffb0f1 | edgar_igl | MAP_PRIVATE, |
269 | e1ffb0f1 | edgar_igl | test_fd, pagesize * 2);
|
270 | e1ffb0f1 | edgar_igl | |
271 | e1ffb0f1 | edgar_igl | fail_unless (p1 != MAP_FAILED); |
272 | e1ffb0f1 | edgar_igl | fail_unless (p2 != MAP_FAILED); |
273 | e1ffb0f1 | edgar_igl | fail_unless (p3 != MAP_FAILED); |
274 | e1ffb0f1 | edgar_igl | |
275 | e1ffb0f1 | edgar_igl | /* Make sure we get pages aligned with the pagesize. The
|
276 | e1ffb0f1 | edgar_igl | target expects this. */
|
277 | e1ffb0f1 | edgar_igl | p = (uintptr_t) p1; |
278 | e1ffb0f1 | edgar_igl | fail_unless ((p & pagemask) == 0);
|
279 | e1ffb0f1 | edgar_igl | p = (uintptr_t) p2; |
280 | e1ffb0f1 | edgar_igl | fail_unless ((p & pagemask) == 0);
|
281 | e1ffb0f1 | edgar_igl | p = (uintptr_t) p3; |
282 | e1ffb0f1 | edgar_igl | fail_unless ((p & pagemask) == 0);
|
283 | e1ffb0f1 | edgar_igl | |
284 | e1ffb0f1 | edgar_igl | /* Verify that the file maps was made correctly. */
|
285 | e1ffb0f1 | edgar_igl | D(printf ("p1=%d p2=%d p3=%d\n", *p1, *p2, *p3));
|
286 | e1ffb0f1 | edgar_igl | fail_unless (*p1 == 0);
|
287 | e1ffb0f1 | edgar_igl | fail_unless (*p2 == (pagesize / sizeof *p2));
|
288 | e1ffb0f1 | edgar_igl | fail_unless (*p3 == ((pagesize * 2) / sizeof *p3)); |
289 | e1ffb0f1 | edgar_igl | |
290 | e1ffb0f1 | edgar_igl | memcpy (dummybuf, p1, pagesize); |
291 | e1ffb0f1 | edgar_igl | memcpy (dummybuf, p2, pagesize); |
292 | e1ffb0f1 | edgar_igl | memcpy (dummybuf, p3, pagesize); |
293 | e1ffb0f1 | edgar_igl | munmap (p1, len); |
294 | e1ffb0f1 | edgar_igl | munmap (p2, len); |
295 | e1ffb0f1 | edgar_igl | munmap (p3, len); |
296 | e1ffb0f1 | edgar_igl | } |
297 | e1ffb0f1 | edgar_igl | fprintf (stderr, " passed\n");
|
298 | e1ffb0f1 | edgar_igl | } |
299 | e1ffb0f1 | edgar_igl | |
300 | e1ffb0f1 | edgar_igl | void check_file_unfixed_eof_mmaps(void) |
301 | e1ffb0f1 | edgar_igl | { |
302 | e1ffb0f1 | edgar_igl | char *cp;
|
303 | e1ffb0f1 | edgar_igl | unsigned int *p1; |
304 | e1ffb0f1 | edgar_igl | uintptr_t p; |
305 | e1ffb0f1 | edgar_igl | int i;
|
306 | e1ffb0f1 | edgar_igl | |
307 | e1ffb0f1 | edgar_igl | fprintf (stderr, "%s", __func__);
|
308 | e1ffb0f1 | edgar_igl | for (i = 0; i < 0x10; i++) |
309 | e1ffb0f1 | edgar_igl | { |
310 | e1ffb0f1 | edgar_igl | p1 = mmap(NULL, pagesize, PROT_READ,
|
311 | e1ffb0f1 | edgar_igl | MAP_PRIVATE, |
312 | e1ffb0f1 | edgar_igl | test_fd, |
313 | e1ffb0f1 | edgar_igl | (test_fsize - sizeof *p1) & ~pagemask);
|
314 | e1ffb0f1 | edgar_igl | |
315 | e1ffb0f1 | edgar_igl | fail_unless (p1 != MAP_FAILED); |
316 | e1ffb0f1 | edgar_igl | |
317 | e1ffb0f1 | edgar_igl | /* Make sure we get pages aligned with the pagesize. The
|
318 | e1ffb0f1 | edgar_igl | target expects this. */
|
319 | e1ffb0f1 | edgar_igl | p = (uintptr_t) p1; |
320 | e1ffb0f1 | edgar_igl | fail_unless ((p & pagemask) == 0);
|
321 | e1ffb0f1 | edgar_igl | /* Verify that the file maps was made correctly. */
|
322 | e1ffb0f1 | edgar_igl | fail_unless (p1[(test_fsize & pagemask) / sizeof *p1 - 1] |
323 | e1ffb0f1 | edgar_igl | == ((test_fsize - sizeof *p1) / sizeof *p1)); |
324 | e1ffb0f1 | edgar_igl | |
325 | e1ffb0f1 | edgar_igl | /* Verify that the end of page is accessable and zeroed. */
|
326 | e1ffb0f1 | edgar_igl | cp = (void *) p1;
|
327 | e1ffb0f1 | edgar_igl | fail_unless (cp[pagesize - 4] == 0); |
328 | e1ffb0f1 | edgar_igl | munmap (p1, pagesize); |
329 | e1ffb0f1 | edgar_igl | } |
330 | e1ffb0f1 | edgar_igl | fprintf (stderr, " passed\n");
|
331 | e1ffb0f1 | edgar_igl | } |
332 | e1ffb0f1 | edgar_igl | |
333 | e1ffb0f1 | edgar_igl | void check_file_fixed_eof_mmaps(void) |
334 | e1ffb0f1 | edgar_igl | { |
335 | e1ffb0f1 | edgar_igl | char *addr;
|
336 | e1ffb0f1 | edgar_igl | char *cp;
|
337 | e1ffb0f1 | edgar_igl | unsigned int *p1; |
338 | e1ffb0f1 | edgar_igl | uintptr_t p; |
339 | e1ffb0f1 | edgar_igl | int i;
|
340 | e1ffb0f1 | edgar_igl | |
341 | e1ffb0f1 | edgar_igl | /* Find a suitable address to start with. */
|
342 | e1ffb0f1 | edgar_igl | addr = mmap(NULL, pagesize * 44, PROT_READ, |
343 | e1ffb0f1 | edgar_igl | MAP_PRIVATE | MAP_ANONYMOUS, |
344 | e1ffb0f1 | edgar_igl | -1, 0); |
345 | e1ffb0f1 | edgar_igl | |
346 | e1ffb0f1 | edgar_igl | fprintf (stderr, "%s addr=%p", __func__, (void *)addr); |
347 | e1ffb0f1 | edgar_igl | fail_unless (addr != MAP_FAILED); |
348 | e1ffb0f1 | edgar_igl | |
349 | e1ffb0f1 | edgar_igl | for (i = 0; i < 0x10; i++) |
350 | e1ffb0f1 | edgar_igl | { |
351 | e1ffb0f1 | edgar_igl | /* Create submaps within our unfixed map. */
|
352 | e1ffb0f1 | edgar_igl | p1 = mmap(addr, pagesize, PROT_READ, |
353 | e1ffb0f1 | edgar_igl | MAP_PRIVATE | MAP_FIXED, |
354 | e1ffb0f1 | edgar_igl | test_fd, |
355 | e1ffb0f1 | edgar_igl | (test_fsize - sizeof *p1) & ~pagemask);
|
356 | e1ffb0f1 | edgar_igl | |
357 | e1ffb0f1 | edgar_igl | fail_unless (p1 != MAP_FAILED); |
358 | e1ffb0f1 | edgar_igl | |
359 | e1ffb0f1 | edgar_igl | /* Make sure we get pages aligned with the pagesize. The
|
360 | e1ffb0f1 | edgar_igl | target expects this. */
|
361 | e1ffb0f1 | edgar_igl | p = (uintptr_t) p1; |
362 | e1ffb0f1 | edgar_igl | fail_unless ((p & pagemask) == 0);
|
363 | e1ffb0f1 | edgar_igl | |
364 | e1ffb0f1 | edgar_igl | /* Verify that the file maps was made correctly. */
|
365 | e1ffb0f1 | edgar_igl | fail_unless (p1[(test_fsize & pagemask) / sizeof *p1 - 1] |
366 | e1ffb0f1 | edgar_igl | == ((test_fsize - sizeof *p1) / sizeof *p1)); |
367 | e1ffb0f1 | edgar_igl | |
368 | e1ffb0f1 | edgar_igl | /* Verify that the end of page is accessable and zeroed. */
|
369 | e1ffb0f1 | edgar_igl | cp = (void *)p1;
|
370 | e1ffb0f1 | edgar_igl | fail_unless (cp[pagesize - 4] == 0); |
371 | e1ffb0f1 | edgar_igl | munmap (p1, pagesize); |
372 | e1ffb0f1 | edgar_igl | addr += pagesize; |
373 | e1ffb0f1 | edgar_igl | } |
374 | e1ffb0f1 | edgar_igl | fprintf (stderr, " passed\n");
|
375 | e1ffb0f1 | edgar_igl | } |
376 | e1ffb0f1 | edgar_igl | |
377 | e1ffb0f1 | edgar_igl | void check_file_fixed_mmaps(void) |
378 | e1ffb0f1 | edgar_igl | { |
379 | 7dd7c987 | edgar_igl | unsigned char *addr; |
380 | e1ffb0f1 | edgar_igl | unsigned int *p1, *p2, *p3, *p4; |
381 | e1ffb0f1 | edgar_igl | int i;
|
382 | e1ffb0f1 | edgar_igl | |
383 | e1ffb0f1 | edgar_igl | /* Find a suitable address to start with. */
|
384 | 7dd7c987 | edgar_igl | addr = mmap(NULL, pagesize * 40 * 4, PROT_READ, |
385 | e1ffb0f1 | edgar_igl | MAP_PRIVATE | MAP_ANONYMOUS, |
386 | e1ffb0f1 | edgar_igl | -1, 0); |
387 | e1ffb0f1 | edgar_igl | fprintf (stderr, "%s addr=%p", __func__, (void *)addr); |
388 | e1ffb0f1 | edgar_igl | fail_unless (addr != MAP_FAILED); |
389 | e1ffb0f1 | edgar_igl | |
390 | e1ffb0f1 | edgar_igl | for (i = 0; i < 40; i++) |
391 | e1ffb0f1 | edgar_igl | { |
392 | e1ffb0f1 | edgar_igl | p1 = mmap(addr, pagesize, PROT_READ, |
393 | e1ffb0f1 | edgar_igl | MAP_PRIVATE | MAP_FIXED, |
394 | e1ffb0f1 | edgar_igl | test_fd, 0);
|
395 | e1ffb0f1 | edgar_igl | p2 = mmap(addr + pagesize, pagesize, PROT_READ, |
396 | e1ffb0f1 | edgar_igl | MAP_PRIVATE | MAP_FIXED, |
397 | e1ffb0f1 | edgar_igl | test_fd, pagesize); |
398 | e1ffb0f1 | edgar_igl | p3 = mmap(addr + pagesize * 2, pagesize, PROT_READ,
|
399 | e1ffb0f1 | edgar_igl | MAP_PRIVATE | MAP_FIXED, |
400 | e1ffb0f1 | edgar_igl | test_fd, pagesize * 2);
|
401 | e1ffb0f1 | edgar_igl | p4 = mmap(addr + pagesize * 3, pagesize, PROT_READ,
|
402 | e1ffb0f1 | edgar_igl | MAP_PRIVATE | MAP_FIXED, |
403 | e1ffb0f1 | edgar_igl | test_fd, pagesize * 3);
|
404 | e1ffb0f1 | edgar_igl | |
405 | e1ffb0f1 | edgar_igl | /* Make sure we get pages aligned with the pagesize.
|
406 | e1ffb0f1 | edgar_igl | The target expects this. */
|
407 | 7dd7c987 | edgar_igl | fail_unless (p1 == (void *)addr);
|
408 | 7dd7c987 | edgar_igl | fail_unless (p2 == (void *)addr + pagesize);
|
409 | 7dd7c987 | edgar_igl | fail_unless (p3 == (void *)addr + pagesize * 2); |
410 | 7dd7c987 | edgar_igl | fail_unless (p4 == (void *)addr + pagesize * 3); |
411 | e1ffb0f1 | edgar_igl | |
412 | e1ffb0f1 | edgar_igl | /* Verify that the file maps was made correctly. */
|
413 | e1ffb0f1 | edgar_igl | fail_unless (*p1 == 0);
|
414 | e1ffb0f1 | edgar_igl | fail_unless (*p2 == (pagesize / sizeof *p2));
|
415 | e1ffb0f1 | edgar_igl | fail_unless (*p3 == ((pagesize * 2) / sizeof *p3)); |
416 | e1ffb0f1 | edgar_igl | fail_unless (*p4 == ((pagesize * 3) / sizeof *p4)); |
417 | e1ffb0f1 | edgar_igl | |
418 | e1ffb0f1 | edgar_igl | memcpy (dummybuf, p1, pagesize); |
419 | e1ffb0f1 | edgar_igl | memcpy (dummybuf, p2, pagesize); |
420 | e1ffb0f1 | edgar_igl | memcpy (dummybuf, p3, pagesize); |
421 | e1ffb0f1 | edgar_igl | memcpy (dummybuf, p4, pagesize); |
422 | e1ffb0f1 | edgar_igl | |
423 | e1ffb0f1 | edgar_igl | munmap (p1, pagesize); |
424 | e1ffb0f1 | edgar_igl | munmap (p2, pagesize); |
425 | e1ffb0f1 | edgar_igl | munmap (p3, pagesize); |
426 | e1ffb0f1 | edgar_igl | munmap (p4, pagesize); |
427 | 7dd7c987 | edgar_igl | addr += pagesize * 4;
|
428 | e1ffb0f1 | edgar_igl | } |
429 | e1ffb0f1 | edgar_igl | fprintf (stderr, " passed\n");
|
430 | e1ffb0f1 | edgar_igl | } |
431 | e1ffb0f1 | edgar_igl | |
432 | e1ffb0f1 | edgar_igl | int main(int argc, char **argv) |
433 | e1ffb0f1 | edgar_igl | { |
434 | e1ffb0f1 | edgar_igl | char tempname[] = "/tmp/.cmmapXXXXXX"; |
435 | e1ffb0f1 | edgar_igl | unsigned int i; |
436 | e1ffb0f1 | edgar_igl | |
437 | e1ffb0f1 | edgar_igl | /* Trust the first argument, otherwise probe the system for our
|
438 | e1ffb0f1 | edgar_igl | pagesize. */
|
439 | e1ffb0f1 | edgar_igl | if (argc > 1) |
440 | e1ffb0f1 | edgar_igl | pagesize = strtoul(argv[1], NULL, 0); |
441 | e1ffb0f1 | edgar_igl | else
|
442 | e1ffb0f1 | edgar_igl | pagesize = sysconf(_SC_PAGESIZE); |
443 | e1ffb0f1 | edgar_igl | |
444 | e1ffb0f1 | edgar_igl | /* Assume pagesize is a power of two. */
|
445 | e1ffb0f1 | edgar_igl | pagemask = pagesize - 1;
|
446 | e1ffb0f1 | edgar_igl | dummybuf = malloc (pagesize); |
447 | e1ffb0f1 | edgar_igl | printf ("pagesize=%u pagemask=%x\n", pagesize, pagemask);
|
448 | e1ffb0f1 | edgar_igl | |
449 | e1ffb0f1 | edgar_igl | test_fd = mkstemp(tempname); |
450 | e1ffb0f1 | edgar_igl | unlink(tempname); |
451 | e1ffb0f1 | edgar_igl | |
452 | e1ffb0f1 | edgar_igl | /* Fill the file with int's counting from zero and up. */
|
453 | e1ffb0f1 | edgar_igl | for (i = 0; i < (pagesize * 4) / sizeof i; i++) |
454 | e1ffb0f1 | edgar_igl | write (test_fd, &i, sizeof i);
|
455 | e1ffb0f1 | edgar_igl | /* Append a few extra writes to make the file end at non
|
456 | e1ffb0f1 | edgar_igl | page boundary. */
|
457 | e1ffb0f1 | edgar_igl | write (test_fd, &i, sizeof i); i++;
|
458 | e1ffb0f1 | edgar_igl | write (test_fd, &i, sizeof i); i++;
|
459 | e1ffb0f1 | edgar_igl | write (test_fd, &i, sizeof i); i++;
|
460 | e1ffb0f1 | edgar_igl | |
461 | e1ffb0f1 | edgar_igl | test_fsize = lseek(test_fd, 0, SEEK_CUR);
|
462 | e1ffb0f1 | edgar_igl | |
463 | e1ffb0f1 | edgar_igl | /* Run the tests. */
|
464 | e1ffb0f1 | edgar_igl | check_aligned_anonymous_unfixed_mmaps(); |
465 | e1ffb0f1 | edgar_igl | check_aligned_anonymous_unfixed_colliding_mmaps(); |
466 | e1ffb0f1 | edgar_igl | check_aligned_anonymous_fixed_mmaps(); |
467 | e1ffb0f1 | edgar_igl | check_file_unfixed_mmaps(); |
468 | e1ffb0f1 | edgar_igl | check_file_fixed_mmaps(); |
469 | e1ffb0f1 | edgar_igl | check_file_fixed_eof_mmaps(); |
470 | e1ffb0f1 | edgar_igl | check_file_unfixed_eof_mmaps(); |
471 | e1ffb0f1 | edgar_igl | |
472 | e1ffb0f1 | edgar_igl | /* Fails at the moment. */
|
473 | e1ffb0f1 | edgar_igl | /* check_aligned_anonymous_fixed_mmaps_collide_with_host(); */
|
474 | e1ffb0f1 | edgar_igl | |
475 | e1ffb0f1 | edgar_igl | return EXIT_SUCCESS;
|
476 | e1ffb0f1 | edgar_igl | } |