1/* Modify saved context. 2 3 Copyright (C) 2009-2022 Free Software Foundation, Inc. 4 5 This file is part of the GNU C Library. 6 7 The GNU C Library is free software; you can redistribute it and/or 8 modify it under the terms of the GNU Lesser General Public License as 9 published by the Free Software Foundation; either version 2.1 of the 10 License, or (at your option) any later version. 11 12 The GNU C Library is distributed in the hope that it will be useful, 13 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 Lesser General Public License for more details. 16 17 You should have received a copy of the GNU Lesser General Public 18 License along with the GNU C Library; if not, see 19 <https://www.gnu.org/licenses/>. */ 20 21#include <sysdep.h> 22 23#include "ucontext_i.h" 24#include "ucontext-internal.h" 25 26/* int swapcontext (ucontext_t *oucp, const ucontext_t *ucp) */ 27 28 .text 29ENTRY(__swapcontext) 30 PTR_ARG (0) 31 /* Set the value returned when swapcontext() returns in this context. 32 And set up x1 to become the return address of the caller, so we 33 can return there with a normal RET instead of an indirect jump. */ 34 stp xzr, x30, [x0, oX0 + 0 * SZREG] 35 /* Arrange the oucp context to return to 2f. */ 36 adr x30, 2f 37 38 stp x18, x19, [x0, oX0 + 18 * SZREG] 39 stp x20, x21, [x0, oX0 + 20 * SZREG] 40 stp x22, x23, [x0, oX0 + 22 * SZREG] 41 stp x24, x25, [x0, oX0 + 24 * SZREG] 42 stp x26, x27, [x0, oX0 + 26 * SZREG] 43 stp x28, x29, [x0, oX0 + 28 * SZREG] 44 str x30, [x0, oX0 + 30 * SZREG] 45 str x30, [x0, oPC] 46 mov x2, sp 47 str x2, [x0, oSP] 48 49 /* Figure out where to place the first context extension 50 block. */ 51 add x2, x0, #oEXTENSION 52 53 /* Write the context extension fpsimd header. */ 54 mov w3, #(FPSIMD_MAGIC & 0xffff) 55 movk w3, #(FPSIMD_MAGIC >> 16), lsl #16 56 str w3, [x2, #oHEAD + oMAGIC] 57 mov w3, #FPSIMD_CONTEXT_SIZE 58 str w3, [x2, #oHEAD + oSIZE] 59 60 /* Fill in the FP SIMD context. */ 61 add x3, x2, #oV0 + 8 * SZVREG 62 stp q8, q9, [x3], #2 * SZVREG 63 stp q10, q11, [x3], #2 * SZVREG 64 stp q12, q13, [x3], #2 * SZVREG 65 stp q14, q15, [x3], #2 * SZVREG 66 67 add x3, x2, #oFPSR 68 69 mrs x4, fpsr 70 str w4, [x3, #oFPSR - oFPSR] 71 72 mrs x4, fpcr 73 str w4, [x3, #oFPCR - oFPSR] 74 75 /* Write the termination context extension header. */ 76 add x2, x2, #FPSIMD_CONTEXT_SIZE 77 78 str xzr, [x2, #oHEAD + oMAGIC] 79 str xzr, [x2, #oHEAD + oSIZE] 80 81 /* Preserve ucp. */ 82 mov x21, x1 83 84 /* rt_sigprocmask (SIG_SETMASK, &ucp->uc_sigmask, &oucp->uc_sigmask, 85 _NSIG8) */ 86 /* Grab the signal mask */ 87 /* rt_sigprocmask (SIG_BLOCK, NULL, &ucp->uc_sigmask, _NSIG8) */ 88 add x2, x0, #UCONTEXT_SIGMASK 89 mov x0, SIG_BLOCK 90 mov x1, 0 91 mov x3, _NSIG8 92 mov x8, SYS_ify (rt_sigprocmask) 93 svc 0 94 cbnz x0, 1f 95 96 mov x22, x30 97 mov x0, x21 98 bl JUMPTARGET (__setcontext) 99 mov x30, x22 100 RET 101 1021: 103 b C_SYMBOL_NAME(__syscall_error) 1042: 105 /* The oucp context is restored here via an indirect branch, 106 x1 must be restored too which has the real return address. */ 107 BTI_J 108 mov x30, x1 109 RET 110PSEUDO_END (__swapcontext) 111weak_alias (__swapcontext, swapcontext) 112