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