blob: f95b452467f07eb024068a3ad82988c82e983bee [file] [log] [blame]
lh9ed821d2023-04-07 01:36:19 -07001/* Copyright (C) 2005-2015 Free Software Foundation, Inc.
2
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 License as
7 published by the Free Software Foundation; either version 2.1 of the
8 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 <http://www.gnu.org/licenses/>. */
18
19#include <sysdep.h>
20#include <libc-symbols.h>
21
22#include "dl-link.h"
23
24#define ip0 x16
25#define ip1 x17
26#define lr x30
27
28 .text
29 .globl _dl_runtime_resolve
30 .type _dl_runtime_resolve, #function
31 cfi_startproc
32 .align 2
33_dl_runtime_resolve:
34 /* AArch64 we get called with:
35 ip0 &PLTGOT[2]
36 ip1 temp(dl resolver entry point)
37 [sp, #8] lr
38 [sp, #0] &PLTGOT[n]
39 */
40
41 cfi_rel_offset (lr, 8)
42
43 /* Save arguments. */
44 stp x8, x9, [sp, #-(80+8*16)]!
45 cfi_adjust_cfa_offset (80+8*16)
46 cfi_rel_offset (x8, 0)
47 cfi_rel_offset (x9, 8)
48
49 stp x6, x7, [sp, #16]
50 cfi_rel_offset (x6, 16)
51 cfi_rel_offset (x7, 24)
52
53 stp x4, x5, [sp, #32]
54 cfi_rel_offset (x4, 32)
55 cfi_rel_offset (x5, 40)
56
57 stp x2, x3, [sp, #48]
58 cfi_rel_offset (x2, 48)
59 cfi_rel_offset (x3, 56)
60
61 stp x0, x1, [sp, #64]
62 cfi_rel_offset (x0, 64)
63 cfi_rel_offset (x1, 72)
64
65 stp q0, q1, [sp, #(80+0*16)]
66 cfi_rel_offset (q0, 80+0*16)
67 cfi_rel_offset (q1, 80+1*16)
68
69 stp q2, q3, [sp, #(80+2*16)]
70 cfi_rel_offset (q0, 80+2*16)
71 cfi_rel_offset (q1, 80+3*16)
72
73 stp q4, q5, [sp, #(80+4*16)]
74 cfi_rel_offset (q0, 80+4*16)
75 cfi_rel_offset (q1, 80+5*16)
76
77 stp q6, q7, [sp, #(80+6*16)]
78 cfi_rel_offset (q0, 80+6*16)
79 cfi_rel_offset (q1, 80+7*16)
80
81 /* Get pointer to linker struct. */
82 ldr x0, [ip0, #-8]
83
84 /* Prepare to call _dl_fixup(). */
85 ldr x1, [sp, 80+8*16] /* Recover &PLTGOT[n] */
86
87 sub x1, x1, ip0
88 add x1, x1, x1, lsl #1
89 lsl x1, x1, #3
90 sub x1, x1, #192
91 lsr x1, x1, #3
92
93 /* Call fixup routine. */
94 bl _dl_fixup
95
96 /* Save the return. */
97 mov ip0, x0
98
99 /* Get arguments and return address back. */
100 ldp q0, q1, [sp, #(80+0*16)]
101 ldp q2, q3, [sp, #(80+2*16)]
102 ldp q4, q5, [sp, #(80+4*16)]
103 ldp q6, q7, [sp, #(80+6*16)]
104 ldp x0, x1, [sp, #64]
105 ldp x2, x3, [sp, #48]
106 ldp x4, x5, [sp, #32]
107 ldp x6, x7, [sp, #16]
108 ldp x8, x9, [sp], #(80+8*16)
109 cfi_adjust_cfa_offset (-(80+8*16))
110
111 ldp ip1, lr, [sp], #16
112 cfi_adjust_cfa_offset (-16)
113
114 /* Jump to the newly found address. */
115 br ip0
116
117 cfi_endproc
118 .size _dl_runtime_resolve, .-_dl_runtime_resolve
119#ifndef PROF
120 .globl _dl_runtime_profile
121 .type _dl_runtime_profile, #function
122 cfi_startproc
123 .align 2
124_dl_runtime_profile:
125 /* AArch64 we get called with:
126 ip0 &PLTGOT[2]
127 ip1 temp(dl resolver entry point)
128 [sp, #8] lr
129 [sp, #0] &PLTGOT[n]
130
131 Stack frame layout:
132 [sp, #...] lr
133 [sp, #...] &PLTGOT[n]
134 [sp, #96] La_aarch64_regs
135 [sp, #48] La_aarch64_retval
136 [sp, #40] frame size return from pltenter
137 [sp, #32] dl_profile_call saved x1
138 [sp, #24] dl_profile_call saved x0
139 [sp, #16] t1
140 [sp, #0] x29, lr <- x29
141 */
142
143# define OFFSET_T1 16
144# define OFFSET_SAVED_CALL_X0 OFFSET_T1 + 8
145# define OFFSET_FS OFFSET_SAVED_CALL_X0 + 16
146# define OFFSET_RV OFFSET_FS + 8
147# define OFFSET_RG OFFSET_RV + DL_SIZEOF_RV
148
149# define SF_SIZE OFFSET_RG + DL_SIZEOF_RG
150
151# define OFFSET_PLTGOTN SF_SIZE
152# define OFFSET_LR OFFSET_PLTGOTN + 8
153
154 /* Save arguments. */
155 sub sp, sp, #SF_SIZE
156 cfi_adjust_cfa_offset (SF_SIZE)
157 stp x29, x30, [SP, #0]
158 mov x29, sp
159 cfi_def_cfa_register (x29)
160 cfi_rel_offset (x29, 0)
161 cfi_rel_offset (lr, 8)
162
163 stp x0, x1, [x29, #OFFSET_RG + DL_OFFSET_RG_X0 + 16*0]
164 cfi_rel_offset (x0, OFFSET_RG + DL_OFFSET_RG_X0 + 16*0 + 0)
165 cfi_rel_offset (x1, OFFSET_RG + DL_OFFSET_RG_X0 + 16*0 + 8)
166 stp x2, x3, [x29, #OFFSET_RG + DL_OFFSET_RG_X0 + 16*1]
167 cfi_rel_offset (x2, OFFSET_RG + DL_OFFSET_RG_X0 + 16*1 + 0)
168 cfi_rel_offset (x3, OFFSET_RG + DL_OFFSET_RG_X0 + 16*1 + 8)
169 stp x4, x5, [x29, #OFFSET_RG + DL_OFFSET_RG_X0 + 16*2]
170 cfi_rel_offset (x4, OFFSET_RG + DL_OFFSET_RG_X0 + 16*2 + 0)
171 cfi_rel_offset (x5, OFFSET_RG + DL_OFFSET_RG_X0 + 16*2 + 8)
172 stp x6, x7, [x29, #OFFSET_RG + DL_OFFSET_RG_X0 + 16*3]
173 cfi_rel_offset (x6, OFFSET_RG + DL_OFFSET_RG_X0 + 16*3 + 0)
174 cfi_rel_offset (x7, OFFSET_RG + DL_OFFSET_RG_X0 + 16*3 + 8)
175
176 stp d0, d1, [X29, #OFFSET_RG + DL_OFFSET_RG_D0 + 16*0]
177 cfi_rel_offset (d0, OFFSET_RG + DL_OFFSET_RG_D0 + 16*0)
178 cfi_rel_offset (d1, OFFSET_RG + DL_OFFSET_RG_D0 + 16*0 + 8)
179 stp d2, d3, [X29, #OFFSET_RG+ DL_OFFSET_RG_D0 + 16*1]
180 cfi_rel_offset (d2, OFFSET_RG + DL_OFFSET_RG_D0 + 16*1 + 0)
181 cfi_rel_offset (d3, OFFSET_RG + DL_OFFSET_RG_D0 + 16*1 + 8)
182 stp d4, d5, [X29, #OFFSET_RG + DL_OFFSET_RG_D0 + 16*2]
183 cfi_rel_offset (d4, OFFSET_RG + DL_OFFSET_RG_D0 + 16*2 + 0)
184 cfi_rel_offset (d5, OFFSET_RG + DL_OFFSET_RG_D0 + 16*2 + 8)
185 stp d6, d7, [X29, #OFFSET_RG + DL_OFFSET_RG_D0 + 16*3]
186 cfi_rel_offset (d6, OFFSET_RG + DL_OFFSET_RG_D0 + 16*3 + 0)
187 cfi_rel_offset (d7, OFFSET_RG + DL_OFFSET_RG_D0 + 16*3 + 8)
188
189 add x0, x29, #SF_SIZE + 16
190 ldr x1, [x29, #OFFSET_LR]
191 stp x0, x1, [x29, #OFFSET_RG + DL_OFFSET_RG_SP]
192
193 /* Get pointer to linker struct. */
194 ldr x0, [ip0, #-8]
195
196 /* Prepare to call _dl_profile_fixup(). */
197 ldr x1, [x29, OFFSET_PLTGOTN] /* Recover &PLTGOT[n] */
198
199 sub x1, x1, ip0
200 add x1, x1, x1, lsl #1
201 lsl x1, x1, #3
202 sub x1, x1, #192
203 lsr x1, x1, #3
204
205 stp x0, x1, [x29, #OFFSET_SAVED_CALL_X0]
206
207 /* Set up extra args for _dl_profile_fixup */
208 ldr x2, [x29, #OFFSET_LR] /* load saved LR */
209 add x3, x29, #OFFSET_RG /* address of La_aarch64_reg */
210 add x4, x29, #OFFSET_FS /* address of framesize */
211 bl _dl_profile_fixup
212
213 ldr ip0, [x29, #OFFSET_FS] /* framesize == 0 */
214 cmp ip0, #0
215 bge 1f
216 cfi_remember_state
217
218 /* Save the return. */
219 mov ip0, x0
220
221 /* Get arguments and return address back. */
222 ldp x0, x1, [x29, #OFFSET_RG + DL_OFFSET_RG_X0 + 16*0]
223 ldp x2, x3, [x29, #OFFSET_RG + DL_OFFSET_RG_X0 + 16*1]
224 ldp x4, x5, [x29, #OFFSET_RG + DL_OFFSET_RG_X0 + 16*2]
225 ldp x6, x7, [x29, #OFFSET_RG + DL_OFFSET_RG_X0 + 16*3]
226 ldp d0, d1, [x29, #OFFSET_RG + DL_OFFSET_RG_D0 + 16*0]
227 ldp d2, d3, [x29, #OFFSET_RG + DL_OFFSET_RG_D0 + 16*1]
228 ldp d4, d5, [x29, #OFFSET_RG + DL_OFFSET_RG_D0 + 16*2]
229 ldp d6, d7, [x29, #OFFSET_RG + DL_OFFSET_RG_D0 + 16*3]
230
231 cfi_def_cfa_register (sp)
232 ldp x29, x30, [x29, #0]
233 cfi_restore(x29)
234 cfi_restore(x30)
235
236 add sp, sp, SF_SIZE + 16
237 cfi_adjust_cfa_offset (- SF_SIZE - 16)
238
239 /* Jump to the newly found address. */
240 br ip0
241
242 cfi_restore_state
2431:
244 /* The new frame size is in ip0. */
245
246 sub x1, x29, ip0
247 and sp, x1, #0xfffffffffffffff0
248
249 str x0, [x29, #OFFSET_T1]
250
251 mov x0, sp
252 add x1, x29, #SF_SIZE + 16
253 mov x2, ip0
254 bl memcpy
255
256 ldr ip0, [x29, #OFFSET_T1]
257
258 /* Call the function. */
259 ldp x0, x1, [x29, #OFFSET_RG + DL_OFFSET_RG_X0 + 16*0]
260 ldp x2, x3, [x29, #OFFSET_RG + DL_OFFSET_RG_X0 + 16*1]
261 ldp x4, x5, [x29, #OFFSET_RG + DL_OFFSET_RG_X0 + 16*2]
262 ldp x6, x7, [x29, #OFFSET_RG + DL_OFFSET_RG_X0 + 16*3]
263 ldp d0, d1, [x29, #OFFSET_RG + DL_OFFSET_RG_D0 + 16*0]
264 ldp d2, d3, [x29, #OFFSET_RG + DL_OFFSET_RG_D0 + 16*1]
265 ldp d4, d5, [x29, #OFFSET_RG + DL_OFFSET_RG_D0 + 16*2]
266 ldp d6, d7, [x29, #OFFSET_RG + DL_OFFSET_RG_D0 + 16*3]
267 blr ip0
268 stp x0, x1, [x29, #OFFSET_RV + DL_OFFSET_RV_X0]
269 stp d0, d1, [x29, #OFFSET_RV + DL_OFFSET_RV_D0 + 16*0]
270 stp d2, d3, [x29, #OFFSET_RV + DL_OFFSET_RV_D0 + 16*1]
271
272 /* Setup call to pltexit */
273 ldp x0, x1, [x29, #OFFSET_SAVED_CALL_X0]
274 add x2, x29, #OFFSET_RG
275 add x3, x29, #OFFSET_RV
276 bl _dl_call_pltexit
277
278 ldp x0, x1, [x29, #OFFSET_RV + DL_OFFSET_RV_X0]
279 ldp d0, d1, [x29, #OFFSET_RV + DL_OFFSET_RV_D0 + 16*0]
280 ldp d2, d3, [x29, #OFFSET_RV + DL_OFFSET_RV_D0 + 16*1]
281 /* LR from within La_aarch64_reg */
282 ldr lr, [x29, #OFFSET_RG + DL_OFFSET_RG_LR]
283 cfi_restore(lr)
284 mov sp, x29
285 cfi_def_cfa_register (sp)
286 ldr x29, [x29, #0]
287 cfi_restore(x29)
288 add sp, sp, SF_SIZE + 16
289 cfi_adjust_cfa_offset (- SF_SIZE - 16)
290
291 br lr
292
293 cfi_endproc
294 .size _dl_runtime_profile, .-_dl_runtime_profile
295#endif
296 .previous