]>
Commit | Line | Data |
---|---|---|
084442fc | 1 | /* PLT trampolines. hppa version. |
688903eb | 2 | Copyright (C) 2005-2018 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 PE |
16 | License along with the GNU C Library. If not, see |
17 | <http://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 | |
084442fc CD |
34 | Enter with r19 = reloc offset, r20 = got-8, r21 = fixup ltp. */ |
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) | |
084442fc | 64 | /* Fillin 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 */ | |
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) | |
084442fc | 76 | |
5abebba4 | 77 | /* Set up args to fixup func, needs only two arguments */ |
084442fc CD |
78 | ldw 8+4(%r20),%r26 /* (1) got[1] == struct link_map */ |
79 | copy %r19,%r25 /* (2) reloc offset */ | |
80 | ||
5abebba4 | 81 | /* Call the real address resolver. */ |
084442fc CD |
82 | bl _dl_fixup,%rp |
83 | copy %r21,%r19 /* set fixup func ltp */ | |
84 | ||
64a1daed JDA |
85 | /* While the linker will set a function pointer to NULL when it |
86 | encounters an undefined weak function, we need to dynamically | |
87 | detect removed weak functions. The issue arises because a weak | |
88 | __gmon_start__ function was added to shared executables to work | |
89 | around issues in _init that are now resolved. The presence of | |
90 | __gmon_start__ in every shared library breaks the linker | |
91 | `--as-needed' option. This __gmon_start__ function does nothing | |
92 | but removal is tricky. Depending on the binding, removal can | |
93 | cause an application using it to fault. The call to _dl_fixup | |
94 | returns NULL when a function isn't resolved. In order to help | |
95 | with __gmon_start__ removal, we return directly to the caller | |
96 | when _dl_fixup returns NULL. This check could be removed when | |
97 | BZ 19170 is fixed. */ | |
1903b38c JDA |
98 | comib,= 0,%r28,1f |
99 | ||
084442fc | 100 | /* Load up the returned func descriptor */ |
0daa0500 CD |
101 | copy %r28, %r22 |
102 | copy %r29, %r19 | |
084442fc CD |
103 | |
104 | /* Reload arguments fp args */ | |
0daa0500 CD |
105 | ldo -56(%sp),%r1 |
106 | fldd,ma -8(%r1),%fr4 | |
107 | fldd,ma -8(%r1),%fr5 | |
108 | fldd,ma -8(%r1),%fr6 | |
109 | fldd,ma -8(%r1),%fr7 | |
084442fc CD |
110 | |
111 | /* Adjust sp, and restore function result address*/ | |
112 | ldwm -128(%sp),%r28 | |
113 | ||
114 | /* Reload static link register */ | |
115 | ldw -16(%sp),%r29 | |
116 | /* Reload general args */ | |
117 | ldw -36(%sp),%r26 | |
118 | ldw -40(%sp),%r25 | |
119 | ldw -44(%sp),%r24 | |
120 | ldw -48(%sp),%r23 | |
121 | ||
122 | /* Jump to new function, but return to previous function */ | |
123 | bv %r0(%r22) | |
124 | ldw -20(%sp),%rp | |
1903b38c JDA |
125 | |
126 | 1: | |
127 | /* Return to previous function */ | |
128 | ldw -148(%sp),%rp | |
129 | bv %r0(%rp) | |
130 | ldo -128(%sp),%sp | |
131 | ||
084442fc CD |
132 | .EXIT |
133 | .PROCEND | |
0daa0500 | 134 | cfi_endproc |
084442fc CD |
135 | .size _dl_runtime_resolve, . - _dl_runtime_resolve |
136 | ||
084442fc | 137 | .text |
084442fc CD |
138 | .global _dl_runtime_profile |
139 | .type _dl_runtime_profile,@function | |
0daa0500 CD |
140 | cfi_startproc |
141 | .align 4 | |
084442fc CD |
142 | _dl_runtime_profile: |
143 | .PROC | |
0daa0500 | 144 | .CALLINFO FRAME=192,CALLS,SAVE_RP,ENTRY_GR=3 |
084442fc CD |
145 | .ENTRY |
146 | ||
147 | /* SAVE_RP says we do */ | |
0daa0500 | 148 | stw %rp, -20(%sp) |
084442fc CD |
149 | /* Save static link register */ |
150 | stw %r29,-16(%sp) | |
084442fc CD |
151 | |
152 | /* Build a call frame, and save structure pointer. */ | |
0daa0500 | 153 | copy %sp, %r1 /* Copy previous sp */ |
084442fc | 154 | /* Save function result address (on entry) */ |
0daa0500 | 155 | stwm %r28,192(%sp) |
084442fc | 156 | /* Fillin some frame info to follow ABI */ |
0daa0500 | 157 | stw %r1,-4(%sp) /* Previous sp */ |
084442fc | 158 | stw %r21,-32(%sp) /* PIC register value */ |
0daa0500 CD |
159 | |
160 | /* Create La_hppa_retval */ | |
5556231d | 161 | /* -140, lrv_r28 |
0daa0500 | 162 | -136, lrv_r29 |
5556231d | 163 | -132, 4 byte pad |
0daa0500 CD |
164 | -128, lr_fr4 (8 bytes) */ |
165 | ||
166 | /* Create save space for _dl_profile_fixup arguments | |
5556231d JM |
167 | -120, Saved reloc offset |
168 | -116, Saved struct link_map | |
0daa0500 CD |
169 | -112, *framesizep */ |
170 | ||
171 | /* Create La_hppa_regs */ | |
172 | /* 32-bit registers */ | |
173 | stw %r26,-108(%sp) | |
174 | stw %r25,-104(%sp) | |
175 | stw %r24,-100(%sp) | |
176 | stw %r23,-96(%sp) | |
177 | /* -92, 4 byte pad */ | |
178 | /* 64-bit floating point registers */ | |
179 | ldo -88(%sp),%r1 | |
180 | fstd,ma %fr4,8(%r1) | |
181 | fstd,ma %fr5,8(%r1) | |
182 | fstd,ma %fr6,8(%r1) | |
183 | fstd,ma %fr7,8(%r1) | |
184 | /* 32-bit stack pointer and return register */ | |
185 | stw %sp,-56(%sp) | |
186 | stw %r2,-52(%sp) | |
187 | ||
084442fc | 188 | |
5abebba4 | 189 | /* Set up args to fixup func, needs five arguments */ |
084442fc | 190 | ldw 8+4(%r20),%r26 /* (1) got[1] == struct link_map */ |
0daa0500 | 191 | stw %r26,-116(%sp) /* Save struct link_map */ |
084442fc | 192 | copy %r19,%r25 /* (2) reloc offset */ |
0daa0500 | 193 | stw %r25,-120(%sp) /* Save reloc offset */ |
084442fc | 194 | copy %rp,%r24 /* (3) profile_fixup needs rp */ |
0daa0500 CD |
195 | ldo -56(%sp),%r23 /* (4) La_hppa_regs */ |
196 | ldo -112(%sp), %r1 | |
084442fc CD |
197 | stw %r1, -52(%sp) /* (5) long int *framesizep */ |
198 | ||
5abebba4 | 199 | /* Call the real address resolver. */ |
084442fc CD |
200 | bl _dl_profile_fixup,%rp |
201 | copy %r21,%r19 /* set fixup func ltp */ | |
202 | ||
0daa0500 CD |
203 | /* Load up the returned function descriptor */ |
204 | copy %r28, %r22 | |
205 | copy %r29, %r19 | |
206 | ||
207 | /* Restore gr/fr/sp/rp */ | |
208 | ldw -108(%sp),%r26 | |
209 | ldw -104(%sp),%r25 | |
210 | ldw -100(%sp),%r24 | |
211 | ldw -96(%sp),%r23 | |
212 | /* -92, 4 byte pad, skip */ | |
213 | ldo -88(%sp),%r1 | |
214 | fldd,ma 8(%r1),%fr4 | |
215 | fldd,ma 8(%r1),%fr5 | |
216 | fldd,ma 8(%r1),%fr6 | |
217 | fldd,ma 8(%r1),%fr7 | |
218 | ldw -52(%sp),%rp | |
219 | ||
220 | /* Reload static link register -(192+16) without adjusting stack */ | |
221 | ldw -208(%sp),%r29 | |
222 | ||
223 | /* *framesizep is >= 0 if we have to run pltexit */ | |
224 | ldw -112(%sp),%r28 | |
225 | cmpb,>>=,N %r0,%r28,L(cpe) | |
084442fc CD |
226 | |
227 | /* Adjust sp, and restore function result address*/ | |
0daa0500 | 228 | ldwm -192(%sp),%r28 |
084442fc CD |
229 | /* Jump to new function, but return to previous function */ |
230 | bv %r0(%r22) | |
231 | ldw -20(%sp),%rp | |
0daa0500 CD |
232 | /* NO RETURN */ |
233 | ||
234 | L(nf): | |
235 | /* Call the returned function descriptor */ | |
236 | bv %r0(%r22) | |
237 | nop | |
238 | b,n L(cont) | |
239 | ||
240 | L(cpe): | |
5556231d | 241 | /* We are going to call the resolved function, but we have a |
0daa0500 CD |
242 | stack frame in the middle. We use the value of framesize to |
243 | guess how much extra frame we need, and how much frame to | |
244 | copy forward. */ | |
245 | ||
246 | /* Round to nearest multiple of 64 */ | |
247 | addi 63, %r28, %r28 | |
248 | depi 0, 27, 6, %r28 | |
249 | ||
250 | /* Calcualte start of stack copy */ | |
251 | ldo -192(%sp),%r2 | |
252 | ||
253 | /* Increate the stack by *framesizep */ | |
254 | copy %sp, %r1 | |
255 | add %sp, %r28, %sp | |
256 | /* Save stack pointer */ | |
257 | stw %r1, -4(%sp) | |
258 | ||
259 | /* Single byte copy of prevous stack onto newly allocated stack */ | |
260 | 1: ldb %r28(%r2), %r1 | |
261 | add %r28, %sp, %r26 | |
262 | stb %r1, 0(%r26) | |
263 | addi,< -1,%r28,%r28 | |
264 | b,n 1b | |
265 | ||
266 | /* Retore r28 and r27 and r2 already points at -192(%sp) */ | |
267 | ldw 0(%r2),%r28 | |
268 | ldw 84(%r2),%r26 | |
269 | ||
270 | /* Calculate address of L(cont) */ | |
271 | b,l L(nf),%r2 | |
272 | depwi 0,31,2,%r2 | |
273 | L(cont): | |
274 | /* Undo fake stack */ | |
275 | ldw -4(%sp),%r1 | |
276 | copy %r1, %sp | |
277 | ||
278 | /* Arguments to _dl_call_pltexit */ | |
5556231d | 279 | ldw -116(%sp), %r26 /* (1) got[1] == struct link_map */ |
5abebba4 | 280 | ldw -120(%sp), %r25 /* (2) reloc offsets */ |
0daa0500 CD |
281 | ldo -56(%sp), %r24 /* (3) *La_hppa_regs */ |
282 | ldo -124(%sp), %r23 /* (4) *La_hppa_retval */ | |
283 | ||
284 | /* Fill *La_hppa_retval */ | |
285 | stw %r28,-140(%sp) | |
286 | stw %r29,-136(%sp) | |
287 | ldo -128(%sp), %r1 | |
288 | fstd %fr4,0(%r1) | |
289 | ||
290 | /* Call _dl_call_pltexit */ | |
291 | bl _dl_call_pltexit,%rp | |
292 | nop | |
293 | ||
294 | /* Restore *La_hppa_retval */ | |
295 | ldw -140(%sp), %r28 | |
296 | ldw -136(%sp), %r29 | |
297 | ldo -128(%sp), %r1 | |
298 | fldd 0(%r1), %fr4 | |
299 | ||
300 | /* Unwind the stack */ | |
301 | ldo 192(%sp),%sp | |
302 | /* Retore callers rp */ | |
303 | ldw -20(%sp),%rp | |
304 | /* Return */ | |
305 | bv,n 0(%r2) | |
084442fc CD |
306 | .EXIT |
307 | .PROCEND | |
186a83ab | 308 | cfi_endproc |
084442fc | 309 | .size _dl_runtime_profile, . - _dl_runtime_profile |