2 * This code is derived from uClibc (original license follows).
3 * https://git.uclibc.org/uClibc/tree/utils/mmap-windows.c
5 /* mmap() replacement for Windows
7 * Author: Mike Frysinger <vapier@gentoo.org>
8 * Placed into the public domain
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
20 #include "WindowsMMap.h"
22 #define WIN32_LEAN_AND_MEAN
25 #include "InstrProfiling.h"
27 COMPILER_RT_VISIBILITY
28 void *mmap(void *start
, size_t length
, int prot
, int flags
, int fd
, off_t offset
)
30 if (prot
& ~(PROT_READ
| PROT_WRITE
| PROT_EXEC
))
33 if (!(flags
& MAP_ANON
) || offset
)
35 } else if (flags
& MAP_ANON
)
39 if (prot
& PROT_WRITE
) {
41 flProtect
= PAGE_EXECUTE_READWRITE
;
43 flProtect
= PAGE_READWRITE
;
44 } else if (prot
& PROT_EXEC
) {
46 flProtect
= PAGE_EXECUTE_READ
;
47 else if (prot
& PROT_EXEC
)
48 flProtect
= PAGE_EXECUTE
;
50 flProtect
= PAGE_READONLY
;
52 off_t end
= length
+ offset
;
55 mmap_fd
= INVALID_HANDLE_VALUE
;
57 mmap_fd
= (HANDLE
)_get_osfhandle(fd
);
58 h
= CreateFileMapping(mmap_fd
, NULL
, flProtect
, DWORD_HI(end
), DWORD_LO(end
), NULL
);
62 DWORD dwDesiredAccess
;
63 if (prot
& PROT_WRITE
)
64 dwDesiredAccess
= FILE_MAP_WRITE
;
66 dwDesiredAccess
= FILE_MAP_READ
;
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
);
79 COMPILER_RT_VISIBILITY
80 void munmap(void *addr
, size_t length
)
82 UnmapViewOfFile(addr
);
83 /* ruh-ro, we leaked handle from CreateFileMapping() ... */
86 COMPILER_RT_VISIBILITY
87 int msync(void *addr
, size_t length
, int flags
)
89 if (flags
& MS_INVALIDATE
)
90 return -1; /* Not supported. */
92 /* Exactly one of MS_ASYNC or MS_SYNC must be specified. */
93 switch (flags
& (MS_ASYNC
| MS_SYNC
)) {
101 if (!FlushViewOfFile(addr
, length
))
104 if (flags
& MS_SYNC
) {
105 /* FIXME: No longer have access to handle from CreateFileMapping(). */
107 * if (!FlushFileBuffers(h))
115 COMPILER_RT_VISIBILITY
116 int madvise(void *addr
, size_t length
, int advice
)
118 if (advice
!= MADV_DONTNEED
)
119 return -1; /* Not supported. */
121 if (!VirtualUnlock(addr
, length
))
127 COMPILER_RT_VISIBILITY
128 int lock(HANDLE handle
, DWORD lockType
, BOOL blocking
) {
129 DWORD flags
= lockType
;
131 flags
|= LOCKFILE_FAIL_IMMEDIATELY
;
133 OVERLAPPED overlapped
;
134 ZeroMemory(&overlapped
, sizeof(OVERLAPPED
));
135 overlapped
.hEvent
= CreateEvent(NULL
, FALSE
, FALSE
, NULL
);
136 BOOL result
= LockFileEx(handle
, flags
, 0, MAXDWORD
, MAXDWORD
, &overlapped
);
138 DWORD dw
= GetLastError();
140 // In non-blocking mode, return an error if the file is locked.
141 if (!blocking
&& dw
== ERROR_LOCK_VIOLATION
)
142 return -1; // EWOULDBLOCK
144 // If the error is ERROR_IO_PENDING, we need to wait until the operation
145 // finishes. Otherwise, we return an error.
146 if (dw
!= ERROR_IO_PENDING
)
150 if (!GetOverlappedResult(handle
, &overlapped
, &dwNumBytes
, TRUE
))
157 COMPILER_RT_VISIBILITY
158 int flock(int fd
, int operation
) {
159 HANDLE handle
= (HANDLE
)_get_osfhandle(fd
);
160 if (handle
== INVALID_HANDLE_VALUE
)
163 BOOL blocking
= (operation
& LOCK_NB
) == 0;
164 int op
= operation
& ~LOCK_NB
;
168 return lock(handle
, LOCKFILE_EXCLUSIVE_LOCK
, blocking
);
171 return lock(handle
, 0, blocking
);
174 if (!UnlockFile(handle
, 0, 0, MAXDWORD
, MAXDWORD
))