]> git.ipfire.org Git - thirdparty/glibc.git/blame - sysdeps/hppa/dl-trampoline.S
Update copyright dates with scripts/update-copyrights
[thirdparty/glibc.git] / sysdeps / hppa / dl-trampoline.S
CommitLineData
084442fc 1/* PLT trampolines. hppa version.
6d7e8eda 2 Copyright (C) 2005-2023 Free Software Foundation, Inc.
084442fc
CD
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
ab84e3ff 16 License along with the GNU C Library. If not, see
5a82c748 17 <https://www.gnu.org/licenses/>. */
084442fc
CD
18
19#include <sysdep.h>
20
21/* This code gets called via the .plt stub, and is used in
5556231d
JM
22 dl-runtime.c to call the `_dl_fixup' function and then redirect
23 to the address it returns. `_dl_fixup' takes two arguments, however
24 `_dl_profile_fixup' takes a number of parameters for use with
0daa0500 25 library auditing (LA).
5556231d 26
084442fc
CD
27 WARNING: This template is also used by gcc's __cffc, and expects
28 that the "bl" for _dl_runtime_resolve exist at a particular offset.
29 Do not change this template without changing gcc, while the prefix
30 "bl" should fix everything so gcc finds the right spot, it will
31 slow down __cffc when it attempts to call fixup to resolve function
32 descriptor references. Please refer to gcc/gcc/config/pa/fptr.c
5556231d 33
1a044511 34 Enter with r19 = reloc offset, r20 = got-8, r21 = fixup ltp, r22 = fp. */
084442fc 35
0daa0500 36 /* RELOCATION MARKER: bl to provide gcc's __cffc with fixup loc. */
084442fc 37 .text
0daa0500 38 /* THIS CODE DOES NOT EXECUTE */
084442fc
CD
39 bl _dl_fixup, %r2
40 .text
084442fc
CD
41 .global _dl_runtime_resolve
42 .type _dl_runtime_resolve,@function
0daa0500
CD
43 cfi_startproc
44 .align 4
084442fc
CD
45_dl_runtime_resolve:
46 .PROC
47 .CALLINFO FRAME=128,CALLS,SAVE_RP,ENTRY_GR=3
48 .ENTRY
49 /* SAVE_RP says we do */
0daa0500 50 stw %rp, -20(%sp)
084442fc
CD
51
52 /* Save static link register */
53 stw %r29,-16(%sp)
5abebba4 54 /* Save argument registers */
084442fc
CD
55 stw %r26,-36(%sp)
56 stw %r25,-40(%sp)
57 stw %r24,-44(%sp)
58 stw %r23,-48(%sp)
59
60 /* Build a call frame, and save structure pointer. */
0daa0500 61 copy %sp, %r1 /* Copy previous sp */
084442fc
CD
62 /* Save function result address (on entry) */
63 stwm %r28,128(%sp)
1a044511 64 /* Fill in some frame info to follow ABI */
0daa0500 65 stw %r1,-4(%sp) /* Previous sp */
084442fc 66 stw %r21,-32(%sp) /* PIC register value */
0daa0500
CD
67
68 /* Save input floating point registers. This must be done
69 in the new frame since the previous frame doesn't have
70 enough space */
1a044511 71 ldo -64(%sp),%r1
0daa0500
CD
72 fstd,ma %fr4,-8(%r1)
73 fstd,ma %fr5,-8(%r1)
74 fstd,ma %fr6,-8(%r1)
1a044511
JDA
75
76 /* Test PA_GP_RELOC bit. */
77 bb,>= %r19,31,2f /* branch if not reloc offset */
0daa0500 78 fstd,ma %fr7,-8(%r1)
084442fc 79
5abebba4 80 /* Set up args to fixup func, needs only two arguments */
084442fc
CD
81 ldw 8+4(%r20),%r26 /* (1) got[1] == struct link_map */
82 copy %r19,%r25 /* (2) reloc offset */
83
5abebba4 84 /* Call the real address resolver. */
1a044511 853: bl _dl_fixup,%rp
084442fc
CD
86 copy %r21,%r19 /* set fixup func ltp */
87
64a1daed
JDA
88 /* While the linker will set a function pointer to NULL when it
89 encounters an undefined weak function, we need to dynamically
90 detect removed weak functions. The issue arises because a weak
91 __gmon_start__ function was added to shared executables to work
92 around issues in _init that are now resolved. The presence of
93 __gmon_start__ in every shared library breaks the linker
94 `--as-needed' option. This __gmon_start__ function does nothing
95 but removal is tricky. Depending on the binding, removal can
96 cause an application using it to fault. The call to _dl_fixup
97 returns NULL when a function isn't resolved. In order to help
98 with __gmon_start__ removal, we return directly to the caller
99 when _dl_fixup returns NULL. This check could be removed when
100 BZ 19170 is fixed. */
1903b38c
JDA
101 comib,= 0,%r28,1f
102
084442fc 103 /* Load up the returned func descriptor */
0daa0500
CD
104 copy %r28, %r22
105 copy %r29, %r19
084442fc
CD
106
107 /* Reload arguments fp args */
1a044511 108 ldo -64(%sp),%r1
0daa0500
CD
109 fldd,ma -8(%r1),%fr4
110 fldd,ma -8(%r1),%fr5
111 fldd,ma -8(%r1),%fr6
112 fldd,ma -8(%r1),%fr7
084442fc
CD
113
114 /* Adjust sp, and restore function result address*/
115 ldwm -128(%sp),%r28
116
117 /* Reload static link register */
118 ldw -16(%sp),%r29
119 /* Reload general args */
120 ldw -36(%sp),%r26
121 ldw -40(%sp),%r25
122 ldw -44(%sp),%r24
123 ldw -48(%sp),%r23
124
125 /* Jump to new function, but return to previous function */
126 bv %r0(%r22)
127 ldw -20(%sp),%rp
1903b38c
JDA
128
1291:
130 /* Return to previous function */
131 ldw -148(%sp),%rp
132 bv %r0(%rp)
133 ldo -128(%sp),%sp
134
1a044511
JDA
1352:
136 /* Set up args for _dl_fix_reloc_arg. */
137 copy %r22,%r26 /* (1) function pointer */
138 depi 0,31,2,%r26 /* clear least significant bits */
139 ldw 8+4(%r20),%r25 /* (2) got[1] == struct link_map */
140
141 /* Save ltp and link map arg for _dl_fixup. */
142 stw %r21,-56(%sp) /* ltp */
143 stw %r25,-60(%sp) /* struct link map */
144
145 /* Find reloc offset. */
146 bl _dl_fix_reloc_arg,%rp
147 copy %r21,%r19 /* set func ltp */
148
149 /* Set up args for _dl_fixup. */
150 ldw -56(%sp),%r21 /* ltp */
151 ldw -60(%sp),%r26 /* (1) struct link map */
152 b 3b
153 copy %ret0,%r25 /* (2) reloc offset */
084442fc
CD
154 .EXIT
155 .PROCEND
0daa0500 156 cfi_endproc
084442fc
CD
157 .size _dl_runtime_resolve, . - _dl_runtime_resolve
158
084442fc 159 .text
084442fc
CD
160 .global _dl_runtime_profile
161 .type _dl_runtime_profile,@function
0daa0500
CD
162 cfi_startproc
163 .align 4
084442fc
CD
164_dl_runtime_profile:
165 .PROC
0daa0500 166 .CALLINFO FRAME=192,CALLS,SAVE_RP,ENTRY_GR=3
084442fc
CD
167 .ENTRY
168
169 /* SAVE_RP says we do */
0daa0500 170 stw %rp, -20(%sp)
084442fc
CD
171 /* Save static link register */
172 stw %r29,-16(%sp)
084442fc
CD
173
174 /* Build a call frame, and save structure pointer. */
0daa0500 175 copy %sp, %r1 /* Copy previous sp */
084442fc 176 /* Save function result address (on entry) */
0daa0500 177 stwm %r28,192(%sp)
1a044511 178 /* Fill in some frame info to follow ABI */
0daa0500 179 stw %r1,-4(%sp) /* Previous sp */
084442fc 180 stw %r21,-32(%sp) /* PIC register value */
0daa0500
CD
181
182 /* Create La_hppa_retval */
5556231d 183 /* -140, lrv_r28
0daa0500 184 -136, lrv_r29
5556231d 185 -132, 4 byte pad
0daa0500
CD
186 -128, lr_fr4 (8 bytes) */
187
188 /* Create save space for _dl_profile_fixup arguments
5556231d
JM
189 -120, Saved reloc offset
190 -116, Saved struct link_map
0daa0500
CD
191 -112, *framesizep */
192
193 /* Create La_hppa_regs */
194 /* 32-bit registers */
195 stw %r26,-108(%sp)
196 stw %r25,-104(%sp)
197 stw %r24,-100(%sp)
198 stw %r23,-96(%sp)
199 /* -92, 4 byte pad */
200 /* 64-bit floating point registers */
201 ldo -88(%sp),%r1
202 fstd,ma %fr4,8(%r1)
203 fstd,ma %fr5,8(%r1)
204 fstd,ma %fr6,8(%r1)
205 fstd,ma %fr7,8(%r1)
0daa0500 206
1a044511
JDA
207 /* Test PA_GP_RELOC bit. */
208 bb,>= %r19,31,2f /* branch if not reloc offset */
209 /* 32-bit stack pointer */
210 stw %sp,-56(%sp)
084442fc 211
5abebba4 212 /* Set up args to fixup func, needs five arguments */
084442fc 213 ldw 8+4(%r20),%r26 /* (1) got[1] == struct link_map */
0daa0500 214 stw %r26,-116(%sp) /* Save struct link_map */
084442fc 215 copy %r19,%r25 /* (2) reloc offset */
0daa0500 216 stw %r25,-120(%sp) /* Save reloc offset */
084442fc 217 copy %rp,%r24 /* (3) profile_fixup needs rp */
0daa0500
CD
218 ldo -56(%sp),%r23 /* (4) La_hppa_regs */
219 ldo -112(%sp), %r1
084442fc
CD
220 stw %r1, -52(%sp) /* (5) long int *framesizep */
221
5abebba4 222 /* Call the real address resolver. */
1a044511 2233: bl _dl_profile_fixup,%rp
084442fc
CD
224 copy %r21,%r19 /* set fixup func ltp */
225
0daa0500
CD
226 /* Load up the returned function descriptor */
227 copy %r28, %r22
228 copy %r29, %r19
229
230 /* Restore gr/fr/sp/rp */
231 ldw -108(%sp),%r26
232 ldw -104(%sp),%r25
233 ldw -100(%sp),%r24
234 ldw -96(%sp),%r23
235 /* -92, 4 byte pad, skip */
236 ldo -88(%sp),%r1
237 fldd,ma 8(%r1),%fr4
238 fldd,ma 8(%r1),%fr5
239 fldd,ma 8(%r1),%fr6
240 fldd,ma 8(%r1),%fr7
1a044511
JDA
241
242 /* Reload rp register -(192+20) without adjusting stack */
243 ldw -212(%sp),%rp
0daa0500
CD
244
245 /* Reload static link register -(192+16) without adjusting stack */
246 ldw -208(%sp),%r29
247
248 /* *framesizep is >= 0 if we have to run pltexit */
249 ldw -112(%sp),%r28
250 cmpb,>>=,N %r0,%r28,L(cpe)
084442fc
CD
251
252 /* Adjust sp, and restore function result address*/
0daa0500 253 ldwm -192(%sp),%r28
084442fc
CD
254 /* Jump to new function, but return to previous function */
255 bv %r0(%r22)
256 ldw -20(%sp),%rp
0daa0500
CD
257 /* NO RETURN */
258
259L(nf):
260 /* Call the returned function descriptor */
261 bv %r0(%r22)
262 nop
263 b,n L(cont)
264
265L(cpe):
5556231d 266 /* We are going to call the resolved function, but we have a
0daa0500
CD
267 stack frame in the middle. We use the value of framesize to
268 guess how much extra frame we need, and how much frame to
269 copy forward. */
270
271 /* Round to nearest multiple of 64 */
272 addi 63, %r28, %r28
273 depi 0, 27, 6, %r28
274
275 /* Calcualte start of stack copy */
276 ldo -192(%sp),%r2
277
278 /* Increate the stack by *framesizep */
279 copy %sp, %r1
280 add %sp, %r28, %sp
281 /* Save stack pointer */
282 stw %r1, -4(%sp)
283
284 /* Single byte copy of prevous stack onto newly allocated stack */
2851: ldb %r28(%r2), %r1
286 add %r28, %sp, %r26
287 stb %r1, 0(%r26)
288 addi,< -1,%r28,%r28
289 b,n 1b
290
291 /* Retore r28 and r27 and r2 already points at -192(%sp) */
292 ldw 0(%r2),%r28
293 ldw 84(%r2),%r26
294
295 /* Calculate address of L(cont) */
296 b,l L(nf),%r2
297 depwi 0,31,2,%r2
298L(cont):
299 /* Undo fake stack */
300 ldw -4(%sp),%r1
301 copy %r1, %sp
302
8c0664e2 303 /* Arguments to _dl_audit_pltexit */
5556231d 304 ldw -116(%sp), %r26 /* (1) got[1] == struct link_map */
5abebba4 305 ldw -120(%sp), %r25 /* (2) reloc offsets */
0daa0500
CD
306 ldo -56(%sp), %r24 /* (3) *La_hppa_regs */
307 ldo -124(%sp), %r23 /* (4) *La_hppa_retval */
308
309 /* Fill *La_hppa_retval */
310 stw %r28,-140(%sp)
311 stw %r29,-136(%sp)
312 ldo -128(%sp), %r1
313 fstd %fr4,0(%r1)
314
8c0664e2
AZ
315 /* Call _dl_audit_pltexit */
316 bl _dl_audit_pltexit,%rp
0daa0500
CD
317 nop
318
319 /* Restore *La_hppa_retval */
320 ldw -140(%sp), %r28
321 ldw -136(%sp), %r29
322 ldo -128(%sp), %r1
323 fldd 0(%r1), %fr4
324
325 /* Unwind the stack */
326 ldo 192(%sp),%sp
327 /* Retore callers rp */
328 ldw -20(%sp),%rp
329 /* Return */
330 bv,n 0(%r2)
1a044511
JDA
331
3322:
333 /* Set up args for _dl_fix_reloc_arg. */
334 copy %r22,%r26 /* (1) function pointer */
335 depi 0,31,2,%r26 /* clear least significant bits */
336 ldw 8+4(%r20),%r25 /* (2) got[1] == struct link_map */
337
338 /* Save ltp and link map arg for _dl_fixup. */
339 stw %r21,-92(%sp) /* ltp */
340 stw %r25,-116(%sp) /* struct link map */
341
342 /* Find reloc offset. */
343 bl _dl_fix_reloc_arg,%rp
344 copy %r21,%r19 /* set func ltp */
345
346 /* Restore fixup ltp. */
347 ldw -92(%sp),%r21 /* ltp */
348
349 /* Set up args to fixup func, needs five arguments */
350 ldw -116(%sp),%r26 /* (1) struct link map */
351 copy %ret0,%r25 /* (2) reloc offset */
352 stw %r25,-120(%sp) /* Save reloc offset */
353 ldw -212(%sp),%r24 /* (3) profile_fixup needs rp */
354 ldo -56(%sp),%r23 /* (4) La_hppa_regs */
355 ldo -112(%sp), %r1
356 b 3b
357 stw %r1, -52(%sp) /* (5) long int *framesizep */
084442fc
CD
358 .EXIT
359 .PROCEND
186a83ab 360 cfi_endproc
084442fc 361 .size _dl_runtime_profile, . - _dl_runtime_profile