]>
Commit | Line | Data |
---|---|---|
4603c51e | 1 | /* PLT trampolines. s390x version. |
2b778ceb | 2 | Copyright (C) 2016-2021 Free Software Foundation, Inc. |
4603c51e SL |
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 | |
5a82c748 | 17 | <https://www.gnu.org/licenses/>. */ |
4603c51e SL |
18 | |
19 | /* The PLT stubs will call _dl_runtime_resolve/_dl_runtime_profile | |
20 | * with the following linkage: | |
21 | * r2 - r6 : parameter registers | |
22 | * f0, f2, f4, f6 : floating point parameter registers | |
23 | * v24, v26, v28, v30, v25, v27, v29, v31 : vector parameter registers | |
24 | * 48(r15), 56(r15) : PLT arguments PLT1, PLT2 | |
25 | * 160(r15) : additional stack parameters | |
5755f5e4 IL |
26 | * The slightly tightened normal clobber rules for function calls apply: |
27 | * r0 : call saved (for __fentry__) | |
28 | * r1 - r5 : call clobbered | |
4603c51e SL |
29 | * r6 - r13 : call saved |
30 | * r14 : return address (call clobbered) | |
31 | * r15 : stack pointer (call saved) | |
32 | * f0 - f7 : call clobbered | |
33 | * f8 - f15 : call saved | |
34 | * v0 - v7 : bytes 0-7 overlap with f0-f7: call clobbered | |
35 | bytes 8-15: call clobbered | |
36 | * v8 - v15 : bytes 0-7 overlap with f8-f15: call saved | |
37 | bytes 8-15: call clobbered | |
38 | * v16 - v31 : call clobbered | |
39 | */ | |
40 | ||
0fb7afa2 IL |
41 | #define CFA_OFF 160 |
42 | #define FRAME_OFF CFA_OFF + FRAME_SIZE | |
43 | #define V24_OFF -288 | |
44 | #define V25_OFF -272 | |
45 | #define V26_OFF -256 | |
46 | #define V27_OFF -240 | |
47 | #define V28_OFF -224 | |
48 | #define V29_OFF -208 | |
49 | #define V30_OFF -192 | |
50 | #define V31_OFF -176 | |
5755f5e4 | 51 | #define R0_OFF -120 |
0fb7afa2 IL |
52 | #define PLT1_OFF -112 |
53 | #define PLT2_OFF -104 | |
54 | #define R2_OFF -96 | |
55 | #define R3_OFF -88 | |
56 | #define R4_OFF -80 | |
57 | #define R5_OFF -72 | |
58 | #define R14_OFF -64 | |
59 | #define R15_OFF -56 | |
60 | #define F0_OFF -48 | |
61 | #define F2_OFF -40 | |
62 | #define F4_OFF -32 | |
63 | #define F6_OFF -24 | |
4603c51e SL |
64 | .globl _dl_runtime_resolve |
65 | .type _dl_runtime_resolve, @function | |
66 | cfi_startproc | |
67 | .align 16 | |
68 | _dl_runtime_resolve: | |
5755f5e4 IL |
69 | stg %r0,CFA_OFF+R0_OFF(%r15) |
70 | cfi_offset (r0, R0_OFF) | |
0fb7afa2 IL |
71 | stmg %r2,%r5,CFA_OFF+R2_OFF(%r15) # save registers |
72 | cfi_offset (r2, R2_OFF) | |
73 | cfi_offset (r3, R3_OFF) | |
74 | cfi_offset (r4, R4_OFF) | |
75 | cfi_offset (r5, R5_OFF) | |
76 | stmg %r14,%r15,CFA_OFF+R14_OFF(%r15) | |
77 | cfi_offset (r14, R14_OFF) | |
78 | cfi_offset (r15, R15_OFF) | |
79 | std %f0,CFA_OFF+F0_OFF(%r15) | |
80 | cfi_offset (f0, F0_OFF) | |
81 | std %f2,CFA_OFF+F2_OFF(%r15) | |
82 | cfi_offset (f2, F2_OFF) | |
83 | std %f4,CFA_OFF+F4_OFF(%r15) | |
84 | cfi_offset (f4, F4_OFF) | |
85 | std %f6,CFA_OFF+F6_OFF(%r15) | |
86 | cfi_offset (f6, F6_OFF) | |
87 | lmg %r2,%r3,CFA_OFF+PLT1_OFF(%r15) # load args saved by PLT | |
4603c51e SL |
88 | lgr %r0,%r15 |
89 | #ifdef RESTORE_VRS | |
0fb7afa2 IL |
90 | # define FRAME_SIZE (CFA_OFF + 128) |
91 | aghi %r15,-FRAME_SIZE # create stack frame | |
92 | cfi_adjust_cfa_offset (FRAME_SIZE) | |
4603c51e SL |
93 | .machine push |
94 | .machine "z13" | |
0fb7afa2 IL |
95 | vstm %v24,%v31,FRAME_OFF+V24_OFF(%r15) # save call-clobbered vr args |
96 | cfi_offset (v24, V24_OFF) | |
97 | cfi_offset (v25, V25_OFF) | |
98 | cfi_offset (v26, V26_OFF) | |
99 | cfi_offset (v27, V27_OFF) | |
100 | cfi_offset (v28, V28_OFF) | |
101 | cfi_offset (v29, V29_OFF) | |
102 | cfi_offset (v30, V30_OFF) | |
103 | cfi_offset (v31, V31_OFF) | |
4603c51e SL |
104 | .machine pop |
105 | #else | |
0fb7afa2 IL |
106 | # define FRAME_SIZE CFA_OFF |
107 | aghi %r15,-FRAME_SIZE # create stack frame | |
108 | cfi_adjust_cfa_offset (FRAME_SIZE) | |
4603c51e SL |
109 | #endif |
110 | stg %r0,0(%r15) # write backchain | |
111 | brasl %r14,_dl_fixup # call _dl_fixup | |
112 | lgr %r1,%r2 # function addr returned in r2 | |
113 | #ifdef RESTORE_VRS | |
114 | .machine push | |
115 | .machine "z13" | |
0fb7afa2 | 116 | vlm %v24,%v31,FRAME_OFF+V24_OFF(%r15) # restore vector registers |
4603c51e | 117 | .machine pop |
4603c51e | 118 | #endif |
0fb7afa2 IL |
119 | lmg %r14,%r15,FRAME_OFF+R14_OFF(%r15) # restore frame and registers |
120 | #undef FRAME_SIZE | |
121 | cfi_def_cfa_offset (CFA_OFF) | |
122 | ld %f0,CFA_OFF+F0_OFF(%r15) | |
123 | ld %f2,CFA_OFF+F2_OFF(%r15) | |
124 | ld %f4,CFA_OFF+F4_OFF(%r15) | |
125 | ld %f6,CFA_OFF+F6_OFF(%r15) | |
126 | lmg %r2,%r5,CFA_OFF+R2_OFF(%r15) | |
5755f5e4 | 127 | lg %r0,CFA_OFF+R0_OFF(%r15) |
4603c51e SL |
128 | br %r1 |
129 | cfi_endproc | |
130 | .size _dl_runtime_resolve, .-_dl_runtime_resolve | |
0fb7afa2 IL |
131 | #undef V24_OFF |
132 | #undef V25_OFF | |
133 | #undef V26_OFF | |
134 | #undef V27_OFF | |
135 | #undef V28_OFF | |
136 | #undef V29_OFF | |
137 | #undef V30_OFF | |
138 | #undef V31_OFF | |
5755f5e4 | 139 | #undef R0_OFF |
0fb7afa2 IL |
140 | #undef PLT1_OFF |
141 | #undef PLT2_OFF | |
142 | #undef R2_OFF | |
143 | #undef R3_OFF | |
144 | #undef R4_OFF | |
145 | #undef R5_OFF | |
146 | #undef R14_OFF | |
147 | #undef R15_OFF | |
148 | #undef F0_OFF | |
149 | #undef F2_OFF | |
150 | #undef F4_OFF | |
151 | #undef F6_OFF | |
4603c51e SL |
152 | |
153 | #ifndef PROF | |
329c6fec IL |
154 | # define SIZEOF_STRUCT_LA_S390_64_REGS 200 |
155 | # define REGS_OFF -360 | |
156 | # define R2_OFF -360 | |
157 | # define R3_OFF -352 | |
158 | # define R4_OFF -344 | |
159 | # define R5_OFF -336 | |
160 | # define R6_OFF -328 | |
161 | # define F0_OFF -320 | |
162 | # define F2_OFF -312 | |
163 | # define F4_OFF -304 | |
164 | # define F6_OFF -296 | |
165 | # define V24_OFF -288 | |
166 | # define V25_OFF -272 | |
167 | # define V26_OFF -256 | |
168 | # define V27_OFF -240 | |
169 | # define V28_OFF -224 | |
170 | # define V29_OFF -208 | |
171 | # define V30_OFF -192 | |
172 | # define V31_OFF -176 | |
bde6320f | 173 | # define R0_OFF -144 |
329c6fec IL |
174 | # define R12_OFF -136 |
175 | # define R14_OFF -128 | |
176 | # define FRAMESIZE_OFF -120 | |
177 | # define PLT1_OFF -112 | |
178 | # define PLT2_OFF -104 | |
179 | # define PREGS_OFF -96 | |
180 | # define RETVAL_OFF -88 | |
181 | # define RET_R2_OFF -88 | |
182 | # define RET_F0_OFF -80 | |
183 | # define RET_V24_OFF -72 | |
4603c51e SL |
184 | .globl _dl_runtime_profile |
185 | .type _dl_runtime_profile, @function | |
186 | cfi_startproc | |
187 | .align 16 | |
188 | _dl_runtime_profile: | |
bde6320f IL |
189 | stg %r0,CFA_OFF+R0_OFF(%r15) |
190 | cfi_offset (r0, R0_OFF) | |
329c6fec IL |
191 | stg %r12,CFA_OFF+R12_OFF(%r15) # r12 is used as backup of r15 |
192 | cfi_offset (r12, R12_OFF) | |
193 | stg %r14,CFA_OFF+R14_OFF(%r15) | |
194 | cfi_offset (r14, R14_OFF) | |
195 | lgr %r12,%r15 # backup stack pointer | |
4603c51e | 196 | cfi_def_cfa_register (12) |
329c6fec IL |
197 | # define FRAME_SIZE (CFA_OFF + SIZEOF_STRUCT_LA_S390_64_REGS) |
198 | aghi %r15,-FRAME_SIZE # create stack frame: | |
199 | stg %r12,0(%r15) # save backchain | |
5cdd1989 | 200 | |
329c6fec IL |
201 | stmg %r2,%r6,FRAME_OFF+R2_OFF(%r15) # save call-clobbered arg regs |
202 | cfi_offset (r2, R2_OFF) # + r6 needed as arg for | |
203 | cfi_offset (r3, R3_OFF) # _dl_profile_fixup | |
204 | cfi_offset (r4, R4_OFF) | |
205 | cfi_offset (r5, R5_OFF) | |
206 | cfi_offset (r6, R6_OFF) | |
207 | std %f0,FRAME_OFF+F0_OFF(%r15) | |
208 | cfi_offset (f0, F0_OFF) | |
209 | std %f2,FRAME_OFF+F2_OFF(%r15) | |
210 | cfi_offset (f2, F2_OFF) | |
211 | std %f4,FRAME_OFF+F4_OFF(%r15) | |
212 | cfi_offset (f4, F4_OFF) | |
213 | std %f6,FRAME_OFF+F6_OFF(%r15) | |
214 | cfi_offset (f6, F6_OFF) | |
215 | # ifdef RESTORE_VRS | |
4603c51e SL |
216 | .machine push |
217 | .machine "z13" | |
329c6fec IL |
218 | vstm %v24,%v31,FRAME_OFF+V24_OFF(%r15) # store call-clobbered |
219 | cfi_offset (v24, V24_OFF) # vr arguments | |
220 | cfi_offset (v25, V25_OFF) | |
221 | cfi_offset (v26, V26_OFF) | |
222 | cfi_offset (v27, V27_OFF) | |
223 | cfi_offset (v28, V28_OFF) | |
224 | cfi_offset (v29, V29_OFF) | |
225 | cfi_offset (v30, V30_OFF) | |
226 | cfi_offset (v31, V31_OFF) | |
4603c51e | 227 | .machine pop |
329c6fec IL |
228 | # endif |
229 | lmg %r2,%r3,CFA_OFF+PLT1_OFF(%r12) # load arguments saved by PLT | |
230 | lgr %r4,%r14 # return address as 3rd parameter | |
231 | la %r5,FRAME_OFF+REGS_OFF(%r15) # struct La_s390_64_regs * | |
232 | la %r6,CFA_OFF+FRAMESIZE_OFF(%r12) # long int * framesize | |
233 | brasl %r14,_dl_profile_fixup # call resolver | |
234 | lgr %r1,%r2 # function addr returned in r2 | |
235 | ld %f0,FRAME_OFF+F0_OFF(%r15) # restore call-clobbered | |
236 | ld %f2,FRAME_OFF+F2_OFF(%r15) # arg fprs | |
237 | ld %f4,FRAME_OFF+F4_OFF(%r15) | |
238 | ld %f6,FRAME_OFF+F6_OFF(%r15) | |
239 | # ifdef RESTORE_VRS | |
4603c51e | 240 | .machine push |
329c6fec IL |
241 | .machine "z13" # restore call-clobbered |
242 | vlm %v24,%v31,FRAME_OFF+V24_OFF(%r15)# arg vrs | |
4603c51e | 243 | .machine pop |
329c6fec IL |
244 | # endif |
245 | lg %r0,CFA_OFF+FRAMESIZE_OFF(%r12) # load framesize | |
4603c51e SL |
246 | ltgr %r0,%r0 |
247 | jnm 1f | |
329c6fec IL |
248 | # framesize < 0 means no |
249 | lmg %r2,%r6,FRAME_OFF+R2_OFF(%r15) # pltexit call, so we can do a | |
250 | # tail call without copying the | |
251 | # arg overflow area | |
252 | lgr %r15,%r12 # remove stack frame | |
4603c51e | 253 | cfi_def_cfa_register (15) |
329c6fec IL |
254 | lg %r14,CFA_OFF+R14_OFF(%r15) # restore registers |
255 | lg %r12,CFA_OFF+R12_OFF(%r15) | |
bde6320f | 256 | lg %r0,CFA_OFF+R0_OFF(%r15) |
329c6fec | 257 | br %r1 # tail call |
4603c51e SL |
258 | |
259 | cfi_def_cfa_register (12) | |
329c6fec IL |
260 | 1: la %r4,FRAME_OFF+REGS_OFF(%r15) # struct La_s390_64_regs * |
261 | stg %r4,CFA_OFF+PREGS_OFF(%r12) | |
262 | jz 4f # framesize == 0 ? | |
263 | aghi %r0,7 # align framesize to 8 | |
4603c51e | 264 | nill %r0,0xfff8 |
329c6fec IL |
265 | slgr %r15,%r0 # make room for framesize bytes |
266 | stg %r12,0(%r15) # save backchain | |
267 | la %r2,FRAME_OFF+REGS_OFF(%r15) | |
268 | la %r3,CFA_OFF(%r12) | |
4603c51e | 269 | srlg %r0,%r0,3 |
329c6fec IL |
270 | 3: mvc 0(8,%r2),0(%r3) # copy additional parameters |
271 | la %r2,8(%r2) # depending on framesize | |
4603c51e SL |
272 | la %r3,8(%r3) |
273 | brctg %r0,3b | |
329c6fec IL |
274 | 4: lmg %r2,%r6,0(%r4) # load register parameters |
275 | basr %r14,%r1 # call resolved function | |
276 | stg %r2,CFA_OFF+RET_R2_OFF(%r12) # store return values r2, f0 | |
277 | std %f0,CFA_OFF+RET_F0_OFF(%r12) # to struct La_s390_64_retval | |
278 | # ifdef RESTORE_VRS | |
5cdd1989 SL |
279 | .machine push |
280 | .machine "z13" | |
329c6fec | 281 | vst %v24,CFA_OFF+RET_V24_OFF(%r12) # store return value v24 |
5cdd1989 | 282 | .machine pop |
329c6fec IL |
283 | # endif |
284 | lmg %r2,%r4,CFA_OFF+PLT1_OFF(%r12) # r2, r3: args saved by PLT | |
285 | # r4: struct La_s390_64_regs * | |
286 | la %r5,CFA_OFF+RETVAL_OFF(%r12) # struct La_s390_64_retval * | |
4603c51e SL |
287 | brasl %r14,_dl_call_pltexit |
288 | ||
329c6fec IL |
289 | lgr %r15,%r12 # remove stack frame |
290 | # undef FRAME_SIZE | |
4603c51e | 291 | cfi_def_cfa_register (15) |
329c6fec IL |
292 | lg %r14,CFA_OFF+R14_OFF(%r15) # restore registers |
293 | lg %r12,CFA_OFF+R12_OFF(%r15) | |
bde6320f | 294 | lg %r0,CFA_OFF+R0_OFF(%r15) |
329c6fec IL |
295 | lg %r2,CFA_OFF+RET_R2_OFF(%r15) # restore return values |
296 | ld %f0,CFA_OFF+RET_F0_OFF(%r15) | |
297 | # ifdef RESTORE_VRS | |
5cdd1989 SL |
298 | .machine push |
299 | .machine "z13" | |
329c6fec | 300 | vl %v24,CFA_OFF+RET_V24_OFF(%r15) # restore return value v24 |
5cdd1989 | 301 | .machine pop |
329c6fec | 302 | # endif |
4603c51e SL |
303 | br %r14 # Jump back to caller |
304 | ||
305 | cfi_endproc | |
306 | .size _dl_runtime_profile, .-_dl_runtime_profile | |
329c6fec IL |
307 | # undef SIZEOF_STRUCT_LA_S390_64_REGS |
308 | # undef REGS_OFF | |
309 | # undef R2_OFF | |
310 | # undef R3_OFF | |
311 | # undef R4_OFF | |
312 | # undef R5_OFF | |
313 | # undef R6_OFF | |
314 | # undef F0_OFF | |
315 | # undef F2_OFF | |
316 | # undef F4_OFF | |
317 | # undef F6_OFF | |
318 | # undef V24_OFF | |
319 | # undef V25_OFF | |
320 | # undef V26_OFF | |
321 | # undef V27_OFF | |
322 | # undef V28_OFF | |
323 | # undef V29_OFF | |
324 | # undef V30_OFF | |
325 | # undef V31_OFF | |
bde6320f | 326 | # undef R0_OFF |
329c6fec IL |
327 | # undef R12_OFF |
328 | # undef R14_OFF | |
329 | # undef FRAMESIZE_OFF | |
330 | # undef PLT1_OFF | |
331 | # undef PLT2_OFF | |
332 | # undef PREGS_OFF | |
333 | # undef RETVAL_OFF | |
334 | # undef RET_R2_OFF | |
335 | # undef RET_F0_OFF | |
336 | # undef RET_V24_OFF | |
4603c51e | 337 | #endif |