1 /* PLT trampolines. PPC64 version.
2 Copyright (C) 2005, 2006 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., 51 Franklin Street, Fifth Floor, Boston MA
21 #include <rtld-global-offsets.h>
25 /* On entry r0 contains the index of the PLT entry we need to fixup
26 and r11 contains the link_map (from PLT0+16). The link_map becomes
27 parm1 (r3) and the index (r0) need to be converted to an offset
28 (index * 24) in parm2 (r4). */
30 EALIGN(_dl_runtime_resolve, 4, 0)
31 /* We need to save the registers used to pass parameters, ie. r3 thru
32 r10; the registers are saved in a stack frame. */
34 cfi_adjust_cfa_offset (128)
46 /* Store the LR in the LR Save area of the previous frame. */
52 /* I'm almost certain we don't have to save cr... be safe. */
54 bl JUMPTARGET(_dl_fixup)
55 /* Put the registers back. */
67 /* Load the target address, toc and static chain reg from the function
68 descriptor returned by fixup. */
74 /* Unwind the stack frame, and jump. */
77 END(_dl_runtime_resolve)
80 +592 previous backchain
107 * VMX Parms in V2-V13, V0-V1 are scratch
123 * FP Parms in FP1-FP13, FP0 is a scratch register
132 * Integer parms in R3-R10, R0 is scratch, R1 SP, R2 is TOC
141 * Parameter save area, Allocated by the call, at least 8 double words
143 +32 Reserved for linker
144 +24 Reserved for compiler
147 r1+0 stack back chain
149 #define FRAME_SIZE 592
153 #define STACK_FRAME 496
154 #define CALLING_LR 488
155 #define CALLING_SP 480
156 #define INT_PARMS 112
157 #define FPR_PARMS 176
159 #define VR_VRSAVE 284
163 .tc _rtld_global_ro[TC],_rtld_global_ro
165 .tc _dl_hwcap[TC],_dl_hwcap
170 /* On entry r0 contains the index of the PLT entry we need to fixup
171 and r11 contains the link_map (from PLT0+16). The link_map becomes
172 parm1 (r3) and the index (r0) needs to be converted to an offset
173 (index * 24) in parm2 (r4). */
175 EALIGN(_dl_profile_resolve, 4, 0)
176 /* Spill r30, r31 to preserve the link_map* and reloc_addr, in case we
177 need to call _dl_call_pltexit. */
182 /* We need to save the registers used to pass parameters, ie. r3 thru
183 r10; the registers are saved in a stack frame. */
184 stdu r1,-FRAME_SIZE(r1)
185 cfi_adjust_cfa_offset (FRAME_SIZE)
186 std r3,INT_PARMS+0(r1)
188 std r4,INT_PARMS+8(r1)
189 sldi r4,r0,1 /* index * 2 */
190 std r5,INT_PARMS+16(r1)
191 add r4,r4,r0 /* index * 3 */
192 std r6,INT_PARMS+24(r1)
193 sldi r4,r4,3 /* index * 24 == PLT offset */
195 std r7,INT_PARMS+32(r1)
196 std r8,INT_PARMS+40(r1)
197 /* Store the LR in the LR Save area of the previous frame. */
198 /* XXX Do we have to do this? */
200 std r5,FRAME_SIZE+16(r1)
202 std r5,CALLING_LR(r1)
204 std r9,INT_PARMS+48(r1)
205 std r10,INT_PARMS+56(r1)
206 std r8,CALLING_SP(r1)
207 /* I'm almost certain we don't have to save cr... be safe. */
209 ld r12,.LC__dl_hwcap@toc(r2)
211 /* Load _rtld-global._dl_hwcap. */
212 ld r12,RTLD_GLOBAL_RO_DL_HWCAP_OFFSET(r12)
214 ld r12,0(r12) /* Load extern _dl_hwcap. */
216 andis. r0,r12,(PPC_FEATURE_HAS_ALTIVEC >> 16)
218 la r10,(VR_PARMS+0)(r1)
219 la r9,(VR_PARMS+16)(r1)
245 /* Save floating registers. */
246 stfd fp1,FPR_PARMS+0(r1)
247 stfd fp2,FPR_PARMS+8(r1)
248 stfd fp3,FPR_PARMS+16(r1)
249 stfd fp4,FPR_PARMS+24(r1)
250 stfd fp5,FPR_PARMS+32(r1)
251 stfd fp6,FPR_PARMS+40(r1)
252 stfd fp7,FPR_PARMS+48(r1)
253 stfd fp8,FPR_PARMS+56(r1)
254 stfd fp9,FPR_PARMS+64(r1)
255 stfd fp10,FPR_PARMS+72(r1)
256 stfd fp11,FPR_PARMS+80(r1)
258 stfd fp12,FPR_PARMS+88(r1)
259 stfd fp13,FPR_PARMS+96(r1)
260 /* Load the extra parameters. */
262 addi r7,r1,STACK_FRAME
263 /* Save link_map* and reloc_addr parms for later. */
267 bl JUMPTARGET(_dl_profile_fixup)
269 /* Test *framesizep > 0 to see if need to do pltexit processing. */
270 ld r0,STACK_FRAME(r1)
271 /* Put the registers back. */
272 lwz r12,VR_VRSAVE(r1)
275 bgt cr1,L(do_pltexit)
276 la r10,(VR_PARMS+0)(r1)
277 la r9,(VR_PARMS+16)(r1)
278 /* VRSAVE must be non-zero if VMX is present and VRs are in use. */
303 ld r0,FRAME_SIZE+16(r1)
304 ld r10,INT_PARMS+56(r1)
305 ld r9,INT_PARMS+48(r1)
306 ld r8,INT_PARMS+40(r1)
307 ld r7,INT_PARMS+32(r1)
310 ld r6,INT_PARMS+24(r1)
311 ld r5,INT_PARMS+16(r1)
312 ld r4,INT_PARMS+8(r1)
314 /* Load the target address, toc and static chain reg from the function
315 descriptor returned by fixup. */
319 ld r3,INT_PARMS+0(r1)
321 /* Load the floating point registers. */
322 lfd fp1,FPR_PARMS+0(r1)
323 lfd fp2,FPR_PARMS+8(r1)
324 lfd fp3,FPR_PARMS+16(r1)
325 lfd fp4,FPR_PARMS+24(r1)
326 lfd fp5,FPR_PARMS+32(r1)
327 lfd fp6,FPR_PARMS+40(r1)
328 lfd fp7,FPR_PARMS+48(r1)
329 lfd fp8,FPR_PARMS+56(r1)
330 lfd fp9,FPR_PARMS+64(r1)
331 lfd fp10,FPR_PARMS+72(r1)
332 lfd fp11,FPR_PARMS+80(r1)
333 lfd fp12,FPR_PARMS+88(r1)
334 lfd fp13,FPR_PARMS+96(r1)
335 /* Unwind the stack frame, and jump. */
338 addi r1,r1,FRAME_SIZE
341 la r10,(VR_PARMS+0)(r1)
342 la r9,(VR_PARMS+16)(r1)
367 ld r0,FRAME_SIZE+16(r1)
368 ld r10,INT_PARMS+56(r1)
369 ld r9,INT_PARMS+48(r1)
370 ld r8,INT_PARMS+40(r1)
371 ld r7,INT_PARMS+32(r1)
374 ld r6,INT_PARMS+24(r1)
375 ld r5,INT_PARMS+16(r1)
376 ld r4,INT_PARMS+8(r1)
378 /* Load the target address, toc and static chain reg from the function
379 descriptor returned by fixup. */
384 ld r3,INT_PARMS+0(r1)
386 /* Load the floating point registers. */
387 lfd fp1,FPR_PARMS+0(r1)
388 lfd fp2,FPR_PARMS+8(r1)
389 lfd fp3,FPR_PARMS+16(r1)
390 lfd fp4,FPR_PARMS+24(r1)
391 lfd fp5,FPR_PARMS+32(r1)
392 lfd fp6,FPR_PARMS+40(r1)
393 lfd fp7,FPR_PARMS+48(r1)
394 lfd fp8,FPR_PARMS+56(r1)
395 lfd fp9,FPR_PARMS+64(r1)
396 lfd fp10,FPR_PARMS+72(r1)
397 lfd fp11,FPR_PARMS+80(r1)
398 lfd fp12,FPR_PARMS+88(r1)
399 lfd fp13,FPR_PARMS+96(r1)
400 /* Call the target function. */
403 lwz r12,VR_VRSAVE(r1)
404 /* But return here and store the return values. */
407 stfd fp1,FPR_PARMS+0(r1)
408 stfd fp2,FPR_PARMS+8(r1)
411 stfd fp3,FPR_PARMS+16(r1)
412 stfd fp4,FPR_PARMS+24(r1)
420 bl JUMPTARGET(_dl_call_pltexit)
422 /* Restore the return values from target function. */
423 lwz r12,VR_VRSAVE(r1)
426 lfd fp1,FPR_PARMS+0(r1)
427 lfd fp2,FPR_PARMS+8(r1)
430 lfd fp3,FPR_PARMS+16(r1)
431 lfd fp4,FPR_PARMS+24(r1)
435 ld r0,FRAME_SIZE+16(r1)
441 END(_dl_profile_resolve)