Merge pull request #511 from negativeExponent/updates
[pcsx_rearmed.git] / deps / mman / mman.c
CommitLineData
81c4586f
PC
1
2#include <windows.h>
3#include <errno.h>
4#include <io.h>
5
6#include "mman.h"
7
8#ifndef FILE_MAP_EXECUTE
9#define FILE_MAP_EXECUTE 0x0020
10#endif /* FILE_MAP_EXECUTE */
11
12static int __map_mman_error(const DWORD err, const int deferr)
13{
14 if (err == 0)
15 return 0;
16 //TODO: implement
17 return err;
18}
19
20static DWORD __map_mmap_prot_page(const int prot)
21{
22 DWORD protect = 0;
23
24 if (prot == PROT_NONE)
25 return protect;
26
27 if ((prot & PROT_EXEC) != 0)
28 {
29 protect = ((prot & PROT_WRITE) != 0) ?
30 PAGE_EXECUTE_READWRITE : PAGE_EXECUTE_READ;
31 }
32 else
33 {
34 protect = ((prot & PROT_WRITE) != 0) ?
35 PAGE_READWRITE : PAGE_READONLY;
36 }
37
38 return protect;
39}
40
41static DWORD __map_mmap_prot_file(const int prot)
42{
43 DWORD desiredAccess = 0;
44
45 if (prot == PROT_NONE)
46 return desiredAccess;
47
48 if ((prot & PROT_READ) != 0)
49 desiredAccess |= FILE_MAP_READ;
50 if ((prot & PROT_WRITE) != 0)
51 desiredAccess |= FILE_MAP_WRITE;
52 if ((prot & PROT_EXEC) != 0)
53 desiredAccess |= FILE_MAP_EXECUTE;
54
55 return desiredAccess;
56}
57
58void* mmap(void *addr, size_t len, int prot, int flags, int fildes, OffsetType off)
59{
60 HANDLE fm, h;
61
62 void * map = MAP_FAILED;
63
64#ifdef _MSC_VER
65#pragma warning(push)
66#pragma warning(disable: 4293)
67#endif
68
69 const DWORD dwFileOffsetLow = (sizeof(OffsetType) <= sizeof(DWORD)) ?
70 (DWORD)off : (DWORD)(off & 0xFFFFFFFFL);
71 const DWORD dwFileOffsetHigh = (sizeof(OffsetType) <= sizeof(DWORD)) ?
72 (DWORD)0 : (DWORD)((off >> 32) & 0xFFFFFFFFL);
73 const DWORD protect = __map_mmap_prot_page(prot);
74 const DWORD desiredAccess = __map_mmap_prot_file(prot);
75
76 const OffsetType maxSize = off + (OffsetType)len;
77
78 const DWORD dwMaxSizeLow = (sizeof(OffsetType) <= sizeof(DWORD)) ?
79 (DWORD)maxSize : (DWORD)(maxSize & 0xFFFFFFFFL);
80 const DWORD dwMaxSizeHigh = (sizeof(OffsetType) <= sizeof(DWORD)) ?
81 (DWORD)0 : (DWORD)((maxSize >> 32) & 0xFFFFFFFFL);
82
83#ifdef _MSC_VER
84#pragma warning(pop)
85#endif
86
87 errno = 0;
88
89 if (len == 0
90 /* Usupported protection combinations */
91 || prot == PROT_EXEC)
92 {
93 errno = EINVAL;
94 return MAP_FAILED;
95 }
96
97 h = ((flags & MAP_ANONYMOUS) == 0) ?
98 (HANDLE)_get_osfhandle(fildes) : INVALID_HANDLE_VALUE;
99
100 if ((flags & MAP_ANONYMOUS) == 0 && h == INVALID_HANDLE_VALUE)
101 {
102 errno = EBADF;
103 return MAP_FAILED;
104 }
105
106 fm = CreateFileMapping(h, NULL, protect, dwMaxSizeHigh, dwMaxSizeLow, NULL);
107
108 if (fm == NULL)
109 {
110 errno = __map_mman_error(GetLastError(), EPERM);
111 return MAP_FAILED;
112 }
113
114 if ((flags & MAP_FIXED) == 0)
115 {
116 map = MapViewOfFile(fm, desiredAccess, dwFileOffsetHigh, dwFileOffsetLow, len);
117 }
118 else
119 {
120 map = MapViewOfFileEx(fm, desiredAccess, dwFileOffsetHigh, dwFileOffsetLow, len, addr);
121 }
122
123 CloseHandle(fm);
124
125 if (map == NULL)
126 {
127 errno = __map_mman_error(GetLastError(), EPERM);
128 return MAP_FAILED;
129 }
130
131 return map;
132}
133
134int munmap(void *addr, size_t len)
135{
136 if (UnmapViewOfFile(addr))
137 return 0;
138
139 errno = __map_mman_error(GetLastError(), EPERM);
140
141 return -1;
142}
143
144int _mprotect(void *addr, size_t len, int prot)
145{
146 DWORD newProtect = __map_mmap_prot_page(prot);
147 DWORD oldProtect = 0;
148
149 if (VirtualProtect(addr, len, newProtect, &oldProtect))
150 return 0;
151
152 errno = __map_mman_error(GetLastError(), EPERM);
153
154 return -1;
155}
156
157int msync(void *addr, size_t len, int flags)
158{
159 if (FlushViewOfFile(addr, len))
160 return 0;
161
162 errno = __map_mman_error(GetLastError(), EPERM);
163
164 return -1;
165}
166
167int mlock(const void *addr, size_t len)
168{
169 if (VirtualLock((LPVOID)addr, len))
170 return 0;
171
172 errno = __map_mman_error(GetLastError(), EPERM);
173
174 return -1;
175}
176
177int munlock(const void *addr, size_t len)
178{
179 if (VirtualUnlock((LPVOID)addr, len))
180 return 0;
181
182 errno = __map_mman_error(GetLastError(), EPERM);
183
184 return -1;
185}