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)
This commit is contained in:
parent
3368ad6f8e
commit
3a7fedb8fb
34
Makefile
34
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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
2
cpu.h
2
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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
|
||||
#include "memmap.h"
|
||||
|
||||
#ifdef MMAP_JIT_CACHE
|
||||
|
||||
#ifdef WIN32
|
||||
|
||||
#include <windows.h>
|
||||
#include <io.h>
|
||||
|
||||
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 <sys/mman.h>
|
||||
|
||||
// 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 */
|
||||
|
57
memmap.h
57
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 <sys/types.h>
|
||||
|
||||
#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 <sys/mman.h>
|
||||
#endif
|
||||
|
||||
#endif
|
||||
void *map_jit_block(unsigned size);
|
||||
void unmap_jit_block(void *bufptr, unsigned size);
|
||||
|
||||
#endif
|
||||
|
|
173
memmap_win32.c
173
memmap_win32.c
|
@ -1,173 +0,0 @@
|
|||
#include <windows.h>
|
||||
#include <errno.h>
|
||||
#include <io.h>
|
||||
|
||||
#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;
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
Loading…
Reference in New Issue