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