/*++ Copyright (c) Microsoft. All rights reserved. Module Name: mremap.c Abstract: This file contains test cases for mremap(). --*/ #include "lxtcommon.h" #include "unittests.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #define LXT_NAME "mremap" void FillMemory(char* Memory, int Size, unsigned char Value) { int i; LxtLogInfo("FillMemory: %p, 0x%x, %u", Memory, Size, Value); for (i = 0; i < Size; i += 1) { if ((i != 0) && ((i % PAGE_SIZE) == 0)) { Value += 1; } Memory[i] = Value; } return; } int CheckMemory(unsigned char* Memory, int Size, unsigned char Value) { int i; LxtLogInfo("CheckMemory: %p, 0x%x, %u", Memory, Size, Value); for (i = 0; i < Size; i += 1) { if ((i != 0) && ((i % PAGE_SIZE) == 0)) { Value += 1; } if (Memory[i] != Value) { LxtLogError("Mismatched byte %d! Value: %d", i, (int)Memory[i]); break; } } return i; } void* ThreadWorker(void* Context) { char* Memory; int Result; LxtLogInfo("Thread started."); for (;;) { Memory = mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, 0, 0); if (Memory == MAP_FAILED) { Result = errno; LxtLogError("Thread memory allocation failed! %d", Result); goto ErrorExit; } munmap(Memory, PAGE_SIZE); } ErrorExit: return NULL; } int MremapTestEntry(int Argc, char* Argv[]) { LXT_ARGS Args; char* PrivateMemory; char* SharedPrivateMemory; char* FileMemory; char* FileMemory2; char* RemappedMemory; char* SpanMemory1; char* SpanMemory2; char* SpanMemory3; int Result; int FileDescriptor; int DevZeroDescriptor; int AllocationSize; char FileBuffer[3 * PAGE_SIZE]; int FailByte; int MapsDescriptor; int BytesRead; char* MapsBuffer; pthread_t Thread; int FileDescriptor2; int FileSize; struct timespec Time; LxtCheckResult(LxtInitialize(Argc, Argv, &Args, LXT_NAME)); LxtLogStart("Start Prep:"); Result = pthread_create(&Thread, NULL, ThreadWorker, NULL); if (Result != 0) { LxtLogError("Thread creation failed! %d", Result); goto ErrorExit; } LxtLogInfo("Thread created."); AllocationSize = 2 * PAGE_SIZE; PrivateMemory = mmap(NULL, AllocationSize, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, 0, 0); if (PrivateMemory == MAP_FAILED) { Result = errno; LxtLogError("PrivateMemory allocation failed! %d", Result); goto ErrorExit; } FillMemory(PrivateMemory, AllocationSize, 1); SharedPrivateMemory = mmap(NULL, AllocationSize, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_SHARED, 0, 0); if (SharedPrivateMemory == MAP_FAILED) { Result = errno; LxtLogError("SharedPrivateMemory allocation failed! %d", Result); goto ErrorExit; } FillMemory(SharedPrivateMemory, AllocationSize, 10); FileDescriptor = open("/data/test.bin", O_RDWR | O_CREAT | O_TRUNC, S_IRWXU); if (FileDescriptor == -1) { Result = errno; LxtLogError("Could not create test file! %d", Result); goto ErrorExit; } write(FileDescriptor, FileBuffer, sizeof(FileBuffer)); FileMemory = mmap(NULL, AllocationSize, PROT_READ | PROT_WRITE, MAP_SHARED, FileDescriptor, 0); if (FileMemory == MAP_FAILED) { Result = errno; LxtLogError("FileMemory allocation failed! %d", Result); goto ErrorExit; } FillMemory(FileMemory, AllocationSize, 20); SpanMemory3 = mmap(NULL, AllocationSize * 3, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_SHARED, 0, 0); if (SpanMemory3 == MAP_FAILED) { Result = errno; LxtLogError("SpanMemory1 allocation failed! %d", Result); goto ErrorExit; } FillMemory(SpanMemory3, AllocationSize * 3, 60); SpanMemory1 = mmap(SpanMemory3, AllocationSize, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE | MAP_FIXED, 0, 0); if (SpanMemory1 == MAP_FAILED) { Result = errno; LxtLogError("SpanMemory1 allocation failed! %d", Result); goto ErrorExit; } FillMemory(SpanMemory1, AllocationSize, 40); SpanMemory2 = mmap(SpanMemory1 + AllocationSize, AllocationSize, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE | MAP_FIXED, 0, 0); if (SpanMemory2 == MAP_FAILED) { Result = errno; LxtLogError("SpanMemory2 allocation failed! %d", Result); goto ErrorExit; } if (SpanMemory2 != (SpanMemory1 + AllocationSize)) { LxtLogError("SpanMemory2 allocation isn't in the right place!"); goto ErrorExit; } FillMemory(SpanMemory2, AllocationSize, 50); LxtLogPassed("Prep complete!"); LxtLogStart("Start Test Cases:"); // // Case 1: Extend private memory. // RemappedMemory = mremap(PrivateMemory, AllocationSize, AllocationSize + PAGE_SIZE, MREMAP_MAYMOVE); if (RemappedMemory == MAP_FAILED) { Result = errno; LxtLogError("Case 1 failed! %d", Result); } else { LxtLogPassed("Case 1 succeeded. %p -> %p", PrivateMemory, RemappedMemory); PrivateMemory = RemappedMemory; FailByte = CheckMemory(RemappedMemory, AllocationSize, 1); if (FailByte != AllocationSize) { LxtLogError("Case 1 memory doesn't match at byte %d!!!", FailByte); } FillMemory(RemappedMemory + AllocationSize, PAGE_SIZE, 3); } // // Case 3: Extend file mapping. // RemappedMemory = mremap(FileMemory, AllocationSize, AllocationSize + PAGE_SIZE, MREMAP_MAYMOVE); if (RemappedMemory == MAP_FAILED) { Result = errno; LxtLogError("Case 3 failed! %d", Result); } else { LxtLogPassed("Case 3 succeeded. %p -> %p", FileMemory, RemappedMemory); FileMemory = RemappedMemory; FailByte = CheckMemory(RemappedMemory, AllocationSize, 20); if (FailByte != AllocationSize) { LxtLogError("Case 3 memory doesn't match at byte %d!!!", FailByte); } FillMemory(RemappedMemory + AllocationSize, PAGE_SIZE, 22); } // // Case 7: Move range that spans two private allocations (same type). // RemappedMemory = mremap(SpanMemory1 + PAGE_SIZE, AllocationSize, AllocationSize + (2 * PAGE_SIZE), MREMAP_MAYMOVE); if (RemappedMemory == MAP_FAILED) { Result = errno; LxtLogError("Case 7 failed! %d", Result); } else { LxtLogPassed("Case 7 succeeded. %p -> %p", SpanMemory1 + PAGE_SIZE, RemappedMemory); FailByte = CheckMemory(RemappedMemory, PAGE_SIZE, 41); if (FailByte != PAGE_SIZE) { LxtLogError("Case 7 first page memory doesn't match at byte %d!!!", FailByte); } FailByte = CheckMemory(RemappedMemory + PAGE_SIZE, PAGE_SIZE, 50); if (FailByte != PAGE_SIZE) { LxtLogError("Case 7 second page memory doesn't match at byte %d!!! V: %d", FailByte); } } // // Case 8: Move range that spans two different allocations (private and shared anonymous). // RemappedMemory = mremap(SpanMemory2 + PAGE_SIZE, AllocationSize, AllocationSize + (2 * PAGE_SIZE), MREMAP_MAYMOVE); if (RemappedMemory == MAP_FAILED) { Result = errno; LxtLogPassed("Case 8 failed as expected. %d", Result); } else { LxtLogError("Case 8 succeeded not expected! %p -> %p", SpanMemory2 + PAGE_SIZE, RemappedMemory); FailByte = CheckMemory(RemappedMemory, PAGE_SIZE, 51); if (FailByte != PAGE_SIZE) { LxtLogError("Case 8 first page memory doesn't match at byte %d!!!", FailByte); } FailByte = CheckMemory(RemappedMemory + PAGE_SIZE, PAGE_SIZE, 60); if (FailByte != PAGE_SIZE) { LxtLogError("Case 8 second page memory doesn't match at byte %d!!!", FailByte); } } // // Case 9: Shrink private allocation. // RemappedMemory = mremap(PrivateMemory, AllocationSize + PAGE_SIZE, AllocationSize, 0); if (RemappedMemory == MAP_FAILED) { Result = errno; LxtLogError("Case 9 failed! %d", Result); } else { LxtLogPassed("Case 9 succeeded. %p -> %p", PrivateMemory, RemappedMemory); PrivateMemory = RemappedMemory; FailByte = CheckMemory(RemappedMemory, AllocationSize, 1); if (FailByte != AllocationSize) { LxtLogError("Case 9 memory doesn't match at byte %d!!!", FailByte); } } // // Case 10: Move and extend with different protections. // Result = mprotect(PrivateMemory, PAGE_SIZE, PROT_READ); if (Result == -1) { Result = errno; LxtLogError("Case 10 protection change failed! %d", Result); goto ErrorExit; } RemappedMemory = mremap(PrivateMemory, AllocationSize, AllocationSize + PAGE_SIZE, MREMAP_MAYMOVE); if (RemappedMemory == MAP_FAILED) { Result = errno; LxtLogPassed("Case 10 failed as expected. %d", Result); } else { LxtLogError("Case 10 succeeded not expected!. %p -> %p", PrivateMemory, RemappedMemory); PrivateMemory = RemappedMemory; FailByte = CheckMemory(RemappedMemory, AllocationSize, 1); if (FailByte != AllocationSize) { LxtLogError("Case 10 memory doesn't match at byte %d!!!", FailByte); } } // // Case 11: Move discontiguous (by mapping offset not VA) file mappings. // FileMemory = mmap(NULL, AllocationSize, PROT_READ | PROT_WRITE, MAP_SHARED, FileDescriptor, 0); if (FileMemory == MAP_FAILED) { Result = errno; LxtLogError("Case 11 map failed! %d", Result); goto ErrorExit; } FillMemory(FileMemory, AllocationSize, 70); RemappedMemory = mmap(FileMemory + PAGE_SIZE, PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_FIXED, FileDescriptor, 0x2000); if (RemappedMemory == MAP_FAILED) { Result = errno; LxtLogError("Case 11 map2 failed! %d", Result); goto ErrorExit; } RemappedMemory = mremap(FileMemory, AllocationSize, AllocationSize + (2 * PAGE_SIZE), MREMAP_MAYMOVE); if (RemappedMemory == MAP_FAILED) { Result = errno; LxtLogPassed("Case 11 failed as expected. %d", Result); } else { LxtLogError("Case 11 succeeded not expected!. %p -> %p", FileMemory, RemappedMemory); FailByte = CheckMemory(RemappedMemory, AllocationSize, 70); if (FailByte != PAGE_SIZE) { LxtLogError("Case 11 memory doesn't match at byte %d!!!", FailByte); } } // // Case 12: Extend within existing VAD (section). // FileMemory = mmap(NULL, 3 * PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, FileDescriptor, 0); if (FileMemory == MAP_FAILED) { Result = errno; LxtLogError("Case 12 map failed! %d", Result); goto ErrorExit; } FillMemory(FileMemory, 3 * PAGE_SIZE, 80); RemappedMemory = mremap(FileMemory, PAGE_SIZE, 3 * PAGE_SIZE, 0); if (RemappedMemory == MAP_FAILED) { Result = errno; LxtLogPassed("Case 12 failed as expected. %d", Result); } else { LxtLogError("Case 12 succeeded not expected! %p -> %p", FileMemory, RemappedMemory); FailByte = CheckMemory(RemappedMemory, 3 * PAGE_SIZE, 80); if (FailByte != PAGE_SIZE) { LxtLogError("Case 12 memory doesn't match at byte %d!!!", FailByte); } } // // Case 13: Extend within existing VAD (private). // PrivateMemory = mmap(NULL, PAGE_SIZE * 3, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, 0, 0); if (PrivateMemory == MAP_FAILED) { Result = errno; LxtLogError("Case 13 map failed! %d", Result); goto ErrorExit; } FillMemory(PrivateMemory, 3 * PAGE_SIZE, 90); RemappedMemory = mremap(PrivateMemory, PAGE_SIZE, 3 * PAGE_SIZE, 0); if (RemappedMemory == MAP_FAILED) { Result = errno; LxtLogPassed("Case 13 failed as expected. %d", Result); } else { LxtLogError("Case 13 succeeded not expected! %p -> %p", FileMemory, RemappedMemory); } // // Case 14: Split VAD during remap shrinking. // RemappedMemory = mremap(PrivateMemory, 2 * PAGE_SIZE, PAGE_SIZE, 0); if (RemappedMemory == MAP_FAILED) { Result = errno; LxtLogError("Case 14 failed! %d", Result); } else { LxtLogPassed("Case 14 succeeded. %p -> %p", PrivateMemory, RemappedMemory); PrivateMemory = RemappedMemory; FailByte = CheckMemory(RemappedMemory, PAGE_SIZE, 90); if (FailByte != PAGE_SIZE) { LxtLogError("Case 14 first page memory doesn't match at byte %d!!!", FailByte); } FailByte = CheckMemory(RemappedMemory + (2 * PAGE_SIZE), PAGE_SIZE, 92); if (FailByte != PAGE_SIZE) { LxtLogError("Case 14 third page memory doesn't match at byte %d!!!", FailByte); } } // // Case 15: Partially committed and no-access private memory. // PrivateMemory = mmap(NULL, PAGE_SIZE * 3, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, 0, 0); if (PrivateMemory == MAP_FAILED) { Result = errno; LxtLogError("Case 15 map failed! %d", Result); goto ErrorExit; } FillMemory(PrivateMemory, PAGE_SIZE, 100); FillMemory(PrivateMemory + (2 * PAGE_SIZE), PAGE_SIZE, 102); Result = mprotect(PrivateMemory, PAGE_SIZE * 3, PROT_NONE); if (Result == -1) { Result = errno; LxtLogError("Case 15 protection change failed! %d", Result); goto ErrorExit; } RemappedMemory = mremap(PrivateMemory, 3 * PAGE_SIZE, 33 * PAGE_SIZE, MREMAP_MAYMOVE); if (RemappedMemory == MAP_FAILED) { Result = errno; LxtLogError("Case 15 failed! %d", Result); } else { LxtLogPassed("Case 15 succeeded. %p -> %p", PrivateMemory, RemappedMemory); PrivateMemory = RemappedMemory; Result = mprotect(PrivateMemory, (33 * PAGE_SIZE), PROT_READ | PROT_WRITE); if (Result == -1) { Result = errno; LxtLogError("Case 15 protection change failed! %d", Result); goto ErrorExit; } FailByte = CheckMemory(RemappedMemory, PAGE_SIZE, 100); if (FailByte != PAGE_SIZE) { LxtLogError("Case 15 first page memory doesn't match at byte %d!!!", FailByte); } FailByte = CheckMemory(RemappedMemory + (2 * PAGE_SIZE), PAGE_SIZE, 102); if (FailByte != PAGE_SIZE) { LxtLogError("Case 15 third page memory doesn't match at byte %d!!!", FailByte); } FillMemory(PrivateMemory + (3 * PAGE_SIZE), (30 * PAGE_SIZE), 103); } // // Case 16: Remap private and shared file mapping of the same file. // FileMemory = mmap(NULL, 2 * PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, FileDescriptor, 0); if (FileMemory == MAP_FAILED) { Result = errno; LxtLogError("Case 16 first page map failed! %d", Result); goto ErrorExit; } RemappedMemory = mmap(FileMemory + PAGE_SIZE, PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_FIXED, FileDescriptor, PAGE_SIZE); if (RemappedMemory == MAP_FAILED) { Result = errno; LxtLogError("Case 16 second page map failed! %d", Result); goto ErrorExit; } RemappedMemory = mremap(FileMemory, 2 * PAGE_SIZE, 3 * PAGE_SIZE, MREMAP_MAYMOVE); if (RemappedMemory == MAP_FAILED) { Result = errno; LxtLogPassed("Case 16 failed as expected. %d", Result); } else { LxtLogError("Case 16 succeeded not expected! %p -> %p", FileMemory, RemappedMemory); } // // Case 17: Remap private section view with no pages copy-on-written. // write(FileDescriptor, FileBuffer, PAGE_SIZE); FileMemory = mmap(NULL, 4 * PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, FileDescriptor, 0); if (FileMemory == MAP_FAILED) { Result = errno; LxtLogError("Case 17 map failed! %d", Result); goto ErrorExit; } FillMemory(FileMemory, 4 * PAGE_SIZE, 110); FileMemory = mmap(FileMemory, 2 * PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_FIXED, FileDescriptor, 0); if (FileMemory == MAP_FAILED) { Result = errno; LxtLogError("Case 17 private map failed! %d", Result); goto ErrorExit; } RemappedMemory = mremap(FileMemory, 2 * PAGE_SIZE, 4 * PAGE_SIZE, MREMAP_MAYMOVE); if (RemappedMemory == MAP_FAILED) { Result = errno; LxtLogError("Case 17 failed! %d", Result); } else { LxtLogPassed("Case 17 succeeded. %p -> %p", FileMemory, RemappedMemory); FileMemory = RemappedMemory; FailByte = CheckMemory(RemappedMemory, 4 * PAGE_SIZE, 110); if (FailByte != (4 * PAGE_SIZE)) { LxtLogError("Case 17 memory doesn't match at byte %d!!!", FailByte); } } // // Case 18: Remap private section view with some pages copy-on-written. // FillMemory((FileMemory + PAGE_SIZE), PAGE_SIZE, 120); RemappedMemory = mremap(FileMemory, 3 * PAGE_SIZE, 4 * PAGE_SIZE, MREMAP_MAYMOVE); if (RemappedMemory == MAP_FAILED) { Result = errno; LxtLogError("Case 18 failed! %d", Result); } else { LxtLogPassed("Case 18 succeeded. %p -> %p", FileMemory, RemappedMemory); FileMemory = RemappedMemory; FailByte = CheckMemory(RemappedMemory, PAGE_SIZE, 110); if (FailByte != PAGE_SIZE) { LxtLogError("Case 18 first page memory doesn't match at byte %d!!!", FailByte); } FailByte = CheckMemory(RemappedMemory + PAGE_SIZE, PAGE_SIZE, 120); if (FailByte != PAGE_SIZE) { LxtLogError("Case 18 second page memory doesn't match at byte %d!!!", FailByte); } FailByte = CheckMemory(RemappedMemory + (2 * PAGE_SIZE), (2 * PAGE_SIZE), 112); if (FailByte != (2 * PAGE_SIZE)) { LxtLogError("Case 18 third/fourth page memory doesn't match at byte %d!!!", FailByte); } } // // Case 19: Large region of copy-on-written pages with same protection. // FileSize = (512 * 1024); FileDescriptor2 = open("/data/test2.bin", O_RDWR | O_CREAT | O_TRUNC, S_IRWXU); if (FileDescriptor2 == -1) { Result = errno; LxtLogError("Could not create test file! %d", Result); goto ErrorExit; } for (FailByte = 0; FailByte < (FileSize / PAGE_SIZE); FailByte += 1) { write(FileDescriptor2, FileBuffer, PAGE_SIZE); } FileMemory = mmap(NULL, FileSize, PROT_READ | PROT_WRITE, MAP_SHARED, FileDescriptor2, 0); if (FileMemory == MAP_FAILED) { Result = errno; LxtLogError("Case 19 map failed! %d", Result); goto ErrorExit; } FillMemory(FileMemory, FileSize, 0); FileMemory = mmap(FileMemory, FileSize, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_FIXED, FileDescriptor2, 0); if (FileMemory == MAP_FAILED) { Result = errno; LxtLogError("Case 19 map failed! %d", Result); goto ErrorExit; } FillMemory(FileMemory + (3 * PAGE_SIZE), FileSize - (6 * PAGE_SIZE), 130); Result = mprotect(FileMemory, FileSize, PROT_READ); if (Result == -1) { Result = errno; LxtLogError("Case 19 protection change failed! %d", Result); goto ErrorExit; } RemappedMemory = mremap(FileMemory, FileSize - PAGE_SIZE, FileSize, MREMAP_MAYMOVE); if (RemappedMemory == MAP_FAILED) { Result = errno; LxtLogError("Case 19 failed! %d", Result); } else { LxtLogPassed("Case 19 succeeded. %p -> %p", FileMemory, RemappedMemory); FileMemory = RemappedMemory; FailByte = CheckMemory(RemappedMemory, (3 * PAGE_SIZE), 0); if (FailByte != (3 * PAGE_SIZE)) { LxtLogError("Case 19 first pages memory doesn't match at byte %d!!!", FailByte); } FailByte = CheckMemory(RemappedMemory + (3 * PAGE_SIZE), FileSize - (6 * PAGE_SIZE), 130); if (FailByte != FileSize - (6 * PAGE_SIZE)) { LxtLogError("Case 19 middle pages memory doesn't match at byte %d!!!", FailByte); } FailByte = CheckMemory(RemappedMemory + FileSize - (3 * PAGE_SIZE), (3 * PAGE_SIZE), ((FileSize / PAGE_SIZE) - 3)); if (FailByte != (3 * PAGE_SIZE)) { LxtLogError("Case 19 third pages memory doesn't match at byte %d!!!", FailByte); } } // // Case 20: Remap an inconsistent DONT_FORK range. // PrivateMemory = mmap(NULL, PAGE_SIZE * 3, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, 0, 0); if (PrivateMemory == MAP_FAILED) { Result = errno; LxtLogError("Case 20 map failed! %d", Result); goto ErrorExit; } FillMemory(PrivateMemory, PAGE_SIZE * 3, 140); Result = madvise(PrivateMemory, 1 * PAGE_SIZE, MADV_DONTFORK); if (Result == -1) { Result = errno; LxtLogError("Case 20 madvise failed! %d", Result); goto ErrorExit; } RemappedMemory = mremap(PrivateMemory, PAGE_SIZE * 2, PAGE_SIZE * 3, MREMAP_MAYMOVE); if (RemappedMemory == MAP_FAILED) { Result = errno; LxtLogPassed("Case 20 failed as expected. %d", Result); } else { LxtLogError("Case 20 succeeded not expected! %p -> %p", PrivateMemory, RemappedMemory); PrivateMemory = RemappedMemory; } // // Case 21: Remap a DONT_FORK range. // Result = madvise(PrivateMemory, 3 * PAGE_SIZE, MADV_DONTFORK); if (Result == -1) { Result = errno; LxtLogError("Case 21 madvise failed! %d", Result); goto ErrorExit; } RemappedMemory = mremap(PrivateMemory, PAGE_SIZE * 2, PAGE_SIZE * 3, MREMAP_MAYMOVE); if (RemappedMemory == MAP_FAILED) { Result = errno; LxtLogError("Case 21 failed! %d", Result); } else { LxtLogPassed("Case 21 succeeded. %p -> %p", PrivateMemory, RemappedMemory); PrivateMemory = RemappedMemory; } // // \Dev\Zero tests. // DevZeroDescriptor = open("/dev/zero", O_RDWR); if (DevZeroDescriptor == -1) { Result = errno; LxtLogError("Could not open \\dev\\zero device! %d", Result); goto ErrorExit; } memset(FileBuffer, 1, PAGE_SIZE); Result = write(DevZeroDescriptor, FileBuffer, PAGE_SIZE); if (Result == -1) { Result = errno; LxtLogError("Failed to write to \\dev\\zero! %d", Result); } else { LxtLogInfo("Write to \\dev\\zero result: %d", Result); } memset(FileBuffer, 5, PAGE_SIZE); Result = read(DevZeroDescriptor, FileBuffer, PAGE_SIZE); if (Result == -1) { Result = errno; LxtLogError("Failed to read from \\dev\\zero! %d", Result); } else { FailByte = CheckMemory(FileBuffer, PAGE_SIZE, 0); if (FailByte == PAGE_SIZE) { LxtLogInfo("Read all zeroes from \\dev\\zero as expected."); } } // // Case 22: Remap private \dev\zero mapping. // FileMemory = mmap(NULL, 1 * 1024 * 1024, PROT_READ | PROT_WRITE, MAP_PRIVATE, DevZeroDescriptor, 0); if (FileMemory == MAP_FAILED) { Result = errno; LxtLogError("Case 22 first map failed! %d", Result); goto ErrorExit; } FillMemory(FileMemory, 50 * PAGE_SIZE, 1); RemappedMemory = mremap(FileMemory, 100 * PAGE_SIZE, 10 * 1024 * 1024, MREMAP_MAYMOVE); if (RemappedMemory == MAP_FAILED) { Result = errno; LxtLogError("Case 22 remap failed! %d", Result); } else { LxtLogPassed("Case 22 succeeded. %p -> %p", FileMemory, RemappedMemory); FileMemory = RemappedMemory; FailByte = CheckMemory(RemappedMemory, (50 * PAGE_SIZE), 1); if (FailByte != (50 * PAGE_SIZE)) { LxtLogError("Case 22 first pages memory doesn't match at byte %d!!!", FailByte); } FailByte = CheckMemory(RemappedMemory + (50 * PAGE_SIZE), PAGE_SIZE, 0); if (FailByte != PAGE_SIZE) { LxtLogError("Case 22 second pages not zero!"); } FillMemory(RemappedMemory, 10 * 1024 * 1024, 1); FailByte = CheckMemory(FileMemory, 10 * 1024 * 1024, 1); if (FailByte != (10 * 1024 * 1024)) { LxtLogError("Case 22 memory doesn't match!"); } } // // Case 23: Second private mapping of \dev\zero of same file descriptor // does not share memory with the first private mapping. // FileMemory2 = mmap(NULL, 2 * 1024 * 1024, PROT_READ | PROT_WRITE, MAP_PRIVATE, DevZeroDescriptor, 0); if (FileMemory2 == MAP_FAILED) { Result = errno; LxtLogError("Case 23 map failed! %d", Result); goto ErrorExit; } FailByte = CheckMemory(FileMemory2, PAGE_SIZE, 0); if (FailByte != PAGE_SIZE) { LxtLogError("Case 23 expected second private mapping to be full of zeroes!"); } // // Case 24: Remap shared \dev\zero mapping. // FileMemory = mmap(NULL, 1 * 1024 * 1024, PROT_READ | PROT_WRITE, MAP_SHARED, DevZeroDescriptor, 0); if (FileMemory == MAP_FAILED) { Result = errno; LxtLogError("Case 24 map failed! %d", Result); goto ErrorExit; } FillMemory(FileMemory, 50 * PAGE_SIZE, 1); RemappedMemory = mremap(FileMemory, 100 * PAGE_SIZE, 1 * 1024 * 1024, MREMAP_MAYMOVE); if (RemappedMemory == MAP_FAILED) { Result = errno; LxtLogError("Case 24 remap failed! %d", Result); } else { LxtLogPassed("Case 24 succeeded. %p -> %p", FileMemory, RemappedMemory); FileMemory = RemappedMemory; FailByte = CheckMemory(RemappedMemory, (50 * PAGE_SIZE), 1); if (FailByte != (50 * PAGE_SIZE)) { LxtLogError("Case 24 first pages memory doesn't match at byte %d!!!", FailByte); } FailByte = CheckMemory(RemappedMemory + (50 * PAGE_SIZE), PAGE_SIZE, 0); if (FailByte != PAGE_SIZE) { LxtLogError("Case 24 second pages not zero!"); } FailByte = CheckMemory(RemappedMemory + (100 * PAGE_SIZE), PAGE_SIZE, 0); if (FailByte != PAGE_SIZE) { LxtLogError("Case 24 third pages not zero!"); } FillMemory(RemappedMemory, 1 * 1024 * 1024, 1); FailByte = CheckMemory(FileMemory, 1 * 1024 * 1024, 1); if (FailByte != (1 * 1024 * 1024)) { LxtLogError("Case 24 memory doesn't match!"); } } // // Case 25: Remap shared \dev\zero mapping smaller. // RemappedMemory = mremap(FileMemory, 1 * 1024 * 1024, PAGE_SIZE, MREMAP_MAYMOVE); if (RemappedMemory == MAP_FAILED) { Result = errno; LxtLogError("Case 25 remap failed! %d", Result); } else { LxtLogPassed("Case 25 succeeded. %p -> %p", FileMemory, RemappedMemory); FileMemory = RemappedMemory; FailByte = CheckMemory(RemappedMemory, PAGE_SIZE, 1); if (FailByte != PAGE_SIZE) { LxtLogError("Case 25 page memory doesn't match at byte %d!!!", FailByte); } } // // Case 26: Map \dev\zero with a section offset. // FileMemory = mmap(NULL, 20 * 1024 * 1024, PROT_READ | PROT_WRITE, MAP_PRIVATE, DevZeroDescriptor, 0x5000); if (FileMemory == MAP_FAILED) { Result = errno; LxtLogError("Case 26 first map failed! %d", Result); goto ErrorExit; } FillMemory(FileMemory, (20 * 1024 * 1024), 1); LxtLogPassed("Case 26 succeeded."); // // Case 27: Remap shared anonymous mapping. // SharedPrivateMemory = mmap(NULL, 3 * PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_SHARED, 0, 0); if (SharedPrivateMemory == MAP_FAILED) { Result = errno; LxtLogError("Case 27 map failed! %d", Result); goto ErrorExit; } FillMemory(SharedPrivateMemory, (2 * PAGE_SIZE), 10); RemappedMemory = mremap(SharedPrivateMemory, 2 * PAGE_SIZE, 3 * PAGE_SIZE, MREMAP_MAYMOVE); if (RemappedMemory == MAP_FAILED) { Result = errno; LxtLogError("Case 27 remap failed! %d", Result); } else { LxtLogPassed("Case 27 succeeded. %p -> %p", SharedPrivateMemory, RemappedMemory); SharedPrivateMemory = RemappedMemory; FailByte = CheckMemory(RemappedMemory, (2 * PAGE_SIZE), 10); if (FailByte != (2 * PAGE_SIZE)) { LxtLogError("Case 27 page memory doesn't match at byte %d!!!", FailByte); } FillMemory(RemappedMemory + (2 * PAGE_SIZE), PAGE_SIZE, 12); } // // Case 28: Remap while chopping off tail. // SharedPrivateMemory = mmap(NULL, 10 * PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, 0, 0); if (SharedPrivateMemory == MAP_FAILED) { Result = errno; LxtLogError("Case 28 map failed! %d", Result); goto ErrorExit; } FillMemory(SharedPrivateMemory, (10 * PAGE_SIZE), 10); RemappedMemory = (char*)LxtMremap( SharedPrivateMemory, 3 * PAGE_SIZE, 20 * PAGE_SIZE, MREMAP_MAYMOVE | MREMAP_FIXED, SharedPrivateMemory + (5 * PAGE_SIZE)); if (RemappedMemory == MAP_FAILED) { Result = errno; LxtLogError("Case 28 remap failed! %d", Result); } else { LxtLogPassed("Case 28 succeeded. %p -> %p", SharedPrivateMemory, RemappedMemory); SharedPrivateMemory = RemappedMemory; FailByte = CheckMemory(RemappedMemory, (3 * PAGE_SIZE), 10); if (FailByte != (3 * PAGE_SIZE)) { LxtLogError("Case 28 page memory doesn't match at byte %d!!!", FailByte); } FillMemory(RemappedMemory + (3 * PAGE_SIZE), (17 * PAGE_SIZE), 13); } // // Case 29: Remap while splitting source VAD. // SharedPrivateMemory = mmap(NULL, 10 * PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, 0, 0); if (SharedPrivateMemory == MAP_FAILED) { Result = errno; LxtLogError("Case 29 map failed! %d", Result); goto ErrorExit; } FillMemory(SharedPrivateMemory, (10 * PAGE_SIZE), 10); RemappedMemory = (char*)LxtMremap( SharedPrivateMemory + (5 * PAGE_SIZE), 4 * PAGE_SIZE, 2 * PAGE_SIZE, MREMAP_MAYMOVE | MREMAP_FIXED, SharedPrivateMemory + PAGE_SIZE); if (RemappedMemory == MAP_FAILED) { Result = errno; LxtLogError("Case 29 remap failed! %d", Result); } else { LxtLogPassed("Case 29 succeeded. %p -> %p", SharedPrivateMemory, RemappedMemory); FailByte = CheckMemory(SharedPrivateMemory, PAGE_SIZE, 10); if (FailByte != PAGE_SIZE) { LxtLogError("Case 29 first page memory doesn't match at byte %d!!!", FailByte); } FailByte = CheckMemory(SharedPrivateMemory + PAGE_SIZE, (2 * PAGE_SIZE), 15); if (FailByte != (2 * PAGE_SIZE)) { LxtLogError("Case 29 second pages memory doesn't match at byte %d!!!", FailByte); } FailByte = CheckMemory(SharedPrivateMemory + (3 * PAGE_SIZE), (2 * PAGE_SIZE), 13); if (FailByte != (2 * PAGE_SIZE)) { LxtLogError("Case 29 third page memory doesn't match at byte %d!!!", FailByte); } FailByte = CheckMemory(SharedPrivateMemory + (9 * PAGE_SIZE), PAGE_SIZE, 19); if (FailByte != PAGE_SIZE) { LxtLogError("Case 29 last page memory doesn't match at byte %d!!!", FailByte); } } fflush(NULL); Thread = fork(); if (Thread == -1) { Result = errno; LxtLogError("Case 20 fork failed! %d", Result); goto ErrorExit; } if (Thread == 0) { LxtLogInfo("Child"); } else { usleep(1000 * 500); LxtLogInfo("Parent slept"); } MapsBuffer = mmap(NULL, (10 * 1024 * 1024), PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, 0, 0); if (MapsBuffer == MAP_FAILED) { Result = errno; LxtLogError("MapsBuffer allocation failed! %d", Result); goto ErrorExit; } LxtLogInfo("Maps (%p):", MapsBuffer); if (Thread == 0) { LxtLogPassed("Child Done!"); } else { LxtLogPassed("Parent Done!"); } ErrorExit: LxtUninitialize(); return Result; }