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

source code of glibc/sysdeps/arm/dl-trampoline.S