text: #!/bin/sh
  
  # -----------------------------------------------------------------------
  #  gentramp.sh - Copyright (c) 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 (c) 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 relevant 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
  