]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/l4re-core/uclibc/lib/contrib/uclibc/utils/mmap-windows.c
Update
[l4.git] / l4 / pkg / l4re-core / uclibc / lib / contrib / uclibc / utils / mmap-windows.c
1 /* mmap() replacement for Windows
2  *
3  * Author: Mike Frysinger <vapier@gentoo.org>
4  * Placed into the public domain
5  */
6
7 /* References:
8  * CreateFileMapping: http://msdn.microsoft.com/en-us/library/aa366537(VS.85).aspx
9  * CloseHandle:       http://msdn.microsoft.com/en-us/library/ms724211(VS.85).aspx
10  * MapViewOfFile:     http://msdn.microsoft.com/en-us/library/aa366761(VS.85).aspx
11  * UnmapViewOfFile:   http://msdn.microsoft.com/en-us/library/aa366882(VS.85).aspx
12  */
13
14 #include <io.h>
15 #include <windows.h>
16 #include <sys/types.h>
17
18 #define PROT_READ     0x1
19 #define PROT_WRITE    0x2
20 /* This flag is only available in WinXP+ */
21 #ifdef FILE_MAP_EXECUTE
22 #define PROT_EXEC     0x4
23 #else
24 #define PROT_EXEC        0x0
25 #define FILE_MAP_EXECUTE 0
26 #endif
27
28 #define MAP_SHARED    0x01
29 #define MAP_PRIVATE   0x02
30 #define MAP_ANONYMOUS 0x20
31 #define MAP_ANON      MAP_ANONYMOUS
32 #define MAP_FAILED    ((void *) -1)
33
34 #ifdef __USE_FILE_OFFSET64
35 # define DWORD_HI(x) (x >> 32)
36 # define DWORD_LO(x) ((x) & 0xffffffff)
37 #else
38 # define DWORD_HI(x) (0)
39 # define DWORD_LO(x) (x)
40 #endif
41
42 static void *mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset)
43 {
44         if (prot & ~(PROT_READ | PROT_WRITE | PROT_EXEC))
45                 return MAP_FAILED;
46         if (fd == -1) {
47                 if (!(flags & MAP_ANON) || offset)
48                         return MAP_FAILED;
49         } else if (flags & MAP_ANON)
50                 return MAP_FAILED;
51
52         DWORD flProtect;
53         if (prot & PROT_WRITE) {
54                 if (prot & PROT_EXEC)
55                         flProtect = PAGE_EXECUTE_READWRITE;
56                 else
57                         flProtect = PAGE_READWRITE;
58         } else if (prot & PROT_EXEC) {
59                 if (prot & PROT_READ)
60                         flProtect = PAGE_EXECUTE_READ;
61                 else if (prot & PROT_EXEC)
62                         flProtect = PAGE_EXECUTE;
63         } else
64                 flProtect = PAGE_READONLY;
65
66         off_t end = length + offset;
67         HANDLE mmap_fd, h;
68         if (fd == -1)
69                 mmap_fd = INVALID_HANDLE_VALUE;
70         else
71                 mmap_fd = (HANDLE)_get_osfhandle(fd);
72         h = CreateFileMapping(mmap_fd, NULL, flProtect, DWORD_HI(end), DWORD_LO(end), NULL);
73         if (h == NULL)
74                 return MAP_FAILED;
75
76         DWORD dwDesiredAccess;
77         if (prot & PROT_WRITE)
78                 dwDesiredAccess = FILE_MAP_WRITE;
79         else
80                 dwDesiredAccess = FILE_MAP_READ;
81         if (prot & PROT_EXEC)
82                 dwDesiredAccess |= FILE_MAP_EXECUTE;
83         if (flags & MAP_PRIVATE)
84                 dwDesiredAccess |= FILE_MAP_COPY;
85         void *ret = MapViewOfFile(h, dwDesiredAccess, DWORD_HI(offset), DWORD_LO(offset), length);
86         if (ret == NULL) {
87                 CloseHandle(h);
88                 ret = MAP_FAILED;
89         }
90         return ret;
91 }
92
93 static void munmap(void *addr, size_t length)
94 {
95         UnmapViewOfFile(addr);
96         /* ruh-ro, we leaked handle from CreateFileMapping() ... */
97 }
98
99 #undef DWORD_HI
100 #undef DWORD_LO