summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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