1 /* 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 License as
7 published by the Free Software Foundation; either version 2.1 of the
8 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/>. */
20 #include <libc-symbols.h>
29 .globl _dl_runtime_resolve
30 .type _dl_runtime_resolve, #function
34 /* AArch64 we get called with:
36 ip1 temp(dl resolver entry point)
41 cfi_rel_offset (lr, 8)
44 stp x8, x9, [sp, #-80]!
45 cfi_adjust_cfa_offset (80)
46 cfi_rel_offset (x8, 0)
47 cfi_rel_offset (x9, 8)
50 cfi_rel_offset (x6, 16)
51 cfi_rel_offset (x7, 24)
54 cfi_rel_offset (x4, 32)
55 cfi_rel_offset (x5, 40)
58 cfi_rel_offset (x2, 48)
59 cfi_rel_offset (x3, 56)
62 cfi_rel_offset (x0, 64)
63 cfi_rel_offset (x1, 72)
65 /* Get pointer to linker struct. */
68 /* Prepare to call _dl_fixup(). */
69 ldr x1, [sp, 80] /* Recover &PLTGOT[n] */
72 add x1, x1, x1, lsl #1
77 /* Call fixup routine. */
80 /* Save the return. */
83 /* Get arguments and return address back. */
89 cfi_adjust_cfa_offset (-80)
91 ldp ip1, lr, [sp], #16
92 cfi_adjust_cfa_offset (-16)
94 /* Jump to the newly found address. */
98 .size _dl_runtime_resolve, .-_dl_runtime_resolve
100 .globl _dl_runtime_profile
101 .type _dl_runtime_profile, #function
105 /* AArch64 we get called with:
107 ip1 temp(dl resolver entry point)
113 [sp, #...] &PLTGOT[n]
114 [sp, #96] La_aarch64_regs
115 [sp, #48] La_aarch64_retval
116 [sp, #40] frame size return from pltenter
117 [sp, #32] dl_profile_call saved x1
118 [sp, #24] dl_profile_call saved x0
120 [sp, #0] x29, lr <- x29
123 # define OFFSET_T1 16
124 # define OFFSET_SAVED_CALL_X0 OFFSET_T1 + 8
125 # define OFFSET_FS OFFSET_SAVED_CALL_X0 + 16
126 # define OFFSET_RV OFFSET_FS + 8
127 # define OFFSET_RG OFFSET_RV + DL_SIZEOF_RV
129 # define SF_SIZE OFFSET_RG + DL_SIZEOF_RG
131 # define OFFSET_PLTGOTN SF_SIZE
132 # define OFFSET_LR OFFSET_PLTGOTN + 8
134 /* Save arguments. */
136 cfi_adjust_cfa_offset (SF_SIZE)
137 stp x29, x30, [SP, #0]
139 cfi_def_cfa_register (x29)
140 cfi_rel_offset (x29, 0)
141 cfi_rel_offset (lr, 8)
143 stp x0, x1, [x29, #OFFSET_RG + DL_OFFSET_RG_X0 + 16*0]
144 cfi_rel_offset (x0, OFFSET_RG + DL_OFFSET_RG_X0 + 16*0 + 0)
145 cfi_rel_offset (x1, OFFSET_RG + DL_OFFSET_RG_X0 + 16*0 + 8)
146 stp x2, x3, [x29, #OFFSET_RG + DL_OFFSET_RG_X0 + 16*1]
147 cfi_rel_offset (x2, OFFSET_RG + DL_OFFSET_RG_X0 + 16*1 + 0)
148 cfi_rel_offset (x3, OFFSET_RG + DL_OFFSET_RG_X0 + 16*1 + 8)
149 stp x4, x5, [x29, #OFFSET_RG + DL_OFFSET_RG_X0 + 16*2]
150 cfi_rel_offset (x4, OFFSET_RG + DL_OFFSET_RG_X0 + 16*2 + 0)
151 cfi_rel_offset (x5, OFFSET_RG + DL_OFFSET_RG_X0 + 16*2 + 8)
152 stp x6, x7, [x29, #OFFSET_RG + DL_OFFSET_RG_X0 + 16*3]
153 cfi_rel_offset (x6, OFFSET_RG + DL_OFFSET_RG_X0 + 16*3 + 0)
154 cfi_rel_offset (x7, OFFSET_RG + DL_OFFSET_RG_X0 + 16*3 + 8)
156 stp d0, d1, [X29, #OFFSET_RG + DL_OFFSET_RG_D0 + 16*0]
157 cfi_rel_offset (d0, OFFSET_RG + DL_OFFSET_RG_D0 + 16*0)
158 cfi_rel_offset (d1, OFFSET_RG + DL_OFFSET_RG_D0 + 16*0 + 8)
159 stp d2, d3, [X29, #OFFSET_RG+ DL_OFFSET_RG_D0 + 16*1]
160 cfi_rel_offset (d2, OFFSET_RG + DL_OFFSET_RG_D0 + 16*1 + 0)
161 cfi_rel_offset (d3, OFFSET_RG + DL_OFFSET_RG_D0 + 16*1 + 8)
162 stp d4, d5, [X29, #OFFSET_RG + DL_OFFSET_RG_D0 + 16*2]
163 cfi_rel_offset (d4, OFFSET_RG + DL_OFFSET_RG_D0 + 16*2 + 0)
164 cfi_rel_offset (d5, OFFSET_RG + DL_OFFSET_RG_D0 + 16*2 + 8)
165 stp d6, d7, [X29, #OFFSET_RG + DL_OFFSET_RG_D0 + 16*3]
166 cfi_rel_offset (d6, OFFSET_RG + DL_OFFSET_RG_D0 + 16*3 + 0)
167 cfi_rel_offset (d7, OFFSET_RG + DL_OFFSET_RG_D0 + 16*3 + 8)
169 add x0, x29, #SF_SIZE + 16
170 ldr x1, [x29, #OFFSET_LR]
171 stp x0, x1, [x29, #OFFSET_RG + DL_OFFSET_RG_SP]
173 /* Get pointer to linker struct. */
176 /* Prepare to call _dl_profile_fixup(). */
177 ldr x1, [x29, OFFSET_PLTGOTN] /* Recover &PLTGOT[n] */
180 add x1, x1, x1, lsl #1
185 stp x0, x1, [x29, #OFFSET_SAVED_CALL_X0]
187 /* Set up extra args for _dl_profile_fixup */
188 ldr x2, [x29, #OFFSET_LR] /* load saved LR */
189 add x3, x29, #OFFSET_RG /* address of La_aarch64_reg */
190 add x4, x29, #OFFSET_FS /* address of framesize */
193 ldr ip0, [x29, #OFFSET_FS] /* framesize == 0 */
198 /* Save the return. */
201 /* Get arguments and return address back. */
202 ldp x0, x1, [x29, #OFFSET_RG + DL_OFFSET_RG_X0 + 16*0]
203 ldp x2, x3, [x29, #OFFSET_RG + DL_OFFSET_RG_X0 + 16*1]
204 ldp x4, x5, [x29, #OFFSET_RG + DL_OFFSET_RG_X0 + 16*2]
205 ldp x6, x7, [x29, #OFFSET_RG + DL_OFFSET_RG_X0 + 16*3]
206 ldp d0, d1, [x29, #OFFSET_RG + DL_OFFSET_RG_D0 + 16*0]
207 ldp d2, d3, [x29, #OFFSET_RG + DL_OFFSET_RG_D0 + 16*1]
208 ldp d4, d5, [x29, #OFFSET_RG + DL_OFFSET_RG_D0 + 16*2]
209 ldp d6, d7, [x29, #OFFSET_RG + DL_OFFSET_RG_D0 + 16*3]
211 cfi_def_cfa_register (sp)
212 ldp x29, x30, [x29, #0]
216 add sp, sp, SF_SIZE + 16
217 cfi_adjust_cfa_offset (- SF_SIZE - 16)
219 /* Jump to the newly found address. */
224 /* The new frame size is in ip0. */
227 and sp, x1, #0xfffffffffffffff0
229 str x0, [x29, #OFFSET_T1]
232 add x1, x29, #SF_SIZE + 16
236 ldr ip0, [x29, #OFFSET_T1]
238 /* Call the function. */
239 ldp x0, x1, [x29, #OFFSET_RG + DL_OFFSET_RG_X0 + 16*0]
240 ldp x2, x3, [x29, #OFFSET_RG + DL_OFFSET_RG_X0 + 16*1]
241 ldp x4, x5, [x29, #OFFSET_RG + DL_OFFSET_RG_X0 + 16*2]
242 ldp x6, x7, [x29, #OFFSET_RG + DL_OFFSET_RG_X0 + 16*3]
243 ldp d0, d1, [x29, #OFFSET_RG + DL_OFFSET_RG_D0 + 16*0]
244 ldp d2, d3, [x29, #OFFSET_RG + DL_OFFSET_RG_D0 + 16*1]
245 ldp d4, d5, [x29, #OFFSET_RG + DL_OFFSET_RG_D0 + 16*2]
246 ldp d6, d7, [x29, #OFFSET_RG + DL_OFFSET_RG_D0 + 16*3]
248 stp x0, x1, [x29, #OFFSET_RV + DL_OFFSET_RV_X0]
249 stp d0, d1, [x29, #OFFSET_RV + DL_OFFSET_RV_D0 + 16*0]
250 stp d2, d3, [x29, #OFFSET_RV + DL_OFFSET_RV_D0 + 16*1]
252 /* Setup call to pltexit */
253 ldp x0, x1, [x29, #OFFSET_SAVED_CALL_X0]
254 add x2, x29, #OFFSET_RG
255 add x3, x29, #OFFSET_RV
258 ldp x0, x1, [x29, #OFFSET_RV + DL_OFFSET_RV_X0]
259 ldp d0, d1, [x29, #OFFSET_RV + DL_OFFSET_RV_D0 + 16*0]
260 ldp d2, d3, [x29, #OFFSET_RV + DL_OFFSET_RV_D0 + 16*1]
261 /* LR from within La_aarch64_reg */
262 ldr lr, [x29, #OFFSET_RG + DL_OFFSET_RG_LR]
265 cfi_def_cfa_register (sp)
268 add sp, sp, SF_SIZE + 16
269 cfi_adjust_cfa_offset (- SF_SIZE - 16)
274 .size _dl_runtime_profile, .-_dl_runtime_profile