// User-mode regression test for mmap-style native file mappings. #include #include #include #include #define TEST_MAP_SIZE 8192u static uint8_t gExpected[TEST_MAP_SIZE]; static void print(const char* s) { SYS_WRITE_CONSOLE_REQUEST req = { SysSvFromCstr(s) }; SysWriteConsole(&req); } static void print_u64(uint64_t v) { char buf[32]; int i = 0; if (v == 0) { print("0"); return; } while (v && i < (int)sizeof(buf)) { buf[i++] = (char)('0' + (v % 10)); v /= 10; } while (i--) { char c = buf[i]; SYS_WRITE_CONSOLE_REQUEST req = { SysSvFromParts(&c, 1) }; SysWriteConsole(&req); } } static void exit_now(int code) { // SysExitProcess should not return, but keep tests from falling through to // the synthetic entry frame if a broken kernel build returns anyway. while (true) SysExitProcess(code); } static void fail_status(const char* what, uint32_t status) { print("mmap_smoke: "); print(what); print(" failed status="); print_u64(status); print("\n"); exit_now(1); } static void fail_msg(const char* msg) { print("mmap_smoke: "); print(msg); print("\n"); exit_now(1); } static uint32_t open_first_existing(uint32_t* fileOut, const char** pathOut) { static const char* candidates[] = { "mmap_smoke.exe", "/apps/mmap_smoke.exe", "0:/apps/mmap_smoke.exe", "1:/apps/mmap_smoke.exe", "/system/init.exe", "0:/system/init.exe", "1:/system/init.exe", "system/init.exe", }; for (size_t i = 0; i < sizeof(candidates) / sizeof(candidates[0]); ++i) { uint32_t file = 0; SYS_OPEN_FILE_REQUEST openReq = SysMakeOpenFileRequest(SysSvFromCstr(candidates[i]), SYS_FILE_ACCESS_READ | SYS_FILE_ACCESS_QUERY, SYS_FILE_OPEN_EXISTING, SYS_FILE_FLAG_NONE, &file); uint32_t s = SysOpenFile(&openReq); if (s == NTLSTATUS_SUCCESS) { *fileOut = file; if (pathOut) *pathOut = candidates[i]; return NTLSTATUS_SUCCESS; } } return NTLSTATUS_NOT_FOUND; } int main(void) { print("mmap_smoke: start\n"); uint32_t file = 0; const char* openedPath = 0; uint32_t s = open_first_existing(&file, &openedPath); if (s != NTLSTATUS_SUCCESS) fail_status("open test file", s); print("mmap_smoke: using "); print(openedPath ? openedPath : ""); print("\n"); size_t got = 0; memset(gExpected, 0xA5, sizeof(gExpected)); SYS_FILE_IO_REQUEST ioReq = SysMakeFileIoRequest(file, gExpected, sizeof(gExpected), &got); s = SysReadFile(&ioReq); if (s != NTLSTATUS_SUCCESS) fail_status("read baseline", s); if (got < 64) fail_msg("baseline read was unexpectedly short"); print("mmap_smoke: baseline read OK\n"); uint32_t mapping = 0; s = SysCreateFileMapping(file, SYS_VM_READ, SYS_MAP_FLAG_NONE, sizeof(gExpected), &mapping); if (s != NTLSTATUS_SUCCESS) fail_status("create file mapping", s); print("mmap_smoke: mapping created\n"); // The mapping object must hold its own file reference. Closing the source // handle before SysMapFile catches lifetime bugs in the object layer. SysCloseHandle(file); file = 0; print("mmap_smoke: source handle closed\n"); void* base = 0; s = SysMapFile(mapping, 0, sizeof(gExpected), SYS_MAP_ACCESS_READ, SYS_MAP_FLAG_NONE, &base); SysCloseHandle(mapping); mapping = 0; if (s != NTLSTATUS_SUCCESS) fail_status("map file view", s); if (!base) fail_msg("map returned null base"); print("mmap_smoke: view mapped\n"); volatile uint8_t* view = (volatile uint8_t*)base; // Touch both pages before comparing. This ensures the test exercises // demand-faulted file-backed VAD pages rather than only VAD creation. (void)view[0]; print("mmap_smoke: first page fault OK\n"); (void)view[4096]; print("mmap_smoke: second page fault OK\n"); for (size_t i = 0; i < got; ++i) { if (view[i] != gExpected[i]) { print("mmap_smoke: byte mismatch at "); print_u64(i); print(" expected="); print_u64(gExpected[i]); print(" got="); print_u64(view[i]); print("\n"); SysFreeVm(base); exit_now(1); } } print("mmap_smoke: mapped bytes match\n"); // If the file is shorter than TEST_MAP_SIZE, the mapped tail must be // zero-filled rather than exposing stale physical memory. for (size_t i = got; i < sizeof(gExpected) && i < got + 64; ++i) { if (view[i] != 0) { print("mmap_smoke: nonzero EOF fill at "); print_u64(i); print(" got="); print_u64(view[i]); print("\n"); SysFreeVm(base); exit_now(1); } } print("mmap_smoke: EOF fill OK\n"); s = SysFreeVm(base); if (s != NTLSTATUS_SUCCESS) fail_status("unmap", s); print("mmap_smoke: PASS\n"); exit_now(0); return 0; }