blob: 2ad0a88d6f1b0b7e9bdf857e4e8f27f8582dcc19 [file] [log] [blame] [raw]
#include <sys/mman.h>
#include <windows.h>
#include <errno.h>
#include <io.h>
#ifndef FILE_MAP_EXECUTE
#define FILE_MAP_EXECUTE 0x0020
#endif /* FILE_MAP_EXECUTE */
static DWORD __map_mmap_prot_page(const int prot) {
DWORD protect = 0;
if(prot == PROT_NONE) return protect;
if((prot & PROT_EXEC) != 0) {
protect = ((prot & PROT_WRITE) != 0) ?
PAGE_EXECUTE_READWRITE : PAGE_EXECUTE_READ;
} else {
protect = ((prot & PROT_WRITE) != 0) ?
PAGE_READWRITE : PAGE_READONLY;
}
return protect;
}
static DWORD __map_mmap_prot_file(const int prot) {
DWORD desiredAccess = 0;
if(prot == PROT_NONE) return desiredAccess;
if((prot & PROT_READ) != 0) desiredAccess |= FILE_MAP_READ;
if((prot & PROT_WRITE) != 0) desiredAccess |= FILE_MAP_WRITE;
if((prot & PROT_EXEC) != 0) desiredAccess |= FILE_MAP_EXECUTE;
return desiredAccess;
}
void *mmap(void *addr, size_t len, int prot, int flags, int fildes, off_t off) {
HANDLE fm, h;
void *map = MAP_FAILED;
#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable: 4293)
#endif
const DWORD dwFileOffsetLow = (sizeof(off_t) <= sizeof(DWORD)) ?
(DWORD)off : (DWORD)(off & 0xFFFFFFFFL);
const DWORD dwFileOffsetHigh = (sizeof(off_t) <= sizeof(DWORD)) ?
(DWORD)0 : (DWORD)((off >> 32) & 0xFFFFFFFFL);
const DWORD protect = __map_mmap_prot_page(prot);
const DWORD desiredAccess = __map_mmap_prot_file(prot);
const off_t maxSize = off + (off_t)len;
const DWORD dwMaxSizeLow = (sizeof(off_t) <= sizeof(DWORD)) ?
(DWORD)maxSize : (DWORD)(maxSize & 0xFFFFFFFFL);
const DWORD dwMaxSizeHigh = (sizeof(off_t) <= sizeof(DWORD)) ?
(DWORD)0 : (DWORD)((maxSize >> 32) & 0xFFFFFFFFL);
#ifdef _MSC_VER
#pragma warning(pop)
#endif
errno = 0;
if(len == 0 ||
/* Unsupported flag combinations */
(flags & MAP_FIXED) ||
/* Usupported protection combinations */
prot == PROT_EXEC) {
errno = EINVAL;
return MAP_FAILED;
}
h = ((flags & MAP_ANONYMOUS) == 0) ? (void *)fildes : INVALID_HANDLE_VALUE;
if((flags & MAP_ANONYMOUS) == 0 && h == INVALID_HANDLE_VALUE) {
errno = EBADF;
return MAP_FAILED;
}
fm = CreateFileMappingW(h, NULL, protect, dwMaxSizeHigh, dwMaxSizeLow, NULL);
if(!fm) {
return MAP_FAILED;
}
map = MapViewOfFile(fm, desiredAccess, dwFileOffsetHigh, dwFileOffsetLow, len);
CloseHandle(fm);
if(!map) {
return MAP_FAILED;
}
return map;
}
int munmap(void *addr, size_t len) {
return UnmapViewOfFile(addr) ? 0 : -1;
}
int mprotect(void *addr, size_t len, int prot) {
DWORD newProtect = __map_mmap_prot_page(prot);
DWORD oldProtect = 0;
return VirtualProtect(addr, len, newProtect, &oldProtect) ? 0 : -1;
}
int msync(void *addr, size_t len, int flags) {
return FlushViewOfFile(addr, len) ? 0 : -1;
}
int mlock(const void *addr, size_t len) {
//if (VirtualLock((LPVOID)addr, len)) return 0;
errno = ENOSYS;
return -1;
}
int munlock(const void *addr, size_t len) {
//if (VirtualUnlock((LPVOID)addr, len)) return 0;
errno = ENOSYS;
return -1;
}