Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/compiler-rt/lib/profile/WindowsMMap.c
35233 views
1
/*
2
* This code is derived from uClibc (original license follows).
3
* https://git.uclibc.org/uClibc/tree/utils/mmap-windows.c
4
*/
5
/* mmap() replacement for Windows
6
*
7
* Author: Mike Frysinger <[email protected]>
8
* Placed into the public domain
9
*/
10
11
/* References:
12
* CreateFileMapping: http://msdn.microsoft.com/en-us/library/aa366537(VS.85).aspx
13
* CloseHandle: http://msdn.microsoft.com/en-us/library/ms724211(VS.85).aspx
14
* MapViewOfFile: http://msdn.microsoft.com/en-us/library/aa366761(VS.85).aspx
15
* UnmapViewOfFile: http://msdn.microsoft.com/en-us/library/aa366882(VS.85).aspx
16
*/
17
18
#if defined(_WIN32)
19
20
#include "WindowsMMap.h"
21
22
#define WIN32_LEAN_AND_MEAN
23
#include <windows.h>
24
25
#include "InstrProfiling.h"
26
27
COMPILER_RT_VISIBILITY
28
void *mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset)
29
{
30
if (prot & ~(PROT_READ | PROT_WRITE | PROT_EXEC))
31
return MAP_FAILED;
32
if (fd == -1) {
33
if (!(flags & MAP_ANON) || offset)
34
return MAP_FAILED;
35
} else if (flags & MAP_ANON)
36
return MAP_FAILED;
37
38
DWORD flProtect;
39
if (prot & PROT_WRITE) {
40
if (prot & PROT_EXEC)
41
flProtect = PAGE_EXECUTE_READWRITE;
42
else
43
flProtect = PAGE_READWRITE;
44
} else if (prot & PROT_EXEC) {
45
if (prot & PROT_READ)
46
flProtect = PAGE_EXECUTE_READ;
47
else if (prot & PROT_EXEC)
48
flProtect = PAGE_EXECUTE;
49
} else
50
flProtect = PAGE_READONLY;
51
52
off_t end = length + offset;
53
HANDLE mmap_fd, h;
54
if (fd == -1)
55
mmap_fd = INVALID_HANDLE_VALUE;
56
else
57
mmap_fd = (HANDLE)_get_osfhandle(fd);
58
h = CreateFileMapping(mmap_fd, NULL, flProtect, DWORD_HI(end), DWORD_LO(end), NULL);
59
if (h == NULL)
60
return MAP_FAILED;
61
62
DWORD dwDesiredAccess;
63
if (prot & PROT_WRITE)
64
dwDesiredAccess = FILE_MAP_WRITE;
65
else
66
dwDesiredAccess = FILE_MAP_READ;
67
if (prot & PROT_EXEC)
68
dwDesiredAccess |= FILE_MAP_EXECUTE;
69
if (flags & MAP_PRIVATE)
70
dwDesiredAccess |= FILE_MAP_COPY;
71
void *ret = MapViewOfFile(h, dwDesiredAccess, DWORD_HI(offset), DWORD_LO(offset), length);
72
if (ret == NULL) {
73
CloseHandle(h);
74
ret = MAP_FAILED;
75
}
76
return ret;
77
}
78
79
COMPILER_RT_VISIBILITY
80
void munmap(void *addr, size_t length)
81
{
82
UnmapViewOfFile(addr);
83
/* ruh-ro, we leaked handle from CreateFileMapping() ... */
84
}
85
86
COMPILER_RT_VISIBILITY
87
int msync(void *addr, size_t length, int flags)
88
{
89
if (flags & MS_INVALIDATE)
90
return -1; /* Not supported. */
91
92
/* Exactly one of MS_ASYNC or MS_SYNC must be specified. */
93
switch (flags & (MS_ASYNC | MS_SYNC)) {
94
case MS_SYNC:
95
case MS_ASYNC:
96
break;
97
default:
98
return -1;
99
}
100
101
if (!FlushViewOfFile(addr, length))
102
return -1;
103
104
if (flags & MS_SYNC) {
105
/* FIXME: No longer have access to handle from CreateFileMapping(). */
106
/*
107
* if (!FlushFileBuffers(h))
108
* return -1;
109
*/
110
}
111
112
return 0;
113
}
114
115
COMPILER_RT_VISIBILITY
116
int madvise(void *addr, size_t length, int advice)
117
{
118
if (advice != MADV_DONTNEED)
119
return -1; /* Not supported. */
120
121
if (!VirtualUnlock(addr, length))
122
return -1;
123
124
return 0;
125
}
126
127
static int lock(HANDLE handle, DWORD lockType, BOOL blocking) {
128
DWORD flags = lockType;
129
if (!blocking)
130
flags |= LOCKFILE_FAIL_IMMEDIATELY;
131
132
OVERLAPPED overlapped;
133
ZeroMemory(&overlapped, sizeof(OVERLAPPED));
134
overlapped.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
135
BOOL result = LockFileEx(handle, flags, 0, MAXDWORD, MAXDWORD, &overlapped);
136
if (!result) {
137
DWORD dw = GetLastError();
138
139
// In non-blocking mode, return an error if the file is locked.
140
if (!blocking && dw == ERROR_LOCK_VIOLATION)
141
return -1; // EWOULDBLOCK
142
143
// If the error is ERROR_IO_PENDING, we need to wait until the operation
144
// finishes. Otherwise, we return an error.
145
if (dw != ERROR_IO_PENDING)
146
return -1;
147
148
DWORD dwNumBytes;
149
if (!GetOverlappedResult(handle, &overlapped, &dwNumBytes, TRUE))
150
return -1;
151
}
152
153
return 0;
154
}
155
156
COMPILER_RT_VISIBILITY
157
int flock(int fd, int operation) {
158
HANDLE handle = (HANDLE)_get_osfhandle(fd);
159
if (handle == INVALID_HANDLE_VALUE)
160
return -1;
161
162
BOOL blocking = (operation & LOCK_NB) == 0;
163
int op = operation & ~LOCK_NB;
164
165
switch (op) {
166
case LOCK_EX:
167
return lock(handle, LOCKFILE_EXCLUSIVE_LOCK, blocking);
168
169
case LOCK_SH:
170
return lock(handle, 0, blocking);
171
172
case LOCK_UN:
173
if (!UnlockFile(handle, 0, 0, MAXDWORD, MAXDWORD))
174
return -1;
175
break;
176
177
default:
178
return -1;
179
}
180
181
return 0;
182
}
183
184
#undef DWORD_HI
185
#undef DWORD_LO
186
187
#endif /* _WIN32 */
188
189