diff --git a/libretro-common/include/memmap.h b/libretro-common/include/memmap.h new file mode 100644 index 0000000000..90b9eef84d --- /dev/null +++ b/libretro-common/include/memmap.h @@ -0,0 +1,41 @@ +/* Copyright (C) 2010-2015 The RetroArch team + * + * --------------------------------------------------------------------------------------- + * The following license statement only applies to this file (memmap.h). + * --------------------------------------------------------------------------------------- + * + * Permission is hereby granted, free of charge, + * to any person obtaining a copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef _LIBRETRO_MEMMAP_H +#define _LIBRETRO_MEMMAP_H + +#if defined(__CELLOS_LV2__) || defined(PSP) || defined(GEKKO) || defined(VITA) || defined(_XBOX) +/* No mman available */ +#elif defined(_WIN32) && !defined(_XBOX) +#include +#include +#include +#else +#define HAVE_MMAP +#include +#endif + +#ifndef MAP_ANONYMOUS +#define MAP_ANONYMOUS MAP_ANON +#endif + +#endif diff --git a/libretro-common/memmap/memmap.c b/libretro-common/memmap/memmap.c new file mode 100644 index 0000000000..b13e287136 --- /dev/null +++ b/libretro-common/memmap/memmap.c @@ -0,0 +1,141 @@ +/* Copyright (C) 2010-2015 The RetroArch team + * + * --------------------------------------------------------------------------------------- + * The following license statement only applies to this file (memmap.c). + * --------------------------------------------------------------------------------------- + * + * Permission is hereby granted, free of charge, + * to any person obtaining a copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include + +#ifdef _WIN32 +#define MAP_SHARED 0x01 +#define MAP_PRIVATE 0x02 +#define MAP_ANONYMOUS 0x20 +#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 +#define PROT_EXEC 0x4 +#else +#define PROT_EXEC 0x0 +#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 + +static void *mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset) +{ + uint32_t flProtect, dwDesiredAccess; + off_t end; + HANDLE mmap_fd, h; + void *ret; + + if (prot & ~(PROT_READ | PROT_WRITE | PROT_EXEC)) + return MAP_FAILED; + + if (fd == -1) + { + if (!(flags & MAP_ANON) || offset) + return MAP_FAILED; + } + else if (flags & MAP_ANON) + return MAP_FAILED; + + if (prot & PROT_WRITE) + { + flProtect = PAGE_READWRITE; + if (prot & PROT_EXEC) + flProtect = PAGE_EXECUTE_READWRITE; + } + else if (prot & PROT_EXEC) + { + flProtect = PAGE_EXECUTE; + 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; +} + +static void munmap(void *addr, size_t length) +{ + UnmapViewOfFile(addr); + /* ruh-ro, we leaked handle from CreateFileMapping() ... */ +} +#elif !defined(HAVE_MMAP) +#define PROT_EXEC 0x04 +#define MAP_FAILED 0 +#define PROT_READ 0 +#define PROT_WRITE 0 +#define MAP_PRIVATE 0 +#define MAP_ANONYMOUS 0 + +void* mmap(void *desired_addr, size_t len, int mmap_prot, int mmap_flags, int fildes, size_t off) +{ + return malloc(len); +} + +void munmap(void *base_addr, size_t len) +{ + free(base_addr); +} + +int mprotect(void *addr, size_t len, int prot) +{ + /* stub - not really needed at this point since this codepath has no dynarecs */ + return 0; +} + +#endif +