1 /* PLT trampolines. s390 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 /* This code is used in dl-runtime.c to call the `fixup' function 20 and then redirect to the address it returns. */ 21 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) 35 * f4, f6 : 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 42 */ 43 44 #define CFA_OFF 96 45 #define FRAME_OFF CFA_OFF + FRAME_SIZE 46 #define V24_OFF -224 47 #define V25_OFF -208 48 #define V26_OFF -192 49 #define V27_OFF -176 50 #define V28_OFF -160 51 #define V29_OFF -144 52 #define V30_OFF -128 53 #define V31_OFF -112 54 #define R0_OFF -76 55 #define PLT1_OFF -72 56 #define PLT2_OFF -68 57 #define R2_OFF -64 58 #define R3_OFF -60 59 #define R4_OFF -56 60 #define R5_OFF -52 61 #define R14_OFF -48 62 #define R15_OFF -44 63 #define F0_OFF -40 64 #define F2_OFF -32 65 .globl _dl_runtime_resolve 66 .type _dl_runtime_resolve, @function 67 cfi_startproc 68 .align 16 69 _dl_runtime_resolve: 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) 84 lr %r0,%r15 85 lm %r2,%r3,CFA_OFF+PLT1_OFF(%r15) # load args saved by PLT 86 #ifdef RESTORE_VRS 87 # define FRAME_SIZE (CFA_OFF + 128) 88 ahi %r15,-FRAME_SIZE # create stack frame 89 cfi_adjust_cfa_offset (FRAME_SIZE) 90 .machine push 91 .machine "z13" 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) 102 .machine pop 103 #else 104 # define FRAME_SIZE CFA_OFF 105 ahi %r15,-FRAME_SIZE # create stack frame 106 cfi_adjust_cfa_offset (FRAME_SIZE) 107 #endif 108 st %r0,0(%r15) # write backchain 109 basr %r1,0 110 0: l %r14,1f-0b(%r1) 111 bas %r14,0(%r14,%r1) # call _dl_fixup 112 lr %r1,%r2 # function addr returned in r2 113 #ifdef RESTORE_VRS 114 .machine push 115 .machine "z13" 116 .machinemode "zarch_nohighgprs" 117 vlm %v24,%v31,FRAME_OFF+V24_OFF(%r15) # restore vector registers 118 .machine pop 119 #endif 120 lm %r14,%r15,FRAME_OFF+R14_OFF(%r15) # restore frame and registers 121 #undef FRAME_SIZE 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) 127 br %r1 128 1: .long _dl_fixup - 0b 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 151 #ifndef PROF 152 # define SIZEOF_STRUCT_LA_S390_32_REGS 168 153 # define REGS_OFF -264 154 # define R2_OFF -264 155 # define R3_OFF -260 156 # define R4_OFF -256 157 # define R5_OFF -252 158 # define R6_OFF -248 159 # define F0_OFF -240 160 # define F2_OFF -232 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 169 # define R0_OFF -88 170 # define R12_OFF -84 171 # define R14_OFF -80 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 183 cfi_startproc 184 .align 16 185 _dl_runtime_profile: 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 197 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) 208 # ifdef RESTORE_VRS 209 .machine push 210 .machine "z13" 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) 221 .machine pop 222 # endif 223 224 lm %r2,%r3,CFA_OFF+PLT1_OFF(%r12) # load arguments saved by PLT 225 lr %r4,%r14 # return address as third parm 226 basr %r1,0 227 0: l %r14,6f-0b(%r1) 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 234 # ifdef RESTORE_VRS 235 .machine push 236 .machine "z13" 237 .machinemode "zarch_nohighgprs" # restore call-clobbered 238 vlm %v24,%v31,FRAME_OFF+V24_OFF(%r15)# arg vrs 239 .machine pop 240 # endif 241 icm %r0,15,CFA_OFF+FRAMESIZE_OFF(%r12) # load & test framesize 242 jnm 2f 243 # framesize < 0 means no 244 lm %r2,%r6,FRAME_OFF+R2_OFF(%r15) # pltexit call, so we can do a 245 # tail call without 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) 252 br %r1 # tail call 253 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 259 lhi %r2,-8 260 nr %r0,%r2 261 slr %r15,%r0 # make room for framesize bytes 262 st %r12,0(%r15) # save backchain 263 la %r2,FRAME_OFF+REGS_OFF(%r15) 264 la %r3,CFA_OFF(%r12) 265 srl %r0,3 266 3: mvc 0(8,%r2),0(%r3) # copy additional parameters 267 la %r2,8(%r2) 268 la %r3,8(%r3) 269 brct %r0,3b 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 274 # ifdef RESTORE_VRS 275 .machine push 276 .machine "z13" 277 vst %v24,CFA_OFF+RET_V24_OFF(%r12) # store return value v24 278 .machine pop 279 # endif 280 lm %r2,%r4,CFA_OFF+PLT1_OFF(%r12) # r2, r3: args saved by PLT 281 # r4: struct La_s390_32_regs * 282 basr %r1,0 283 5: l %r14,7f-5b(%r1) 284 la %r5,CFA_OFF+RETVAL_OFF(%r12) # struct La_s390_32_retval * 285 bas %r14,0(%r14,%r1) # call _dl_audit_pltexit 286 287 lr %r15,%r12 # remove stack frame 288 # undef FRAME_SIZE 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) 295 # ifdef RESTORE_VRS 296 .machine push 297 .machine "z13" 298 vl %v24,CFA_OFF+RET_V24_OFF(%r15) # restore return value v24 299 .machine pop 300 # endif 301 br %r14 302 303 6: .long _dl_profile_fixup - 0b 304 7: .long _dl_audit_pltexit - 5b 305 cfi_endproc 306 .size _dl_runtime_profile, .-_dl_runtime_profile 307 # undef SIZEOF_STRUCT_LA_S390_32_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 V24_OFF 317 # undef V25_OFF 318 # undef V26_OFF 319 # undef V27_OFF 320 # undef V28_OFF 321 # undef V29_OFF 322 # undef V30_OFF 323 # undef V31_OFF 324 # undef R0_OFF 325 # undef R12_OFF 326 # undef R14_OFF 327 # undef FRAMESIZE_OFF 328 # undef PLT1_OFF 329 # undef PLT2_OFF 330 # undef PREGS_OFF 331 # undef RETVAL_OFF 332 # undef RET_R2_OFF 333 # undef RET_R3_OFF 334 # undef RET_F0_OFF 335 # undef RET_V24_OFF 336 #endif 337