From: twinaphex Date: Sat, 13 Dec 2014 04:53:54 +0000 (+0100) Subject: psxmem: Add mman wrapper for Win32 and use it for PCSX ReARmed libretro Win32 X-Git-Tag: r20~22 X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?p=pcsx_rearmed.git;a=commitdiff_plain;h=ce0e7ac9c11993f9165615dec870c50e1c3b39bf;hp=1e1cccd9ef788b3582002283f6cb7e48db53677f psxmem: Add mman wrapper for Win32 and use it for PCSX ReARmed libretro Win32 Conflicts: Makefile.libretro --- diff --git a/Makefile b/Makefile index cc19e774..58de43a4 100644 --- a/Makefile +++ b/Makefile @@ -189,6 +189,10 @@ endif ifeq "$(PLATFORM)" "libretro" OBJS += frontend/libretro.o CFLAGS += -DFRONTEND_SUPPORTS_RGB565 + +ifeq ($(MMAP_WIN32),1) +OBJS += libpcsxcore/memmap_win32.o +endif endif ifeq "$(USE_PLUGIN_LIB)" "1" diff --git a/Makefile.libretro b/Makefile.libretro index d92b9ade..a8f63faa 100644 --- a/Makefile.libretro +++ b/Makefile.libretro @@ -21,6 +21,8 @@ CFLAGS ?= TARGET_NAME := pcsx_rearmed +MMAP_WIN32=0 + ifeq ($(platform), unix) TARGET := $(TARGET_NAME)_libretro.so fpic := -fPIC @@ -141,6 +143,7 @@ else LD_FLAGS := -fPIC SHARED := -shared -static-libgcc -static-libstdc++ -s -Wl,--version-script=libretro/link.T CFLAGS += -D__WIN32__ -D__WIN32_LIBRETRO__ + MMAP_WIN32=1 endif CFLAGS += -fPIC diff --git a/libpcsxcore/memmap.h b/libpcsxcore/memmap.h new file mode 100644 index 00000000..ad56f047 --- /dev/null +++ b/libpcsxcore/memmap.h @@ -0,0 +1,56 @@ +#ifndef _MEMMAP_H +#define _MEMMAP_H + +#ifdef _WIN32 + +#ifndef _WIN32_WINNT // Allow use of features specific to Windows XP or later. +#define _WIN32_WINNT 0x0501 // Change this to the appropriate value to target other versions of Windows. +#endif + +/* All the headers include this file. */ +#ifndef _MSC_VER +#include <_mingw.h> +#endif + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define PROT_NONE 0 +#define PROT_READ 1 +#define PROT_WRITE 2 +#define PROT_EXEC 4 + +#define MAP_FILE 0 +#define MAP_SHARED 1 +#define MAP_PRIVATE 2 +#define MAP_TYPE 0xf +#define MAP_FIXED 0x10 +#define MAP_ANONYMOUS 0x20 +#define MAP_ANON MAP_ANONYMOUS + +#define MAP_FAILED ((void *)-1) + +/* Flags for msync. */ +#define MS_ASYNC 1 +#define MS_SYNC 2 +#define MS_INVALIDATE 4 + +void* mmap(void *addr, size_t len, int prot, int flags, int fildes, off_t off); +int munmap(void *addr, size_t len); +int mprotect(void *addr, size_t len, int prot); +int msync(void *addr, size_t len, int flags); +int mlock(const void *addr, size_t len); +int munlock(const void *addr, size_t len); + +#ifdef __cplusplus +}; +#endif + +#else +#include +#endif + +#endif diff --git a/libpcsxcore/memmap_win32.c b/libpcsxcore/memmap_win32.c new file mode 100644 index 00000000..f4dbdd61 --- /dev/null +++ b/libpcsxcore/memmap_win32.c @@ -0,0 +1,173 @@ +#include +#include +#include + +#include "mman.h" + +#ifndef FILE_MAP_EXECUTE +#define FILE_MAP_EXECUTE 0x0020 +#endif /* FILE_MAP_EXECUTE */ + +static int __map_mman_error(const DWORD err, const int deferr) +{ + if (err == 0) + return 0; + /* TODO: implement */ + return err; +} + +static DWORD __map_mmap_prot_page(const int prot) +{ + DWORD protect = 0; + + if (prot == PROT_NONE) + return 0; + + 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 0; + + 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) != 0 + /* Usupported protection combinations */ + || prot == PROT_EXEC) + { + errno = EINVAL; + return MAP_FAILED; + } + + h = ((flags & MAP_ANONYMOUS) == 0) ? + (HANDLE)_get_osfhandle(fildes) : INVALID_HANDLE_VALUE; + + if ((flags & MAP_ANONYMOUS) == 0 && h == INVALID_HANDLE_VALUE) + { + errno = EBADF; + return MAP_FAILED; + } + + fm = CreateFileMapping(h, NULL, protect, dwMaxSizeHigh, dwMaxSizeLow, NULL); + + if (!fm) + goto error; + + map = MapViewOfFile(fm, desiredAccess, dwFileOffsetHigh, dwFileOffsetLow, len); + + CloseHandle(fm); + + if (!map) + goto error; + + return map; +error: + errno = __map_mman_error(GetLastError(), EPERM); + return MAP_FAILED; +} + +int munmap(void *addr, size_t len) +{ + if (UnmapViewOfFile(addr)) + return 0; + + errno = __map_mman_error(GetLastError(), EPERM); + + return -1; +} + +int mprotect(void *addr, size_t len, int prot) +{ + DWORD newProtect = __map_mmap_prot_page(prot); + DWORD oldProtect = 0; + + if (VirtualProtect(addr, len, newProtect, &oldProtect)) + return 0; + + errno = __map_mman_error(GetLastError(), EPERM); + + return -1; +} + +int msync(void *addr, size_t len, int flags) +{ + if (FlushViewOfFile(addr, len)) + return 0; + + errno = __map_mman_error(GetLastError(), EPERM); + + return -1; +} + +int mlock(const void *addr, size_t len) +{ + if (VirtualLock((LPVOID)addr, len)) + return 0; + + errno = __map_mman_error(GetLastError(), EPERM); + + return -1; +} + +int munlock(const void *addr, size_t len) +{ + if (VirtualUnlock((LPVOID)addr, len)) + return 0; + + errno = __map_mman_error(GetLastError(), EPERM); + + return -1; +} + diff --git a/libpcsxcore/psxmem.c b/libpcsxcore/psxmem.c index 7001744b..86da68ce 100644 --- a/libpcsxcore/psxmem.c +++ b/libpcsxcore/psxmem.c @@ -28,7 +28,8 @@ #include "r3000a.h" #include "psxhw.h" #include "debug.h" -#include + +#include "memmap.h" #ifndef MAP_ANONYMOUS #define MAP_ANONYMOUS MAP_ANON