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