IsoSpec
Loading...
Searching...
No Matches
mman.cpp
1/*
2 * NOLINT(legal/copyright) - the original authors did not slap a (C) notice in here,
3 * for whatever reason, and I'm in no position to do that for them.
4 *
5 * This file has been included as a part of IsoSpec project, under a MIT licence. It
6 * comes from the repository:
7 *
8 * https://github.com/witwall/mman-win32
9 *
10 * which itself is a mirror of:
11 *
12 * https://code.google.com/archive/p/mman-win32/
13 */
14
15#include "platform.h"
16#if ISOSPEC_GOT_MMAN && !ISOSPEC_GOT_SYSTEM_MMAN
17
18#define NOMINMAX
19#include <windows.h>
20#include <errno.h>
21#include <io.h>
22
23#include "mman.h"
24
25#ifndef FILE_MAP_EXECUTE
26#define FILE_MAP_EXECUTE 0x0020
27#endif /* FILE_MAP_EXECUTE */
28
29
30static int __map_mman_error(const DWORD err, const int /* deferr */)
31{
32 if (err == 0)
33 return 0;
34 // TODO: implement NOLINT(readability/todo) - well, should be assigned to the original authors
35 return err;
36}
37
38static DWORD __map_mmap_prot_page(const int prot)
39{
40 DWORD protect = 0;
41
42 if (prot == PROT_NONE)
43 return protect;
44
45 if ((prot & PROT_EXEC) != 0)
46 {
47 protect = ((prot & PROT_WRITE) != 0) ?
48 PAGE_EXECUTE_READWRITE : PAGE_EXECUTE_READ;
49 }
50 else
51 {
52 protect = ((prot & PROT_WRITE) != 0) ?
53 PAGE_READWRITE : PAGE_READONLY;
54 }
55
56 return protect;
57}
58
59static DWORD __map_mmap_prot_file(const int prot)
60{
61 DWORD desiredAccess = 0;
62
63 if (prot == PROT_NONE)
64 return desiredAccess;
65
66 if ((prot & PROT_READ) != 0)
67 desiredAccess |= FILE_MAP_READ;
68 if ((prot & PROT_WRITE) != 0)
69 desiredAccess |= FILE_MAP_WRITE;
70 if ((prot & PROT_EXEC) != 0)
71 desiredAccess |= FILE_MAP_EXECUTE;
72
73 return desiredAccess;
74}
75
76void* mmap(void * /* addr */, size_t len, int prot, int flags, int fildes, OffsetType off)
77{
78 HANDLE fm, h;
79
80 void * map = MAP_FAILED;
81
82#ifdef _MSC_VER
83#pragma warning(push)
84#pragma warning(disable: 4293)
85#endif
86
87 const DWORD dwFileOffsetLow = (sizeof(OffsetType) <= sizeof(DWORD)) ?
88 (DWORD)off : (DWORD)(off & 0xFFFFFFFFL);
89 const DWORD dwFileOffsetHigh = (sizeof(OffsetType) <= sizeof(DWORD)) ?
90 (DWORD)0 : (DWORD)((off >> 32) & 0xFFFFFFFFL);
91 const DWORD protect = __map_mmap_prot_page(prot);
92 const DWORD desiredAccess = __map_mmap_prot_file(prot);
93
94 const OffsetType maxSize = off + (OffsetType)len;
95
96 const DWORD dwMaxSizeLow = (sizeof(OffsetType) <= sizeof(DWORD)) ?
97 (DWORD)maxSize : (DWORD)(maxSize & 0xFFFFFFFFL);
98 const DWORD dwMaxSizeHigh = (sizeof(OffsetType) <= sizeof(DWORD)) ?
99 (DWORD)0 : (DWORD)((maxSize >> 32) & 0xFFFFFFFFL);
100
101#ifdef _MSC_VER
102#pragma warning(pop)
103#endif
104
105 errno = 0;
106
107 if (len == 0
108 /* Unsupported flag combinations */
109 || (flags & MAP_FIXED) != 0
110 /* Usupported protection combinations */
111 || prot == PROT_EXEC)
112 {
113 errno = EINVAL;
114 return MAP_FAILED;
115 }
116
117 h = ((flags & MAP_ANONYMOUS) == 0) ?
118 (HANDLE)_get_osfhandle(fildes) : INVALID_HANDLE_VALUE;
119
120 if ((flags & MAP_ANONYMOUS) == 0 && h == INVALID_HANDLE_VALUE)
121 {
122 errno = EBADF;
123 return MAP_FAILED;
124 }
125
126 fm = CreateFileMapping(h, NULL, protect, dwMaxSizeHigh, dwMaxSizeLow, NULL);
127
128 if (fm == NULL)
129 {
130 errno = __map_mman_error(GetLastError(), EPERM);
131 return MAP_FAILED;
132 }
133
134 map = MapViewOfFile(fm, desiredAccess, dwFileOffsetHigh, dwFileOffsetLow, len);
135
136 CloseHandle(fm);
137
138 if (map == NULL)
139 {
140 errno = __map_mman_error(GetLastError(), EPERM);
141 return MAP_FAILED;
142 }
143
144 return map;
145}
146
147int munmap(void *addr, size_t /* len */)
148{
149 if (UnmapViewOfFile(addr))
150 return 0;
151
152 errno = __map_mman_error(GetLastError(), EPERM);
153
154 return -1;
155}
156
157#if 0
158// Unused by IsoSpec
159
160
161int _mprotect(void *addr, size_t len, int prot)
162{
163 DWORD newProtect = __map_mmap_prot_page(prot);
164 DWORD oldProtect = 0;
165
166 if (VirtualProtect(addr, len, newProtect, &oldProtect))
167 return 0;
168
169 errno = __map_mman_error(GetLastError(), EPERM);
170
171 return -1;
172}
173
174int msync(void *addr, size_t len, int /* flags */)
175{
176 if (FlushViewOfFile(addr, len))
177 return 0;
178
179 errno = __map_mman_error(GetLastError(), EPERM);
180
181 return -1;
182}
183
184int mlock(const void *addr, size_t len)
185{
186 if (VirtualLock((LPVOID)addr, len))
187 return 0;
188
189 errno = __map_mman_error(GetLastError(), EPERM);
190
191 return -1;
192}
193
194int munlock(const void *addr, size_t len)
195{
196 if (VirtualUnlock((LPVOID)addr, len))
197 return 0;
198
199 errno = __map_mman_error(GetLastError(), EPERM);
200
201 return -1;
202}
203#endif
204
205#endif