2005-12-15 Roland McGrath <roland@redhat.com>
[glibc-ports.git] / sysdeps / arm / dl-trampoline.S
blob0224fa1d1cbfd3ad9b86c6289025c5b52f85829e
1 /* PLT trampolines.  ARM version.
2    Copyright (C) 2005 Free Software Foundation, Inc.
3    This file is part of the GNU C Library.
5    The GNU C Library is free software; you can redistribute it and/or
6    modify it under the terms of the GNU Lesser General Public
7    License as published by the Free Software Foundation; either
8    version 2.1 of the License, or (at your option) any later version.
10    The GNU C Library is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13    Lesser General Public License for more details.
15    You should have received a copy of the GNU Lesser General Public
16    License along with the GNU C Library; if not, write to the Free
17    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
18    02111-1307 USA.  */
20 #include <sysdep.h>
21 #include <libc-symbols.h>
23 #if defined(__USE_BX__)
24 #define BX(x) bx        x
25 #else
26 #define BX(x) mov       pc, x
27 #endif
29         .text
30         .globl _dl_runtime_resolve
31         .type _dl_runtime_resolve, #function
32         cfi_startproc
33         .align 2
34 _dl_runtime_resolve:
35         cfi_adjust_cfa_offset (4)
36         cfi_rel_offset (lr, 0)
38         @ we get called with
39         @       stack[0] contains the return address from this call
40         @       ip contains &GOT[n+3] (pointer to function)
41         @       lr points to &GOT[2]
43         @ Save arguments.  We save r4 to realign the stack.
44         stmdb   sp!,{r0-r4}
45         cfi_adjust_cfa_offset (20)
46         cfi_rel_offset (r0, 0)
47         cfi_rel_offset (r1, 4)
48         cfi_rel_offset (r2, 8)
49         cfi_rel_offset (r3, 12)
51         @ get pointer to linker struct
52         ldr     r0, [lr, #-4]
54         @ prepare to call _dl_fixup()
55         @ change &GOT[n+3] into 8*n        NOTE: reloc are 8 bytes each
56         sub     r1, ip, lr
57         sub     r1, r1, #4
58         add     r1, r1, r1
60         @ call fixup routine
61         bl      _dl_fixup
63         @ save the return
64         mov     ip, r0
66         @ get arguments and return address back.  We restore r4
67         @ only to realign the stack.
68         ldmia   sp!, {r0-r4,lr}
69         cfi_adjust_cfa_offset (-24)
71         @ jump to the newly found address
72         BX(ip)
74         cfi_endproc
75         .size _dl_runtime_resolve, .-_dl_runtime_resolve
77 #ifndef PROF
78         .globl _dl_runtime_profile
79         .type _dl_runtime_profile, #function
80         cfi_startproc
81         .align 2
82 _dl_runtime_profile:
83         cfi_adjust_cfa_offset (4)
84         cfi_rel_offset (lr, 0)
86         @ we get called with
87         @       stack[0] contains the return address from this call
88         @       ip contains &GOT[n+3] (pointer to function)
89         @       lr points to &GOT[2]
91         @ Stack layout:
92         @ 212 - saved lr
93         @ 208 - framesize returned from pltenter
94         @ 16 - La_arm_regs
95         @ 8 - Saved two arguments to _dl_profile_fixup
96         @ 4 - Saved result of _dl_profile_fixup
97         @ 0 - outgoing argument to _dl_profile_fixup
98         @ For now, we only save the general purpose registers.
100         sub     sp, sp, #196
101         cfi_adjust_cfa_offset (196)
102         stmia   sp, {r0-r3}
103         cfi_rel_offset (r0, 0)
104         cfi_rel_offset (r1, 4)
105         cfi_rel_offset (r2, 8)
106         cfi_rel_offset (r3, 12)
108         sub     sp, sp, #16
109         cfi_adjust_cfa_offset (16)
111         @ Save sp and lr.
112         add     r0, sp, #216
113         str     r0, [sp, #32]
114         ldr     r2, [sp, #212]
115         str     r2, [sp, #36]
117         @ get pointer to linker struct
118         ldr     r0, [lr, #-4]
120         @ prepare to call _dl_profile_fixup()
121         @ change &GOT[n+3] into 8*n        NOTE: reloc are 8 bytes each
122         sub     r1, ip, lr
123         sub     r1, r1, #4
124         add     r1, r1, r1
126         @ Save these two arguments for pltexit.
127         add     r3, sp, #8
128         stmia   r3!, {r0,r1}
130         @ Set up extra args for _dl_profile_fixup.
131         @ r2 and r3 are already loaded.
132         add     ip, sp, #208
133         str     ip, [sp, #0]
135         @ call profiling fixup routine
136         bl      _dl_profile_fixup
138         @ The address to call is now in r0.
140         @ Check whether we're wrapping this function.
141         ldr     ip, [sp, #208]
142         cmp     ip, #0
143         bge     1f
144         cfi_remember_state
146         @ save the return
147         mov     ip, r0
149         @ get arguments and return address back
150         add     sp, sp, #16
151         cfi_adjust_cfa_offset (-16)
152         ldmia   sp, {r0-r3,sp,lr}
153         cfi_adjust_cfa_offset (-200)
155         @ jump to the newly found address
156         BX(ip)
158         cfi_restore_state
160         @ The new frame size is in ip.
162         @ New stack layout:
163         @ 268 - saved r7
164         @ 264 - saved result of _dl_profile_fixup
165         @ 72 - La_arm_regs
166         @ 64 - Saved two arguments to _dl_profile_fixup
167         @ 0 - La_arm_retval
168         @ For now, we only save the general purpose registers.
170         @ Build the new frame.
171         str     r7, [sp, #212]
172         cfi_rel_offset (r7, 212)
173         sub     r7, sp, #56
174         cfi_def_cfa_register (r7)
175         cfi_adjust_cfa_offset (56)
176         sub     sp, sp, ip
177         bic     sp, sp, #7
179         @ Save the _dl_profile_fixup result around the call to memcpy.
180         str     r0, [r7, #264]
182         @ Copy the stack arguments.
183         mov     r0, sp
184         add     r1, r7, #272
185         mov     r2, ip
186         bl      memcpy
188         @ Call the function.
189         add     ip, r7, #72
190         ldmia   ip, {r0-r3}
191         ldr     ip, [r7, #264]
192         mov     lr, pc
193         BX(ip)
194         stmia   r7, {r0-r3}
196         @ Call pltexit.
197         add     ip, r7, #64
198         ldmia   ip, {r0,r1}
199         add     r2, r7, #72
200         add     r3, r7, #0
201         bl      _dl_call_pltexit
203         @ Return to caller.
204         ldmia   r7, {r0-r3}
205         mov     sp, r7
206         cfi_def_cfa_register (sp)
207         ldr     r7, [sp, #268]
208         ldr     lr, [sp, #92]
209         add     sp, sp, #272
210         cfi_adjust_cfa_offset (-272)
211         BX(lr)
213         cfi_endproc
214         .size _dl_runtime_profile, .-_dl_runtime_profile
215 #endif
216         .previous