#!/bin/sh

# ———————————————————————– # gentramp.sh - Copyright © 2010, Plausible Labs Cooperative, Inc. #

# ARM Trampoline Page Generator # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the # “Software''), to deal in the Software without restriction, including # without limitation the rights to use, copy, modify, merge, publish, # distribute, sublicense, and/or sell copies of the Software, and to # permit persons to whom the Software is furnished to do so, subject to # the following conditions: # # The above copyright notice and this permission notice shall be included # in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED “AS IS'', WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER # DEALINGS IN THE SOFTWARE. # ———————————————————————–

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 license header

cat << EOF # Copyright © 2010, Plausible Labs Cooperative, Inc. #

# Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the # “Software''), to deal in the Software without restriction, including # without limitation the rights to use, copy, modify, merge, publish, # distribute, sublicense, and/or sell copies of the Software, and to # permit persons to whom the Software is furnished to do so, subject to # the following conditions: # # The above copyright notice and this permission notice shall be included # in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED “AS IS'', WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER # DEALINGS IN THE SOFTWARE. # ———————————————————————–

EOF

# Write out the trampoline table, aligned to the page boundary
echo ".text"
echo ".align 12"
echo ".globl _ffi_closure_trampoline_table_page"
echo "_ffi_closure_trampoline_table_page:"

}

# WARNING - Don't modify the trampoline code size without also updating the relevent libffi code trampoline () {

cat << END

// trampoline
// Save to stack
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