1 /* PLT trampolines. s390 version.
2 Copyright (C) 2016-2018 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 <http://www.gnu.org/licenses/>. */
19 /* This code is used in dl-runtime.c to call the `fixup' function
20 and then redirect to the address it returns. */
22 /* The PLT stubs will call _dl_runtime_resolve/_dl_runtime_profile
23 * with the following linkage:
24 * r2 - r6 : parameter registers
25 * f0, f2 : floating point parameter registers
26 * v24, v26, v28, v30, v25, v27, v29, v31 : vector parameter registers
27 * 24(r15), 28(r15) : PLT arguments PLT1, PLT2
28 * 96(r15) : additional stack parameters
29 * The slightly tightened normal clobber rules for function calls apply:
30 * r0 : call saved (for __fentry__)
31 * r1 - r5 : call clobbered
32 * r6 - r13 : call saved
33 * r14 : return address (call clobbered)
34 * r15 : stack pointer (call saved)
36 * f0 - f3, f5, f7 - f15 : call clobbered
37 * v0 - v3, v5, v7 - v15 : bytes 0-7 overlap with fprs: call clobbered
38 bytes 8-15: call clobbered
39 * v4, v6 : bytes 0-7 overlap with f4, f6: call saved
40 bytes 8-15: call clobbered
41 * v16 - v31 : call clobbered
45 #define FRAME_OFF CFA_OFF + FRAME_SIZE
65 .globl _dl_runtime_resolve
66 .type _dl_runtime_resolve
, @function
70 st
%r0
,CFA_OFF
+R0_OFF(%r15
)
71 cfi_offset (r0
, R0_OFF
)
72 stm
%r2
,%r5
,CFA_OFF
+R2_OFF(%r15
) # save registers
73 cfi_offset (r2
, R2_OFF
)
74 cfi_offset (r3
, R3_OFF
)
75 cfi_offset (r4
, R4_OFF
)
76 cfi_offset (r5
, R5_OFF
)
77 stm
%r14
,%r15
,CFA_OFF
+R14_OFF(%r15
)
78 cfi_offset (r14
, R14_OFF
)
79 cfi_offset (r15
, R15_OFF
)
80 std
%f0
,CFA_OFF
+F0_OFF(%r15
)
81 cfi_offset (f0
, F0_OFF
)
82 std
%f2
,CFA_OFF
+F2_OFF(%r15
)
83 cfi_offset (f2
, F2_OFF
)
85 lm
%r2
,%r3
,CFA_OFF
+PLT1_OFF(%r15
) # load args saved by PLT
87 # define FRAME_SIZE (CFA_OFF + 128)
88 ahi
%r15
,-FRAME_SIZE
# create stack frame
89 cfi_adjust_cfa_offset (FRAME_SIZE
)
92 .machinemode
"zarch_nohighgprs"
93 vstm
%v24
,%v31
,FRAME_OFF
+V24_OFF(%r15
) # save call-clobbered vr args
94 cfi_offset (v24
, V24_OFF
)
95 cfi_offset (v25
, V25_OFF
)
96 cfi_offset (v26
, V26_OFF
)
97 cfi_offset (v27
, V27_OFF
)
98 cfi_offset (v28
, V28_OFF
)
99 cfi_offset (v29
, V29_OFF
)
100 cfi_offset (v30
, V30_OFF
)
101 cfi_offset (v31
, V31_OFF
)
104 # define FRAME_SIZE CFA_OFF
105 ahi
%r15
,-FRAME_SIZE
# create stack frame
106 cfi_adjust_cfa_offset (FRAME_SIZE
)
108 st
%r0
,0(%r15
) # write backchain
111 bas
%r14
,0(%r14
,%r1
) # call _dl_fixup
112 lr
%r1
,%r2
# function addr returned in r2
116 .machinemode
"zarch_nohighgprs"
117 vlm
%v24
,%v31
,FRAME_OFF
+V24_OFF(%r15
) # restore vector registers
120 lm
%r14
,%r15
,FRAME_OFF
+R14_OFF(%r15
) # restore frame and registers
122 cfi_def_cfa_offset (CFA_OFF
)
123 ld
%f0
,CFA_OFF
+F0_OFF(%r15
)
124 ld
%f2
,CFA_OFF
+F2_OFF(%r15
)
125 lm
%r2
,%r5
,CFA_OFF
+R2_OFF(%r15
)
126 l
%r0
,CFA_OFF
+R0_OFF(%r15
)
128 1: .long _dl_fixup
- 0b
130 .size _dl_runtime_resolve
, .-_dl_runtime_resolve
152 # define SIZEOF_STRUCT_LA_S390_32_REGS 168
153 # define REGS_OFF -264
161 # define V24_OFF -224
162 # define V25_OFF -208
163 # define V26_OFF -192
164 # define V27_OFF -176
165 # define V28_OFF -160
166 # define V29_OFF -144
167 # define V30_OFF -128
168 # define V31_OFF -112
172 # define FRAMESIZE_OFF -76
173 # define PLT1_OFF -72
174 # define PLT2_OFF -68
175 # define PREGS_OFF -64
176 # define RETVAL_OFF -56
177 # define RET_R2_OFF -56
178 # define RET_R3_OFF -52
179 # define RET_F0_OFF -48
180 # define RET_V24_OFF -40
181 .globl _dl_runtime_profile
182 .type _dl_runtime_profile
, @function
186 st
%r0
,CFA_OFF
+R0_OFF(%r15
)
187 cfi_offset (r0
, R0_OFF
)
188 st
%r12
,CFA_OFF
+R12_OFF(%r15
) # r12 is used as backup of r15
189 cfi_offset (r12
, R12_OFF
)
190 st
%r14
,CFA_OFF
+R14_OFF(%r15
)
191 cfi_offset (r14
, R14_OFF
)
192 lr
%r12
,%r15
# backup stack pointer
193 cfi_def_cfa_register (12)
194 # define FRAME_SIZE (CFA_OFF + SIZEOF_STRUCT_LA_S390_32_REGS)
195 ahi
%r15
,-FRAME_SIZE
# create stack frame:
196 st
%r12
,0(%r15
) # save backchain
198 stm
%r2
,%r6
,FRAME_OFF
+R2_OFF(%r15
) # save registers
199 cfi_offset (r2
, R2_OFF
) # + r6 needed as arg for
200 cfi_offset (r3
, R3_OFF
) # _dl_profile_fixup
201 cfi_offset (r4
, R4_OFF
)
202 cfi_offset (r5
, R5_OFF
)
203 cfi_offset (r6
, R6_OFF
)
204 std
%f0
,FRAME_OFF
+F0_OFF(%r15
)
205 cfi_offset (f0
, F0_OFF
)
206 std
%f2
,FRAME_OFF
+F2_OFF(%r15
)
207 cfi_offset (f2
, F2_OFF
)
211 .machinemode
"zarch_nohighgprs"
212 vstm
%v24
,%v31
,FRAME_OFF
+V24_OFF(%r15
) # store call-clobbered
213 cfi_offset (v24
, V24_OFF
) # vr arguments
214 cfi_offset (v25
, V25_OFF
)
215 cfi_offset (v26
, V26_OFF
)
216 cfi_offset (v27
, V27_OFF
)
217 cfi_offset (v28
, V28_OFF
)
218 cfi_offset (v29
, V29_OFF
)
219 cfi_offset (v30
, V30_OFF
)
220 cfi_offset (v31
, V31_OFF
)
224 lm
%r2
,%r3
,CFA_OFF
+PLT1_OFF(%r12
) # load arguments saved by PLT
225 lr
%r4
,%r14
# return address as third parm
228 la
%r5
,FRAME_OFF
+REGS_OFF(%r15
) # struct La_s390_32_regs *
229 la
%r6
,CFA_OFF
+FRAMESIZE_OFF(%r12
) # long int * framesize
230 bas
%r14
,0(%r14
,%r1
) # call resolver
231 lr
%r1
,%r2
# function addr returned in r2
232 ld
%f0
,FRAME_OFF
+F0_OFF(%r15
) # restore call-clobbered
233 ld
%f2
,FRAME_OFF
+F2_OFF(%r15
) # arg fprs
237 .machinemode
"zarch_nohighgprs" # restore call-clobbered
238 vlm
%v24
,%v31
,FRAME_OFF
+V24_OFF(%r15
)# arg vrs
241 icm
%r0
,15,CFA_OFF
+FRAMESIZE_OFF(%r12
) # load & test framesize
243 # framesize < 0 means no
244 lm
%r2
,%r6
,FRAME_OFF
+R2_OFF(%r15
) # pltexit call, so we can do a
246 # copying the arg overflow area
247 lr
%r15
,%r12
# remove stack frame
248 cfi_def_cfa_register (15)
249 l
%r14
,CFA_OFF
+R14_OFF(%r15
) # restore registers
250 l
%r12
,CFA_OFF
+R12_OFF(%r15
)
251 l
%r0
,CFA_OFF
+R0_OFF(%r15
)
254 cfi_def_cfa_register (12)
255 2: la
%r4
,FRAME_OFF
+REGS_OFF(%r15
) # struct La_s390_32_regs *
256 st
%r4
,CFA_OFF
+PREGS_OFF(%r12
)
257 jz
4f
# framesize == 0 ?
258 ahi
%r0
,7 # align framesize to 8
261 slr
%r15
,%r0
# make room for framesize bytes
262 st
%r12
,0(%r15
) # save backchain
263 la
%r2
,FRAME_OFF
+REGS_OFF(%r15
)
266 3: mvc
0(8,%r2
),0(%r3
) # copy additional parameters
270 4: lm
%r2
,%r6
,0(%r4
) # load register parameters
271 basr
%r14
,%r1
# call resolved function
272 stm
%r2
,%r3
,CFA_OFF
+RET_R2_OFF(%r12
) # store return vals r2, r3, f0
273 std
%f0
,CFA_OFF
+RET_F0_OFF(%r12
) # to struct La_s390_32_retval
277 vst
%v24
,CFA_OFF
+RET_V24_OFF(%r12
) # store return value v24
280 lm
%r2
,%r4
,CFA_OFF
+PLT1_OFF(%r12
) # r2, r3: args saved by PLT
281 # r4: struct La_s390_32_regs *
284 la
%r5
,CFA_OFF
+RETVAL_OFF(%r12
) # struct La_s390_32_retval *
285 bas
%r14
,0(%r14
,%r1
) # call _dl_call_pltexit
287 lr
%r15
,%r12
# remove stack frame
289 cfi_def_cfa_register (15)
290 l
%r14
,CFA_OFF
+R14_OFF(%r15
) # restore registers
291 l
%r12
,CFA_OFF
+R12_OFF(%r15
)
292 l
%r0
,CFA_OFF
+R0_OFF(%r15
)
293 lm
%r2
,%r3
,CFA_OFF
+RET_R2_OFF(%r15
) # restore return values
294 ld
%f0
,CFA_OFF
+RET_F0_OFF(%r15
)
298 vl
%v24
,CFA_OFF
+RET_V24_OFF(%r15
) # restore return value v24
303 6: .long _dl_profile_fixup
- 0b
304 7: .long _dl_call_pltexit
- 5b
306 .size _dl_runtime_profile
, .-_dl_runtime_profile
307 # undef SIZEOF_STRUCT_LA_S390_32_REGS
327 # undef FRAMESIZE_OFF