Commit 68ce0c383ece84f69945d1c8c3fed03f7f9cb5d6

Landon Fuller 2010-09-19T08:38:19

Add a shell script that generates the ARM trampoline page. This generates a page of 340 trampolines, aligned within one page. The trampolines use pc-relative addressing to reference config data (context, jump address) from a page placed directly prior to the trampoline page. This can be used on systems -- such as iOS -- that do not support writable, executable memory by remapping the executable page containing the trampolines directly above a newly allocated writable config page.

diff --git a/src/arm/gentramp.sh b/src/arm/gentramp.sh
new file mode 100755
index 0000000..5eb2033
--- /dev/null
+++ b/src/arm/gentramp.sh
@@ -0,0 +1,60 @@
+#!/bin/sh
+
+PROGNAME=$0
+
+# Each trampoline is exactly 3 instructions, or 12 bytes. If any of these values change,
+# the entire arm trampoline implementation must be updated to match, too.
+
+# Size of an individual trampoline, in bytes
+TRAMPOLINE_SIZE=12
+
+# Page size, in bytes
+PAGE_SIZE=4096
+
+# Compute the size of the reachable config page; The first 16 bytes of the config page
+# are unreachable due to our maximum pc-relative ldr offset.
+PAGE_AVAIL=`expr $PAGE_SIZE - 16`
+
+# Compute the number of of available trampolines. 
+TRAMPOLINE_COUNT=`expr $PAGE_AVAIL / $TRAMPOLINE_SIZE`
+
+header () {
+    echo "# GENERATED CODE - DO NOT EDIT"
+    echo "# This file was generated by $PROGNAME"
+    echo ""
+
+    # Write out the trampoline table, aligned to the page boundary
+    echo ".text"
+    echo ".align 12"
+    echo ".globl _ffi_closure_trampoline_table"
+    echo "_ffi_closure_trampoline_table:"
+}
+
+
+# WARNING - Don't modify the trampoline code size without also updating the relevent libffi code
+trampoline () {
+    cat << END
+    stmfd sp!, {r0-r3}
+    // Load the context argument from the config page.
+    // This places the first usable config value at _ffi_closure_trampoline_table-4080
+    // This accounts for the above 4-byte stmfd instruction, plus 8 bytes constant when loading from pc.
+    ldr r0, [pc, #-4092]
+
+    // Load the jump address from the config page.
+    ldr pc, [pc, #-4092]
+END
+}
+
+main () {
+    # Write out the header
+    header
+
+    # Write out the trampolines
+    local i=0
+    while [ $i -lt ${TRAMPOLINE_COUNT} ]; do
+        trampoline
+        local i=`expr $i + 1`
+    done
+}
+
+main