]>
Commit | Line | Data |
---|---|---|
084442fc | 1 | /* PLT trampolines. hppa version. |
568035b7 | 2 | Copyright (C) 2005-2013 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) | |
0daa0500 | 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 CD |
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 */ | |
0daa0500 CD |
86 | copy %r28, %r22 |
87 | copy %r29, %r19 | |
084442fc CD |
88 | |
89 | /* Reload arguments fp args */ | |
0daa0500 CD |
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 | |
084442fc CD |
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 | |
0daa0500 | 112 | cfi_endproc |
084442fc CD |
113 | .size _dl_runtime_resolve, . - _dl_runtime_resolve |
114 | ||
084442fc | 115 | .text |
084442fc CD |
116 | .global _dl_runtime_profile |
117 | .type _dl_runtime_profile,@function | |
0daa0500 CD |
118 | cfi_startproc |
119 | .align 4 | |
084442fc CD |
120 | _dl_runtime_profile: |
121 | .PROC | |
0daa0500 | 122 | .CALLINFO FRAME=192,CALLS,SAVE_RP,ENTRY_GR=3 |
084442fc CD |
123 | .ENTRY |
124 | ||
125 | /* SAVE_RP says we do */ | |
0daa0500 | 126 | stw %rp, -20(%sp) |
084442fc CD |
127 | /* Save static link register */ |
128 | stw %r29,-16(%sp) | |
084442fc CD |
129 | |
130 | /* Build a call frame, and save structure pointer. */ | |
0daa0500 | 131 | copy %sp, %r1 /* Copy previous sp */ |
084442fc | 132 | /* Save function result address (on entry) */ |
0daa0500 | 133 | stwm %r28,192(%sp) |
084442fc | 134 | /* Fillin some frame info to follow ABI */ |
0daa0500 | 135 | stw %r1,-4(%sp) /* Previous sp */ |
084442fc | 136 | stw %r21,-32(%sp) /* PIC register value */ |
0daa0500 CD |
137 | |
138 | /* Create La_hppa_retval */ | |
5556231d | 139 | /* -140, lrv_r28 |
0daa0500 | 140 | -136, lrv_r29 |
5556231d | 141 | -132, 4 byte pad |
0daa0500 CD |
142 | -128, lr_fr4 (8 bytes) */ |
143 | ||
144 | /* Create save space for _dl_profile_fixup arguments | |
5556231d JM |
145 | -120, Saved reloc offset |
146 | -116, Saved struct link_map | |
0daa0500 CD |
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 | ||
084442fc CD |
166 | |
167 | /* Set up args to fixup func, needs five arguments */ | |
168 | ldw 8+4(%r20),%r26 /* (1) got[1] == struct link_map */ | |
0daa0500 | 169 | stw %r26,-116(%sp) /* Save struct link_map */ |
084442fc | 170 | copy %r19,%r25 /* (2) reloc offset */ |
0daa0500 | 171 | stw %r25,-120(%sp) /* Save reloc offset */ |
084442fc | 172 | copy %rp,%r24 /* (3) profile_fixup needs rp */ |
0daa0500 CD |
173 | ldo -56(%sp),%r23 /* (4) La_hppa_regs */ |
174 | ldo -112(%sp), %r1 | |
084442fc CD |
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 | ||
0daa0500 CD |
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) | |
084442fc CD |
204 | |
205 | /* Adjust sp, and restore function result address*/ | |
0daa0500 | 206 | ldwm -192(%sp),%r28 |
084442fc CD |
207 | /* Jump to new function, but return to previous function */ |
208 | bv %r0(%r22) | |
209 | ldw -20(%sp),%rp | |
0daa0500 CD |
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): | |
5556231d | 219 | /* We are going to call the resolved function, but we have a |
0daa0500 CD |
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 */ | |
5556231d | 257 | ldw -116(%sp), %r26 /* (1) got[1] == struct link_map */ |
0daa0500 CD |
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) | |
084442fc CD |
284 | .EXIT |
285 | .PROCEND | |
186a83ab | 286 | cfi_endproc |
084442fc CD |
287 | .size _dl_runtime_profile, . - _dl_runtime_profile |
288 |