// POSIX compatibility support for mmap-style file mappings. #include #include #include #include "posix_internal.h" #include "posix_fd.h" static uint32_t PosixProtToSysMapAccess(int prot, int flags) { uint32_t access = 0; if (prot & PROT_EXEC) access |= SYS_MAP_ACCESS_EXECUTE; if (prot & PROT_WRITE) { access |= (flags & MAP_SHARED) ? SYS_MAP_ACCESS_WRITE : SYS_MAP_ACCESS_COPY; } else if (flags & MAP_PRIVATE) { access |= SYS_MAP_ACCESS_COPY; } if (prot & PROT_READ) access |= SYS_MAP_ACCESS_READ; if (!access) access = SYS_MAP_ACCESS_READ; return access; } __declspec(dllexport) void* mmap(void* addr, size_t length, int prot, int flags, int fd, off_t offset) { if (addr || length == 0 || offset < 0 || ((uint64_t)offset & 0xFFFu)) { errno = EINVAL; return MAP_FAILED; } if (!(flags & MAP_PRIVATE) && !(flags & MAP_SHARED)) { errno = EINVAL; return MAP_FAILED; } POSIX_OPEN_DESCRIPTION* description = PosixFdAcquire(fd); if (!description) return MAP_FAILED; if (description->Type != PosixFdFile) { PosixFdRelease(description); errno = EBADF; return MAP_FAILED; } uint64_t maxSize = (uint64_t)offset + (uint64_t)length; if (maxSize < (uint64_t)offset) { PosixFdRelease(description); errno = EINVAL; return MAP_FAILED; } uint32_t protect = (prot & PROT_WRITE) ? SYS_VM_READWRITE : SYS_VM_READ; if (prot & PROT_EXEC) protect = (prot & PROT_WRITE) ? SYS_VM_EXECUTE_READWRITE : SYS_VM_EXECUTE_READ; uint32_t mapping = 0; SYS_CREATE_FILE_MAPPING_REQUEST createMapping = { sizeof(SYS_CREATE_FILE_MAPPING_REQUEST), description->KHandle, protect, SYS_MAP_FLAG_NONE, maxSize, &mapping }; uint32_t s = SysCreateFileMapping(&createMapping); PosixFdRelease(description); if (s != NTLSTATUS_SUCCESS) { errno = PosixStatusToErrno(s); return MAP_FAILED; } void* base = (void*)0; SYS_MAP_FILE_REQUEST mapFile = { sizeof(SYS_MAP_FILE_REQUEST), mapping, PosixProtToSysMapAccess(prot, flags), SYS_MAP_FLAG_NONE, (uint64_t)offset, length, &base }; s = SysMapFile(&mapFile); SysCloseHandle(mapping); if (s != NTLSTATUS_SUCCESS) { errno = PosixStatusToErrno(s); return MAP_FAILED; } return base; } __declspec(dllexport) int munmap(void* addr, size_t length) { (void)length; if (!addr) { errno = EINVAL; return -1; } uint32_t s = SysFreeVm(addr); if (s != NTLSTATUS_SUCCESS) { errno = PosixStatusToErrno(s); return -1; } return 0; } __declspec(dllexport) int msync(void* addr, size_t length, int flags) { (void)addr; (void)length; (void)flags; return 0; }