1 /* PLT trampolines. s390x version. 2 Copyright (C) 2016-2022 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 <https://www.gnu.org/licenses/>. */ 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 26 * The slightly tightened normal clobber rules for function calls apply: 27 * r0 : call saved (for __fentry__) 28 * r1 - r5 : call clobbered 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 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 51 #define R0_OFF -120 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 64 .globl _dl_runtime_resolve 65 .type _dl_runtime_resolve, @function 66 cfi_startproc 67 .align 16 68 _dl_runtime_resolve: 69 stg %r0,CFA_OFF+R0_OFF(%r15) 70 cfi_offset (r0, R0_OFF) 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 88 lgr %r0,%r15 89 #ifdef RESTORE_VRS 90 # define FRAME_SIZE (CFA_OFF + 128) 91 aghi %r15,-FRAME_SIZE # create stack frame 92 cfi_adjust_cfa_offset (FRAME_SIZE) 93 .machine push 94 .machine "z13" 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) 104 .machine pop 105 #else 106 # define FRAME_SIZE CFA_OFF 107 aghi %r15,-FRAME_SIZE # create stack frame 108 cfi_adjust_cfa_offset (FRAME_SIZE) 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" 116 vlm %v24,%v31,FRAME_OFF+V24_OFF(%r15) # restore vector registers 117 .machine pop 118 #endif 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) 127 lg %r0,CFA_OFF+R0_OFF(%r15) 128 br %r1 129 cfi_endproc 130 .size _dl_runtime_resolve, .-_dl_runtime_resolve 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 139 #undef R0_OFF 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 152 153 #ifndef PROF 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 173 # define R0_OFF -144 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 184 .globl _dl_runtime_profile 185 .type _dl_runtime_profile, @function 186 cfi_startproc 187 .align 16 188 _dl_runtime_profile: 189 stg %r0,CFA_OFF+R0_OFF(%r15) 190 cfi_offset (r0, R0_OFF) 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 196 cfi_def_cfa_register (12) 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 200 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 216 .machine push 217 .machine "z13" 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) 227 .machine pop 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 240 .machine push 241 .machine "z13" # restore call-clobbered 242 vlm %v24,%v31,FRAME_OFF+V24_OFF(%r15)# arg vrs 243 .machine pop 244 # endif 245 lg %r0,CFA_OFF+FRAMESIZE_OFF(%r12) # load framesize 246 ltgr %r0,%r0 247 jnm 1f 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 253 cfi_def_cfa_register (15) 254 lg %r14,CFA_OFF+R14_OFF(%r15) # restore registers 255 lg %r12,CFA_OFF+R12_OFF(%r15) 256 lg %r0,CFA_OFF+R0_OFF(%r15) 257 br %r1 # tail call 258 259 cfi_def_cfa_register (12) 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 264 nill %r0,0xfff8 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) 269 srlg %r0,%r0,3 270 3: mvc 0(8,%r2),0(%r3) # copy additional parameters 271 la %r2,8(%r2) # depending on framesize 272 la %r3,8(%r3) 273 brctg %r0,3b 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 279 .machine push 280 .machine "z13" 281 vst %v24,CFA_OFF+RET_V24_OFF(%r12) # store return value v24 282 .machine pop 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 * 287 brasl %r14,_dl_audit_pltexit 288 289 lgr %r15,%r12 # remove stack frame 290 # undef FRAME_SIZE 291 cfi_def_cfa_register (15) 292 lg %r14,CFA_OFF+R14_OFF(%r15) # restore registers 293 lg %r12,CFA_OFF+R12_OFF(%r15) 294 lg %r0,CFA_OFF+R0_OFF(%r15) 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 298 .machine push 299 .machine "z13" 300 vl %v24,CFA_OFF+RET_V24_OFF(%r15) # restore return value v24 301 .machine pop 302 # endif 303 br %r14 # Jump back to caller 304 305 cfi_endproc 306 .size _dl_runtime_profile, .-_dl_runtime_profile 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 326 # undef R0_OFF 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 337 #endif 338