• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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@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
mmap(void * start,size_t length,int prot,int flags,int fd,off_t offset)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
munmap(void * addr,size_t length)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
msync(void * addr,size_t length,int flags)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
flock(int fd,int operation)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