From c9598604c6872d87b6c818c92efc4bce357d988c Mon Sep 17 00:00:00 2001
From: Paul Sokolovsky <pfalcon@users.sourceforge.net>
Date: Sat, 18 Jun 2016 00:18:01 +0300
Subject: [PATCH] unix/alloc: Add option to use uPy's alloc-exec implementation
 even for libffi.

When built for Linux, libffi includes very bloated and workaround exec-alloc
implementation required to work around SELinux and other "sekuritee" features
which real people don't use. MicroPython has own alloc-exec implementation,
used to alloc memory for @micropython.native code. With this option enabled,
uPy's implementation will override libffi's. This saves 11K on x86_64 (and
that accounts for more than half of the libffi code size).

TODO: Possibly, we want to refactor this option to allow either use uPy's
implementation even for libffi, or allow to use libffi's implementation even
for uPy.
---
 unix/alloc.c        | 16 ++++++++++++++--
 unix/mpconfigport.h |  5 +++++
 2 files changed, 19 insertions(+), 2 deletions(-)

diff --git a/unix/alloc.c b/unix/alloc.c
index a0676a0ae..72b9d2a87 100644
--- a/unix/alloc.c
+++ b/unix/alloc.c
@@ -33,7 +33,7 @@
 #include "py/mpstate.h"
 #include "py/gc.h"
 
-#if MICROPY_EMIT_NATIVE
+#if MICROPY_EMIT_NATIVE || (MICROPY_PY_FFI && MICROPY_FORCE_PLAT_ALLOC_EXEC)
 
 #if defined(__OpenBSD__) || defined(__MACH__)
 #define MAP_ANONYMOUS MAP_ANON
@@ -85,4 +85,16 @@ void mp_unix_mark_exec(void) {
     }
 }
 
-#endif // MICROPY_EMIT_NATIVE
+#if MICROPY_FORCE_PLAT_ALLOC_EXEC
+void *ffi_closure_alloc(size_t size, void **code) {
+    mp_uint_t dummy;
+    mp_unix_alloc_exec(size, code, &dummy);
+    return *code;
+}
+
+void ffi_closure_free(void *ptr) {
+    // TODO
+}
+#endif
+
+#endif // MICROPY_EMIT_NATIVE || (MICROPY_PY_FFI && MICROPY_FORCE_PLAT_ALLOC_EXEC)
diff --git a/unix/mpconfigport.h b/unix/mpconfigport.h
index c824a46fd..20ad2e26d 100644
--- a/unix/mpconfigport.h
+++ b/unix/mpconfigport.h
@@ -234,6 +234,11 @@ void mp_unix_free_exec(void *ptr, mp_uint_t size);
 void mp_unix_mark_exec(void);
 #define MP_PLAT_ALLOC_EXEC(min_size, ptr, size) mp_unix_alloc_exec(min_size, ptr, size)
 #define MP_PLAT_FREE_EXEC(ptr, size) mp_unix_free_exec(ptr, size)
+#ifndef MICROPY_FORCE_PLAT_ALLOC_EXEC
+// Use MP_PLAT_ALLOC_EXEC for any executable memory allocation, including for FFI
+// (overriding libffi own implementation)
+#define MICROPY_FORCE_PLAT_ALLOC_EXEC (1)
+#endif
 
 #if MICROPY_PY_OS_DUPTERM
 #define MP_PLAT_PRINT_STRN(str, len) mp_hal_stdout_tx_strn_cooked(str, len)
-- 
GitLab