Reimplement memmap.c for Windows

This commit is contained in:
twinaphex 2015-09-01 11:29:50 +02:00
parent d58771cbb1
commit aa282c5780
2 changed files with 61 additions and 110 deletions

View File

@ -34,23 +34,10 @@
#include <sys/mman.h> #include <sys/mman.h>
#endif #endif
#if !defined(HAVE_MMAN)
#define PROT_EXEC 0x04
#define MAP_FAILED 0
#define PROT_READ 0
#define PROT_WRITE 0
#define MAP_PRIVATE 0
#define MAP_ANONYMOUS 0
#endif
#ifndef MAP_ANONYMOUS
#define MAP_ANONYMOUS MAP_ANON
#endif
#if !defined(HAVE_MMAN) || defined(_WIN32) #if !defined(HAVE_MMAN) || defined(_WIN32)
void* mmap(void *desired_addr, size_t len, int mmap_prot, int mmap_flags, int fildes, size_t off); void* mmap(void *addr, size_t len, int mmap_prot, int mmap_flags, int fildes, size_t off);
void munmap(void *base_addr, size_t len); int munmap(void *addr, size_t len);
int mprotect(void *addr, size_t len, int prot); int mprotect(void *addr, size_t len, int prot);
#endif #endif

View File

@ -23,109 +23,72 @@
#include <stdint.h> #include <stdint.h>
#include <memmap.h> #include <memmap.h>
#ifndef PROT_READ
#define PROT_READ 0x1 /* Page can be read */
#endif
#ifndef PROT_WRITE
#define PROT_WRITE 0x2 /* Page can be written. */
#endif
#ifndef PROT_EXEC
#define PROT_EXEC 0x4 /* Page can be executed. */
#endif
#ifndef PROT_NONE
#define PROT_NONE 0x0 /* Page can not be accessed. */
#endif
#ifdef _WIN32 #ifdef _WIN32
#define MAP_SHARED 0x01
#ifndef MAP_PRIVATE
#define MAP_PRIVATE 0x02
#endif
#ifndef MAP_ANONYMOUS
#define MAP_ANONYMOUS 0x20
#endif
#define MAP_ANON MAP_ANONYMOUS
#define MAP_FAILED ((void *) -1)
#define PROT_READ 0x1
#define PROT_WRITE 0x2
/* This flag is only available in WinXP+ */
#ifdef FILE_MAP_EXECUTE
#ifndef PROT_EXEC
#define PROT_EXEC 0x4
#endif
#else
#ifndef PROT_EXEC
#define PROT_EXEC 0x0
#endif
#define FILE_MAP_EXECUTE 0
#endif
#ifdef __USE_FILE_OFFSET64
# define DWORD_HI(x) (x >> 32)
# define DWORD_LO(x) ((x) & 0xffffffff)
#else
# define DWORD_HI(x) (0)
# define DWORD_LO(x) (x)
#endif
void* mmap(void *addr, size_t len, int prot, int flags, int fildes, size_t offset) void* mmap(void *addr, size_t len, int prot, int flags, int fildes, size_t offset)
{ {
uint32_t flProtect, dwDesiredAccess; void *map = (void*)NULL;
off_t end; HANDLE handle = INVALID_HANDLE_VALUE;
HANDLE mmap_fd, h;
void *ret;
if (prot & ~(PROT_READ | PROT_WRITE | PROT_EXEC)) switch (prot)
return MAP_FAILED;
if (fd == -1)
{ {
if (!(flags & MAP_ANON) || offset) case PROT_READ:
return MAP_FAILED; default:
} {
else if (flags & MAP_ANON) handle = CreateFileMapping((HANDLE) _get_osfhandle(fildes), 0, PAGE_READONLY, 0,
return MAP_FAILED; len, 0);
if (!handle)
if (prot & PROT_WRITE) break;
{ map = (void*)MapViewOfFile(handle, FILE_MAP_READ, 0, 0, len);
flProtect = PAGE_READWRITE; CloseHandle(handle);
if (prot & PROT_EXEC) break;
flProtect = PAGE_EXECUTE_READWRITE; }
case PROT_WRITE:
{
handle = CreateFileMapping((HANDLE) _get_osfhandle(fildes),0,PAGE_READWRITE,0,
len, 0);
if (!handle)
break;
map = (void*)MapViewOfFile(handle, FILE_MAP_WRITE, 0, 0, len);
CloseHandle(handle);
break;
}
case PROT_READWRITE:
{
handle = CreateFileMapping((HANDLE) _get_osfhandle(fildes),0,PAGE_READWRITE,0,
len, 0);
if (!handle)
break;
map = (void*)MapViewOfFile(handle, FILE_MAP_ALL_ACCESS, 0, 0, len);
CloseHandle(handle);
break;
}
} }
else if (prot & PROT_EXEC) if (map == (void*)NULL)
{ return((void*)MAP_FAILED);
flProtect = PAGE_EXECUTE; return((void*) ((int8_t*)map + offset));
if (prot & PROT_READ)
flProtect = PAGE_EXECUTE_READ;
}
else
flProtect = PAGE_READONLY;
end = length + offset;
if (fd == -1)
mmap_fd = INVALID_HANDLE_VALUE;
else
mmap_fd = (HANDLE)_get_osfhandle(fd);
h = CreateFileMapping(mmap_fd, NULL, flProtect, DWORD_HI(end), DWORD_LO(end), NULL);
if (h == NULL)
return MAP_FAILED;
dwDesiredAccess = FILE_MAP_READ;
if (prot & PROT_WRITE)
dwDesiredAccess = FILE_MAP_WRITE;
if (prot & PROT_EXEC)
dwDesiredAccess |= FILE_MAP_EXECUTE;
if (flags & MAP_PRIVATE)
dwDesiredAccess |= FILE_MAP_COPY;
ret = MapViewOfFile(h, dwDesiredAccess, DWORD_HI(offset), DWORD_LO(offset), length);
if (ret == NULL)
{
CloseHandle(h);
ret = MAP_FAILED;
}
return ret;
} }
void munmap(void *addr, size_t length) int munmap(void *addr, size_t length)
{ {
UnmapViewOfFile(addr); if (!UnmapViewOfFile(addr))
/* ruh-ro, we leaked handle from CreateFileMapping() ... */ return -1;
return 0;
} }
int mprotect(void *addr, size_t len, int prot) int mprotect(void *addr, size_t len, int prot)
@ -144,9 +107,10 @@ void* mmap(void *addr, size_t len, int prot, int flags, int fildes, size_t offse
return malloc(len); return malloc(len);
} }
void munmap(void *addr, size_t len) int munmap(void *addr, size_t len)
{ {
free(addr); free(addr);
return 0;
} }
int mprotect(void *addr, size_t len, int prot) int mprotect(void *addr, size_t len, int prot)