]> git.ipfire.org Git - thirdparty/glibc.git/blame - sysdeps/powerpc/powerpc64/dl-trampoline.S
Update copyright dates with scripts/update-copyrights.
[thirdparty/glibc.git] / sysdeps / powerpc / powerpc64 / dl-trampoline.S
CommitLineData
82221992 1/* PLT trampolines. PPC64 version.
688903eb 2 Copyright (C) 2005-2018 Free Software Foundation, Inc.
82221992
UD
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
7 License as published by the Free Software Foundation; either
8 version 2.1 of the 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
59ba27a6
PE
16 License along with the GNU C Library; if not, see
17 <http://www.gnu.org/licenses/>. */
82221992
UD
18
19#include <sysdep.h>
bb4bb82b 20#include <rtld-global-offsets.h>
82221992 21
82221992 22
bb4bb82b
UD
23 .section ".text"
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). */
9f0d7b6d 28
8b8a692c 29#define FRAME_SIZE (FRAME_MIN_SIZE+64)
82221992 30/* We need to save the registers used to pass parameters, ie. r3 thru
bebff237
AM
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. */
8b8a692c 35#define INT_PARMS FRAME_MIN_SIZE
d5b41185 36ENTRY (_dl_runtime_resolve, 4)
bebff237
AM
37 stdu r1,-FRAME_SIZE(r1)
38 cfi_adjust_cfa_offset (FRAME_SIZE)
39 std r3,INT_PARMS+0(r1)
85555eeb 40 mr r3,r11
bebff237 41 std r4,INT_PARMS+8(r1)
85555eeb 42 sldi r4,r0,1
bebff237 43 std r5,INT_PARMS+16(r1)
85555eeb 44 add r4,r4,r0
bebff237 45 std r6,INT_PARMS+24(r1)
85555eeb 46 sldi r4,r4,3
bebff237 47 std r7,INT_PARMS+32(r1)
85555eeb 48 mflr r0
bebff237
AM
49 std r8,INT_PARMS+40(r1)
50/* Store the LR in the LR Save area. */
8b8a692c
UW
51 std r0,FRAME_SIZE+FRAME_LR_SAVE(r1)
52 cfi_offset (lr, FRAME_LR_SAVE)
bebff237
AM
53 std r9,INT_PARMS+48(r1)
54 std r10,INT_PARMS+56(r1)
82221992 55 bl JUMPTARGET(_dl_fixup)
bebff237
AM
56#ifndef SHARED
57 nop
58#endif
82221992 59/* Put the registers back. */
8b8a692c 60 ld r0,FRAME_SIZE+FRAME_LR_SAVE(r1)
bebff237
AM
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)
85555eeb 65 mtlr r0
bebff237
AM
66 ld r6,INT_PARMS+24(r1)
67 ld r5,INT_PARMS+16(r1)
68 ld r4,INT_PARMS+8(r1)
d31beafa
UW
69/* Prepare for calling the function returned by fixup. */
70 PPC64_LOAD_FUNCPTR r3
bebff237 71 ld r3,INT_PARMS+0(r1)
122b66de
UW
72#if _CALL_ELF == 2
73/* Restore the caller's TOC in case we jump to a local entry point. */
8b8a692c 74 ld r2,FRAME_SIZE+FRAME_TOC_SAVE(r1)
122b66de 75#endif
82221992 76/* Unwind the stack frame, and jump. */
bebff237 77 addi r1,r1,FRAME_SIZE
82221992
UD
78 bctr
79END(_dl_runtime_resolve)
bebff237
AM
80#undef FRAME_SIZE
81#undef INT_PARMS
82221992 82
61cd8fe4
UW
83 /* Stack layout: ELFv2 ABI.
84 +752 previous backchain
85 +744 spill_r31
86 +736 spill_r30
87 +720 v8
88 +704 v7
89 +688 v6
90 +672 v5
91 +656 v4
92 +640 v3
93 +624 v2
94 +608 v1
95 +600 fp10
96 ELFv1 ABI +592 fp9
97 +592 previous backchain +584 fp8
98 +584 spill_r31 +576 fp7
99 +576 spill_r30 +568 fp6
100 +560 v1 +560 fp5
101 +552 fp4 +552 fp4
102 +544 fp3 +544 fp3
103 +536 fp2 +536 fp2
104 +528 fp1 +528 fp1
105 +520 r4 +520 r4
106 +512 r3 +512 r3
bb4bb82b
UD
107 return values
108 +504 free
109 +496 stackframe
110 +488 lr
111 +480 r1
112 +464 v13
113 +448 v12
114 +432 v11
115 +416 v10
116 +400 v9
117 +384 v8
118 +368 v7
119 +352 v6
120 +336 v5
121 +320 v4
122 +304 v3
123 +288 v2
124 * VMX Parms in V2-V13, V0-V1 are scratch
125 +284 vrsave
126 +280 free
127 +272 fp13
128 +264 fp12
129 +256 fp11
130 +248 fp10
131 +240 fp9
132 +232 fp8
133 +224 fp7
134 +216 fp6
135 +208 fp5
136 +200 fp4
137 +192 fp3
138 +184 fp2
139 +176 fp1
140 * FP Parms in FP1-FP13, FP0 is a scratch register
141 +168 r10
142 +160 r9
143 +152 r8
144 +144 r7
145 +136 r6
146 +128 r5
147 +120 r4
148 +112 r3
149 * Integer parms in R3-R10, R0 is scratch, R1 SP, R2 is TOC
150 +104 parm8
151 +96 parm7
152 +88 parm6
153 +80 parm5
154 +72 parm4
155 +64 parm3
156 +56 parm2
157 +48 parm1
8b8a692c
UW
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
9f0d7b6d 163 +16 LR save area
bb4bb82b
UD
164 +8 CR save area
165 r1+0 stack back chain
166 */
61cd8fe4
UW
167#if _CALL_ELF == 2
168# define FRAME_SIZE 752
169# define VR_RTN 608
170#else
171# define FRAME_SIZE 592
172# define VR_RTN 560
173#endif
bb4bb82b
UD
174#define INT_RTN 512
175#define FPR_RTN 528
bb4bb82b
UD
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
181#define VR_PARMS 288
182#define VR_VRSAVE 284
183 .section ".toc","aw"
184.LC__dl_hwcap:
185# ifdef SHARED
37fb1dc0 186 .tc _rtld_local_ro[TC],_rtld_local_ro
bb4bb82b
UD
187# else
188 .tc _dl_hwcap[TC],_dl_hwcap
189# endif
190 .section ".text"
82221992 191
bb4bb82b
UD
192 .machine "altivec"
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). */
9f0d7b6d 197#ifndef PROF
d5b41185 198ENTRY (_dl_profile_resolve, 4)
bb4bb82b
UD
199/* Spill r30, r31 to preserve the link_map* and reloc_addr, in case we
200 need to call _dl_call_pltexit. */
201 std r31,-8(r1)
202 std r30,-16(r1)
82221992
UD
203/* We need to save the registers used to pass parameters, ie. r3 thru
204 r10; the registers are saved in a stack frame. */
bb4bb82b 205 stdu r1,-FRAME_SIZE(r1)
a7e91561 206 cfi_adjust_cfa_offset (FRAME_SIZE)
bebff237
AM
207 cfi_offset(r31,-8)
208 cfi_offset(r30,-16)
bb4bb82b 209 std r3,INT_PARMS+0(r1)
4e2d5491 210 mr r3,r11
bb4bb82b
UD
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 */
4e2d5491 217 mflr r5
bb4bb82b
UD
218 std r7,INT_PARMS+32(r1)
219 std r8,INT_PARMS+40(r1)
61cd8fe4 220/* Store the LR in the LR Save area. */
bb4bb82b 221 la r8,FRAME_SIZE(r1)
8b8a692c
UW
222 std r5,FRAME_SIZE+FRAME_LR_SAVE(r1)
223 cfi_offset (lr, FRAME_LR_SAVE)
bb4bb82b 224 std r5,CALLING_LR(r1)
bb4bb82b
UD
225 std r9,INT_PARMS+48(r1)
226 std r10,INT_PARMS+56(r1)
227 std r8,CALLING_SP(r1)
bb4bb82b
UD
228 ld r12,.LC__dl_hwcap@toc(r2)
229#ifdef SHARED
37fb1dc0 230 /* Load _rtld_local_ro._dl_hwcap. */
bb4bb82b
UD
231 ld r12,RTLD_GLOBAL_RO_DL_HWCAP_OFFSET(r12)
232#else
233 ld r12,0(r12) /* Load extern _dl_hwcap. */
234#endif
235 andis. r0,r12,(PPC_FEATURE_HAS_ALTIVEC >> 16)
236 beq L(saveFP)
237 la r10,(VR_PARMS+0)(r1)
238 la r9,(VR_PARMS+16)(r1)
239 li r11,32
240 li r12,64
241 stvx v2,0,r10
242 stvx v3,0,r9
9f0d7b6d 243
bb4bb82b
UD
244 stvx v4,r11,r10
245 stvx v5,r11,r9
246 addi r11,r11,64
9f0d7b6d 247
bb4bb82b
UD
248 stvx v6,r12,r10
249 stvx v7,r12,r9
250 addi r12,r12,64
9f0d7b6d 251
bb4bb82b
UD
252 stvx v8,r11,r10
253 stvx v9,r11,r9
254 addi r11,r11,64
9f0d7b6d 255
bb4bb82b
UD
256 stvx v10,r12,r10
257 stvx v11,r12,r9
258 mfspr r0,VRSAVE
9f0d7b6d 259
bb4bb82b
UD
260 stvx v12,r11,r10
261 stvx v13,r11,r9
262L(saveFP):
263 stw r0,VR_VRSAVE(r1)
4e2d5491 264/* Save floating registers. */
bb4bb82b
UD
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)
4e2d5491 276 li r0,-1
bb4bb82b
UD
277 stfd fp12,FPR_PARMS+88(r1)
278 stfd fp13,FPR_PARMS+96(r1)
279/* Load the extra parameters. */
280 addi r6,r1,INT_PARMS
281 addi r7,r1,STACK_FRAME
282/* Save link_map* and reloc_addr parms for later. */
283 mr r31,r3
284 mr r30,r4
285 std r0,0(r7)
82221992 286 bl JUMPTARGET(_dl_profile_fixup)
bebff237 287#ifndef SHARED
bb4bb82b 288 nop
bebff237 289#endif
bb4bb82b
UD
290/* Test *framesizep > 0 to see if need to do pltexit processing. */
291 ld r0,STACK_FRAME(r1)
9f0d7b6d 292/* Put the registers back. */
bb4bb82b
UD
293 lwz r12,VR_VRSAVE(r1)
294 cmpdi cr1,r0,0
295 cmpdi cr0,r12,0
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. */
300 beq L(restoreFXR)
301 li r11,32
302 li r12,64
303 lvx v2,0,r10
304 lvx v3,0,r9
9f0d7b6d 305
bb4bb82b
UD
306 lvx v4,r11,r10
307 lvx v5,r11,r9
308 addi r11,r11,64
9f0d7b6d 309
bb4bb82b
UD
310 lvx v6,r12,r10
311 lvx v7,r12,r9
312 addi r12,r12,64
9f0d7b6d 313
bb4bb82b
UD
314 lvx v8,r11,r10
315 lvx v9,r11,r9
316 addi r11,r11,64
9f0d7b6d 317
bb4bb82b
UD
318 lvx v10,r12,r10
319 lvx v11,r12,r9
9f0d7b6d 320
bb4bb82b
UD
321 lvx v12,r11,r10
322 lvx v13,r11,r9
323L(restoreFXR):
8b8a692c 324 ld r0,FRAME_SIZE+FRAME_LR_SAVE(r1)
bb4bb82b
UD
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)
4e2d5491 329 mtlr r0
bb4bb82b
UD
330 ld r6,INT_PARMS+24(r1)
331 ld r5,INT_PARMS+16(r1)
332 ld r4,INT_PARMS+8(r1)
d31beafa
UW
333/* Prepare for calling the function returned by fixup. */
334 PPC64_LOAD_FUNCPTR r3
bb4bb82b 335 ld r3,INT_PARMS+0(r1)
122b66de
UW
336#if _CALL_ELF == 2
337/* Restore the caller's TOC in case we jump to a local entry point. */
8b8a692c 338 ld r2,FRAME_SIZE+FRAME_TOC_SAVE(r1)
122b66de 339#endif
4e2d5491 340/* Load the floating point registers. */
bb4bb82b
UD
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)
82221992 354/* Unwind the stack frame, and jump. */
61cd8fe4
UW
355 ld r31,FRAME_SIZE-8(r1)
356 ld r30,FRAME_SIZE-16(r1)
bb4bb82b 357 addi r1,r1,FRAME_SIZE
82221992 358 bctr
61cd8fe4 359
bb4bb82b
UD
360L(do_pltexit):
361 la r10,(VR_PARMS+0)(r1)
362 la r9,(VR_PARMS+16)(r1)
363 beq L(restoreFXR2)
364 li r11,32
365 li r12,64
366 lvx v2,0,r10
367 lvx v3,0,r9
9f0d7b6d 368
bb4bb82b
UD
369 lvx v4,r11,r10
370 lvx v5,r11,r9
371 addi r11,r11,64
9f0d7b6d 372
bb4bb82b
UD
373 lvx v6,r12,r10
374 lvx v7,r12,r9
375 addi r12,r12,64
9f0d7b6d 376
bb4bb82b
UD
377 lvx v8,r11,r10
378 lvx v9,r11,r9
379 addi r11,r11,64
9f0d7b6d 380
bb4bb82b
UD
381 lvx v10,r12,r10
382 lvx v11,r12,r9
9f0d7b6d 383
bb4bb82b
UD
384 lvx v12,r11,r10
385 lvx v13,r11,r9
386L(restoreFXR2):
8b8a692c 387 ld r0,FRAME_SIZE+FRAME_LR_SAVE(r1)
bb4bb82b
UD
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)
392 mtlr r0
bb4bb82b
UD
393 ld r6,INT_PARMS+24(r1)
394 ld r5,INT_PARMS+16(r1)
395 ld r4,INT_PARMS+8(r1)
d31beafa 396/* Prepare for calling the function returned by fixup. */
8b8a692c 397 std r2,FRAME_TOC_SAVE(r1)
d31beafa 398 PPC64_LOAD_FUNCPTR r3
bb4bb82b 399 ld r3,INT_PARMS+0(r1)
bb4bb82b
UD
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. */
415 bctrl
8b8a692c 416 ld r2,FRAME_TOC_SAVE(r1)
bb4bb82b
UD
417 lwz r12,VR_VRSAVE(r1)
418/* But return here and store the return values. */
419 std r3,INT_RTN(r1)
420 std r4,INT_RTN+8(r1)
61cd8fe4
UW
421 stfd fp1,FPR_RTN+0(r1)
422 stfd fp2,FPR_RTN+8(r1)
bb4bb82b
UD
423 cmpdi cr0,r12,0
424 la r10,VR_RTN(r1)
61cd8fe4
UW
425 stfd fp3,FPR_RTN+16(r1)
426 stfd fp4,FPR_RTN+24(r1)
427#if _CALL_ELF == 2
428 la r12,VR_RTN+16(r1)
429 stfd fp5,FPR_RTN+32(r1)
430 stfd fp6,FPR_RTN+40(r1)
431 li r5,32
432 li r6,64
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)
437#endif
bb4bb82b
UD
438 mr r3,r31
439 mr r4,r30
440 beq L(callpltexit)
441 stvx v2,0,r10
61cd8fe4
UW
442#if _CALL_ELF == 2
443 stvx v3,0,r12
444 stvx v4,r5,r10
445 stvx v5,r5,r12
446 addi r5,r5,64
447 stvx v6,r6,r10
448 stvx v7,r6,r12
449 stvx v8,r5,r10
450 stvx v9,r5,r12
451#endif
bb4bb82b
UD
452L(callpltexit):
453 addi r5,r1,INT_PARMS
454 addi r6,r1,INT_RTN
455 bl JUMPTARGET(_dl_call_pltexit)
bebff237 456#ifndef SHARED
bb4bb82b 457 nop
bebff237 458#endif
9f0d7b6d 459/* Restore the return values from target function. */
bb4bb82b
UD
460 lwz r12,VR_VRSAVE(r1)
461 ld r3,INT_RTN(r1)
462 ld r4,INT_RTN+8(r1)
61cd8fe4
UW
463 lfd fp1,FPR_RTN+0(r1)
464 lfd fp2,FPR_RTN+8(r1)
bb4bb82b 465 cmpdi cr0,r12,0
61cd8fe4
UW
466 la r11,VR_RTN(r1)
467 lfd fp3,FPR_RTN+16(r1)
468 lfd fp4,FPR_RTN+24(r1)
469#if _CALL_ELF == 2
470 la r12,VR_RTN+16(r1)
471 lfd fp5,FPR_RTN+32(r1)
472 lfd fp6,FPR_RTN+40(r1)
473 li r30,32
474 li r31,64
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)
479#endif
bb4bb82b 480 beq L(pltexitreturn)
61cd8fe4
UW
481 lvx v2,0,r11
482#if _CALL_ELF == 2
483 lvx v3,0,r12
484 lvx v4,r30,r11
485 lvx v5,r30,r12
486 addi r30,r30,64
487 lvx v6,r31,r11
488 lvx v7,r31,r12
489 lvx v8,r30,r11
490 lvx v9,r30,r12
491#endif
bb4bb82b 492L(pltexitreturn):
8b8a692c 493 ld r0,FRAME_SIZE+FRAME_LR_SAVE(r1)
61cd8fe4
UW
494 ld r31,FRAME_SIZE-8(r1)
495 ld r30,FRAME_SIZE-16(r1)
bb4bb82b
UD
496 mtlr r0
497 ld r1,0(r1)
498 blr
82221992 499END(_dl_profile_resolve)
9f0d7b6d 500#endif