Fri May 26 18:55:41 2017 UTC ()
Implement a W^X-aware closure allocator. Overhead is one page per
closure, but the number should normally be moderately small. A smarter
scheme can be implemented if necessary. Requires NetBSD 7.99.72+.
Bump revision.
(joerg)
diff -r1.31 -r1.32 pkgsrc/devel/libffi/Makefile
diff -r1.43 -r1.44 pkgsrc/devel/libffi/distinfo
diff -r0 -r1.1 pkgsrc/devel/libffi/patches/patch-src_closures.c
--- pkgsrc/devel/libffi/Makefile 2017/01/28 15:39:56 1.31
+++ pkgsrc/devel/libffi/Makefile 2017/05/26 18:55:41 1.32
| @@ -1,17 +1,17 @@ | | | @@ -1,17 +1,17 @@ |
1 | # $NetBSD: Makefile,v 1.31 2017/01/28 15:39:56 wiz Exp $ | | 1 | # $NetBSD: Makefile,v 1.32 2017/05/26 18:55:41 joerg Exp $ |
2 | | | 2 | |
3 | DISTNAME= libffi-3.2.1 | | 3 | DISTNAME= libffi-3.2.1 |
4 | PKGREVISION= 2 | | 4 | PKGREVISION= 3 |
5 | CATEGORIES= devel | | 5 | CATEGORIES= devel |
6 | MASTER_SITES= ftp://sourceware.org/pub/libffi/ | | 6 | MASTER_SITES= ftp://sourceware.org/pub/libffi/ |
7 | | | 7 | |
8 | MAINTAINER= asau@inbox.ru | | 8 | MAINTAINER= asau@inbox.ru |
9 | HOMEPAGE= https://www.sourceware.org/libffi/ | | 9 | HOMEPAGE= https://www.sourceware.org/libffi/ |
10 | COMMENT= Foreign function interface | | 10 | COMMENT= Foreign function interface |
11 | LICENSE= mit | | 11 | LICENSE= mit |
12 | | | 12 | |
13 | USE_LANGUAGES= c c++ | | 13 | USE_LANGUAGES= c c++ |
14 | USE_LIBTOOL= yes | | 14 | USE_LIBTOOL= yes |
15 | USE_TOOLS+= pkg-config | | 15 | USE_TOOLS+= pkg-config |
16 | GNU_CONFIGURE= yes | | 16 | GNU_CONFIGURE= yes |
17 | CONFIGURE_ARGS= --includedir=${PREFIX}/include | | 17 | CONFIGURE_ARGS= --includedir=${PREFIX}/include |
--- pkgsrc/devel/libffi/distinfo 2016/11/03 11:40:28 1.43
+++ pkgsrc/devel/libffi/distinfo 2017/05/26 18:55:41 1.44
| @@ -1,17 +1,18 @@ | | | @@ -1,17 +1,18 @@ |
1 | $NetBSD: distinfo,v 1.43 2016/11/03 11:40:28 maya Exp $ | | 1 | $NetBSD: distinfo,v 1.44 2017/05/26 18:55:41 joerg Exp $ |
2 | | | 2 | |
3 | SHA1 (libffi-3.2.1.tar.gz) = 280c265b789e041c02e5c97815793dfc283fb1e6 | | 3 | SHA1 (libffi-3.2.1.tar.gz) = 280c265b789e041c02e5c97815793dfc283fb1e6 |
4 | RMD160 (libffi-3.2.1.tar.gz) = 9b546a3d002380bec3f00d86fc47d730abf51dfd | | 4 | RMD160 (libffi-3.2.1.tar.gz) = 9b546a3d002380bec3f00d86fc47d730abf51dfd |
5 | SHA512 (libffi-3.2.1.tar.gz) = 980ca30a8d76f963fca722432b1fe5af77d7a4e4d2eac5144fbc5374d4c596609a293440573f4294207e1bdd9fda80ad1e1cafb2ffb543df5a275bc3bd546483 | | 5 | SHA512 (libffi-3.2.1.tar.gz) = 980ca30a8d76f963fca722432b1fe5af77d7a4e4d2eac5144fbc5374d4c596609a293440573f4294207e1bdd9fda80ad1e1cafb2ffb543df5a275bc3bd546483 |
6 | Size (libffi-3.2.1.tar.gz) = 940837 bytes | | 6 | Size (libffi-3.2.1.tar.gz) = 940837 bytes |
7 | SHA1 (patch-aa) = 5218c8d895f97c812b7ca8d07c55b82ebcdc87d4 | | 7 | SHA1 (patch-aa) = 5218c8d895f97c812b7ca8d07c55b82ebcdc87d4 |
8 | SHA1 (patch-ac) = 63fba2e9486b73485a4f633927f5041110c43239 | | 8 | SHA1 (patch-ac) = 63fba2e9486b73485a4f633927f5041110c43239 |
9 | SHA1 (patch-ad) = db57395ff721d7b56edec8a3a64b4b529258341c | | 9 | SHA1 (patch-ad) = db57395ff721d7b56edec8a3a64b4b529258341c |
10 | SHA1 (patch-ae) = fdb84a49c15041826396e4d3a6dda2de719801c0 | | 10 | SHA1 (patch-ae) = fdb84a49c15041826396e4d3a6dda2de719801c0 |
11 | SHA1 (patch-af) = bf64b4082f24947cd47aba0758c347e5ddac3d7e | | 11 | SHA1 (patch-af) = bf64b4082f24947cd47aba0758c347e5ddac3d7e |
12 | SHA1 (patch-ag) = ae6a89f6b2be00c52139be6dcd14d0ebfe85d8f7 | | 12 | SHA1 (patch-ag) = ae6a89f6b2be00c52139be6dcd14d0ebfe85d8f7 |
13 | SHA1 (patch-aj) = 5179cfd150bc7de15eb1c5ee0a327016c2c32b3e | | 13 | SHA1 (patch-aj) = 5179cfd150bc7de15eb1c5ee0a327016c2c32b3e |
14 | SHA1 (patch-src_alpha_osf.S) = 50d564a1d88284f04f6896719fa3613e9b0be70b | | 14 | SHA1 (patch-src_alpha_osf.S) = 50d564a1d88284f04f6896719fa3613e9b0be70b |
15 | SHA1 (patch-src_arm_sysv.S) = 2c97e0d069a4df2e1f5b6604e54b2d02c92691e2 | | 15 | SHA1 (patch-src_arm_sysv.S) = 2c97e0d069a4df2e1f5b6604e54b2d02c92691e2 |
| | | 16 | SHA1 (patch-src_closures.c) = 04f27d89e0604b6358f809fea8692e8d8e476511 |
16 | SHA1 (patch-src_m88k_elfbsd.S) = 6572c7fa39c00096cb4a80bb88993ff1b4aaa8cc | | 17 | SHA1 (patch-src_m88k_elfbsd.S) = 6572c7fa39c00096cb4a80bb88993ff1b4aaa8cc |
17 | SHA1 (patch-src_x86_win32.S) = 8a41cbc7237d6a171605a66e91d8d92a57181569 | | 18 | SHA1 (patch-src_x86_win32.S) = 8a41cbc7237d6a171605a66e91d8d92a57181569 |
$NetBSD: patch-src_closures.c,v 1.1 2017/05/26 18:55:41 joerg Exp $
--- src/closures.c.orig 2017-05-22 23:16:12.516083134 +0000
+++ src/closures.c
@@ -33,6 +33,83 @@
#include <ffi.h>
#include <ffi_common.h>
+#ifdef __NetBSD__
+#include <sys/param.h>
+#endif
+
+#if __NetBSD_Version__ - 0 >= 799007200
+/* NetBSD with PROT_MPROTECT */
+#include <sys/mman.h>
+
+#include <stddef.h>
+#include <unistd.h>
+
+static const size_t overhead =
+ (sizeof(max_align_t) > sizeof(void *) + sizeof(size_t)) ?
+ sizeof(max_align_t)
+ : sizeof(void *) + sizeof(size_t);
+
+#define ADD_TO_POINTER(p, d) ((void *)((uintptr_t)(p) + (d)))
+
+void *
+ffi_closure_alloc (size_t size, void **code)
+{
+ static size_t page_size;
+ size_t rounded_size;
+ void *codeseg, *dataseg;
+ int prot;
+
+
+ /* Expect that PAX mprotect is active and a separate code mapping is necessary. */
+ if (!code)
+ return NULL;
+
+ /* Obtain system page size. */
+ if (!page_size)
+ page_size = sysconf(_SC_PAGESIZE);
+
+ /* Round allocation size up to the next page, keeping in mind the size field and pointer to code map. */
+ rounded_size = (size + overhead + page_size - 1) & ~(page_size - 1);
+
+ /* Primary mapping is RW, but request permission to switch to PROT_EXEC later. */
+ prot = PROT_READ | PROT_WRITE | PROT_MPROTECT(PROT_EXEC);
+ dataseg = mmap(NULL, rounded_size, prot, MAP_ANON | MAP_PRIVATE, -1, 0);
+ if (dataseg == MAP_FAILED)
+ return NULL;
+
+ /* Create secondary mapping and switch it to RX. */
+ codeseg = mremap(dataseg, rounded_size, NULL, rounded_size, MAP_REMAPDUP);
+ if (codeseg == MAP_FAILED) {
+ munmap(dataseg, rounded_size);
+ return NULL;
+ }
+ if (mprotect(codeseg, rounded_size, PROT_READ | PROT_EXEC) == -1) {
+ munmap(codeseg, rounded_size);
+ munmap(dataseg, rounded_size);
+ return NULL;
+ }
+
+ /* Remember allocation size and location of the secondary mapping for ffi_closure_free. */
+ memcpy(dataseg, &rounded_size, sizeof(rounded_size));
+ memcpy(ADD_TO_POINTER(dataseg, sizeof(size_t)), &codeseg, sizeof(void *));
+ *code = ADD_TO_POINTER(codeseg, overhead);
+ return ADD_TO_POINTER(dataseg, overhead);
+}
+
+void
+ffi_closure_free (void *ptr)
+{
+ void *codeseg, *dataseg;
+ size_t rounded_size;
+
+ dataseg = ADD_TO_POINTER(ptr, overhead);
+ memcpy(&rounded_size, dataseg, sizeof(rounded_size));
+ memcpy(&codeseg, ADD_TO_POINTER(dataseg, sizeof(size_t)), sizeof(void *));
+ munmap(dataseg, rounded_size);
+ munmap(codeseg, rounded_size);
+}
+#else /* !NetBSD with PROT_MPROTECT */
+
#if !FFI_MMAP_EXEC_WRIT && !FFI_EXEC_TRAMPOLINE_TABLE
# if __gnu_linux__ && !defined(__ANDROID__)
/* This macro indicates it may be forbidden to map anonymous memory
@@ -686,3 +763,5 @@ ffi_closure_free (void *ptr)
# endif /* ! FFI_MMAP_EXEC_WRIT */
#endif /* FFI_CLOSURES */
+
+#endif /* NetBSD with PROT_MPROTECT */