diff options
-rwxr-xr-x | src/arm/gentramp.sh | 60 |
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 |