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