summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLandon Fuller <landonf@bikemonkey.org>2010-09-19 08:38:19 -0700
committerLandon Fuller <landonf@bikemonkey.org>2010-09-19 08:38:19 -0700
commit68ce0c383ece84f69945d1c8c3fed03f7f9cb5d6 (patch)
treeaf2e7d45357bf0a8f7cbccbefbbb8d199203cf31 /src
parent75af086be8830a8eafe9b1ebda199d788bcb0c62 (diff)
downloadlibffi-68ce0c383ece84f69945d1c8c3fed03f7f9cb5d6.tar.gz
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.
Diffstat (limited to 'src')
-rwxr-xr-xsrc/arm/gentramp.sh60
1 files changed, 60 insertions, 0 deletions
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