xref: /netbsd-src/sys/external/bsd/compiler_rt/dist/lib/profile/WindowsMMap.c (revision ef84fd3bd8895f4e6be1e38baf19e6dc3255bc64)
1*ef84fd3bSjoerg /*
2*ef84fd3bSjoerg  * This code is derived from uClibc (original license follows).
3*ef84fd3bSjoerg  * https://git.uclibc.org/uClibc/tree/utils/mmap-windows.c
4*ef84fd3bSjoerg  */
5*ef84fd3bSjoerg  /* mmap() replacement for Windows
6*ef84fd3bSjoerg  *
7*ef84fd3bSjoerg  * Author: Mike Frysinger <vapier@gentoo.org>
8*ef84fd3bSjoerg  * Placed into the public domain
9*ef84fd3bSjoerg  */
10*ef84fd3bSjoerg 
11*ef84fd3bSjoerg /* References:
12*ef84fd3bSjoerg  * CreateFileMapping: http://msdn.microsoft.com/en-us/library/aa366537(VS.85).aspx
13*ef84fd3bSjoerg  * CloseHandle:       http://msdn.microsoft.com/en-us/library/ms724211(VS.85).aspx
14*ef84fd3bSjoerg  * MapViewOfFile:     http://msdn.microsoft.com/en-us/library/aa366761(VS.85).aspx
15*ef84fd3bSjoerg  * UnmapViewOfFile:   http://msdn.microsoft.com/en-us/library/aa366882(VS.85).aspx
16*ef84fd3bSjoerg  */
17*ef84fd3bSjoerg 
18*ef84fd3bSjoerg #if defined(_WIN32)
19*ef84fd3bSjoerg 
20*ef84fd3bSjoerg #include "WindowsMMap.h"
21*ef84fd3bSjoerg #include "InstrProfiling.h"
22*ef84fd3bSjoerg 
23*ef84fd3bSjoerg #ifdef __USE_FILE_OFFSET64
24*ef84fd3bSjoerg # define DWORD_HI(x) (x >> 32)
25*ef84fd3bSjoerg # define DWORD_LO(x) ((x) & 0xffffffff)
26*ef84fd3bSjoerg #else
27*ef84fd3bSjoerg # define DWORD_HI(x) (0)
28*ef84fd3bSjoerg # define DWORD_LO(x) (x)
29*ef84fd3bSjoerg #endif
30*ef84fd3bSjoerg 
31*ef84fd3bSjoerg COMPILER_RT_VISIBILITY
mmap(void * start,size_t length,int prot,int flags,int fd,off_t offset)32*ef84fd3bSjoerg void *mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset)
33*ef84fd3bSjoerg {
34*ef84fd3bSjoerg   if (prot & ~(PROT_READ | PROT_WRITE | PROT_EXEC))
35*ef84fd3bSjoerg     return MAP_FAILED;
36*ef84fd3bSjoerg   if (fd == -1) {
37*ef84fd3bSjoerg     if (!(flags & MAP_ANON) || offset)
38*ef84fd3bSjoerg       return MAP_FAILED;
39*ef84fd3bSjoerg   } else if (flags & MAP_ANON)
40*ef84fd3bSjoerg     return MAP_FAILED;
41*ef84fd3bSjoerg 
42*ef84fd3bSjoerg   DWORD flProtect;
43*ef84fd3bSjoerg   if (prot & PROT_WRITE) {
44*ef84fd3bSjoerg     if (prot & PROT_EXEC)
45*ef84fd3bSjoerg       flProtect = PAGE_EXECUTE_READWRITE;
46*ef84fd3bSjoerg     else
47*ef84fd3bSjoerg       flProtect = PAGE_READWRITE;
48*ef84fd3bSjoerg   } else if (prot & PROT_EXEC) {
49*ef84fd3bSjoerg     if (prot & PROT_READ)
50*ef84fd3bSjoerg       flProtect = PAGE_EXECUTE_READ;
51*ef84fd3bSjoerg     else if (prot & PROT_EXEC)
52*ef84fd3bSjoerg       flProtect = PAGE_EXECUTE;
53*ef84fd3bSjoerg   } else
54*ef84fd3bSjoerg     flProtect = PAGE_READONLY;
55*ef84fd3bSjoerg 
56*ef84fd3bSjoerg   off_t end = length + offset;
57*ef84fd3bSjoerg   HANDLE mmap_fd, h;
58*ef84fd3bSjoerg   if (fd == -1)
59*ef84fd3bSjoerg     mmap_fd = INVALID_HANDLE_VALUE;
60*ef84fd3bSjoerg   else
61*ef84fd3bSjoerg     mmap_fd = (HANDLE)_get_osfhandle(fd);
62*ef84fd3bSjoerg   h = CreateFileMapping(mmap_fd, NULL, flProtect, DWORD_HI(end), DWORD_LO(end), NULL);
63*ef84fd3bSjoerg   if (h == NULL)
64*ef84fd3bSjoerg     return MAP_FAILED;
65*ef84fd3bSjoerg 
66*ef84fd3bSjoerg   DWORD dwDesiredAccess;
67*ef84fd3bSjoerg   if (prot & PROT_WRITE)
68*ef84fd3bSjoerg     dwDesiredAccess = FILE_MAP_WRITE;
69*ef84fd3bSjoerg   else
70*ef84fd3bSjoerg     dwDesiredAccess = FILE_MAP_READ;
71*ef84fd3bSjoerg   if (prot & PROT_EXEC)
72*ef84fd3bSjoerg     dwDesiredAccess |= FILE_MAP_EXECUTE;
73*ef84fd3bSjoerg   if (flags & MAP_PRIVATE)
74*ef84fd3bSjoerg     dwDesiredAccess |= FILE_MAP_COPY;
75*ef84fd3bSjoerg   void *ret = MapViewOfFile(h, dwDesiredAccess, DWORD_HI(offset), DWORD_LO(offset), length);
76*ef84fd3bSjoerg   if (ret == NULL) {
77*ef84fd3bSjoerg     CloseHandle(h);
78*ef84fd3bSjoerg     ret = MAP_FAILED;
79*ef84fd3bSjoerg   }
80*ef84fd3bSjoerg   return ret;
81*ef84fd3bSjoerg }
82*ef84fd3bSjoerg 
83*ef84fd3bSjoerg COMPILER_RT_VISIBILITY
munmap(void * addr,size_t length)84*ef84fd3bSjoerg void munmap(void *addr, size_t length)
85*ef84fd3bSjoerg {
86*ef84fd3bSjoerg   UnmapViewOfFile(addr);
87*ef84fd3bSjoerg   /* ruh-ro, we leaked handle from CreateFileMapping() ... */
88*ef84fd3bSjoerg }
89*ef84fd3bSjoerg 
90*ef84fd3bSjoerg COMPILER_RT_VISIBILITY
msync(void * addr,size_t length,int flags)91*ef84fd3bSjoerg int msync(void *addr, size_t length, int flags)
92*ef84fd3bSjoerg {
93*ef84fd3bSjoerg   if (flags & MS_INVALIDATE)
94*ef84fd3bSjoerg     return -1; /* Not supported. */
95*ef84fd3bSjoerg 
96*ef84fd3bSjoerg   /* Exactly one of MS_ASYNC or MS_SYNC must be specified. */
97*ef84fd3bSjoerg   switch (flags & (MS_ASYNC | MS_SYNC)) {
98*ef84fd3bSjoerg     case MS_SYNC:
99*ef84fd3bSjoerg     case MS_ASYNC:
100*ef84fd3bSjoerg       break;
101*ef84fd3bSjoerg     default:
102*ef84fd3bSjoerg       return -1;
103*ef84fd3bSjoerg   }
104*ef84fd3bSjoerg 
105*ef84fd3bSjoerg   if (!FlushViewOfFile(addr, length))
106*ef84fd3bSjoerg     return -1;
107*ef84fd3bSjoerg 
108*ef84fd3bSjoerg   if (flags & MS_SYNC) {
109*ef84fd3bSjoerg     /* FIXME: No longer have access to handle from CreateFileMapping(). */
110*ef84fd3bSjoerg     /*
111*ef84fd3bSjoerg      * if (!FlushFileBuffers(h))
112*ef84fd3bSjoerg      *   return -1;
113*ef84fd3bSjoerg      */
114*ef84fd3bSjoerg   }
115*ef84fd3bSjoerg 
116*ef84fd3bSjoerg   return 0;
117*ef84fd3bSjoerg }
118*ef84fd3bSjoerg 
119*ef84fd3bSjoerg COMPILER_RT_VISIBILITY
flock(int fd,int operation)120*ef84fd3bSjoerg int flock(int fd, int operation)
121*ef84fd3bSjoerg {
122*ef84fd3bSjoerg   return -1; /* Not supported. */
123*ef84fd3bSjoerg }
124*ef84fd3bSjoerg 
125*ef84fd3bSjoerg #undef DWORD_HI
126*ef84fd3bSjoerg #undef DWORD_LO
127*ef84fd3bSjoerg 
128*ef84fd3bSjoerg #endif /* _WIN32 */
129