summaryrefslogtreecommitdiffstats
path: root/src/platform
diff options
context:
space:
mode:
authorMarkus Mittendrein <git@maxmitti.tk>2019-03-08 00:22:20 +0100
committerMarkus Mittendrein <git@maxmitti.tk>2019-03-08 00:25:57 +0100
commit31693290ed717d700480774f4f6b49dbe9b9b704 (patch)
tree4cbbeb7ea82a950ea3c9ebadea6276d750482c4b /src/platform
parent841ee0e92516827e6dd6f2101903b5ec1cc85fb4 (diff)
downloadcc4group-31693290ed717d700480774f4f6b49dbe9b9b704.tar.gz
cc4group-31693290ed717d700480774f4f6b49dbe9b9b704.zip
Windows support (hopefully!)
Diffstat (limited to 'src/platform')
-rw-r--r--src/platform/platform.h32
-rw-r--r--src/platform/unix.c13
-rw-r--r--src/platform/windows.c108
3 files changed, 153 insertions, 0 deletions
diff --git a/src/platform/platform.h b/src/platform/platform.h
new file mode 100644
index 0000000..aaa6138
--- /dev/null
+++ b/src/platform/platform.h
@@ -0,0 +1,32 @@
+#pragma once
+
+#include <stddef.h>
+#include <sys/types.h>
+
+#ifdef CC4GROUP_PLATFORM_WINDOWS
+ #define PROT_READ 0x1
+ #define PROT_WRITE 0x2
+ /* This flag is only available in WinXP+ */
+ #ifdef FILE_MAP_EXECUTE
+ #define PROT_EXEC 0x4
+ #else
+ #define PROT_EXEC 0x0
+ #define FILE_MAP_EXECUTE 0
+ #endif
+
+ #define MAP_SHARED 0x01
+ #define MAP_PRIVATE 0x02
+ #define MAP_ANONYMOUS 0x20
+ #define MAP_ANON MAP_ANONYMOUS
+ #define MAP_FAILED ((void *) -1)
+
+ #define cc4group_mkdir(path, mode) mkdir((path))
+#else
+ #include <sys/mman.h>
+
+ #define cc4group_mkdir(path, mode) mkdir((path), (mode))
+ #define O_BINARY 0
+#endif
+
+void *cc4group_mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset, void** extra);
+int cc4group_munmap(void *addr, size_t length, void* extra); \ No newline at end of file
diff --git a/src/platform/unix.c b/src/platform/unix.c
new file mode 100644
index 0000000..ecf5166
--- /dev/null
+++ b/src/platform/unix.c
@@ -0,0 +1,13 @@
+#include "platform.h"
+
+void *cc4group_mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset, void** extra)
+{
+ (void)extra;
+ return mmap(start, length, prot, flags, fd, offset);
+}
+
+int cc4group_munmap(void *addr, size_t length, void* extra)
+{
+ (void)extra;
+ return munmap(addr, length);
+}
diff --git a/src/platform/windows.c b/src/platform/windows.c
new file mode 100644
index 0000000..fb37837
--- /dev/null
+++ b/src/platform/windows.c
@@ -0,0 +1,108 @@
+/* mmap() replacement for Windows
+ *
+ * Author: Mike Frysinger <vapier@gentoo.org>
+ * Modified to not leak the CreateFileMapping-Handle, as well as fixed MAP_PRIVATE to actually work by Markus Mittendrein
+ * Placed into the public domain
+ */
+
+/* References:
+ * CreateFileMapping: http://msdn.microsoft.com/en-us/library/aa366537(VS.85).aspx
+ * CloseHandle: http://msdn.microsoft.com/en-us/library/ms724211(VS.85).aspx
+ * MapViewOfFile: http://msdn.microsoft.com/en-us/library/aa366761(VS.85).aspx
+ * https://source.winehq.org/source/dlls/kernel32/virtual.c#0356
+ * UnmapViewOfFile: http://msdn.microsoft.com/en-us/library/aa366882(VS.85).aspx
+ */
+
+#include <io.h>
+#include <windows.h>
+#include <sys/types.h>
+
+#include <stdio.h>
+
+#include "platform.h"
+
+#ifdef __USE_FILE_OFFSET64
+# define DWORD_HI(x) (x >> 32)
+# define DWORD_LO(x) ((x) & 0xffffffff)
+#else
+# define DWORD_HI(x) (0)
+# define DWORD_LO(x) (x)
+#endif
+
+void *cc4group_mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset, void** extra)
+{
+ (void)start;
+ if (prot & ~(PROT_READ | PROT_WRITE | PROT_EXEC))
+ return MAP_FAILED;
+ if (fd == -1) {
+ if (!(flags & MAP_ANON) || offset)
+ return MAP_FAILED;
+ } else if (flags & MAP_ANON)
+ return MAP_FAILED;
+
+ DWORD flProtect;
+ if (prot & PROT_WRITE) {
+ if (prot & PROT_EXEC) {
+ if(prot & MAP_PRIVATE)
+ flProtect = PAGE_EXECUTE_WRITECOPY;
+ else
+ flProtect = PAGE_EXECUTE_READWRITE;
+ }
+ else {
+ if(prot & MAP_PRIVATE)
+ flProtect = PAGE_WRITECOPY;
+ else
+ flProtect = PAGE_READWRITE;
+ }
+ } else if (prot & PROT_EXEC) {
+ if (prot & PROT_READ)
+ flProtect = PAGE_EXECUTE_READ;
+ else if (prot & PROT_EXEC)
+ flProtect = PAGE_EXECUTE;
+ } else
+ flProtect = PAGE_READONLY;
+
+ off_t end = length + offset;
+ HANDLE mmap_fd, h;
+ if (fd == -1)
+ mmap_fd = INVALID_HANDLE_VALUE;
+ else
+ mmap_fd = (HANDLE)_get_osfhandle(fd);
+ h = CreateFileMapping(mmap_fd, NULL, flProtect, DWORD_HI(end), DWORD_LO(end), NULL);
+ if (h == NULL)
+ return MAP_FAILED;
+
+ DWORD dwDesiredAccess;
+ if (flags & MAP_PRIVATE)
+ dwDesiredAccess = FILE_MAP_COPY;
+ else if (prot & PROT_WRITE)
+ dwDesiredAccess = FILE_MAP_WRITE;
+ else
+ dwDesiredAccess = FILE_MAP_READ;
+ if (prot & PROT_EXEC)
+ dwDesiredAccess |= FILE_MAP_EXECUTE;
+ if (flags & MAP_PRIVATE)
+ dwDesiredAccess |= FILE_MAP_COPY;
+
+ void *ret = MapViewOfFile(h, dwDesiredAccess, DWORD_HI(offset), DWORD_LO(offset), length);
+ if (ret == NULL) {
+ CloseHandle(h);
+ ret = MAP_FAILED;
+ }
+
+ *extra = h;
+
+ return ret;
+}
+
+int cc4group_munmap(void *addr, size_t length, void* extra)
+{
+ (void)length;
+ UnmapViewOfFile(addr);
+ CloseHandle(extra);
+ /* ruh-ro, we leaked handle from CreateFileMapping() ... */
+ return 0;
+}
+
+#undef DWORD_HI
+#undef DWORD_LO