summaryrefslogtreecommitdiff
path: root/libffi/src/arm/gentramp.sh
blob: 74f0b867daec8f08c52f312850cc698a809962fc (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
#!/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 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