blob: 1799392f0af160d46116e96b382ae5c4aaaacc42 [file] [log] [blame]
lh9ed821d2023-04-07 01:36:19 -07001/* 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
42static 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
93static 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