Mercurial > pub > dyncall > dyncall
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); } +