From 3a7fedb8fb31bee214f91bf44b7b7f4a27f0c831 Mon Sep 17 00:00:00 2001 From: David Guillen Fandos Date: Fri, 5 Nov 2021 18:23:05 +0100 Subject: [PATCH] Simplify MMAP machinery for Win/Lin/Mac/Android This gets rid of the bloated memmap_win32.c in favour of a much simpler wrapper. This will be needed in the future since the wrapper does not support MAP_FIXED maps (necessary for some platforms) --- Makefile | 34 ++++----- Makefile.common | 5 +- arm/arm_stub.S | 2 +- cpu.h | 2 +- cpu_threaded.c | 2 +- jni/Android.mk | 4 +- libretro/libretro.c | 10 +-- memmap.c | 35 +++++++++ memmap.h | 57 +-------------- memmap_win32.c | 173 -------------------------------------------- mips/mips_stub.S | 2 +- x86/x86_stub.S | 13 +--- 12 files changed, 67 insertions(+), 272 deletions(-) create mode 100644 memmap.c delete mode 100644 memmap_win32.c diff --git a/Makefile b/Makefile index 61bcc12..734b71e 100644 --- a/Makefile +++ b/Makefile @@ -1,8 +1,7 @@ DEBUG=0 FRONTEND_SUPPORTS_RGB565=1 FORCE_32BIT_ARCH=0 -HAVE_MMAP=0 -HAVE_MMAP_WIN32=0 +MMAP_JIT_CACHE=0 UNAME=$(shell uname -a) @@ -75,7 +74,7 @@ ifeq ($(platform), unix) CFLAGS += $(FORCE_32BIT) LDFLAGS += -Wl,--no-undefined ifeq ($(HAVE_DYNAREC),1) - HAVE_MMAP = 1 + MMAP_JIT_CACHE = 1 endif # Linux portable @@ -86,7 +85,7 @@ else ifeq ($(platform), linux-portable) LIBM := CFLAGS += $(FORCE_32BIT) ifeq ($(HAVE_DYNAREC),1) - HAVE_MMAP = 1 + MMAP_JIT_CACHE = 1 endif # OS X @@ -101,7 +100,7 @@ else ifeq ($(platform), osx) fpic += -mmacosx-version-min=10.1 SHARED := -dynamiclib ifeq ($(HAVE_DYNAREC),1) - HAVE_MMAP = 1 + MMAP_JIT_CACHE = 1 endif ifeq ($(CROSS_COMPILE),1) @@ -172,7 +171,7 @@ else ifeq ($(platform), qnx) TARGET := $(TARGET_NAME)_libretro_qnx.so fpic := -fPIC SHARED := -shared -Wl,--version-script=link.T - HAVE_MMAP = 1 + MMAP_JIT_CACHE = 1 CPU_ARCH := arm CC = qcc -Vgcc_ntoarmv7le @@ -257,7 +256,7 @@ else ifeq ($(platform), rpi3) CFLAGS += -fomit-frame-pointer -ffast-math CXXFLAGS = $(CFLAGS) -fno-rtti -fno-exceptions -std=gnu++11 CPU_ARCH := arm - HAVE_MMAP = 1 + MMAP_JIT_CACHE = 1 HAVE_DYNAREC = 1 # Raspberry Pi 2 @@ -269,7 +268,7 @@ else ifeq ($(platform), rpi2) CFLAGS += -fomit-frame-pointer -ffast-math CXXFLAGS = $(CFLAGS) -fno-rtti -fno-exceptions -std=gnu++11 CPU_ARCH := arm - HAVE_MMAP = 1 + MMAP_JIT_CACHE = 1 HAVE_DYNAREC = 1 # Raspberry Pi 1 @@ -282,7 +281,7 @@ else ifeq ($(platform), rpi1) CFLAGS += -fomit-frame-pointer -ffast-math CXXFLAGS = $(CFLAGS) -fno-rtti -fno-exceptions -std=gnu++11 CPU_ARCH := arm - HAVE_MMAP = 1 + MMAP_JIT_CACHE = 1 HAVE_DYNAREC = 1 # Classic Platforms #################### @@ -310,7 +309,7 @@ else ifeq ($(platform), classic_armv7_a7) ARCH = arm BUILTIN_GPU = neon CPU_ARCH := arm - HAVE_MMAP = 1 + MMAP_JIT_CACHE = 1 HAVE_DYNAREC = 1 ifeq ($(shell echo `$(CC) -dumpversion` "< 4.9" | bc -l), 1) CFLAGS += -march=armv7-a @@ -352,7 +351,7 @@ else ifneq (,$(findstring armv,$(platform))) TARGET := $(TARGET_NAME)_libretro.so SHARED := -shared -Wl,--version-script=link.T CPU_ARCH := arm - HAVE_MMAP = 1 + MMAP_JIT_CACHE = 1 fpic := -fPIC ifneq (,$(findstring cortexa5,$(platform))) CFLAGS += -marm -mcpu=cortex-a5 @@ -463,14 +462,13 @@ else SHARED := -shared -static-libgcc -static-libstdc++ -s -Wl,--version-script=link.T CFLAGS += -D__WIN32__ -D__WIN32_LIBRETRO__ ifeq ($(HAVE_DYNAREC),1) - HAVE_MMAP = 1 - HAVE_MMAP_WIN32 = 1 + MMAP_JIT_CACHE = 1 endif endif -ifeq ($(HAVE_MMAP), 1) -CFLAGS += -DHAVE_MMAP +ifeq ($(MMAP_JIT_CACHE), 1) +CFLAGS += -DMMAP_JIT_CACHE endif # Add -DTRACE_INSTRUCTIONS to trace instruction execution @@ -487,11 +485,11 @@ DEFINES += -DHAVE_DYNAREC endif ifeq ($(CPU_ARCH), arm) -DEFINES += -DARM_ARCH + DEFINES += -DARM_ARCH else ifeq ($(CPU_ARCH), mips) -DEFINES += -DMIPS_ARCH + DEFINES += -DMIPS_ARCH else ifeq ($(CPU_ARCH), x86_32) -DEFINES += -DX86_ARCH + DEFINES += -DX86_ARCH endif include Makefile.common diff --git a/Makefile.common b/Makefile.common index bf0c441..bc4cdd3 100644 --- a/Makefile.common +++ b/Makefile.common @@ -12,6 +12,7 @@ SOURCES_C := $(CORE_DIR)/main.c \ $(CORE_DIR)/input.c \ $(CORE_DIR)/sound.c \ $(CORE_DIR)/cheats.c \ + $(CORE_DIR)/memmap.c \ $(CORE_DIR)/libretro/libretro.c \ $(CORE_DIR)/gba_cc_lut.c \ $(LIBRETRO_COMM_DIR)/compat/compat_posix_string.c \ @@ -51,7 +52,3 @@ endif endif -ifeq ($(HAVE_MMAP_WIN32),1) -SOURCES_C += $(CORE_DIR)/memmap_win32.c -endif - diff --git a/arm/arm_stub.S b/arm/arm_stub.S index 1bfee10..b395425 100644 --- a/arm/arm_stub.S +++ b/arm/arm_stub.S @@ -840,7 +840,7 @@ defsymbl(palette_ram_converted) @ Vita and 3DS (and of course mmap) map their own cache sections through some @ platform-speficic mechanisms. -#if !defined(HAVE_MMAP) && !defined(VITA) && !defined(_3DS) +#if !defined(MMAP_JIT_CACHE) && !defined(VITA) && !defined(_3DS) @ Make this section executable! .text diff --git a/cpu.h b/cpu.h index c2a6ad6..97bbe64 100644 --- a/cpu.h +++ b/cpu.h @@ -131,7 +131,7 @@ s32 translate_block_arm(u32 pc, translation_region_type translation_region, s32 translate_block_thumb(u32 pc, translation_region_type translation_region, u32 smc_enable); -#if defined(HAVE_MMAP) +#if defined(MMAP_JIT_CACHE) extern u8* rom_translation_cache; extern u8* ram_translation_cache; #elif defined(_3DS) diff --git a/cpu_threaded.c b/cpu_threaded.c index f0c5704..0f500dc 100644 --- a/cpu_threaded.c +++ b/cpu_threaded.c @@ -32,7 +32,7 @@ u8 *last_rom_translation_ptr = NULL; u8 *last_ram_translation_ptr = NULL; -#if defined(HAVE_MMAP) +#if defined(MMAP_JIT_CACHE) u8* rom_translation_cache; u8* ram_translation_cache; u8 *rom_translation_ptr; diff --git a/jni/Android.mk b/jni/Android.mk index 3d1e36a..2161b62 100644 --- a/jni/Android.mk +++ b/jni/Android.mk @@ -9,11 +9,11 @@ HAVE_DYNAREC := COREFLAGS := -DINLINE=inline -D__LIBRETRO__ -DFRONTEND_SUPPORTS_RGB565 ifeq ($(TARGET_ARCH),arm) - COREFLAGS += -DARM_ARCH -DHAVE_MMAP + COREFLAGS += -DARM_ARCH -DMMAP_JIT_CACHE CPU_ARCH := arm HAVE_DYNAREC := 1 else ifeq ($(TARGET_ARCH),x86) - COREFLAGS += -DHAVE_MMAP + COREFLAGS += -DMMAP_JIT_CACHE CPU_ARCH := x86_32 HAVE_DYNAREC := 1 endif diff --git a/libretro/libretro.c b/libretro/libretro.c index d496489..9633509 100644 --- a/libretro/libretro.c +++ b/libretro/libretro.c @@ -458,9 +458,9 @@ void retro_get_system_av_info(struct retro_system_av_info* info) void retro_init(void) { #if defined(HAVE_DYNAREC) - #if defined(HAVE_MMAP) - rom_translation_cache = mmap(NULL, ROM_TRANSLATION_CACHE_SIZE + RAM_TRANSLATION_CACHE_SIZE, - PROT_READ | PROT_WRITE | PROT_EXEC, MAP_ANON | MAP_PRIVATE, -1, 0); + #if defined(MMAP_JIT_CACHE) + rom_translation_cache = map_jit_block(ROM_TRANSLATION_CACHE_SIZE + RAM_TRANSLATION_CACHE_SIZE); + printf("rom_translation_cache %llx\n", (unsigned long long)rom_translation_cache); ram_translation_cache = &rom_translation_cache[ROM_TRANSLATION_CACHE_SIZE]; #elif defined(_3DS) if (__ctr_svchax && !translation_caches_inited) @@ -548,8 +548,8 @@ void retro_deinit(void) perf_cb.perf_log(); memory_term(); -#if defined(HAVE_MMAP) && defined(HAVE_DYNAREC) - munmap(rom_translation_cache, ROM_TRANSLATION_CACHE_SIZE + RAM_TRANSLATION_CACHE_SIZE); +#if defined(MMAP_JIT_CACHE) && defined(HAVE_DYNAREC) + unmap_jit_block(rom_translation_cache, ROM_TRANSLATION_CACHE_SIZE + RAM_TRANSLATION_CACHE_SIZE); #endif #if defined(_3DS) && defined(HAVE_DYNAREC) diff --git a/memmap.c b/memmap.c new file mode 100644 index 0000000..84b86b4 --- /dev/null +++ b/memmap.c @@ -0,0 +1,35 @@ + +#include "memmap.h" + +#ifdef MMAP_JIT_CACHE + +#ifdef WIN32 + + #include + #include + + void *map_jit_block(unsigned size) { + return VirtualAlloc(0, size, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); + } + + void unmap_jit_block(void *bufptr, unsigned size) { + VirtualFree(bufptr, 0, MEM_RELEASE); + } + +#else + + #include + + // Posix implementation + void *map_jit_block(unsigned size) { + return mmap(0, size, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_ANON | MAP_PRIVATE, -1, 0); + } + + void unmap_jit_block(void *bufptr, unsigned size) { + munmap(bufptr, size); + } + +#endif /* WIN32 */ + +#endif /* MMAP_JIT_CACHE */ + diff --git a/memmap.h b/memmap.h index e80d720..9bcc6c2 100644 --- a/memmap.h +++ b/memmap.h @@ -1,60 +1,7 @@ #ifndef _MEMMAP_H #define _MEMMAP_H -#ifdef HAVE_MMAP - -#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 +void *map_jit_block(unsigned size); +void unmap_jit_block(void *bufptr, unsigned size); #endif diff --git a/memmap_win32.c b/memmap_win32.c deleted file mode 100644 index f4dbdd6..0000000 --- a/memmap_win32.c +++ /dev/null @@ -1,173 +0,0 @@ -#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/mips/mips_stub.S b/mips/mips_stub.S index 7c7621d..87672e1 100644 --- a/mips/mips_stub.S +++ b/mips/mips_stub.S @@ -595,7 +595,7 @@ fnptrs: .long execute_store_cpsr_body # 7 .long process_cheats # 8 -#if !defined(HAVE_MMAP) +#if !defined(MMAP_JIT_CACHE) # Make this section executable! .text diff --git a/x86/x86_stub.S b/x86/x86_stub.S index 356e7f5..8b6741c 100644 --- a/x86/x86_stub.S +++ b/x86/x86_stub.S @@ -585,16 +585,7 @@ defsymbl(reg_mode) defsymbl(memory_map_read) .space 0x8000 -#if !defined(HAVE_MMAP) - -# Make this section executable! -.text -.section .jit,"awx",%nobits -.align 4 -defsymbl(rom_translation_cache) - .space ROM_TRANSLATION_CACHE_SIZE -defsymbl(ram_translation_cache) - .space RAM_TRANSLATION_CACHE_SIZE - +#ifndef MMAP_JIT_CACHE + #error "x86 dynarec builds *require* MMAP_JIT_CACHE" #endif