| xf.li | bdd93d5 | 2023-05-12 07:10:14 -0700 | [diff] [blame] | 1 | /* PLT trampolines. hppa version. | 
|  | 2 | Copyright (C) 2005-2016 Free Software Foundation, Inc. | 
|  | 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 | 
|  | 16 | License along with the GNU C Library.  If not, see | 
|  | 17 | <http://www.gnu.org/licenses/>.  */ | 
|  | 18 |  | 
|  | 19 | #include <sysdep.h> | 
|  | 20 |  | 
|  | 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). | 
|  | 26 |  | 
|  | 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 | 
|  | 33 |  | 
|  | 34 | Enter with r19 = reloc offset, r20 = got-8, r21 = fixup ltp.  */ | 
|  | 35 |  | 
|  | 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) | 
|  | 51 |  | 
|  | 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) | 
|  | 59 |  | 
|  | 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 | /* Fillin some frame info to follow ABI */ | 
|  | 65 | stw	%r1,-4(%sp)	/* Previous sp */ | 
|  | 66 | stw	%r21,-32(%sp)	/* PIC register value */ | 
|  | 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 */ | 
|  | 71 | ldo	-56(%sp),%r1 | 
|  | 72 | fstd,ma	%fr4,-8(%r1) | 
|  | 73 | fstd,ma	%fr5,-8(%r1) | 
|  | 74 | fstd,ma	%fr6,-8(%r1) | 
|  | 75 | fstd,ma	%fr7,-8(%r1) | 
|  | 76 |  | 
|  | 77 | /* Set up args to fixup func, needs only two arguments  */ | 
|  | 78 | ldw	8+4(%r20),%r26		/* (1) got[1] == struct link_map */ | 
|  | 79 | copy	%r19,%r25		/* (2) reloc offset  */ | 
|  | 80 |  | 
|  | 81 | /* Call the real address resolver. */ | 
|  | 82 | bl	_dl_fixup,%rp | 
|  | 83 | copy	%r21,%r19		/* set fixup func ltp */ | 
|  | 84 |  | 
|  | 85 | /* Load up the returned func descriptor */ | 
|  | 86 | copy	%r28, %r22 | 
|  | 87 | copy	%r29, %r19 | 
|  | 88 |  | 
|  | 89 | /* Reload arguments fp args */ | 
|  | 90 | ldo	-56(%sp),%r1 | 
|  | 91 | fldd,ma	-8(%r1),%fr4 | 
|  | 92 | fldd,ma	-8(%r1),%fr5 | 
|  | 93 | fldd,ma	-8(%r1),%fr6 | 
|  | 94 | fldd,ma	-8(%r1),%fr7 | 
|  | 95 |  | 
|  | 96 | /* Adjust sp, and restore function result address*/ | 
|  | 97 | ldwm	-128(%sp),%r28 | 
|  | 98 |  | 
|  | 99 | /* Reload static link register */ | 
|  | 100 | ldw	-16(%sp),%r29 | 
|  | 101 | /* Reload general args */ | 
|  | 102 | ldw	-36(%sp),%r26 | 
|  | 103 | ldw	-40(%sp),%r25 | 
|  | 104 | ldw	-44(%sp),%r24 | 
|  | 105 | ldw	-48(%sp),%r23 | 
|  | 106 |  | 
|  | 107 | /* Jump to new function, but return to previous function */ | 
|  | 108 | bv	%r0(%r22) | 
|  | 109 | ldw	-20(%sp),%rp | 
|  | 110 | .EXIT | 
|  | 111 | .PROCEND | 
|  | 112 | cfi_endproc | 
|  | 113 | .size   _dl_runtime_resolve, . - _dl_runtime_resolve | 
|  | 114 |  | 
|  | 115 | .text | 
|  | 116 | .global _dl_runtime_profile | 
|  | 117 | .type _dl_runtime_profile,@function | 
|  | 118 | cfi_startproc | 
|  | 119 | .align 4 | 
|  | 120 | _dl_runtime_profile: | 
|  | 121 | .PROC | 
|  | 122 | .CALLINFO FRAME=192,CALLS,SAVE_RP,ENTRY_GR=3 | 
|  | 123 | .ENTRY | 
|  | 124 |  | 
|  | 125 | /* SAVE_RP says we do */ | 
|  | 126 | stw	%rp, -20(%sp) | 
|  | 127 | /* Save static link register */ | 
|  | 128 | stw	%r29,-16(%sp) | 
|  | 129 |  | 
|  | 130 | /* Build a call frame, and save structure pointer. */ | 
|  | 131 | copy	%sp, %r1	/* Copy previous sp */ | 
|  | 132 | /* Save function result address (on entry) */ | 
|  | 133 | stwm	%r28,192(%sp) | 
|  | 134 | /* Fillin some frame info to follow ABI */ | 
|  | 135 | stw	%r1,-4(%sp)	/* Previous sp */ | 
|  | 136 | stw	%r21,-32(%sp)	/* PIC register value */ | 
|  | 137 |  | 
|  | 138 | /* Create La_hppa_retval */ | 
|  | 139 | /* -140, lrv_r28 | 
|  | 140 | -136, lrv_r29 | 
|  | 141 | -132, 4 byte pad | 
|  | 142 | -128, lr_fr4 (8 bytes) */ | 
|  | 143 |  | 
|  | 144 | /* Create save space for _dl_profile_fixup arguments | 
|  | 145 | -120, Saved reloc offset | 
|  | 146 | -116, Saved struct link_map | 
|  | 147 | -112, *framesizep */ | 
|  | 148 |  | 
|  | 149 | /* Create La_hppa_regs */ | 
|  | 150 | /* 32-bit registers */ | 
|  | 151 | stw	%r26,-108(%sp) | 
|  | 152 | stw	%r25,-104(%sp) | 
|  | 153 | stw	%r24,-100(%sp) | 
|  | 154 | stw	%r23,-96(%sp) | 
|  | 155 | /* -92, 4 byte pad */ | 
|  | 156 | /* 64-bit floating point registers */ | 
|  | 157 | ldo	-88(%sp),%r1 | 
|  | 158 | fstd,ma	%fr4,8(%r1) | 
|  | 159 | fstd,ma	%fr5,8(%r1) | 
|  | 160 | fstd,ma	%fr6,8(%r1) | 
|  | 161 | fstd,ma	%fr7,8(%r1) | 
|  | 162 | /* 32-bit stack pointer and return register */ | 
|  | 163 | stw	%sp,-56(%sp) | 
|  | 164 | stw	%r2,-52(%sp) | 
|  | 165 |  | 
|  | 166 |  | 
|  | 167 | /* Set up args to fixup func, needs five arguments  */ | 
|  | 168 | ldw	8+4(%r20),%r26		/* (1) got[1] == struct link_map */ | 
|  | 169 | stw	%r26,-116(%sp)		/* Save struct link_map */ | 
|  | 170 | copy	%r19,%r25		/* (2) reloc offset  */ | 
|  | 171 | stw	%r25,-120(%sp)		/* Save reloc offset */ | 
|  | 172 | copy    %rp,%r24		/* (3) profile_fixup needs rp */ | 
|  | 173 | ldo	-56(%sp),%r23		/* (4) La_hppa_regs */ | 
|  | 174 | ldo	-112(%sp), %r1 | 
|  | 175 | stw	%r1, -52(%sp)		/* (5) long int *framesizep */ | 
|  | 176 |  | 
|  | 177 | /* Call the real address resolver. */ | 
|  | 178 | bl	_dl_profile_fixup,%rp | 
|  | 179 | copy	%r21,%r19		/* set fixup func ltp */ | 
|  | 180 |  | 
|  | 181 | /* Load up the returned function descriptor */ | 
|  | 182 | copy	%r28, %r22 | 
|  | 183 | copy	%r29, %r19 | 
|  | 184 |  | 
|  | 185 | /* Restore gr/fr/sp/rp */ | 
|  | 186 | ldw	-108(%sp),%r26 | 
|  | 187 | ldw	-104(%sp),%r25 | 
|  | 188 | ldw	-100(%sp),%r24 | 
|  | 189 | ldw	-96(%sp),%r23 | 
|  | 190 | /* -92, 4 byte pad, skip */ | 
|  | 191 | ldo	-88(%sp),%r1 | 
|  | 192 | fldd,ma	8(%r1),%fr4 | 
|  | 193 | fldd,ma	8(%r1),%fr5 | 
|  | 194 | fldd,ma	8(%r1),%fr6 | 
|  | 195 | fldd,ma	8(%r1),%fr7 | 
|  | 196 | ldw	-52(%sp),%rp | 
|  | 197 |  | 
|  | 198 | /* Reload static link register -(192+16) without adjusting stack */ | 
|  | 199 | ldw	-208(%sp),%r29 | 
|  | 200 |  | 
|  | 201 | /* *framesizep is >= 0 if we have to run pltexit */ | 
|  | 202 | ldw	-112(%sp),%r28 | 
|  | 203 | cmpb,>>=,N %r0,%r28,L(cpe) | 
|  | 204 |  | 
|  | 205 | /* Adjust sp, and restore function result address*/ | 
|  | 206 | ldwm	-192(%sp),%r28 | 
|  | 207 | /* Jump to new function, but return to previous function */ | 
|  | 208 | bv	%r0(%r22) | 
|  | 209 | ldw	-20(%sp),%rp | 
|  | 210 | /* NO RETURN */ | 
|  | 211 |  | 
|  | 212 | L(nf): | 
|  | 213 | /* Call the returned function descriptor */ | 
|  | 214 | bv	%r0(%r22) | 
|  | 215 | nop | 
|  | 216 | b,n	L(cont) | 
|  | 217 |  | 
|  | 218 | L(cpe): | 
|  | 219 | /* We are going to call the resolved function, but we have a | 
|  | 220 | stack frame in the middle. We use the value of framesize to | 
|  | 221 | guess how much extra frame we need, and how much frame to | 
|  | 222 | copy forward. */ | 
|  | 223 |  | 
|  | 224 | /* Round to nearest multiple of 64 */ | 
|  | 225 | addi	63, %r28, %r28 | 
|  | 226 | depi	0, 27, 6, %r28 | 
|  | 227 |  | 
|  | 228 | /* Calcualte start of stack copy */ | 
|  | 229 | ldo	-192(%sp),%r2 | 
|  | 230 |  | 
|  | 231 | /* Increate the stack by *framesizep */ | 
|  | 232 | copy	%sp, %r1 | 
|  | 233 | add	%sp, %r28, %sp | 
|  | 234 | /* Save stack pointer */ | 
|  | 235 | stw	%r1, -4(%sp) | 
|  | 236 |  | 
|  | 237 | /* Single byte copy of prevous stack onto newly allocated stack */ | 
|  | 238 | 1:	ldb	%r28(%r2), %r1 | 
|  | 239 | add	%r28, %sp, %r26 | 
|  | 240 | stb	%r1, 0(%r26) | 
|  | 241 | addi,<	-1,%r28,%r28 | 
|  | 242 | b,n	1b | 
|  | 243 |  | 
|  | 244 | /* Retore r28 and r27 and r2 already points at -192(%sp) */ | 
|  | 245 | ldw	0(%r2),%r28 | 
|  | 246 | ldw	84(%r2),%r26 | 
|  | 247 |  | 
|  | 248 | /* Calculate address of L(cont) */ | 
|  | 249 | b,l	L(nf),%r2 | 
|  | 250 | depwi 0,31,2,%r2 | 
|  | 251 | L(cont): | 
|  | 252 | /* Undo fake stack */ | 
|  | 253 | ldw	-4(%sp),%r1 | 
|  | 254 | copy	%r1, %sp | 
|  | 255 |  | 
|  | 256 | /* Arguments to _dl_call_pltexit */ | 
|  | 257 | ldw	-116(%sp), %r26		/* (1) got[1] == struct link_map */ | 
|  | 258 | ldw	-120(%sp), %r25		/* (2) reloc offsets */ | 
|  | 259 | ldo	-56(%sp), %r24		/* (3) *La_hppa_regs */ | 
|  | 260 | ldo	-124(%sp), %r23		/* (4) *La_hppa_retval */ | 
|  | 261 |  | 
|  | 262 | /* Fill *La_hppa_retval */ | 
|  | 263 | stw	%r28,-140(%sp) | 
|  | 264 | stw	%r29,-136(%sp) | 
|  | 265 | ldo	-128(%sp), %r1 | 
|  | 266 | fstd	%fr4,0(%r1) | 
|  | 267 |  | 
|  | 268 | /* Call _dl_call_pltexit */ | 
|  | 269 | bl	_dl_call_pltexit,%rp | 
|  | 270 | nop | 
|  | 271 |  | 
|  | 272 | /* Restore *La_hppa_retval */ | 
|  | 273 | ldw	-140(%sp), %r28 | 
|  | 274 | ldw	-136(%sp), %r29 | 
|  | 275 | ldo	-128(%sp), %r1 | 
|  | 276 | fldd	0(%r1), %fr4 | 
|  | 277 |  | 
|  | 278 | /* Unwind the stack */ | 
|  | 279 | ldo	192(%sp),%sp | 
|  | 280 | /* Retore callers rp */ | 
|  | 281 | ldw -20(%sp),%rp | 
|  | 282 | /* Return */ | 
|  | 283 | bv,n	0(%r2) | 
|  | 284 | .EXIT | 
|  | 285 | .PROCEND | 
|  | 286 | cfi_endproc | 
|  | 287 | .size   _dl_runtime_profile, . - _dl_runtime_profile |