On i386, it's better for a jit to ask for exec memory upfront, so uvm
knows to place it in the exec segment. Otherwise, if you mmap non-exec
and mprotect it, you wind up with a high mapping and the segment must
be enlarged to cover the whole process.

I sent Mike a slightly different diff; this is what he ended up
committing to git. I think we should add it to the port.

diff --git a/src/lj_mcode.c b/src/lj_mcode.c
index f8f8406..d95ebeb 100644
--- a/src/lj_mcode.c
+++ b/src/lj_mcode.c
@@ -145,7 +145,7 @@ static void mcode_free(jit_State *J, void *p, size_t sz)
 
 /* -- MCode area protection ----------------------------------------------- */
 
-/* Define this ONLY if the page protection twiddling becomes a bottleneck. */
+/* Define this ONLY if page protection twiddling becomes a bottleneck. */
 #ifdef LUAJIT_UNPROTECT_MCODE
 
 /* It's generally considered to be a potential security risk to have
@@ -252,7 +252,20 @@ static void *mcode_alloc(jit_State *J, size_t sz)
 #else
 
 /* All memory addresses are reachable by relative jumps. */
-#define mcode_alloc(J, sz)     mcode_alloc_at((J), 0, (sz), MCPROT_GEN)
+static void *mcode_alloc(jit_State *J, size_t sz)
+{
+#ifdef __OpenBSD__
+  /* Allow better executable memory allocation for OpenBSD W^X mode. */
+  void *p = mcode_alloc_at(J, 0, sz, MCPROT_RUN);
+  if (p && mcode_setprot(p, sz, MCPROT_GEN)) {
+    mcode_free(J, p, sz);
+    return NULL;
+  }
+  return p;
+#else
+  return mcode_alloc_at(J, 0, sz, MCPROT_GEN);
+#endif
+}
 
 #endif
 

Reply via email to