1 /* PLT trampolines. PPC64 version.
2 Copyright (C) 2005-2014 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/>. */
20 #include <rtld-global-offsets.h>
24 /* On entry r0 contains the index of the PLT entry we need to fixup
25 and r11 contains the link_map (from PLT0+16). The link_map becomes
26 parm1 (r3) and the index (r0) need to be converted to an offset
27 (index * 24) in parm2 (r4). */
29 #define FRAME_SIZE (FRAME_MIN_SIZE+64)
30 /* We need to save the registers used to pass parameters, ie. r3 thru
31 r10; Use local var space rather than the parameter save area,
32 because gcc as of 2010/05 doesn't allocate a proper stack frame for
33 a function that makes no calls except for __tls_get_addr and we
34 might be here resolving the __tls_get_addr call. */
35 #define INT_PARMS FRAME_MIN_SIZE
36 EALIGN(_dl_runtime_resolve, 4, 0)
37 stdu r1,-FRAME_SIZE(r1)
38 cfi_adjust_cfa_offset (FRAME_SIZE)
39 std r3,INT_PARMS+0(r1)
41 std r4,INT_PARMS+8(r1)
43 std r5,INT_PARMS+16(r1)
45 std r6,INT_PARMS+24(r1)
47 std r7,INT_PARMS+32(r1)
49 std r8,INT_PARMS+40(r1)
50 /* Store the LR in the LR Save area. */
51 std r0,FRAME_SIZE+FRAME_LR_SAVE(r1)
52 cfi_offset (lr, FRAME_LR_SAVE)
53 std r9,INT_PARMS+48(r1)
54 std r10,INT_PARMS+56(r1)
55 bl JUMPTARGET(_dl_fixup)
59 /* Put the registers back. */
60 ld r0,FRAME_SIZE+FRAME_LR_SAVE(r1)
61 ld r10,INT_PARMS+56(r1)
62 ld r9,INT_PARMS+48(r1)
63 ld r8,INT_PARMS+40(r1)
64 ld r7,INT_PARMS+32(r1)
66 ld r6,INT_PARMS+24(r1)
67 ld r5,INT_PARMS+16(r1)
69 /* Prepare for calling the function returned by fixup. */
73 /* Restore the caller's TOC in case we jump to a local entry point. */
74 ld r2,FRAME_SIZE+FRAME_TOC_SAVE(r1)
76 /* Unwind the stack frame, and jump. */
79 END(_dl_runtime_resolve)
83 /* Stack layout: ELFv2 ABI.
84 +752 previous backchain
97 +592 previous backchain +584 fp8
98 +584 spill_r31 +576 fp7
99 +576 spill_r30 +568 fp6
124 * VMX Parms in V2-V13, V0-V1 are scratch
140 * FP Parms in FP1-FP13, FP0 is a scratch register
149 * Integer parms in R3-R10, R0 is scratch, R1 SP, R2 is TOC
158 * Parameter save area
159 * (v1 ABI: Allocated by the call, at least 8 double words)
160 +40 v1 ABI: TOC save area
161 +32 v1 ABI: Reserved for linker
162 +24 v1 ABI: Reserved for compiler / v2 ABI: TOC save area
165 r1+0 stack back chain
168 # define FRAME_SIZE 752
171 # define FRAME_SIZE 592
176 #define STACK_FRAME 496
177 #define CALLING_LR 488
178 #define CALLING_SP 480
179 #define INT_PARMS 112
180 #define FPR_PARMS 176
182 #define VR_VRSAVE 284
186 .tc _rtld_local_ro[TC],_rtld_local_ro
188 .tc _dl_hwcap[TC],_dl_hwcap
193 /* On entry r0 contains the index of the PLT entry we need to fixup
194 and r11 contains the link_map (from PLT0+16). The link_map becomes
195 parm1 (r3) and the index (r0) needs to be converted to an offset
196 (index * 24) in parm2 (r4). */
198 EALIGN(_dl_profile_resolve, 4, 0)
199 /* Spill r30, r31 to preserve the link_map* and reloc_addr, in case we
200 need to call _dl_call_pltexit. */
203 /* We need to save the registers used to pass parameters, ie. r3 thru
204 r10; the registers are saved in a stack frame. */
205 stdu r1,-FRAME_SIZE(r1)
206 cfi_adjust_cfa_offset (FRAME_SIZE)
209 std r3,INT_PARMS+0(r1)
211 std r4,INT_PARMS+8(r1)
212 sldi r4,r0,1 /* index * 2 */
213 std r5,INT_PARMS+16(r1)
214 add r4,r4,r0 /* index * 3 */
215 std r6,INT_PARMS+24(r1)
216 sldi r4,r4,3 /* index * 24 == PLT offset */
218 std r7,INT_PARMS+32(r1)
219 std r8,INT_PARMS+40(r1)
220 /* Store the LR in the LR Save area. */
222 std r5,FRAME_SIZE+FRAME_LR_SAVE(r1)
223 cfi_offset (lr, FRAME_LR_SAVE)
224 std r5,CALLING_LR(r1)
225 std r9,INT_PARMS+48(r1)
226 std r10,INT_PARMS+56(r1)
227 std r8,CALLING_SP(r1)
228 ld r12,.LC__dl_hwcap@toc(r2)
230 /* Load _rtld_local_ro._dl_hwcap. */
231 ld r12,RTLD_GLOBAL_RO_DL_HWCAP_OFFSET(r12)
233 ld r12,0(r12) /* Load extern _dl_hwcap. */
235 andis. r0,r12,(PPC_FEATURE_HAS_ALTIVEC >> 16)
237 la r10,(VR_PARMS+0)(r1)
238 la r9,(VR_PARMS+16)(r1)
264 /* Save floating registers. */
265 stfd fp1,FPR_PARMS+0(r1)
266 stfd fp2,FPR_PARMS+8(r1)
267 stfd fp3,FPR_PARMS+16(r1)
268 stfd fp4,FPR_PARMS+24(r1)
269 stfd fp5,FPR_PARMS+32(r1)
270 stfd fp6,FPR_PARMS+40(r1)
271 stfd fp7,FPR_PARMS+48(r1)
272 stfd fp8,FPR_PARMS+56(r1)
273 stfd fp9,FPR_PARMS+64(r1)
274 stfd fp10,FPR_PARMS+72(r1)
275 stfd fp11,FPR_PARMS+80(r1)
277 stfd fp12,FPR_PARMS+88(r1)
278 stfd fp13,FPR_PARMS+96(r1)
279 /* Load the extra parameters. */
281 addi r7,r1,STACK_FRAME
282 /* Save link_map* and reloc_addr parms for later. */
286 bl JUMPTARGET(_dl_profile_fixup)
290 /* Test *framesizep > 0 to see if need to do pltexit processing. */
291 ld r0,STACK_FRAME(r1)
292 /* Put the registers back. */
293 lwz r12,VR_VRSAVE(r1)
296 bgt cr1,L(do_pltexit)
297 la r10,(VR_PARMS+0)(r1)
298 la r9,(VR_PARMS+16)(r1)
299 /* VRSAVE must be non-zero if VMX is present and VRs are in use. */
324 ld r0,FRAME_SIZE+FRAME_LR_SAVE(r1)
325 ld r10,INT_PARMS+56(r1)
326 ld r9,INT_PARMS+48(r1)
327 ld r8,INT_PARMS+40(r1)
328 ld r7,INT_PARMS+32(r1)
330 ld r6,INT_PARMS+24(r1)
331 ld r5,INT_PARMS+16(r1)
332 ld r4,INT_PARMS+8(r1)
333 /* Prepare for calling the function returned by fixup. */
334 PPC64_LOAD_FUNCPTR r3
335 ld r3,INT_PARMS+0(r1)
337 /* Restore the caller's TOC in case we jump to a local entry point. */
338 ld r2,FRAME_SIZE+FRAME_TOC_SAVE(r1)
340 /* Load the floating point registers. */
341 lfd fp1,FPR_PARMS+0(r1)
342 lfd fp2,FPR_PARMS+8(r1)
343 lfd fp3,FPR_PARMS+16(r1)
344 lfd fp4,FPR_PARMS+24(r1)
345 lfd fp5,FPR_PARMS+32(r1)
346 lfd fp6,FPR_PARMS+40(r1)
347 lfd fp7,FPR_PARMS+48(r1)
348 lfd fp8,FPR_PARMS+56(r1)
349 lfd fp9,FPR_PARMS+64(r1)
350 lfd fp10,FPR_PARMS+72(r1)
351 lfd fp11,FPR_PARMS+80(r1)
352 lfd fp12,FPR_PARMS+88(r1)
353 lfd fp13,FPR_PARMS+96(r1)
354 /* Unwind the stack frame, and jump. */
355 ld r31,FRAME_SIZE-8(r1)
356 ld r30,FRAME_SIZE-16(r1)
357 addi r1,r1,FRAME_SIZE
361 la r10,(VR_PARMS+0)(r1)
362 la r9,(VR_PARMS+16)(r1)
387 ld r0,FRAME_SIZE+FRAME_LR_SAVE(r1)
388 ld r10,INT_PARMS+56(r1)
389 ld r9,INT_PARMS+48(r1)
390 ld r8,INT_PARMS+40(r1)
391 ld r7,INT_PARMS+32(r1)
393 ld r6,INT_PARMS+24(r1)
394 ld r5,INT_PARMS+16(r1)
395 ld r4,INT_PARMS+8(r1)
396 /* Prepare for calling the function returned by fixup. */
397 std r2,FRAME_TOC_SAVE(r1)
398 PPC64_LOAD_FUNCPTR r3
399 ld r3,INT_PARMS+0(r1)
400 /* Load the floating point registers. */
401 lfd fp1,FPR_PARMS+0(r1)
402 lfd fp2,FPR_PARMS+8(r1)
403 lfd fp3,FPR_PARMS+16(r1)
404 lfd fp4,FPR_PARMS+24(r1)
405 lfd fp5,FPR_PARMS+32(r1)
406 lfd fp6,FPR_PARMS+40(r1)
407 lfd fp7,FPR_PARMS+48(r1)
408 lfd fp8,FPR_PARMS+56(r1)
409 lfd fp9,FPR_PARMS+64(r1)
410 lfd fp10,FPR_PARMS+72(r1)
411 lfd fp11,FPR_PARMS+80(r1)
412 lfd fp12,FPR_PARMS+88(r1)
413 lfd fp13,FPR_PARMS+96(r1)
414 /* Call the target function. */
416 ld r2,FRAME_TOC_SAVE(r1)
417 lwz r12,VR_VRSAVE(r1)
418 /* But return here and store the return values. */
421 stfd fp1,FPR_RTN+0(r1)
422 stfd fp2,FPR_RTN+8(r1)
425 stfd fp3,FPR_RTN+16(r1)
426 stfd fp4,FPR_RTN+24(r1)
429 stfd fp5,FPR_RTN+32(r1)
430 stfd fp6,FPR_RTN+40(r1)
433 stfd fp7,FPR_RTN+48(r1)
434 stfd fp8,FPR_RTN+56(r1)
435 stfd fp9,FPR_RTN+64(r1)
436 stfd fp10,FPR_RTN+72(r1)
455 bl JUMPTARGET(_dl_call_pltexit)
459 /* Restore the return values from target function. */
460 lwz r12,VR_VRSAVE(r1)
463 lfd fp1,FPR_RTN+0(r1)
464 lfd fp2,FPR_RTN+8(r1)
467 lfd fp3,FPR_RTN+16(r1)
468 lfd fp4,FPR_RTN+24(r1)
471 lfd fp5,FPR_RTN+32(r1)
472 lfd fp6,FPR_RTN+40(r1)
475 lfd fp7,FPR_RTN+48(r1)
476 lfd fp8,FPR_RTN+56(r1)
477 lfd fp9,FPR_RTN+64(r1)
478 lfd fp10,FPR_RTN+72(r1)
493 ld r0,FRAME_SIZE+FRAME_LR_SAVE(r1)
494 ld r31,FRAME_SIZE-8(r1)
495 ld r30,FRAME_SIZE-16(r1)
499 END(_dl_profile_resolve)