Mercurial > pub > dyncall > dyncall
diff dyncallback/dyncall_alloc_wx_mmap.c @ 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 | 3e629dc19168 |
children | 030fbb70aa1b |
line wrap: on
line diff
--- 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); } +