1/* Save current context. 2 Copyright (C) 2002-2021 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#include <sysdep.h> 20#include <rtld-global-offsets.h> 21#include <shlib-compat.h> 22 23#define __ASSEMBLY__ 24#include <asm/ptrace.h> 25#include <asm/errno.h> 26#include "ucontext_i.h" 27 28 29#if SHLIB_COMPAT (libc, GLIBC_2_3, GLIBC_2_3_4) 30ENTRY(__novec_getcontext) 31 CALL_MCOUNT 1 32 std r0,(SIGCONTEXT_GP_REGS+(PT_R0*8))(r3) 33 std r1,(SIGCONTEXT_GP_REGS+(PT_R1*8))(r3) 34 mflr r0 35 std r2,(SIGCONTEXT_GP_REGS+(PT_R2*8))(r3) 36 std r0,FRAME_LR_SAVE(r1) 37 cfi_offset (lr, FRAME_LR_SAVE) 38 std r0,(SIGCONTEXT_GP_REGS+(PT_LNK*8))(r3) 39 std r0,(SIGCONTEXT_GP_REGS+(PT_NIP*8))(r3) 40 stdu r1,-128(r1) 41 cfi_adjust_cfa_offset (128) 42 std r4,(SIGCONTEXT_GP_REGS+(PT_R4*8))(r3) 43 std r5,(SIGCONTEXT_GP_REGS+(PT_R5*8))(r3) 44 std r6,(SIGCONTEXT_GP_REGS+(PT_R6*8))(r3) 45 std r7,(SIGCONTEXT_GP_REGS+(PT_R7*8))(r3) 46 std r8,(SIGCONTEXT_GP_REGS+(PT_R8*8))(r3) 47 std r9,(SIGCONTEXT_GP_REGS+(PT_R9*8))(r3) 48 std r10,(SIGCONTEXT_GP_REGS+(PT_R10*8))(r3) 49 std r11,(SIGCONTEXT_GP_REGS+(PT_R11*8))(r3) 50 std r12,(SIGCONTEXT_GP_REGS+(PT_R12*8))(r3) 51 std r13,(SIGCONTEXT_GP_REGS+(PT_R13*8))(r3) 52 std r14,(SIGCONTEXT_GP_REGS+(PT_R14*8))(r3) 53 std r15,(SIGCONTEXT_GP_REGS+(PT_R15*8))(r3) 54 std r16,(SIGCONTEXT_GP_REGS+(PT_R16*8))(r3) 55 std r17,(SIGCONTEXT_GP_REGS+(PT_R17*8))(r3) 56 std r18,(SIGCONTEXT_GP_REGS+(PT_R18*8))(r3) 57 std r19,(SIGCONTEXT_GP_REGS+(PT_R19*8))(r3) 58 std r20,(SIGCONTEXT_GP_REGS+(PT_R20*8))(r3) 59 std r21,(SIGCONTEXT_GP_REGS+(PT_R21*8))(r3) 60 std r22,(SIGCONTEXT_GP_REGS+(PT_R22*8))(r3) 61 std r23,(SIGCONTEXT_GP_REGS+(PT_R23*8))(r3) 62 std r24,(SIGCONTEXT_GP_REGS+(PT_R24*8))(r3) 63 std r25,(SIGCONTEXT_GP_REGS+(PT_R25*8))(r3) 64 std r26,(SIGCONTEXT_GP_REGS+(PT_R26*8))(r3) 65 std r27,(SIGCONTEXT_GP_REGS+(PT_R27*8))(r3) 66 std r28,(SIGCONTEXT_GP_REGS+(PT_R28*8))(r3) 67 std r29,(SIGCONTEXT_GP_REGS+(PT_R29*8))(r3) 68 std r30,(SIGCONTEXT_GP_REGS+(PT_R30*8))(r3) 69 std r31,(SIGCONTEXT_GP_REGS+(PT_R31*8))(r3) 70 mfctr r0 71 std r0,(SIGCONTEXT_GP_REGS+(PT_CTR*8))(r3) 72 mfxer r0 73 std r0,(SIGCONTEXT_GP_REGS+(PT_XER*8))(r3) 74 mfcr r0 75 std r0,(SIGCONTEXT_GP_REGS+(PT_CCR*8))(r3) 76 77 /* Set the return value of swapcontext to "success". R3 is the only 78 register whose value is not preserved in the saved context. */ 79 li r0,0 80 std r0,(SIGCONTEXT_GP_REGS+(PT_R3*8))(r3) 81 82 /* Zero fill fields that can't be set in user state or are unused. */ 83 std r0,(SIGCONTEXT_GP_REGS+(PT_MSR*8))(r3) 84 std r0,(SIGCONTEXT_GP_REGS+(34*8))(r3) 85 std r0,(SIGCONTEXT_GP_REGS+(PT_SOFTE*8))(r3) 86 std r0,(SIGCONTEXT_GP_REGS+(40*8))(r3) 87 std r0,(SIGCONTEXT_GP_REGS+(41*8))(r3) 88 std r0,(SIGCONTEXT_GP_REGS+(42*8))(r3) 89 std r0,(SIGCONTEXT_GP_REGS+(PT_RESULT*8))(r3) 90 91 /* Set the PT_REGS pointer to the address of sigcontext's gp_regs 92 field. Struct pt_regs and elf_gregset_t are the same thing. 93 We kept the regs field for backwards compatibility with 94 libraries built before we extended sigcontext. */ 95 addi r0,r3,SIGCONTEXT_GP_REGS 96 std r0,SIGCONTEXT_PT_REGS(r3) 97 98 stfd fp0,(SIGCONTEXT_FP_REGS+(PT_R0*8))(r3) 99 stfd fp1,(SIGCONTEXT_FP_REGS+(PT_R1*8))(r3) 100 stfd fp2,(SIGCONTEXT_FP_REGS+(PT_R2*8))(r3) 101 stfd fp3,(SIGCONTEXT_FP_REGS+(PT_R3*8))(r3) 102 stfd fp4,(SIGCONTEXT_FP_REGS+(PT_R4*8))(r3) 103 stfd fp5,(SIGCONTEXT_FP_REGS+(PT_R5*8))(r3) 104 stfd fp6,(SIGCONTEXT_FP_REGS+(PT_R6*8))(r3) 105 stfd fp7,(SIGCONTEXT_FP_REGS+(PT_R7*8))(r3) 106 stfd fp8,(SIGCONTEXT_FP_REGS+(PT_R8*8))(r3) 107 stfd fp9,(SIGCONTEXT_FP_REGS+(PT_R9*8))(r3) 108 stfd fp10,(SIGCONTEXT_FP_REGS+(PT_R10*8))(r3) 109 stfd fp11,(SIGCONTEXT_FP_REGS+(PT_R11*8))(r3) 110 stfd fp12,(SIGCONTEXT_FP_REGS+(PT_R12*8))(r3) 111 stfd fp13,(SIGCONTEXT_FP_REGS+(PT_R13*8))(r3) 112 stfd fp14,(SIGCONTEXT_FP_REGS+(PT_R14*8))(r3) 113 stfd fp15,(SIGCONTEXT_FP_REGS+(PT_R15*8))(r3) 114 stfd fp16,(SIGCONTEXT_FP_REGS+(PT_R16*8))(r3) 115 stfd fp17,(SIGCONTEXT_FP_REGS+(PT_R17*8))(r3) 116 stfd fp18,(SIGCONTEXT_FP_REGS+(PT_R18*8))(r3) 117 stfd fp19,(SIGCONTEXT_FP_REGS+(PT_R19*8))(r3) 118 stfd fp20,(SIGCONTEXT_FP_REGS+(PT_R20*8))(r3) 119 stfd fp21,(SIGCONTEXT_FP_REGS+(PT_R21*8))(r3) 120 stfd fp22,(SIGCONTEXT_FP_REGS+(PT_R22*8))(r3) 121 stfd fp23,(SIGCONTEXT_FP_REGS+(PT_R23*8))(r3) 122 stfd fp24,(SIGCONTEXT_FP_REGS+(PT_R24*8))(r3) 123 stfd fp25,(SIGCONTEXT_FP_REGS+(PT_R25*8))(r3) 124 stfd fp26,(SIGCONTEXT_FP_REGS+(PT_R26*8))(r3) 125 stfd fp27,(SIGCONTEXT_FP_REGS+(PT_R27*8))(r3) 126 stfd fp28,(SIGCONTEXT_FP_REGS+(PT_R28*8))(r3) 127 stfd fp29,(SIGCONTEXT_FP_REGS+(PT_R29*8))(r3) 128 mffs fp0 129 stfd fp30,(SIGCONTEXT_FP_REGS+(PT_R30*8))(r3) 130 stfd fp31,(SIGCONTEXT_FP_REGS+(PT_R31*8))(r3) 131 stfd fp0,(SIGCONTEXT_FP_REGS+(32*8))(r3) 132 133 addi r5,r3,UCONTEXT_SIGMASK 134 li r4,0 135 li r3,SIG_BLOCK 136 bl JUMPTARGET(__sigprocmask) 137 nop 138 139 ld r0,128+FRAME_LR_SAVE(r1) 140 addi r1,r1,128 141 mtlr r0 142 blr 143PSEUDO_END(__novec_getcontext) 144 145compat_symbol (libc, __novec_getcontext, getcontext, GLIBC_2_3) 146 147#endif 148 149 .section ".toc","aw" 150.LC__dl_hwcap: 151#ifdef SHARED 152 .tc _rtld_global_ro[TC],_rtld_global_ro 153#else 154 .tc _dl_hwcap[TC],_dl_hwcap 155#endif 156 .section ".text" 157 158 .machine "altivec" 159ENTRY(__getcontext) 160 CALL_MCOUNT 1 161 std r0,(SIGCONTEXT_GP_REGS+(PT_R0*8))(r3) 162 std r1,(SIGCONTEXT_GP_REGS+(PT_R1*8))(r3) 163 mflr r0 164 std r2,(SIGCONTEXT_GP_REGS+(PT_R2*8))(r3) 165 std r0,FRAME_LR_SAVE(r1) 166 cfi_offset (lr, FRAME_LR_SAVE) 167 std r0,(SIGCONTEXT_GP_REGS+(PT_LNK*8))(r3) 168 std r0,(SIGCONTEXT_GP_REGS+(PT_NIP*8))(r3) 169 stdu r1,-128(r1) 170 cfi_adjust_cfa_offset (128) 171 std r4,(SIGCONTEXT_GP_REGS+(PT_R4*8))(r3) 172 std r5,(SIGCONTEXT_GP_REGS+(PT_R5*8))(r3) 173 std r6,(SIGCONTEXT_GP_REGS+(PT_R6*8))(r3) 174 std r7,(SIGCONTEXT_GP_REGS+(PT_R7*8))(r3) 175 std r8,(SIGCONTEXT_GP_REGS+(PT_R8*8))(r3) 176 std r9,(SIGCONTEXT_GP_REGS+(PT_R9*8))(r3) 177 std r10,(SIGCONTEXT_GP_REGS+(PT_R10*8))(r3) 178 std r11,(SIGCONTEXT_GP_REGS+(PT_R11*8))(r3) 179 std r12,(SIGCONTEXT_GP_REGS+(PT_R12*8))(r3) 180 std r13,(SIGCONTEXT_GP_REGS+(PT_R13*8))(r3) 181 std r14,(SIGCONTEXT_GP_REGS+(PT_R14*8))(r3) 182 std r15,(SIGCONTEXT_GP_REGS+(PT_R15*8))(r3) 183 std r16,(SIGCONTEXT_GP_REGS+(PT_R16*8))(r3) 184 std r17,(SIGCONTEXT_GP_REGS+(PT_R17*8))(r3) 185 std r18,(SIGCONTEXT_GP_REGS+(PT_R18*8))(r3) 186 std r19,(SIGCONTEXT_GP_REGS+(PT_R19*8))(r3) 187 std r20,(SIGCONTEXT_GP_REGS+(PT_R20*8))(r3) 188 std r21,(SIGCONTEXT_GP_REGS+(PT_R21*8))(r3) 189 std r22,(SIGCONTEXT_GP_REGS+(PT_R22*8))(r3) 190 std r23,(SIGCONTEXT_GP_REGS+(PT_R23*8))(r3) 191 std r24,(SIGCONTEXT_GP_REGS+(PT_R24*8))(r3) 192 std r25,(SIGCONTEXT_GP_REGS+(PT_R25*8))(r3) 193 std r26,(SIGCONTEXT_GP_REGS+(PT_R26*8))(r3) 194 std r27,(SIGCONTEXT_GP_REGS+(PT_R27*8))(r3) 195 std r28,(SIGCONTEXT_GP_REGS+(PT_R28*8))(r3) 196 std r29,(SIGCONTEXT_GP_REGS+(PT_R29*8))(r3) 197 std r30,(SIGCONTEXT_GP_REGS+(PT_R30*8))(r3) 198 std r31,(SIGCONTEXT_GP_REGS+(PT_R31*8))(r3) 199 mfctr r0 200 std r0,(SIGCONTEXT_GP_REGS+(PT_CTR*8))(r3) 201 mfxer r0 202 std r0,(SIGCONTEXT_GP_REGS+(PT_XER*8))(r3) 203 mfcr r0 204 std r0,(SIGCONTEXT_GP_REGS+(PT_CCR*8))(r3) 205 206 /* Set the return value of swapcontext to "success". R3 is the only 207 register whose value is not preserved in the saved context. */ 208 li r0,0 209 std r0,(SIGCONTEXT_GP_REGS+(PT_R3*8))(r3) 210 211 /* Zero fill fields that can't be set in user state or are unused. */ 212 std r0,(SIGCONTEXT_GP_REGS+(PT_MSR*8))(r3) 213 std r0,(SIGCONTEXT_GP_REGS+(34*8))(r3) 214 std r0,(SIGCONTEXT_GP_REGS+(PT_SOFTE*8))(r3) 215 std r0,(SIGCONTEXT_GP_REGS+(40*8))(r3) 216 std r0,(SIGCONTEXT_GP_REGS+(41*8))(r3) 217 std r0,(SIGCONTEXT_GP_REGS+(42*8))(r3) 218 std r0,(SIGCONTEXT_GP_REGS+(PT_RESULT*8))(r3) 219 220 /* Set the PT_REGS pointer to the address of sigcontext's gp_regs 221 field. Struct pt_regs and elf_gregset_t are the same thing. 222 We kept the regs field for backwards compatibility with 223 libraries built before we extended sigcontext. */ 224 addi r0,r3,SIGCONTEXT_GP_REGS 225 std r0,SIGCONTEXT_PT_REGS(r3) 226 227 stfd fp0,(SIGCONTEXT_FP_REGS+(PT_R0*8))(r3) 228 stfd fp1,(SIGCONTEXT_FP_REGS+(PT_R1*8))(r3) 229 stfd fp2,(SIGCONTEXT_FP_REGS+(PT_R2*8))(r3) 230 stfd fp3,(SIGCONTEXT_FP_REGS+(PT_R3*8))(r3) 231 stfd fp4,(SIGCONTEXT_FP_REGS+(PT_R4*8))(r3) 232 stfd fp5,(SIGCONTEXT_FP_REGS+(PT_R5*8))(r3) 233 stfd fp6,(SIGCONTEXT_FP_REGS+(PT_R6*8))(r3) 234 stfd fp7,(SIGCONTEXT_FP_REGS+(PT_R7*8))(r3) 235 stfd fp8,(SIGCONTEXT_FP_REGS+(PT_R8*8))(r3) 236 stfd fp9,(SIGCONTEXT_FP_REGS+(PT_R9*8))(r3) 237 stfd fp10,(SIGCONTEXT_FP_REGS+(PT_R10*8))(r3) 238 stfd fp11,(SIGCONTEXT_FP_REGS+(PT_R11*8))(r3) 239 stfd fp12,(SIGCONTEXT_FP_REGS+(PT_R12*8))(r3) 240 stfd fp13,(SIGCONTEXT_FP_REGS+(PT_R13*8))(r3) 241 stfd fp14,(SIGCONTEXT_FP_REGS+(PT_R14*8))(r3) 242 stfd fp15,(SIGCONTEXT_FP_REGS+(PT_R15*8))(r3) 243 stfd fp16,(SIGCONTEXT_FP_REGS+(PT_R16*8))(r3) 244 stfd fp17,(SIGCONTEXT_FP_REGS+(PT_R17*8))(r3) 245 stfd fp18,(SIGCONTEXT_FP_REGS+(PT_R18*8))(r3) 246 stfd fp19,(SIGCONTEXT_FP_REGS+(PT_R19*8))(r3) 247 stfd fp20,(SIGCONTEXT_FP_REGS+(PT_R20*8))(r3) 248 stfd fp21,(SIGCONTEXT_FP_REGS+(PT_R21*8))(r3) 249 stfd fp22,(SIGCONTEXT_FP_REGS+(PT_R22*8))(r3) 250 stfd fp23,(SIGCONTEXT_FP_REGS+(PT_R23*8))(r3) 251 stfd fp24,(SIGCONTEXT_FP_REGS+(PT_R24*8))(r3) 252 stfd fp25,(SIGCONTEXT_FP_REGS+(PT_R25*8))(r3) 253 stfd fp26,(SIGCONTEXT_FP_REGS+(PT_R26*8))(r3) 254 stfd fp27,(SIGCONTEXT_FP_REGS+(PT_R27*8))(r3) 255 stfd fp28,(SIGCONTEXT_FP_REGS+(PT_R28*8))(r3) 256 stfd fp29,(SIGCONTEXT_FP_REGS+(PT_R29*8))(r3) 257 mffs fp0 258 stfd fp30,(SIGCONTEXT_FP_REGS+(PT_R30*8))(r3) 259 stfd fp31,(SIGCONTEXT_FP_REGS+(PT_R31*8))(r3) 260 stfd fp0,(SIGCONTEXT_FP_REGS+(32*8))(r3) 261 262 ld r5,.LC__dl_hwcap@toc(r2) 263# ifdef SHARED 264/* Load _rtld-global._dl_hwcap. */ 265 ld r5,RTLD_GLOBAL_RO_DL_HWCAP_OFFSET(r5) 266# else 267 ld r5,0(r5) /* Load extern _dl_hwcap. */ 268# endif 269 la r10,(SIGCONTEXT_V_RESERVE+8)(r3) 270 la r9,(SIGCONTEXT_V_RESERVE+24)(r3) 271 272 andis. r5,r5,(PPC_FEATURE_HAS_ALTIVEC >> 16) 273 274 clrrdi r10,r10,4 275 beq L(has_no_vec) 276 clrrdi r9,r9,4 277 mr r5,r10 /* Capture *v_regs value in r5. */ 278 279 stvx v0,0,r10 280 stvx v1,0,r9 281 addi r10,r10,32 282 addi r9,r9,32 283 284 stvx v2,0,r10 285 stvx v3,0,r9 286 addi r10,r10,32 287 addi r9,r9,32 288 289 stvx v4,0,r10 290 stvx v5,0,r9 291 addi r10,r10,32 292 addi r9,r9,32 293 294 stvx v6,0,r10 295 stvx v7,0,r9 296 addi r10,r10,32 297 addi r9,r9,32 298 299 stvx v8,0,r10 300 stvx v9,0,r9 301 addi r10,r10,32 302 addi r9,r9,32 303 304 stvx v10,0,r10 305 stvx v11,0,r9 306 addi r10,r10,32 307 addi r9,r9,32 308 309 stvx v12,0,r10 310 stvx v13,0,r9 311 addi r10,r10,32 312 addi r9,r9,32 313 314 stvx v14,0,r10 315 stvx v15,0,r9 316 addi r10,r10,32 317 addi r9,r9,32 318 319 stvx v16,0,r10 320 stvx v17,0,r9 321 addi r10,r10,32 322 addi r9,r9,32 323 324 stvx v18,0,r10 325 stvx v19,0,r9 326 addi r10,r10,32 327 addi r9,r9,32 328 329 stvx v20,0,r10 330 stvx v21,0,r9 331 addi r10,r10,32 332 addi r9,r9,32 333 334 stvx v22,0,r10 335 stvx v23,0,r9 336 addi r10,r10,32 337 addi r9,r9,32 338 339 stvx v24,0,r10 340 stvx v25,0,r9 341 addi r10,r10,32 342 addi r9,r9,32 343 344 stvx v26,0,r10 345 stvx v27,0,r9 346 addi r10,r10,32 347 addi r9,r9,32 348 349 stvx v28,0,r10 350 stvx v29,0,r9 351 addi r10,r10,32 352 addi r9,r9,32 353 354 stvx v30,0,r10 355 stvx v31,0,r9 356 addi r10,r10,32 357 addi r9,r9,32 358 359 mfvscr v0 360 mfspr r0,VRSAVE 361 stvx v0,0,r10 362 stw r0,0(9) 363 364L(has_no_vec): 365/* 366 Store either a NULL or a quadword aligned pointer to the Vector register 367 array into *v_regs. 368*/ 369 std r5,(SIGCONTEXT_V_REGS_PTR)(r3) 370 371 addi r5,r3,UCONTEXT_SIGMASK 372 li r4,0 373 li r3,SIG_BLOCK 374 bl JUMPTARGET(__sigprocmask) 375 nop 376 377 ld r0,128+FRAME_LR_SAVE(r1) 378 addi r1,r1,128 379 mtlr r0 380 blr 381PSEUDO_END(__getcontext) 382 383versioned_symbol (libc, __getcontext, getcontext, GLIBC_2_3_4) 384