arm: Use push/pop mnemonics
[glibc.git] / ports / sysdeps / arm / dl-trampoline.S
blobf2d1679a642557c980c77b7a7fc58339b046667b
1 /* PLT trampolines.  ARM version.
2    Copyright (C) 2005-2013 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, see
17    <http://www.gnu.org/licenses/>.  */
19 /* ??? Needs more rearrangement for the LDM to handle thumb mode.  */
20 #define NO_THUMB
21 #include <sysdep.h>
22 #include <libc-symbols.h>
24 #if defined(__USE_BX__)
25 #define BX(x) bx        x
26 #else
27 #define BX(x) mov       pc, x
28 #endif
30         .text
31         .globl _dl_runtime_resolve
32         .type _dl_runtime_resolve, #function
33         CFI_SECTIONS
34         cfi_startproc
35         .align 2
36 _dl_runtime_resolve:
37         cfi_adjust_cfa_offset (4)
38         cfi_rel_offset (lr, 0)
40         @ we get called with
41         @       stack[0] contains the return address from this call
42         @       ip contains &GOT[n+3] (pointer to function)
43         @       lr points to &GOT[2]
45         @ Save arguments.  We save r4 to realign the stack.
46         push    {r0-r4}
47         cfi_adjust_cfa_offset (20)
48         cfi_rel_offset (r0, 0)
49         cfi_rel_offset (r1, 4)
50         cfi_rel_offset (r2, 8)
51         cfi_rel_offset (r3, 12)
53         @ get pointer to linker struct
54         ldr     r0, [lr, #-4]
56         @ prepare to call _dl_fixup()
57         @ change &GOT[n+3] into 8*n        NOTE: reloc are 8 bytes each
58         sub     r1, ip, lr
59         sub     r1, r1, #4
60         add     r1, r1, r1
62         @ call fixup routine
63         bl      _dl_fixup
65         @ save the return
66         mov     ip, r0
68         @ get arguments and return address back.  We restore r4
69         @ only to realign the stack.
70         pop     {r0-r4,lr}
71         cfi_adjust_cfa_offset (-24)
73         @ jump to the newly found address
74         BX(ip)
76         cfi_endproc
77         .size _dl_runtime_resolve, .-_dl_runtime_resolve
79 #ifndef PROF
80         .globl _dl_runtime_profile
81         .type _dl_runtime_profile, #function
82         CFI_SECTIONS
83         cfi_startproc
84         .align 2
85 _dl_runtime_profile:
86         cfi_adjust_cfa_offset (4)
87         cfi_rel_offset (lr, 0)
89         @ we get called with
90         @       stack[0] contains the return address from this call
91         @       ip contains &GOT[n+3] (pointer to function)
92         @       lr points to &GOT[2]
94         @ Stack layout:
95         @ 212 - saved lr
96         @ 208 - framesize returned from pltenter
97         @ 16 - La_arm_regs
98         @ 8 - Saved two arguments to _dl_profile_fixup
99         @ 4 - Saved result of _dl_profile_fixup
100         @ 0 - outgoing argument to _dl_profile_fixup
101         @ For now, we only save the general purpose registers.
103         sub     sp, sp, #196
104         cfi_adjust_cfa_offset (196)
105         stmia   sp, {r0-r3}
106         cfi_rel_offset (r0, 0)
107         cfi_rel_offset (r1, 4)
108         cfi_rel_offset (r2, 8)
109         cfi_rel_offset (r3, 12)
111         sub     sp, sp, #16
112         cfi_adjust_cfa_offset (16)
114         @ Save sp and lr.
115         add     r0, sp, #216
116         str     r0, [sp, #32]
117         ldr     r2, [sp, #212]
118         str     r2, [sp, #36]
120         @ get pointer to linker struct
121         ldr     r0, [lr, #-4]
123         @ prepare to call _dl_profile_fixup()
124         @ change &GOT[n+3] into 8*n        NOTE: reloc are 8 bytes each
125         sub     r1, ip, lr
126         sub     r1, r1, #4
127         add     r1, r1, r1
129         @ Save these two arguments for pltexit.
130         add     r3, sp, #8
131         stmia   r3!, {r0,r1}
133         @ Set up extra args for _dl_profile_fixup.
134         @ r2 and r3 are already loaded.
135         add     ip, sp, #208
136         str     ip, [sp, #0]
138         @ call profiling fixup routine
139         bl      _dl_profile_fixup
141         @ The address to call is now in r0.
143         @ Check whether we're wrapping this function.
144         ldr     ip, [sp, #208]
145         cmp     ip, #0
146         bge     1f
147         cfi_remember_state
149         @ save the return
150         mov     ip, r0
152         @ get arguments and return address back
153         add     sp, sp, #16
154         cfi_adjust_cfa_offset (-16)
155         ldmia   sp, {r0-r3,sp,lr}
156         cfi_adjust_cfa_offset (-200)
158         @ jump to the newly found address
159         BX(ip)
161         cfi_restore_state
163         @ The new frame size is in ip.
165         @ New stack layout:
166         @ 268 - saved r7
167         @ 264 - saved result of _dl_profile_fixup
168         @ 72 - La_arm_regs
169         @ 64 - Saved two arguments to _dl_profile_fixup
170         @ 0 - La_arm_retval
171         @ For now, we only save the general purpose registers.
173         @ Build the new frame.
174         str     r7, [sp, #212]
175         cfi_rel_offset (r7, 212)
176         sub     r7, sp, #56
177         cfi_def_cfa_register (r7)
178         cfi_adjust_cfa_offset (56)
179         sub     sp, sp, ip
180         bic     sp, sp, #7
182         @ Save the _dl_profile_fixup result around the call to memcpy.
183         str     r0, [r7, #264]
185         @ Copy the stack arguments.
186         mov     r0, sp
187         add     r1, r7, #272
188         mov     r2, ip
189         bl      memcpy
191         @ Call the function.
192         add     ip, r7, #72
193         ldmia   ip, {r0-r3}
194         ldr     ip, [r7, #264]
195         mov     lr, pc
196         BX(ip)
197         stmia   r7, {r0-r3}
199         @ Call pltexit.
200         add     ip, r7, #64
201         ldmia   ip, {r0,r1}
202         add     r2, r7, #72
203         add     r3, r7, #0
204         bl      _dl_call_pltexit
206         @ Return to caller.
207         ldmia   r7, {r0-r3}
208         mov     sp, r7
209         cfi_def_cfa_register (sp)
210         ldr     r7, [sp, #268]
211         ldr     lr, [sp, #92]
212         add     sp, sp, #272
213         cfi_adjust_cfa_offset (-272)
214         BX(lr)
216         cfi_endproc
217         .size _dl_runtime_profile, .-_dl_runtime_profile
218 #endif
219         .previous