changeset 185:a41bc98e101c

- impl. for allocwx stuff on POSIX-strict systems where there is no MAP_ANON for mmap()
author Tassilo Philipp
date Fri, 24 Feb 2017 23:05:53 +0100
parents f44808587a3c
children e210193f6cf1
files ChangeLog dyncallback/dyncall_alloc_wx_mmap.c
diffstat 2 files changed, 44 insertions(+), 6 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Fri Feb 17 09:34:12 2017 +0100
+++ b/ChangeLog	Fri Feb 24 23:05:53 2017 +0100
@@ -14,10 +14,11 @@
   o PPC64 single-precision float fixes for more than 13 float args (thanks Masanori!)
   o MIPS o32 (big- and little-endian), EABI (32 bit, little-endian) and n64 (big-endian) support
   o SPARC (32-bit) support
+  o POSIX compliance: fallback for wx alloc on systems that don't have mmap()'s MAP_ANON
 general:
-  o marked assembly code as not needing an execstack, for security and better/easier integration
-    into other projects/builds; modern toolchains do that automatically on compilation, but not
-    for hand written assembly code (thanks Thorsten Behrens for report and analysis)
+  o marked assembly code as not needing an execstack, for safer/easier integration into other
+    projects/builds, where needed; this is needed b/c of questionable default behaviours of some
+    toolchains (thanks Thorsten Behrens for report and analysis)
 doc:
   o working html doc generation from TEX sources
   o SPARC (32-bit) calling convention description
--- a/dyncallback/dyncall_alloc_wx_mmap.c	Fri Feb 17 09:34:12 2017 +0100
+++ b/dyncallback/dyncall_alloc_wx_mmap.c	Fri Feb 24 23:05:53 2017 +0100
@@ -6,7 +6,7 @@
  Description: Allocate write/executable memory - Implementation for posix
  License:
 
-   Copyright (c) 2007-2015 Daniel Adler <dadler@uni-goettingen.de>,
+   Copyright (c) 2007-2017 Daniel Adler <dadler@uni-goettingen.de>,
                            Tassilo Philipp <tphilipp@potion-studios.com>
 
    Permission to use, copy, modify, and distribute this software for any
@@ -29,15 +29,52 @@
 #include <sys/types.h>
 #include <sys/mman.h>
 
+/* MAP_ANON is not POSIX, if lacking, we'll use a portable fallback on *nix systems */
+#if !defined(MAP_ANON)
+#  if defined(MAP_ANONYMOUS)
+#    define MAP_ANON MAP_ANONYMOUS
+#  elif defined(DC_UNIX)
+#    include <fcntl.h>
+#  else
+#    error "Platform implementation missing for anonymous rwx memory"
+#  endif
+#endif
+
+
 int dcAllocWX(size_t size, void** pp)
 {
-  void* p = mmap(0, size, PROT_EXEC|PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANON, -1, 0);
-  if (p == ( (void*)-1 ) ) return -1;
+  void* p;
+#if !defined(MAP_ANON) && defined(DC_UNIX)
+  // Hack around not having POSIX' MAP_ANON by going through /dev/zero; store
+  // file descriptor to close on dcFreeWX at beginning of memory, as tiny hack
+  int fd = open("/dev/zero", O_RDWR);
+  if(fd == -1)
+    return -1;
+  p = mmap(0, size+sizeof(int), PROT_EXEC|PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0);
+  if(p == MAP_FAILED) {
+    close(fd);
+    return -1;
+  }
+  *(int*)p = fd;
+  p += sizeof(int);
+#else
+  p = mmap(0, size, PROT_EXEC|PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANON, -1, 0);
+  if(p == MAP_FAILED)
+    return -1;
+#endif
+
   *pp = p;
   return 0;
 }
 
 void dcFreeWX(void* p, size_t size)
 {
+#if !defined(MAP_ANON) && defined(DC_UNIX)
+  // Close file descriptor of no-MAP_ANON workaround (see above)
+  p -= sizeof(int);
+  size += sizeof(int);
+  close(*(int*)p);
+#endif
   munmap(p, size);
 }
+