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