sparc64: Remove unwind information from signal return stubs [BZ#31244]
[glibc.git] / sysdeps / hppa / dl-trampoline.S
blobb336f20b26c7dc092d3baf581ecfc5f73183de5a
1 /* PLT trampolines. hppa 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/>.  */
19 #include <sysdep.h>
21 /* This code gets called via the .plt stub, and is used in
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
25    library auditing (LA).
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
34    Enter with r19 = reloc offset, r20 = got-8, r21 = fixup ltp, r22 = fp.  */
36         /* RELOCATION MARKER: bl to provide gcc's __cffc with fixup loc. */
37         .text
38         /* THIS CODE DOES NOT EXECUTE */
39         bl      _dl_fixup, %r2
40         .text
41         .global _dl_runtime_resolve
42         .type _dl_runtime_resolve,@function
43         cfi_startproc
44         .align 4
45 _dl_runtime_resolve:
46         .PROC
47         .CALLINFO FRAME=128,CALLS,SAVE_RP,ENTRY_GR=3
48         .ENTRY
49         /* SAVE_RP says we do */
50         stw     %rp, -20(%sp)
52         /* Save static link register */
53         stw     %r29,-16(%sp)
54         /* Save argument registers */
55         stw     %r26,-36(%sp)
56         stw     %r25,-40(%sp)
57         stw     %r24,-44(%sp)
58         stw     %r23,-48(%sp)
60         /* Build a call frame, and save structure pointer. */
61         copy    %sp, %r1        /* Copy previous sp */
62         /* Save function result address (on entry) */
63         stwm    %r28,128(%sp)
64         /* Fill in some frame info to follow ABI */
65         stw     %r1,-4(%sp)     /* Previous sp */
66         stw     %r21,-32(%sp)   /* PIC register value */
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 */
71         ldo     -64(%sp),%r1
72         fstd,ma %fr4,-8(%r1)
73         fstd,ma %fr5,-8(%r1)
74         fstd,ma %fr6,-8(%r1)
76         /* Test PA_GP_RELOC bit.  */
77         bb,>=   %r19,31,2f              /* branch if not reloc offset */
78         fstd,ma %fr7,-8(%r1)
80         /* Set up args to fixup func, needs only two arguments  */
81         ldw     8+4(%r20),%r26          /* (1) got[1] == struct link_map */
82         copy    %r19,%r25               /* (2) reloc offset  */
84         /* Call the real address resolver. */
85 3:      bl      _dl_fixup,%rp
86         copy    %r21,%r19               /* set fixup func ltp */
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.  */
101         comib,= 0,%r28,1f
103         /* Load up the returned func descriptor */
104         copy    %r28, %r22
105         copy    %r29, %r19
107         /* Reload arguments fp args */
108         ldo     -64(%sp),%r1
109         fldd,ma -8(%r1),%fr4
110         fldd,ma -8(%r1),%fr5
111         fldd,ma -8(%r1),%fr6
112         fldd,ma -8(%r1),%fr7
114         /* Adjust sp, and restore function result address*/
115         ldwm    -128(%sp),%r28
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
125         /* Jump to new function, but return to previous function */
126         bv      %r0(%r22)
127         ldw     -20(%sp),%rp
130         /* Return to previous function */
131         ldw     -148(%sp),%rp
132         bv      %r0(%rp)
133         ldo     -128(%sp),%sp
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 */
141         /* Save ltp and link map arg for _dl_fixup.  */
142         stw     %r21,-56(%sp)           /* ltp */
143         stw     %r25,-60(%sp)           /* struct link map */
145         /* Find reloc offset. */
146         bl      _dl_fix_reloc_arg,%rp
147         copy    %r21,%r19               /* set func ltp */
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 */
154         .EXIT
155         .PROCEND
156         cfi_endproc
157         .size   _dl_runtime_resolve, . - _dl_runtime_resolve
159 #ifdef SHARED
160         .text
161         .global _dl_runtime_profile
162         .type _dl_runtime_profile,@function
163         cfi_startproc
164         .align 4
165 _dl_runtime_profile:
166         .PROC
167         .CALLINFO FRAME=192,CALLS,SAVE_RP,ENTRY_GR=3
168         .ENTRY
170         /* SAVE_RP says we do */
171         stw     %rp, -20(%sp)
172         /* Save static link register */
173         stw     %r29,-16(%sp)
175         /* Build a call frame, and save structure pointer. */
176         copy    %sp, %r1        /* Copy previous sp */
177         /* Save function result address (on entry) */
178         stwm    %r28,192(%sp)
179         /* Fill in some frame info to follow ABI */
180         stw     %r1,-4(%sp)     /* Previous sp */
181         stw     %r21,-32(%sp)   /* PIC register value */
183         /* Create La_hppa_retval */
184         /* -140, lrv_r28
185            -136, lrv_r29
186            -132, 4 byte pad
187            -128, lr_fr4 (8 bytes) */
189         /* Create save space for _dl_profile_fixup arguments
190            -120, Saved reloc offset
191            -116, Saved struct link_map
192            -112, *framesizep */
194         /* Create La_hppa_regs */
195         /* 32-bit registers */
196         stw     %r26,-108(%sp)
197         stw     %r25,-104(%sp)
198         stw     %r24,-100(%sp)
199         stw     %r23,-96(%sp)
200         /* -92, 4 byte pad */
201         /* 64-bit floating point registers */
202         ldo     -88(%sp),%r1
203         fstd,ma %fr4,8(%r1)
204         fstd,ma %fr5,8(%r1)
205         fstd,ma %fr6,8(%r1)
206         fstd,ma %fr7,8(%r1)
208         /* Test PA_GP_RELOC bit.  */
209         bb,>=   %r19,31,2f              /* branch if not reloc offset */
210         /* 32-bit stack pointer */
211         stw     %sp,-56(%sp)
213         /* Set up args to fixup func, needs five arguments  */
214         ldw     8+4(%r20),%r26          /* (1) got[1] == struct link_map */
215         stw     %r26,-116(%sp)          /* Save struct link_map */
216         copy    %r19,%r25               /* (2) reloc offset  */
217         stw     %r25,-120(%sp)          /* Save reloc offset */
218         copy    %rp,%r24                /* (3) profile_fixup needs rp */
219         ldo     -56(%sp),%r23           /* (4) La_hppa_regs */
220         ldo     -112(%sp), %r1
221         stw     %r1, -52(%sp)           /* (5) long int *framesizep */
223         /* Call the real address resolver. */
224 3:      bl      _dl_profile_fixup,%rp
225         copy    %r21,%r19               /* set fixup func ltp */
227         /* Load up the returned function descriptor */
228         copy    %r28, %r22
229         copy    %r29, %r19
231         /* Restore gr/fr/sp/rp */
232         ldw     -108(%sp),%r26
233         ldw     -104(%sp),%r25
234         ldw     -100(%sp),%r24
235         ldw     -96(%sp),%r23
236         /* -92, 4 byte pad, skip */
237         ldo     -88(%sp),%r1
238         fldd,ma 8(%r1),%fr4
239         fldd,ma 8(%r1),%fr5
240         fldd,ma 8(%r1),%fr6
241         fldd,ma 8(%r1),%fr7
243         /* Reload rp register -(192+20) without adjusting stack */
244         ldw     -212(%sp),%rp
246         /* Reload static link register -(192+16) without adjusting stack */
247         ldw     -208(%sp),%r29
249         /* *framesizep is >= 0 if we have to run pltexit */
250         ldw     -112(%sp),%r28
251         cmpb,>>=,N %r0,%r28,L(cpe)
253         /* Adjust sp, and restore function result address*/
254         ldwm    -192(%sp),%r28
255         /* Jump to new function, but return to previous function */
256         bv      %r0(%r22)
257         ldw     -20(%sp),%rp
258         /* NO RETURN */
260 L(nf):
261         /* Call the returned function descriptor */
262         bv      %r0(%r22)
263         nop
264         b,n     L(cont)
266 L(cpe):
267         /* We are going to call the resolved function, but we have a
268            stack frame in the middle. We use the value of framesize to
269            guess how much extra frame we need, and how much frame to
270            copy forward. */
272         /* Round to nearest multiple of 64 */
273         addi    63, %r28, %r28
274         depi    0, 27, 6, %r28
276         /* Calculate start of stack copy */
277         ldo     -192(%sp),%r2
279         /* Increate the stack by *framesizep */
280         copy    %sp, %r1
281         add     %sp, %r28, %sp
282         /* Save stack pointer */
283         stw     %r1, -4(%sp)
285         /* Single byte copy of previous stack onto newly allocated stack */
286 1:      ldb     %r28(%r2), %r1
287         add     %r28, %sp, %r26
288         stb     %r1, 0(%r26)
289         addi,<  -1,%r28,%r28
290         b,n     1b
292         /* Restore r28 and r27 and r2 already points at -192(%sp) */
293         ldw     0(%r2),%r28
294         ldw     84(%r2),%r26
296         /* Calculate address of L(cont) */
297         b,l     L(nf),%r2
298         depwi 0,31,2,%r2
299 L(cont):
300         /* Undo fake stack */
301         ldw     -4(%sp),%r1
302         copy    %r1, %sp
304         /* Arguments to _dl_audit_pltexit */
305         ldw     -116(%sp), %r26         /* (1) got[1] == struct link_map */
306         ldw     -120(%sp), %r25         /* (2) reloc offsets */
307         ldo     -56(%sp), %r24          /* (3) *La_hppa_regs */
308         ldo     -124(%sp), %r23         /* (4) *La_hppa_retval */
310         /* Fill *La_hppa_retval */
311         stw     %r28,-140(%sp)
312         stw     %r29,-136(%sp)
313         ldo     -128(%sp), %r1
314         fstd    %fr4,0(%r1)
316         /* Call _dl_audit_pltexit */
317         bl      _dl_audit_pltexit,%rp
318         nop
320         /* Restore *La_hppa_retval */
321         ldw     -140(%sp), %r28
322         ldw     -136(%sp), %r29
323         ldo     -128(%sp), %r1
324         fldd    0(%r1), %fr4
326         /* Unwind the stack */
327         ldo     192(%sp),%sp
328         /* Restore callers rp */
329         ldw -20(%sp),%rp
330         /* Return */
331         bv,n    0(%r2)
334         /* Set up args for _dl_fix_reloc_arg.  */
335         copy    %r22,%r26               /* (1) function pointer */
336         depi    0,31,2,%r26             /* clear least significant bits */
337         ldw     8+4(%r20),%r25          /* (2) got[1] == struct link_map */
339         /* Save ltp and link map arg for _dl_fixup.  */
340         stw     %r21,-92(%sp)           /* ltp */
341         stw     %r25,-116(%sp)          /* struct link map */
343         /* Find reloc offset. */
344         bl      _dl_fix_reloc_arg,%rp
345         copy    %r21,%r19               /* set func ltp */
347          /* Restore fixup ltp.  */
348         ldw     -92(%sp),%r21           /* ltp */
350         /* Set up args to fixup func, needs five arguments  */
351         ldw     -116(%sp),%r26          /* (1) struct link map */
352         copy    %ret0,%r25              /* (2) reloc offset  */
353         stw     %r25,-120(%sp)          /* Save reloc offset */
354         ldw     -212(%sp),%r24          /* (3) profile_fixup needs rp */
355         ldo     -56(%sp),%r23           /* (4) La_hppa_regs */
356         ldo     -112(%sp), %r1
357         b       3b
358         stw     %r1, -52(%sp)           /* (5) long int *framesizep */
359         .EXIT
360         .PROCEND
361         cfi_endproc
362         .size   _dl_runtime_profile, . - _dl_runtime_profile
363 #endif