fc99395c |
1 | #ifndef MMAN_H |
2 | #define MMAN_H |
3 | |
4 | #ifdef __cplusplus |
5 | extern "C" { |
6 | #endif |
7 | |
f72db18e |
8 | #include <stdlib.h> |
9 | #include <stdio.h> |
5dbff29e |
10 | #include <string.h> |
f72db18e |
11 | #include <stdint.h> |
12 | #include <malloc.h> |
fc99395c |
13 | |
f72db18e |
14 | #include "3ds_utils.h" |
15 | |
16 | #define PROT_READ 0b001 |
17 | #define PROT_WRITE 0b010 |
18 | #define PROT_EXEC 0b100 |
fc99395c |
19 | #define MAP_PRIVATE 2 |
f72db18e |
20 | #define MAP_FIXED 0x10 |
fc99395c |
21 | #define MAP_ANONYMOUS 0x20 |
22 | |
23 | #define MAP_FAILED ((void *)-1) |
24 | |
f72db18e |
25 | static void* dynarec_cache = NULL; |
26 | static void* dynarec_cache_mapping = NULL; |
27 | |
fc99395c |
28 | static inline void* mmap(void *addr, size_t len, int prot, int flags, int fd, off_t offset) |
29 | { |
fc99395c |
30 | (void)fd; |
31 | (void)offset; |
32 | |
33 | void* addr_out; |
34 | |
f72db18e |
35 | if((prot == (PROT_READ | PROT_WRITE | PROT_EXEC)) && |
06facfd2 |
36 | (flags == (MAP_PRIVATE | MAP_ANONYMOUS))) |
f72db18e |
37 | { |
38 | if(__ctr_svchax) |
39 | { |
40 | /* this hack works only for pcsx_rearmed */ |
41 | uint32_t currentHandle; |
42 | |
5dbff29e |
43 | if (!dynarec_cache) { |
f72db18e |
44 | dynarec_cache = memalign(0x1000, len); |
5dbff29e |
45 | if (!dynarec_cache) |
46 | return MAP_FAILED; |
47 | } |
f72db18e |
48 | |
49 | svcDuplicateHandle(¤tHandle, 0xFFFF8001); |
50 | svcControlProcessMemory(currentHandle, addr, dynarec_cache, |
51 | len, MEMOP_MAP, prot); |
52 | svcCloseHandle(currentHandle); |
53 | dynarec_cache_mapping = addr; |
5dbff29e |
54 | memset(addr, 0, len); |
f72db18e |
55 | return addr; |
56 | } |
57 | else |
58 | { |
59 | printf("tried to mmap RWX pages without svcControlProcessMemory access !\n"); |
60 | return MAP_FAILED; |
61 | } |
62 | |
63 | } |
64 | |
5dbff29e |
65 | addr_out = memalign(0x1000, len); |
66 | if (!addr_out) |
fc99395c |
67 | return MAP_FAILED; |
68 | |
5dbff29e |
69 | memset(addr_out, 0, len); |
fc99395c |
70 | return addr_out; |
71 | } |
72 | |
73 | static inline int mprotect(void *addr, size_t len, int prot) |
74 | { |
f72db18e |
75 | if(__ctr_svchax) |
fc99395c |
76 | { |
77 | uint32_t currentHandle; |
78 | svcDuplicateHandle(¤tHandle, 0xFFFF8001); |
f72db18e |
79 | svcControlProcessMemory(currentHandle, addr, NULL, |
fc99395c |
80 | len, MEMOP_PROT, prot); |
81 | svcCloseHandle(currentHandle); |
82 | return 0; |
83 | } |
84 | |
1f3b70a9 |
85 | printf("mprotect called without svcControlProcessMemory access !\n"); |
fc99395c |
86 | return -1; |
87 | } |
88 | |
89 | static inline int munmap(void *addr, size_t len) |
90 | { |
f72db18e |
91 | if((addr == dynarec_cache_mapping) && __ctr_svchax) |
92 | { |
93 | uint32_t currentHandle; |
94 | svcDuplicateHandle(¤tHandle, 0xFFFF8001); |
95 | svcControlProcessMemory(currentHandle, |
96 | dynarec_cache, dynarec_cache_mapping, |
97 | len, MEMOP_UNMAP, 0b111); |
98 | svcCloseHandle(currentHandle); |
99 | dynarec_cache_mapping = NULL; |
100 | |
101 | } |
102 | else |
103 | free(addr); |
104 | |
fc99395c |
105 | return 0; |
fc99395c |
106 | } |
107 | |
108 | #ifdef __cplusplus |
109 | }; |
110 | #endif |
111 | |
112 | #endif // MMAN_H |
113 | |