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 #ifdef __USE_FILE_OFFSET64
28 # define DWORD_HI(x) (x >> 32)
29 # define DWORD_LO(x) ((x) & 0xffffffff)
31 # define DWORD_HI(x) (0)
32 # define DWORD_LO(x) (x)
35 COMPILER_RT_VISIBILITY
36 void *mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset)
38 if (prot & ~(PROT_READ | PROT_WRITE | PROT_EXEC))
41 if (!(flags & MAP_ANON) || offset)
43 } else if (flags & MAP_ANON)
47 if (prot & PROT_WRITE) {
49 flProtect = PAGE_EXECUTE_READWRITE;
51 flProtect = PAGE_READWRITE;
52 } else if (prot & PROT_EXEC) {
54 flProtect = PAGE_EXECUTE_READ;
55 else if (prot & PROT_EXEC)
56 flProtect = PAGE_EXECUTE;
58 flProtect = PAGE_READONLY;
60 off_t end = length + offset;
63 mmap_fd = INVALID_HANDLE_VALUE;
65 mmap_fd = (HANDLE)_get_osfhandle(fd);
66 h = CreateFileMapping(mmap_fd, NULL, flProtect, DWORD_HI(end), DWORD_LO(end), NULL);
70 DWORD dwDesiredAccess;
71 if (prot & PROT_WRITE)
72 dwDesiredAccess = FILE_MAP_WRITE;
74 dwDesiredAccess = FILE_MAP_READ;
76 dwDesiredAccess |= FILE_MAP_EXECUTE;
77 if (flags & MAP_PRIVATE)
78 dwDesiredAccess |= FILE_MAP_COPY;
79 void *ret = MapViewOfFile(h, dwDesiredAccess, DWORD_HI(offset), DWORD_LO(offset), length);
87 COMPILER_RT_VISIBILITY
88 void munmap(void *addr, size_t length)
90 UnmapViewOfFile(addr);
91 /* ruh-ro, we leaked handle from CreateFileMapping() ... */
94 COMPILER_RT_VISIBILITY
95 int msync(void *addr, size_t length, int flags)
97 if (flags & MS_INVALIDATE)
98 return -1; /* Not supported. */
100 /* Exactly one of MS_ASYNC or MS_SYNC must be specified. */
101 switch (flags & (MS_ASYNC | MS_SYNC)) {
109 if (!FlushViewOfFile(addr, length))
112 if (flags & MS_SYNC) {
113 /* FIXME: No longer have access to handle from CreateFileMapping(). */
115 * if (!FlushFileBuffers(h))
123 COMPILER_RT_VISIBILITY
124 int lock(HANDLE handle, DWORD lockType, BOOL blocking) {
125 DWORD flags = lockType;
127 flags |= LOCKFILE_FAIL_IMMEDIATELY;
129 OVERLAPPED overlapped;
130 ZeroMemory(&overlapped, sizeof(OVERLAPPED));
131 overlapped.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
132 BOOL result = LockFileEx(handle, flags, 0, MAXDWORD, MAXDWORD, &overlapped);
134 DWORD dw = GetLastError();
136 // In non-blocking mode, return an error if the file is locked.
137 if (!blocking && dw == ERROR_LOCK_VIOLATION)
138 return -1; // EWOULDBLOCK
140 // If the error is ERROR_IO_PENDING, we need to wait until the operation
141 // finishes. Otherwise, we return an error.
142 if (dw != ERROR_IO_PENDING)
146 if (!GetOverlappedResult(handle, &overlapped, &dwNumBytes, TRUE))
153 COMPILER_RT_VISIBILITY
154 int flock(int fd, int operation) {
155 HANDLE handle = (HANDLE)_get_osfhandle(fd);
156 if (handle == INVALID_HANDLE_VALUE)
159 BOOL blocking = (operation & LOCK_NB) == 0;
160 int op = operation & ~LOCK_NB;
164 return lock(handle, LOCKFILE_EXCLUSIVE_LOCK, blocking);
167 return lock(handle, 0, blocking);
170 if (!UnlockFile(handle, 0, 0, MAXDWORD, MAXDWORD))