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 #include "InstrProfiling.h" 22 23 #define WIN32_LEAN_AND_MEAN 24 #include <windows.h> 25 26 #ifdef __USE_FILE_OFFSET64 27 # define DWORD_HI(x) (x >> 32) 28 # define DWORD_LO(x) ((x) & 0xffffffff) 29 #else 30 # define DWORD_HI(x) (0) 31 # define DWORD_LO(x) (x) 32 #endif 33 34 COMPILER_RT_VISIBILITY 35 void *mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset) 36 { 37 if (prot & ~(PROT_READ | PROT_WRITE | PROT_EXEC)) 38 return MAP_FAILED; 39 if (fd == -1) { 40 if (!(flags & MAP_ANON) || offset) 41 return MAP_FAILED; 42 } else if (flags & MAP_ANON) 43 return MAP_FAILED; 44 45 DWORD flProtect; 46 if (prot & PROT_WRITE) { 47 if (prot & PROT_EXEC) 48 flProtect = PAGE_EXECUTE_READWRITE; 49 else 50 flProtect = PAGE_READWRITE; 51 } else if (prot & PROT_EXEC) { 52 if (prot & PROT_READ) 53 flProtect = PAGE_EXECUTE_READ; 54 else if (prot & PROT_EXEC) 55 flProtect = PAGE_EXECUTE; 56 } else 57 flProtect = PAGE_READONLY; 58 59 off_t end = length + offset; 60 HANDLE mmap_fd, h; 61 if (fd == -1) 62 mmap_fd = INVALID_HANDLE_VALUE; 63 else 64 mmap_fd = (HANDLE)_get_osfhandle(fd); 65 h = CreateFileMapping(mmap_fd, NULL, flProtect, DWORD_HI(end), DWORD_LO(end), NULL); 66 if (h == NULL) 67 return MAP_FAILED; 68 69 DWORD dwDesiredAccess; 70 if (prot & PROT_WRITE) 71 dwDesiredAccess = FILE_MAP_WRITE; 72 else 73 dwDesiredAccess = FILE_MAP_READ; 74 if (prot & PROT_EXEC) 75 dwDesiredAccess |= FILE_MAP_EXECUTE; 76 if (flags & MAP_PRIVATE) 77 dwDesiredAccess |= FILE_MAP_COPY; 78 void *ret = MapViewOfFile(h, dwDesiredAccess, DWORD_HI(offset), DWORD_LO(offset), length); 79 if (ret == NULL) { 80 CloseHandle(h); 81 ret = MAP_FAILED; 82 } 83 return ret; 84 } 85 86 COMPILER_RT_VISIBILITY 87 void munmap(void *addr, size_t length) 88 { 89 UnmapViewOfFile(addr); 90 /* ruh-ro, we leaked handle from CreateFileMapping() ... */ 91 } 92 93 COMPILER_RT_VISIBILITY 94 int msync(void *addr, size_t length, int flags) 95 { 96 if (flags & MS_INVALIDATE) 97 return -1; /* Not supported. */ 98 99 /* Exactly one of MS_ASYNC or MS_SYNC must be specified. */ 100 switch (flags & (MS_ASYNC | MS_SYNC)) { 101 case MS_SYNC: 102 case MS_ASYNC: 103 break; 104 default: 105 return -1; 106 } 107 108 if (!FlushViewOfFile(addr, length)) 109 return -1; 110 111 if (flags & MS_SYNC) { 112 /* FIXME: No longer have access to handle from CreateFileMapping(). */ 113 /* 114 * if (!FlushFileBuffers(h)) 115 * return -1; 116 */ 117 } 118 119 return 0; 120 } 121 122 COMPILER_RT_VISIBILITY 123 int flock(int fd, int operation) 124 { 125 return -1; /* Not supported. */ 126 } 127 128 #undef DWORD_HI 129 #undef DWORD_LO 130 131 #endif /* _WIN32 */ 132