diff options
Diffstat (limited to 'frontend/3ds/sys/mman.h')
-rw-r--r-- | frontend/3ds/sys/mman.h | 107 |
1 files changed, 107 insertions, 0 deletions
diff --git a/frontend/3ds/sys/mman.h b/frontend/3ds/sys/mman.h new file mode 100644 index 0000000..e295b89 --- /dev/null +++ b/frontend/3ds/sys/mman.h @@ -0,0 +1,107 @@ +#ifndef MMAN_H +#define MMAN_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include <stdlib.h> +#include <stdio.h> +#include <stdint.h> +#include <malloc.h> + +#include "3ds_utils.h" + +#define PROT_READ 0b001 +#define PROT_WRITE 0b010 +#define PROT_EXEC 0b100 +#define MAP_PRIVATE 2 +#define MAP_FIXED 0x10 +#define MAP_ANONYMOUS 0x20 + +#define MAP_FAILED ((void *)-1) + +static void* dynarec_cache = NULL; +static void* dynarec_cache_mapping = NULL; + +static inline void* mmap(void *addr, size_t len, int prot, int flags, int fd, off_t offset) +{ + (void)fd; + (void)offset; + + void* addr_out; + + if((prot == (PROT_READ | PROT_WRITE | PROT_EXEC)) && + (flags == (MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS))) + { + if(__ctr_svchax) + { + /* this hack works only for pcsx_rearmed */ + uint32_t currentHandle; + + if(!dynarec_cache) + dynarec_cache = memalign(0x1000, len); + + svcDuplicateHandle(¤tHandle, 0xFFFF8001); + svcControlProcessMemory(currentHandle, addr, dynarec_cache, + len, MEMOP_MAP, prot); + svcCloseHandle(currentHandle); + dynarec_cache_mapping = addr; + return addr; + } + else + { + printf("tried to mmap RWX pages without svcControlProcessMemory access !\n"); + return MAP_FAILED; + } + + } + + addr_out = malloc(len); + if(!addr_out) + return MAP_FAILED; + + return addr_out; +} + +static inline int mprotect(void *addr, size_t len, int prot) +{ + if(__ctr_svchax) + { + uint32_t currentHandle; + svcDuplicateHandle(¤tHandle, 0xFFFF8001); + svcControlProcessMemory(currentHandle, addr, NULL, + len, MEMOP_PROT, prot); + svcCloseHandle(currentHandle); + return 0; + } + + printf("mprotect called without svcControlProcessMemory access !\n"); + return -1; +} + +static inline int munmap(void *addr, size_t len) +{ + if((addr == dynarec_cache_mapping) && __ctr_svchax) + { + uint32_t currentHandle; + svcDuplicateHandle(¤tHandle, 0xFFFF8001); + svcControlProcessMemory(currentHandle, + dynarec_cache, dynarec_cache_mapping, + len, MEMOP_UNMAP, 0b111); + svcCloseHandle(currentHandle); + dynarec_cache_mapping = NULL; + + } + else + free(addr); + + return 0; +} + +#ifdef __cplusplus +}; +#endif + +#endif // MMAN_H + |