diff options
author | Landon Fuller <landonf@bikemonkey.org> | 2010-09-19 08:38:19 -0700 |
---|---|---|
committer | Landon Fuller <landonf@bikemonkey.org> | 2010-09-19 08:38:19 -0700 |
commit | 68ce0c383ece84f69945d1c8c3fed03f7f9cb5d6 (patch) | |
tree | af2e7d45357bf0a8f7cbccbefbbb8d199203cf31 /src | |
parent | 75af086be8830a8eafe9b1ebda199d788bcb0c62 (diff) | |
download | libffi-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-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 |