master
c 1,296 lines 34 KB
Raw
1 /*++
2
3 Copyright (c) Microsoft. All rights reserved.
4
5 Module Name:
6
7 mremap.c
8
9 Abstract:
10
11 This file contains test cases for mremap().
12
13 --*/
14
15 #include "lxtcommon.h"
16 #include "unittests.h"
17 #include <stdio.h>
18 #include <string.h>
19 #include <sys/mman.h>
20 #include <sched.h>
21 #include <signal.h>
22 #include <sys/types.h>
23 #include <sys/stat.h>
24 #include <sys/ioctl.h>
25 #include <sys/syscall.h>
26 #include <fcntl.h>
27 #include <errno.h>
28 #include <time.h>
29 #include <pthread.h>
30
31 #define LXT_NAME "mremap"
32
33 void FillMemory(char* Memory, int Size, unsigned char Value)
34 {
35 int i;
36
37 LxtLogInfo("FillMemory: %p, 0x%x, %u", Memory, Size, Value);
38
39 for (i = 0; i < Size; i += 1)
40 {
41
42 if ((i != 0) && ((i % PAGE_SIZE) == 0))
43 {
44 Value += 1;
45 }
46
47 Memory[i] = Value;
48 }
49
50 return;
51 }
52
53 int CheckMemory(unsigned char* Memory, int Size, unsigned char Value)
54 {
55 int i;
56
57 LxtLogInfo("CheckMemory: %p, 0x%x, %u", Memory, Size, Value);
58
59 for (i = 0; i < Size; i += 1)
60 {
61
62 if ((i != 0) && ((i % PAGE_SIZE) == 0))
63 {
64 Value += 1;
65 }
66
67 if (Memory[i] != Value)
68 {
69 LxtLogError("Mismatched byte %d! Value: %d", i, (int)Memory[i]);
70 break;
71 }
72 }
73
74 return i;
75 }
76
77 void* ThreadWorker(void* Context)
78 {
79 char* Memory;
80 int Result;
81
82 LxtLogInfo("Thread started.");
83
84 for (;;)
85 {
86
87 Memory = mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, 0, 0);
88
89 if (Memory == MAP_FAILED)
90 {
91 Result = errno;
92 LxtLogError("Thread memory allocation failed! %d", Result);
93 goto ErrorExit;
94 }
95
96 munmap(Memory, PAGE_SIZE);
97 }
98
99 ErrorExit:
100
101 return NULL;
102 }
103
104 int MremapTestEntry(int Argc, char* Argv[])
105 {
106 LXT_ARGS Args;
107 char* PrivateMemory;
108 char* SharedPrivateMemory;
109 char* FileMemory;
110 char* FileMemory2;
111 char* RemappedMemory;
112 char* SpanMemory1;
113 char* SpanMemory2;
114 char* SpanMemory3;
115 int Result;
116 int FileDescriptor;
117 int DevZeroDescriptor;
118 int AllocationSize;
119 char FileBuffer[3 * PAGE_SIZE];
120 int FailByte;
121 int MapsDescriptor;
122 int BytesRead;
123 char* MapsBuffer;
124 pthread_t Thread;
125 int FileDescriptor2;
126 int FileSize;
127 struct timespec Time;
128
129 LxtCheckResult(LxtInitialize(Argc, Argv, &Args, LXT_NAME));
130
131 LxtLogStart("Start Prep:");
132
133 Result = pthread_create(&Thread, NULL, ThreadWorker, NULL);
134
135 if (Result != 0)
136 {
137 LxtLogError("Thread creation failed! %d", Result);
138 goto ErrorExit;
139 }
140
141 LxtLogInfo("Thread created.");
142
143 AllocationSize = 2 * PAGE_SIZE;
144
145 PrivateMemory = mmap(NULL, AllocationSize, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, 0, 0);
146
147 if (PrivateMemory == MAP_FAILED)
148 {
149 Result = errno;
150 LxtLogError("PrivateMemory allocation failed! %d", Result);
151 goto ErrorExit;
152 }
153
154 FillMemory(PrivateMemory, AllocationSize, 1);
155
156 SharedPrivateMemory = mmap(NULL, AllocationSize, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_SHARED, 0, 0);
157
158 if (SharedPrivateMemory == MAP_FAILED)
159 {
160 Result = errno;
161 LxtLogError("SharedPrivateMemory allocation failed! %d", Result);
162 goto ErrorExit;
163 }
164
165 FillMemory(SharedPrivateMemory, AllocationSize, 10);
166
167 FileDescriptor = open("/data/test.bin", O_RDWR | O_CREAT | O_TRUNC, S_IRWXU);
168
169 if (FileDescriptor == -1)
170 {
171 Result = errno;
172 LxtLogError("Could not create test file! %d", Result);
173 goto ErrorExit;
174 }
175
176 write(FileDescriptor, FileBuffer, sizeof(FileBuffer));
177
178 FileMemory = mmap(NULL, AllocationSize, PROT_READ | PROT_WRITE, MAP_SHARED, FileDescriptor, 0);
179
180 if (FileMemory == MAP_FAILED)
181 {
182 Result = errno;
183 LxtLogError("FileMemory allocation failed! %d", Result);
184 goto ErrorExit;
185 }
186
187 FillMemory(FileMemory, AllocationSize, 20);
188 SpanMemory3 = mmap(NULL, AllocationSize * 3, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_SHARED, 0, 0);
189
190 if (SpanMemory3 == MAP_FAILED)
191 {
192 Result = errno;
193 LxtLogError("SpanMemory1 allocation failed! %d", Result);
194 goto ErrorExit;
195 }
196
197 FillMemory(SpanMemory3, AllocationSize * 3, 60);
198
199 SpanMemory1 = mmap(SpanMemory3, AllocationSize, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE | MAP_FIXED, 0, 0);
200
201 if (SpanMemory1 == MAP_FAILED)
202 {
203 Result = errno;
204 LxtLogError("SpanMemory1 allocation failed! %d", Result);
205 goto ErrorExit;
206 }
207
208 FillMemory(SpanMemory1, AllocationSize, 40);
209
210 SpanMemory2 =
211 mmap(SpanMemory1 + AllocationSize, AllocationSize, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE | MAP_FIXED, 0, 0);
212
213 if (SpanMemory2 == MAP_FAILED)
214 {
215 Result = errno;
216 LxtLogError("SpanMemory2 allocation failed! %d", Result);
217 goto ErrorExit;
218 }
219
220 if (SpanMemory2 != (SpanMemory1 + AllocationSize))
221 {
222 LxtLogError("SpanMemory2 allocation isn't in the right place!");
223 goto ErrorExit;
224 }
225
226 FillMemory(SpanMemory2, AllocationSize, 50);
227 LxtLogPassed("Prep complete!");
228
229 LxtLogStart("Start Test Cases:");
230
231 //
232 // Case 1: Extend private memory.
233 //
234
235 RemappedMemory = mremap(PrivateMemory, AllocationSize, AllocationSize + PAGE_SIZE, MREMAP_MAYMOVE);
236
237 if (RemappedMemory == MAP_FAILED)
238 {
239
240 Result = errno;
241 LxtLogError("Case 1 failed! %d", Result);
242 }
243 else
244 {
245
246 LxtLogPassed("Case 1 succeeded. %p -> %p", PrivateMemory, RemappedMemory);
247 PrivateMemory = RemappedMemory;
248
249 FailByte = CheckMemory(RemappedMemory, AllocationSize, 1);
250
251 if (FailByte != AllocationSize)
252 {
253 LxtLogError("Case 1 memory doesn't match at byte %d!!!", FailByte);
254 }
255
256 FillMemory(RemappedMemory + AllocationSize, PAGE_SIZE, 3);
257 }
258
259 //
260 // Case 3: Extend file mapping.
261 //
262
263 RemappedMemory = mremap(FileMemory, AllocationSize, AllocationSize + PAGE_SIZE, MREMAP_MAYMOVE);
264
265 if (RemappedMemory == MAP_FAILED)
266 {
267
268 Result = errno;
269 LxtLogError("Case 3 failed! %d", Result);
270 }
271 else
272 {
273
274 LxtLogPassed("Case 3 succeeded. %p -> %p", FileMemory, RemappedMemory);
275 FileMemory = RemappedMemory;
276
277 FailByte = CheckMemory(RemappedMemory, AllocationSize, 20);
278
279 if (FailByte != AllocationSize)
280 {
281 LxtLogError("Case 3 memory doesn't match at byte %d!!!", FailByte);
282 }
283
284 FillMemory(RemappedMemory + AllocationSize, PAGE_SIZE, 22);
285 }
286
287 //
288 // Case 7: Move range that spans two private allocations (same type).
289 //
290
291 RemappedMemory = mremap(SpanMemory1 + PAGE_SIZE, AllocationSize, AllocationSize + (2 * PAGE_SIZE), MREMAP_MAYMOVE);
292
293 if (RemappedMemory == MAP_FAILED)
294 {
295
296 Result = errno;
297 LxtLogError("Case 7 failed! %d", Result);
298 }
299 else
300 {
301
302 LxtLogPassed("Case 7 succeeded. %p -> %p", SpanMemory1 + PAGE_SIZE, RemappedMemory);
303
304 FailByte = CheckMemory(RemappedMemory, PAGE_SIZE, 41);
305
306 if (FailByte != PAGE_SIZE)
307 {
308 LxtLogError("Case 7 first page memory doesn't match at byte %d!!!", FailByte);
309 }
310
311 FailByte = CheckMemory(RemappedMemory + PAGE_SIZE, PAGE_SIZE, 50);
312
313 if (FailByte != PAGE_SIZE)
314 {
315 LxtLogError("Case 7 second page memory doesn't match at byte %d!!! V: %d", FailByte);
316 }
317 }
318
319 //
320 // Case 8: Move range that spans two different allocations (private and shared anonymous).
321 //
322
323 RemappedMemory = mremap(SpanMemory2 + PAGE_SIZE, AllocationSize, AllocationSize + (2 * PAGE_SIZE), MREMAP_MAYMOVE);
324
325 if (RemappedMemory == MAP_FAILED)
326 {
327
328 Result = errno;
329 LxtLogPassed("Case 8 failed as expected. %d", Result);
330 }
331 else
332 {
333
334 LxtLogError("Case 8 succeeded not expected! %p -> %p", SpanMemory2 + PAGE_SIZE, RemappedMemory);
335
336 FailByte = CheckMemory(RemappedMemory, PAGE_SIZE, 51);
337
338 if (FailByte != PAGE_SIZE)
339 {
340 LxtLogError("Case 8 first page memory doesn't match at byte %d!!!", FailByte);
341 }
342
343 FailByte = CheckMemory(RemappedMemory + PAGE_SIZE, PAGE_SIZE, 60);
344
345 if (FailByte != PAGE_SIZE)
346 {
347 LxtLogError("Case 8 second page memory doesn't match at byte %d!!!", FailByte);
348 }
349 }
350
351 //
352 // Case 9: Shrink private allocation.
353 //
354
355 RemappedMemory = mremap(PrivateMemory, AllocationSize + PAGE_SIZE, AllocationSize, 0);
356
357 if (RemappedMemory == MAP_FAILED)
358 {
359
360 Result = errno;
361 LxtLogError("Case 9 failed! %d", Result);
362 }
363 else
364 {
365 LxtLogPassed("Case 9 succeeded. %p -> %p", PrivateMemory, RemappedMemory);
366 PrivateMemory = RemappedMemory;
367
368 FailByte = CheckMemory(RemappedMemory, AllocationSize, 1);
369
370 if (FailByte != AllocationSize)
371 {
372 LxtLogError("Case 9 memory doesn't match at byte %d!!!", FailByte);
373 }
374 }
375
376 //
377 // Case 10: Move and extend with different protections.
378 //
379
380 Result = mprotect(PrivateMemory, PAGE_SIZE, PROT_READ);
381
382 if (Result == -1)
383 {
384 Result = errno;
385 LxtLogError("Case 10 protection change failed! %d", Result);
386 goto ErrorExit;
387 }
388
389 RemappedMemory = mremap(PrivateMemory, AllocationSize, AllocationSize + PAGE_SIZE, MREMAP_MAYMOVE);
390
391 if (RemappedMemory == MAP_FAILED)
392 {
393
394 Result = errno;
395 LxtLogPassed("Case 10 failed as expected. %d", Result);
396 }
397 else
398 {
399 LxtLogError("Case 10 succeeded not expected!. %p -> %p", PrivateMemory, RemappedMemory);
400 PrivateMemory = RemappedMemory;
401
402 FailByte = CheckMemory(RemappedMemory, AllocationSize, 1);
403
404 if (FailByte != AllocationSize)
405 {
406 LxtLogError("Case 10 memory doesn't match at byte %d!!!", FailByte);
407 }
408 }
409
410 //
411 // Case 11: Move discontiguous (by mapping offset not VA) file mappings.
412 //
413
414 FileMemory = mmap(NULL, AllocationSize, PROT_READ | PROT_WRITE, MAP_SHARED, FileDescriptor, 0);
415
416 if (FileMemory == MAP_FAILED)
417 {
418 Result = errno;
419 LxtLogError("Case 11 map failed! %d", Result);
420 goto ErrorExit;
421 }
422
423 FillMemory(FileMemory, AllocationSize, 70);
424
425 RemappedMemory = mmap(FileMemory + PAGE_SIZE, PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_FIXED, FileDescriptor, 0x2000);
426
427 if (RemappedMemory == MAP_FAILED)
428 {
429 Result = errno;
430 LxtLogError("Case 11 map2 failed! %d", Result);
431 goto ErrorExit;
432 }
433
434 RemappedMemory = mremap(FileMemory, AllocationSize, AllocationSize + (2 * PAGE_SIZE), MREMAP_MAYMOVE);
435
436 if (RemappedMemory == MAP_FAILED)
437 {
438
439 Result = errno;
440 LxtLogPassed("Case 11 failed as expected. %d", Result);
441 }
442 else
443 {
444
445 LxtLogError("Case 11 succeeded not expected!. %p -> %p", FileMemory, RemappedMemory);
446
447 FailByte = CheckMemory(RemappedMemory, AllocationSize, 70);
448
449 if (FailByte != PAGE_SIZE)
450 {
451 LxtLogError("Case 11 memory doesn't match at byte %d!!!", FailByte);
452 }
453 }
454
455 //
456 // Case 12: Extend within existing VAD (section).
457 //
458
459 FileMemory = mmap(NULL, 3 * PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, FileDescriptor, 0);
460
461 if (FileMemory == MAP_FAILED)
462 {
463 Result = errno;
464 LxtLogError("Case 12 map failed! %d", Result);
465 goto ErrorExit;
466 }
467
468 FillMemory(FileMemory, 3 * PAGE_SIZE, 80);
469
470 RemappedMemory = mremap(FileMemory, PAGE_SIZE, 3 * PAGE_SIZE, 0);
471
472 if (RemappedMemory == MAP_FAILED)
473 {
474
475 Result = errno;
476 LxtLogPassed("Case 12 failed as expected. %d", Result);
477 }
478 else
479 {
480
481 LxtLogError("Case 12 succeeded not expected! %p -> %p", FileMemory, RemappedMemory);
482
483 FailByte = CheckMemory(RemappedMemory, 3 * PAGE_SIZE, 80);
484
485 if (FailByte != PAGE_SIZE)
486 {
487 LxtLogError("Case 12 memory doesn't match at byte %d!!!", FailByte);
488 }
489 }
490
491 //
492 // Case 13: Extend within existing VAD (private).
493 //
494
495 PrivateMemory = mmap(NULL, PAGE_SIZE * 3, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, 0, 0);
496
497 if (PrivateMemory == MAP_FAILED)
498 {
499 Result = errno;
500 LxtLogError("Case 13 map failed! %d", Result);
501 goto ErrorExit;
502 }
503
504 FillMemory(PrivateMemory, 3 * PAGE_SIZE, 90);
505
506 RemappedMemory = mremap(PrivateMemory, PAGE_SIZE, 3 * PAGE_SIZE, 0);
507
508 if (RemappedMemory == MAP_FAILED)
509 {
510
511 Result = errno;
512 LxtLogPassed("Case 13 failed as expected. %d", Result);
513 }
514 else
515 {
516 LxtLogError("Case 13 succeeded not expected! %p -> %p", FileMemory, RemappedMemory);
517 }
518
519 //
520 // Case 14: Split VAD during remap shrinking.
521 //
522
523 RemappedMemory = mremap(PrivateMemory, 2 * PAGE_SIZE, PAGE_SIZE, 0);
524
525 if (RemappedMemory == MAP_FAILED)
526 {
527
528 Result = errno;
529 LxtLogError("Case 14 failed! %d", Result);
530 }
531 else
532 {
533
534 LxtLogPassed("Case 14 succeeded. %p -> %p", PrivateMemory, RemappedMemory);
535 PrivateMemory = RemappedMemory;
536
537 FailByte = CheckMemory(RemappedMemory, PAGE_SIZE, 90);
538
539 if (FailByte != PAGE_SIZE)
540 {
541 LxtLogError("Case 14 first page memory doesn't match at byte %d!!!", FailByte);
542 }
543
544 FailByte = CheckMemory(RemappedMemory + (2 * PAGE_SIZE), PAGE_SIZE, 92);
545
546 if (FailByte != PAGE_SIZE)
547 {
548 LxtLogError("Case 14 third page memory doesn't match at byte %d!!!", FailByte);
549 }
550 }
551
552 //
553 // Case 15: Partially committed and no-access private memory.
554 //
555
556 PrivateMemory = mmap(NULL, PAGE_SIZE * 3, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, 0, 0);
557
558 if (PrivateMemory == MAP_FAILED)
559 {
560 Result = errno;
561 LxtLogError("Case 15 map failed! %d", Result);
562 goto ErrorExit;
563 }
564
565 FillMemory(PrivateMemory, PAGE_SIZE, 100);
566 FillMemory(PrivateMemory + (2 * PAGE_SIZE), PAGE_SIZE, 102);
567
568 Result = mprotect(PrivateMemory, PAGE_SIZE * 3, PROT_NONE);
569
570 if (Result == -1)
571 {
572 Result = errno;
573 LxtLogError("Case 15 protection change failed! %d", Result);
574 goto ErrorExit;
575 }
576
577 RemappedMemory = mremap(PrivateMemory, 3 * PAGE_SIZE, 33 * PAGE_SIZE, MREMAP_MAYMOVE);
578
579 if (RemappedMemory == MAP_FAILED)
580 {
581
582 Result = errno;
583 LxtLogError("Case 15 failed! %d", Result);
584 }
585 else
586 {
587
588 LxtLogPassed("Case 15 succeeded. %p -> %p", PrivateMemory, RemappedMemory);
589 PrivateMemory = RemappedMemory;
590
591 Result = mprotect(PrivateMemory, (33 * PAGE_SIZE), PROT_READ | PROT_WRITE);
592
593 if (Result == -1)
594 {
595 Result = errno;
596 LxtLogError("Case 15 protection change failed! %d", Result);
597 goto ErrorExit;
598 }
599
600 FailByte = CheckMemory(RemappedMemory, PAGE_SIZE, 100);
601
602 if (FailByte != PAGE_SIZE)
603 {
604 LxtLogError("Case 15 first page memory doesn't match at byte %d!!!", FailByte);
605 }
606
607 FailByte = CheckMemory(RemappedMemory + (2 * PAGE_SIZE), PAGE_SIZE, 102);
608
609 if (FailByte != PAGE_SIZE)
610 {
611 LxtLogError("Case 15 third page memory doesn't match at byte %d!!!", FailByte);
612 }
613
614 FillMemory(PrivateMemory + (3 * PAGE_SIZE), (30 * PAGE_SIZE), 103);
615 }
616
617 //
618 // Case 16: Remap private and shared file mapping of the same file.
619 //
620
621 FileMemory = mmap(NULL, 2 * PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, FileDescriptor, 0);
622
623 if (FileMemory == MAP_FAILED)
624 {
625 Result = errno;
626 LxtLogError("Case 16 first page map failed! %d", Result);
627 goto ErrorExit;
628 }
629
630 RemappedMemory = mmap(FileMemory + PAGE_SIZE, PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_FIXED, FileDescriptor, PAGE_SIZE);
631
632 if (RemappedMemory == MAP_FAILED)
633 {
634 Result = errno;
635 LxtLogError("Case 16 second page map failed! %d", Result);
636 goto ErrorExit;
637 }
638
639 RemappedMemory = mremap(FileMemory, 2 * PAGE_SIZE, 3 * PAGE_SIZE, MREMAP_MAYMOVE);
640
641 if (RemappedMemory == MAP_FAILED)
642 {
643
644 Result = errno;
645 LxtLogPassed("Case 16 failed as expected. %d", Result);
646 }
647 else
648 {
649 LxtLogError("Case 16 succeeded not expected! %p -> %p", FileMemory, RemappedMemory);
650 }
651
652 //
653 // Case 17: Remap private section view with no pages copy-on-written.
654 //
655
656 write(FileDescriptor, FileBuffer, PAGE_SIZE);
657
658 FileMemory = mmap(NULL, 4 * PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, FileDescriptor, 0);
659
660 if (FileMemory == MAP_FAILED)
661 {
662 Result = errno;
663 LxtLogError("Case 17 map failed! %d", Result);
664 goto ErrorExit;
665 }
666
667 FillMemory(FileMemory, 4 * PAGE_SIZE, 110);
668
669 FileMemory = mmap(FileMemory, 2 * PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_FIXED, FileDescriptor, 0);
670
671 if (FileMemory == MAP_FAILED)
672 {
673 Result = errno;
674 LxtLogError("Case 17 private map failed! %d", Result);
675 goto ErrorExit;
676 }
677
678 RemappedMemory = mremap(FileMemory, 2 * PAGE_SIZE, 4 * PAGE_SIZE, MREMAP_MAYMOVE);
679
680 if (RemappedMemory == MAP_FAILED)
681 {
682
683 Result = errno;
684 LxtLogError("Case 17 failed! %d", Result);
685 }
686 else
687 {
688
689 LxtLogPassed("Case 17 succeeded. %p -> %p", FileMemory, RemappedMemory);
690 FileMemory = RemappedMemory;
691
692 FailByte = CheckMemory(RemappedMemory, 4 * PAGE_SIZE, 110);
693
694 if (FailByte != (4 * PAGE_SIZE))
695 {
696 LxtLogError("Case 17 memory doesn't match at byte %d!!!", FailByte);
697 }
698 }
699
700 //
701 // Case 18: Remap private section view with some pages copy-on-written.
702 //
703
704 FillMemory((FileMemory + PAGE_SIZE), PAGE_SIZE, 120);
705
706 RemappedMemory = mremap(FileMemory, 3 * PAGE_SIZE, 4 * PAGE_SIZE, MREMAP_MAYMOVE);
707
708 if (RemappedMemory == MAP_FAILED)
709 {
710
711 Result = errno;
712 LxtLogError("Case 18 failed! %d", Result);
713 }
714 else
715 {
716
717 LxtLogPassed("Case 18 succeeded. %p -> %p", FileMemory, RemappedMemory);
718 FileMemory = RemappedMemory;
719
720 FailByte = CheckMemory(RemappedMemory, PAGE_SIZE, 110);
721
722 if (FailByte != PAGE_SIZE)
723 {
724 LxtLogError("Case 18 first page memory doesn't match at byte %d!!!", FailByte);
725 }
726
727 FailByte = CheckMemory(RemappedMemory + PAGE_SIZE, PAGE_SIZE, 120);
728
729 if (FailByte != PAGE_SIZE)
730 {
731 LxtLogError("Case 18 second page memory doesn't match at byte %d!!!", FailByte);
732 }
733
734 FailByte = CheckMemory(RemappedMemory + (2 * PAGE_SIZE), (2 * PAGE_SIZE), 112);
735
736 if (FailByte != (2 * PAGE_SIZE))
737 {
738 LxtLogError("Case 18 third/fourth page memory doesn't match at byte %d!!!", FailByte);
739 }
740 }
741
742 //
743 // Case 19: Large region of copy-on-written pages with same protection.
744 //
745
746 FileSize = (512 * 1024);
747
748 FileDescriptor2 = open("/data/test2.bin", O_RDWR | O_CREAT | O_TRUNC, S_IRWXU);
749
750 if (FileDescriptor2 == -1)
751 {
752 Result = errno;
753 LxtLogError("Could not create test file! %d", Result);
754 goto ErrorExit;
755 }
756
757 for (FailByte = 0; FailByte < (FileSize / PAGE_SIZE); FailByte += 1)
758 {
759 write(FileDescriptor2, FileBuffer, PAGE_SIZE);
760 }
761
762 FileMemory = mmap(NULL, FileSize, PROT_READ | PROT_WRITE, MAP_SHARED, FileDescriptor2, 0);
763
764 if (FileMemory == MAP_FAILED)
765 {
766 Result = errno;
767 LxtLogError("Case 19 map failed! %d", Result);
768 goto ErrorExit;
769 }
770
771 FillMemory(FileMemory, FileSize, 0);
772
773 FileMemory = mmap(FileMemory, FileSize, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_FIXED, FileDescriptor2, 0);
774
775 if (FileMemory == MAP_FAILED)
776 {
777 Result = errno;
778 LxtLogError("Case 19 map failed! %d", Result);
779 goto ErrorExit;
780 }
781
782 FillMemory(FileMemory + (3 * PAGE_SIZE), FileSize - (6 * PAGE_SIZE), 130);
783
784 Result = mprotect(FileMemory, FileSize, PROT_READ);
785
786 if (Result == -1)
787 {
788 Result = errno;
789 LxtLogError("Case 19 protection change failed! %d", Result);
790 goto ErrorExit;
791 }
792
793 RemappedMemory = mremap(FileMemory, FileSize - PAGE_SIZE, FileSize, MREMAP_MAYMOVE);
794
795 if (RemappedMemory == MAP_FAILED)
796 {
797
798 Result = errno;
799 LxtLogError("Case 19 failed! %d", Result);
800 }
801 else
802 {
803
804 LxtLogPassed("Case 19 succeeded. %p -> %p", FileMemory, RemappedMemory);
805 FileMemory = RemappedMemory;
806
807 FailByte = CheckMemory(RemappedMemory, (3 * PAGE_SIZE), 0);
808
809 if (FailByte != (3 * PAGE_SIZE))
810 {
811 LxtLogError("Case 19 first pages memory doesn't match at byte %d!!!", FailByte);
812 }
813
814 FailByte = CheckMemory(RemappedMemory + (3 * PAGE_SIZE), FileSize - (6 * PAGE_SIZE), 130);
815
816 if (FailByte != FileSize - (6 * PAGE_SIZE))
817 {
818 LxtLogError("Case 19 middle pages memory doesn't match at byte %d!!!", FailByte);
819 }
820
821 FailByte = CheckMemory(RemappedMemory + FileSize - (3 * PAGE_SIZE), (3 * PAGE_SIZE), ((FileSize / PAGE_SIZE) - 3));
822
823 if (FailByte != (3 * PAGE_SIZE))
824 {
825 LxtLogError("Case 19 third pages memory doesn't match at byte %d!!!", FailByte);
826 }
827 }
828
829 //
830 // Case 20: Remap an inconsistent DONT_FORK range.
831 //
832
833 PrivateMemory = mmap(NULL, PAGE_SIZE * 3, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, 0, 0);
834
835 if (PrivateMemory == MAP_FAILED)
836 {
837 Result = errno;
838 LxtLogError("Case 20 map failed! %d", Result);
839 goto ErrorExit;
840 }
841
842 FillMemory(PrivateMemory, PAGE_SIZE * 3, 140);
843
844 Result = madvise(PrivateMemory, 1 * PAGE_SIZE, MADV_DONTFORK);
845
846 if (Result == -1)
847 {
848 Result = errno;
849 LxtLogError("Case 20 madvise failed! %d", Result);
850 goto ErrorExit;
851 }
852
853 RemappedMemory = mremap(PrivateMemory, PAGE_SIZE * 2, PAGE_SIZE * 3, MREMAP_MAYMOVE);
854
855 if (RemappedMemory == MAP_FAILED)
856 {
857
858 Result = errno;
859 LxtLogPassed("Case 20 failed as expected. %d", Result);
860 }
861 else
862 {
863
864 LxtLogError("Case 20 succeeded not expected! %p -> %p", PrivateMemory, RemappedMemory);
865 PrivateMemory = RemappedMemory;
866 }
867
868 //
869 // Case 21: Remap a DONT_FORK range.
870 //
871
872 Result = madvise(PrivateMemory, 3 * PAGE_SIZE, MADV_DONTFORK);
873
874 if (Result == -1)
875 {
876 Result = errno;
877 LxtLogError("Case 21 madvise failed! %d", Result);
878 goto ErrorExit;
879 }
880
881 RemappedMemory = mremap(PrivateMemory, PAGE_SIZE * 2, PAGE_SIZE * 3, MREMAP_MAYMOVE);
882
883 if (RemappedMemory == MAP_FAILED)
884 {
885
886 Result = errno;
887 LxtLogError("Case 21 failed! %d", Result);
888 }
889 else
890 {
891
892 LxtLogPassed("Case 21 succeeded. %p -> %p", PrivateMemory, RemappedMemory);
893 PrivateMemory = RemappedMemory;
894 }
895
896 //
897 // \Dev\Zero tests.
898 //
899
900 DevZeroDescriptor = open("/dev/zero", O_RDWR);
901
902 if (DevZeroDescriptor == -1)
903 {
904 Result = errno;
905 LxtLogError("Could not open \\dev\\zero device! %d", Result);
906 goto ErrorExit;
907 }
908
909 memset(FileBuffer, 1, PAGE_SIZE);
910
911 Result = write(DevZeroDescriptor, FileBuffer, PAGE_SIZE);
912
913 if (Result == -1)
914 {
915 Result = errno;
916 LxtLogError("Failed to write to \\dev\\zero! %d", Result);
917 }
918 else
919 {
920 LxtLogInfo("Write to \\dev\\zero result: %d", Result);
921 }
922
923 memset(FileBuffer, 5, PAGE_SIZE);
924
925 Result = read(DevZeroDescriptor, FileBuffer, PAGE_SIZE);
926
927 if (Result == -1)
928 {
929 Result = errno;
930 LxtLogError("Failed to read from \\dev\\zero! %d", Result);
931 }
932 else
933 {
934
935 FailByte = CheckMemory(FileBuffer, PAGE_SIZE, 0);
936
937 if (FailByte == PAGE_SIZE)
938 {
939 LxtLogInfo("Read all zeroes from \\dev\\zero as expected.");
940 }
941 }
942
943 //
944 // Case 22: Remap private \dev\zero mapping.
945 //
946
947 FileMemory = mmap(NULL, 1 * 1024 * 1024, PROT_READ | PROT_WRITE, MAP_PRIVATE, DevZeroDescriptor, 0);
948
949 if (FileMemory == MAP_FAILED)
950 {
951 Result = errno;
952 LxtLogError("Case 22 first map failed! %d", Result);
953 goto ErrorExit;
954 }
955
956 FillMemory(FileMemory, 50 * PAGE_SIZE, 1);
957
958 RemappedMemory = mremap(FileMemory, 100 * PAGE_SIZE, 10 * 1024 * 1024, MREMAP_MAYMOVE);
959
960 if (RemappedMemory == MAP_FAILED)
961 {
962
963 Result = errno;
964 LxtLogError("Case 22 remap failed! %d", Result);
965 }
966 else
967 {
968
969 LxtLogPassed("Case 22 succeeded. %p -> %p", FileMemory, RemappedMemory);
970 FileMemory = RemappedMemory;
971
972 FailByte = CheckMemory(RemappedMemory, (50 * PAGE_SIZE), 1);
973
974 if (FailByte != (50 * PAGE_SIZE))
975 {
976 LxtLogError("Case 22 first pages memory doesn't match at byte %d!!!", FailByte);
977 }
978
979 FailByte = CheckMemory(RemappedMemory + (50 * PAGE_SIZE), PAGE_SIZE, 0);
980
981 if (FailByte != PAGE_SIZE)
982 {
983 LxtLogError("Case 22 second pages not zero!");
984 }
985
986 FillMemory(RemappedMemory, 10 * 1024 * 1024, 1);
987
988 FailByte = CheckMemory(FileMemory, 10 * 1024 * 1024, 1);
989
990 if (FailByte != (10 * 1024 * 1024))
991 {
992 LxtLogError("Case 22 memory doesn't match!");
993 }
994 }
995
996 //
997 // Case 23: Second private mapping of \dev\zero of same file descriptor
998 // does not share memory with the first private mapping.
999 //
1000
1001 FileMemory2 = mmap(NULL, 2 * 1024 * 1024, PROT_READ | PROT_WRITE, MAP_PRIVATE, DevZeroDescriptor, 0);
1002
1003 if (FileMemory2 == MAP_FAILED)
1004 {
1005 Result = errno;
1006 LxtLogError("Case 23 map failed! %d", Result);
1007 goto ErrorExit;
1008 }
1009
1010 FailByte = CheckMemory(FileMemory2, PAGE_SIZE, 0);
1011
1012 if (FailByte != PAGE_SIZE)
1013 {
1014 LxtLogError("Case 23 expected second private mapping to be full of zeroes!");
1015 }
1016
1017 //
1018 // Case 24: Remap shared \dev\zero mapping.
1019 //
1020
1021 FileMemory = mmap(NULL, 1 * 1024 * 1024, PROT_READ | PROT_WRITE, MAP_SHARED, DevZeroDescriptor, 0);
1022
1023 if (FileMemory == MAP_FAILED)
1024 {
1025 Result = errno;
1026 LxtLogError("Case 24 map failed! %d", Result);
1027 goto ErrorExit;
1028 }
1029
1030 FillMemory(FileMemory, 50 * PAGE_SIZE, 1);
1031
1032 RemappedMemory = mremap(FileMemory, 100 * PAGE_SIZE, 1 * 1024 * 1024, MREMAP_MAYMOVE);
1033
1034 if (RemappedMemory == MAP_FAILED)
1035 {
1036
1037 Result = errno;
1038 LxtLogError("Case 24 remap failed! %d", Result);
1039 }
1040 else
1041 {
1042
1043 LxtLogPassed("Case 24 succeeded. %p -> %p", FileMemory, RemappedMemory);
1044 FileMemory = RemappedMemory;
1045
1046 FailByte = CheckMemory(RemappedMemory, (50 * PAGE_SIZE), 1);
1047
1048 if (FailByte != (50 * PAGE_SIZE))
1049 {
1050 LxtLogError("Case 24 first pages memory doesn't match at byte %d!!!", FailByte);
1051 }
1052
1053 FailByte = CheckMemory(RemappedMemory + (50 * PAGE_SIZE), PAGE_SIZE, 0);
1054
1055 if (FailByte != PAGE_SIZE)
1056 {
1057 LxtLogError("Case 24 second pages not zero!");
1058 }
1059
1060 FailByte = CheckMemory(RemappedMemory + (100 * PAGE_SIZE), PAGE_SIZE, 0);
1061
1062 if (FailByte != PAGE_SIZE)
1063 {
1064 LxtLogError("Case 24 third pages not zero!");
1065 }
1066
1067 FillMemory(RemappedMemory, 1 * 1024 * 1024, 1);
1068
1069 FailByte = CheckMemory(FileMemory, 1 * 1024 * 1024, 1);
1070
1071 if (FailByte != (1 * 1024 * 1024))
1072 {
1073 LxtLogError("Case 24 memory doesn't match!");
1074 }
1075 }
1076
1077 //
1078 // Case 25: Remap shared \dev\zero mapping smaller.
1079 //
1080
1081 RemappedMemory = mremap(FileMemory, 1 * 1024 * 1024, PAGE_SIZE, MREMAP_MAYMOVE);
1082
1083 if (RemappedMemory == MAP_FAILED)
1084 {
1085
1086 Result = errno;
1087 LxtLogError("Case 25 remap failed! %d", Result);
1088 }
1089 else
1090 {
1091
1092 LxtLogPassed("Case 25 succeeded. %p -> %p", FileMemory, RemappedMemory);
1093 FileMemory = RemappedMemory;
1094
1095 FailByte = CheckMemory(RemappedMemory, PAGE_SIZE, 1);
1096
1097 if (FailByte != PAGE_SIZE)
1098 {
1099 LxtLogError("Case 25 page memory doesn't match at byte %d!!!", FailByte);
1100 }
1101 }
1102
1103 //
1104 // Case 26: Map \dev\zero with a section offset.
1105 //
1106
1107 FileMemory = mmap(NULL, 20 * 1024 * 1024, PROT_READ | PROT_WRITE, MAP_PRIVATE, DevZeroDescriptor, 0x5000);
1108
1109 if (FileMemory == MAP_FAILED)
1110 {
1111 Result = errno;
1112 LxtLogError("Case 26 first map failed! %d", Result);
1113 goto ErrorExit;
1114 }
1115 FillMemory(FileMemory, (20 * 1024 * 1024), 1);
1116
1117 LxtLogPassed("Case 26 succeeded.");
1118
1119 //
1120 // Case 27: Remap shared anonymous mapping.
1121 //
1122
1123 SharedPrivateMemory = mmap(NULL, 3 * PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_SHARED, 0, 0);
1124
1125 if (SharedPrivateMemory == MAP_FAILED)
1126 {
1127 Result = errno;
1128 LxtLogError("Case 27 map failed! %d", Result);
1129 goto ErrorExit;
1130 }
1131
1132 FillMemory(SharedPrivateMemory, (2 * PAGE_SIZE), 10);
1133
1134 RemappedMemory = mremap(SharedPrivateMemory, 2 * PAGE_SIZE, 3 * PAGE_SIZE, MREMAP_MAYMOVE);
1135
1136 if (RemappedMemory == MAP_FAILED)
1137 {
1138
1139 Result = errno;
1140 LxtLogError("Case 27 remap failed! %d", Result);
1141 }
1142 else
1143 {
1144
1145 LxtLogPassed("Case 27 succeeded. %p -> %p", SharedPrivateMemory, RemappedMemory);
1146 SharedPrivateMemory = RemappedMemory;
1147
1148 FailByte = CheckMemory(RemappedMemory, (2 * PAGE_SIZE), 10);
1149
1150 if (FailByte != (2 * PAGE_SIZE))
1151 {
1152 LxtLogError("Case 27 page memory doesn't match at byte %d!!!", FailByte);
1153 }
1154
1155 FillMemory(RemappedMemory + (2 * PAGE_SIZE), PAGE_SIZE, 12);
1156 }
1157
1158 //
1159 // Case 28: Remap while chopping off tail.
1160 //
1161
1162 SharedPrivateMemory = mmap(NULL, 10 * PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, 0, 0);
1163
1164 if (SharedPrivateMemory == MAP_FAILED)
1165 {
1166 Result = errno;
1167 LxtLogError("Case 28 map failed! %d", Result);
1168 goto ErrorExit;
1169 }
1170
1171 FillMemory(SharedPrivateMemory, (10 * PAGE_SIZE), 10);
1172
1173 RemappedMemory = (char*)LxtMremap(
1174 SharedPrivateMemory, 3 * PAGE_SIZE, 20 * PAGE_SIZE, MREMAP_MAYMOVE | MREMAP_FIXED, SharedPrivateMemory + (5 * PAGE_SIZE));
1175
1176 if (RemappedMemory == MAP_FAILED)
1177 {
1178
1179 Result = errno;
1180 LxtLogError("Case 28 remap failed! %d", Result);
1181 }
1182 else
1183 {
1184
1185 LxtLogPassed("Case 28 succeeded. %p -> %p", SharedPrivateMemory, RemappedMemory);
1186 SharedPrivateMemory = RemappedMemory;
1187
1188 FailByte = CheckMemory(RemappedMemory, (3 * PAGE_SIZE), 10);
1189
1190 if (FailByte != (3 * PAGE_SIZE))
1191 {
1192 LxtLogError("Case 28 page memory doesn't match at byte %d!!!", FailByte);
1193 }
1194
1195 FillMemory(RemappedMemory + (3 * PAGE_SIZE), (17 * PAGE_SIZE), 13);
1196 }
1197
1198 //
1199 // Case 29: Remap while splitting source VAD.
1200 //
1201
1202 SharedPrivateMemory = mmap(NULL, 10 * PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, 0, 0);
1203
1204 if (SharedPrivateMemory == MAP_FAILED)
1205 {
1206 Result = errno;
1207 LxtLogError("Case 29 map failed! %d", Result);
1208 goto ErrorExit;
1209 }
1210
1211 FillMemory(SharedPrivateMemory, (10 * PAGE_SIZE), 10);
1212
1213 RemappedMemory = (char*)LxtMremap(
1214 SharedPrivateMemory + (5 * PAGE_SIZE), 4 * PAGE_SIZE, 2 * PAGE_SIZE, MREMAP_MAYMOVE | MREMAP_FIXED, SharedPrivateMemory + PAGE_SIZE);
1215
1216 if (RemappedMemory == MAP_FAILED)
1217 {
1218
1219 Result = errno;
1220 LxtLogError("Case 29 remap failed! %d", Result);
1221 }
1222 else
1223 {
1224
1225 LxtLogPassed("Case 29 succeeded. %p -> %p", SharedPrivateMemory, RemappedMemory);
1226
1227 FailByte = CheckMemory(SharedPrivateMemory, PAGE_SIZE, 10);
1228 if (FailByte != PAGE_SIZE)
1229 {
1230 LxtLogError("Case 29 first page memory doesn't match at byte %d!!!", FailByte);
1231 }
1232
1233 FailByte = CheckMemory(SharedPrivateMemory + PAGE_SIZE, (2 * PAGE_SIZE), 15);
1234 if (FailByte != (2 * PAGE_SIZE))
1235 {
1236 LxtLogError("Case 29 second pages memory doesn't match at byte %d!!!", FailByte);
1237 }
1238
1239 FailByte = CheckMemory(SharedPrivateMemory + (3 * PAGE_SIZE), (2 * PAGE_SIZE), 13);
1240 if (FailByte != (2 * PAGE_SIZE))
1241 {
1242 LxtLogError("Case 29 third page memory doesn't match at byte %d!!!", FailByte);
1243 }
1244
1245 FailByte = CheckMemory(SharedPrivateMemory + (9 * PAGE_SIZE), PAGE_SIZE, 19);
1246 if (FailByte != PAGE_SIZE)
1247 {
1248 LxtLogError("Case 29 last page memory doesn't match at byte %d!!!", FailByte);
1249 }
1250 }
1251
1252 fflush(NULL);
1253
1254 Thread = fork();
1255
1256 if (Thread == -1)
1257 {
1258 Result = errno;
1259 LxtLogError("Case 20 fork failed! %d", Result);
1260 goto ErrorExit;
1261 }
1262
1263 if (Thread == 0)
1264 {
1265 LxtLogInfo("Child");
1266 }
1267 else
1268 {
1269 usleep(1000 * 500);
1270 LxtLogInfo("Parent slept");
1271 }
1272
1273 MapsBuffer = mmap(NULL, (10 * 1024 * 1024), PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, 0, 0);
1274
1275 if (MapsBuffer == MAP_FAILED)
1276 {
1277 Result = errno;
1278 LxtLogError("MapsBuffer allocation failed! %d", Result);
1279 goto ErrorExit;
1280 }
1281
1282 LxtLogInfo("Maps (%p):", MapsBuffer);
1283
1284 if (Thread == 0)
1285 {
1286 LxtLogPassed("Child Done!");
1287 }
1288 else
1289 {
1290 LxtLogPassed("Parent Done!");
1291 }
1292
1293 ErrorExit:
1294 LxtUninitialize();
1295 return Result;
1296 }