1 /* PLT trampolines. PPC64 version.
2 Copyright (C) 2005-2024 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 <https://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 .hidden _dl_runtime_resolve
36 #define INT_PARMS FRAME_MIN_SIZE
37 ENTRY (_dl_runtime_resolve, 4)
38 stdu r1,-FRAME_SIZE(r1)
39 cfi_adjust_cfa_offset (FRAME_SIZE)
40 std r3,INT_PARMS+0(r1)
42 std r4,INT_PARMS+8(r1)
44 std r5,INT_PARMS+16(r1)
46 std r6,INT_PARMS+24(r1)
48 std r7,INT_PARMS+32(r1)
50 std r8,INT_PARMS+40(r1)
51 /* Store the LR in the LR Save area. */
52 std r0,FRAME_SIZE+FRAME_LR_SAVE(r1)
53 cfi_offset (lr, FRAME_LR_SAVE)
54 std r9,INT_PARMS+48(r1)
55 std r10,INT_PARMS+56(r1)
56 bl JUMPTARGET(_dl_fixup)
60 /* Put the registers back. */
61 ld r0,FRAME_SIZE+FRAME_LR_SAVE(r1)
62 ld r10,INT_PARMS+56(r1)
63 ld r9,INT_PARMS+48(r1)
64 ld r8,INT_PARMS+40(r1)
65 ld r7,INT_PARMS+32(r1)
67 ld r6,INT_PARMS+24(r1)
68 ld r5,INT_PARMS+16(r1)
70 /* Prepare for calling the function returned by fixup. */
74 /* Restore the caller's TOC in case we jump to a local entry point. */
75 ld r2,FRAME_SIZE+FRAME_TOC_SAVE(r1)
77 /* Unwind the stack frame, and jump. */
80 END(_dl_runtime_resolve)
84 /* Stack layout: ELFv2 ABI.
85 +752 previous backchain
98 +592 previous backchain +584 fp8
99 +584 spill_r31 +576 fp7
100 +576 spill_r30 +568 fp6
125 * VMX Parms in V2-V13, V0-V1 are scratch
141 * FP Parms in FP1-FP13, FP0 is a scratch register
150 * Integer parms in R3-R10, R0 is scratch, R1 SP, R2 is TOC
159 * Parameter save area
160 * (v1 ABI: Allocated by the call, at least 8 double words)
161 +40 v1 ABI: TOC save area
162 +32 v1 ABI: Reserved for linker
163 +24 v1 ABI: Reserved for compiler / v2 ABI: TOC save area
166 r1+0 stack back chain
169 # define FRAME_SIZE 752
172 # define FRAME_SIZE 592
177 #define STACK_FRAME 496
178 #define CALLING_LR 488
179 #define CALLING_SP 480
180 #define INT_PARMS 112
181 #define FPR_PARMS 176
183 #define VR_VRSAVE 284
187 .tc _rtld_local_ro[TC],_rtld_local_ro
189 .tc _dl_hwcap[TC],_dl_hwcap
194 /* On entry r0 contains the index of the PLT entry we need to fixup
195 and r11 contains the link_map (from PLT0+16). The link_map becomes
196 parm1 (r3) and the index (r0) needs to be converted to an offset
197 (index * 24) in parm2 (r4). */
198 #if !defined PROF && defined SHARED
199 .hidden _dl_profile_resolve
200 ENTRY (_dl_profile_resolve, 4)
201 /* Spill r30, r31 to preserve the link_map* and reloc_addr, in case we
202 need to call _dl_audit_pltexit. */
205 /* We need to save the registers used to pass parameters, ie. r3 thru
206 r10; the registers are saved in a stack frame. */
207 stdu r1,-FRAME_SIZE(r1)
208 cfi_adjust_cfa_offset (FRAME_SIZE)
211 std r3,INT_PARMS+0(r1)
213 std r4,INT_PARMS+8(r1)
214 sldi r4,r0,1 /* index * 2 */
215 std r5,INT_PARMS+16(r1)
216 add r4,r4,r0 /* index * 3 */
217 std r6,INT_PARMS+24(r1)
218 sldi r4,r4,3 /* index * 24 == PLT offset */
220 std r7,INT_PARMS+32(r1)
221 std r8,INT_PARMS+40(r1)
222 /* Store the LR in the LR Save area. */
224 std r5,FRAME_SIZE+FRAME_LR_SAVE(r1)
225 cfi_offset (lr, FRAME_LR_SAVE)
226 std r5,CALLING_LR(r1)
227 std r9,INT_PARMS+48(r1)
228 std r10,INT_PARMS+56(r1)
229 std r8,CALLING_SP(r1)
230 addis r12,r2,.LC__dl_hwcap@toc@ha
231 ld r12,.LC__dl_hwcap@toc@l(r12)
233 /* Load _rtld_local_ro._dl_hwcap. */
234 ld r12,RTLD_GLOBAL_RO_DL_HWCAP_OFFSET(r12)
236 /* Load extern _dl_hwcap. */
239 andis. r0,r12,(PPC_FEATURE_HAS_ALTIVEC >> 16)
241 la r10,(VR_PARMS+0)(r1)
242 la r9,(VR_PARMS+16)(r1)
268 /* Save floating registers. */
269 stfd fp1,FPR_PARMS+0(r1)
270 stfd fp2,FPR_PARMS+8(r1)
271 stfd fp3,FPR_PARMS+16(r1)
272 stfd fp4,FPR_PARMS+24(r1)
273 stfd fp5,FPR_PARMS+32(r1)
274 stfd fp6,FPR_PARMS+40(r1)
275 stfd fp7,FPR_PARMS+48(r1)
276 stfd fp8,FPR_PARMS+56(r1)
277 stfd fp9,FPR_PARMS+64(r1)
278 stfd fp10,FPR_PARMS+72(r1)
279 stfd fp11,FPR_PARMS+80(r1)
281 stfd fp12,FPR_PARMS+88(r1)
282 stfd fp13,FPR_PARMS+96(r1)
283 /* Load the extra parameters. */
285 addi r7,r1,STACK_FRAME
286 /* Save link_map* and reloc_addr parms for later. */
290 bl JUMPTARGET(_dl_profile_fixup)
294 /* Test *framesizep > 0 to see if need to do pltexit processing. */
295 ld r0,STACK_FRAME(r1)
296 /* Put the registers back. */
297 lwz r12,VR_VRSAVE(r1)
300 bgt cr1,L(do_pltexit)
301 la r10,(VR_PARMS+0)(r1)
302 la r9,(VR_PARMS+16)(r1)
303 /* VRSAVE must be non-zero if VMX is present and VRs are in use. */
328 ld r0,FRAME_SIZE+FRAME_LR_SAVE(r1)
329 ld r10,INT_PARMS+56(r1)
330 ld r9,INT_PARMS+48(r1)
331 ld r8,INT_PARMS+40(r1)
332 ld r7,INT_PARMS+32(r1)
334 ld r6,INT_PARMS+24(r1)
335 ld r5,INT_PARMS+16(r1)
336 ld r4,INT_PARMS+8(r1)
337 /* Prepare for calling the function returned by fixup. */
338 PPC64_LOAD_FUNCPTR r3
339 ld r3,INT_PARMS+0(r1)
341 /* Restore the caller's TOC in case we jump to a local entry point. */
342 ld r2,FRAME_SIZE+FRAME_TOC_SAVE(r1)
344 /* Load the floating point registers. */
345 lfd fp1,FPR_PARMS+0(r1)
346 lfd fp2,FPR_PARMS+8(r1)
347 lfd fp3,FPR_PARMS+16(r1)
348 lfd fp4,FPR_PARMS+24(r1)
349 lfd fp5,FPR_PARMS+32(r1)
350 lfd fp6,FPR_PARMS+40(r1)
351 lfd fp7,FPR_PARMS+48(r1)
352 lfd fp8,FPR_PARMS+56(r1)
353 lfd fp9,FPR_PARMS+64(r1)
354 lfd fp10,FPR_PARMS+72(r1)
355 lfd fp11,FPR_PARMS+80(r1)
356 lfd fp12,FPR_PARMS+88(r1)
357 lfd fp13,FPR_PARMS+96(r1)
358 /* Unwind the stack frame, and jump. */
359 ld r31,FRAME_SIZE-8(r1)
360 ld r30,FRAME_SIZE-16(r1)
361 addi r1,r1,FRAME_SIZE
365 la r10,(VR_PARMS+0)(r1)
366 la r9,(VR_PARMS+16)(r1)
391 ld r0,FRAME_SIZE+FRAME_LR_SAVE(r1)
392 ld r10,INT_PARMS+56(r1)
393 ld r9,INT_PARMS+48(r1)
394 ld r8,INT_PARMS+40(r1)
395 ld r7,INT_PARMS+32(r1)
397 ld r6,INT_PARMS+24(r1)
398 ld r5,INT_PARMS+16(r1)
399 ld r4,INT_PARMS+8(r1)
400 /* Prepare for calling the function returned by fixup. */
401 std r2,FRAME_TOC_SAVE(r1)
402 PPC64_LOAD_FUNCPTR r3
403 ld r3,INT_PARMS+0(r1)
404 /* Load the floating point registers. */
405 lfd fp1,FPR_PARMS+0(r1)
406 lfd fp2,FPR_PARMS+8(r1)
407 lfd fp3,FPR_PARMS+16(r1)
408 lfd fp4,FPR_PARMS+24(r1)
409 lfd fp5,FPR_PARMS+32(r1)
410 lfd fp6,FPR_PARMS+40(r1)
411 lfd fp7,FPR_PARMS+48(r1)
412 lfd fp8,FPR_PARMS+56(r1)
413 lfd fp9,FPR_PARMS+64(r1)
414 lfd fp10,FPR_PARMS+72(r1)
415 lfd fp11,FPR_PARMS+80(r1)
416 lfd fp12,FPR_PARMS+88(r1)
417 lfd fp13,FPR_PARMS+96(r1)
418 /* Call the target function. */
420 ld r2,FRAME_TOC_SAVE(r1)
421 lwz r12,VR_VRSAVE(r1)
422 /* But return here and store the return values. */
425 stfd fp1,FPR_RTN+0(r1)
426 stfd fp2,FPR_RTN+8(r1)
429 stfd fp3,FPR_RTN+16(r1)
430 stfd fp4,FPR_RTN+24(r1)
433 stfd fp5,FPR_RTN+32(r1)
434 stfd fp6,FPR_RTN+40(r1)
437 stfd fp7,FPR_RTN+48(r1)
438 stfd fp8,FPR_RTN+56(r1)
439 stfd fp9,FPR_RTN+64(r1)
440 stfd fp10,FPR_RTN+72(r1)
459 bl JUMPTARGET(_dl_audit_pltexit)
463 /* Restore the return values from target function. */
464 lwz r12,VR_VRSAVE(r1)
467 lfd fp1,FPR_RTN+0(r1)
468 lfd fp2,FPR_RTN+8(r1)
471 lfd fp3,FPR_RTN+16(r1)
472 lfd fp4,FPR_RTN+24(r1)
475 lfd fp5,FPR_RTN+32(r1)
476 lfd fp6,FPR_RTN+40(r1)
479 lfd fp7,FPR_RTN+48(r1)
480 lfd fp8,FPR_RTN+56(r1)
481 lfd fp9,FPR_RTN+64(r1)
482 lfd fp10,FPR_RTN+72(r1)
497 ld r0,FRAME_SIZE+FRAME_LR_SAVE(r1)
498 ld r31,FRAME_SIZE-8(r1)
499 ld r30,FRAME_SIZE-16(r1)
503 END(_dl_profile_resolve)