1 | /* Save current 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 | #include "ucontext_i.h" |
23 | #include "ucontext-internal.h" |
24 | |
25 | /* int getcontext (ucontext_t *ucp) |
26 | |
27 | Returns 0 on success -1 and errno on failure. |
28 | */ |
29 | |
30 | .text |
31 | |
32 | ENTRY(__getcontext) |
33 | PTR_ARG (0) |
34 | /* The saved context will return to the getcontext() call point |
35 | with a return value of 0 */ |
36 | str xzr, [x0, oX0 + 0 * SZREG] |
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 | |
46 | /* Place LR into the saved PC, this will ensure that when |
47 | switching to this saved context with setcontext() control |
48 | will pass back to the caller of getcontext(), we have |
49 | already arrange to return the appropriate return value in x0 |
50 | above. */ |
51 | str x30, [x0, oPC] |
52 | |
53 | /* Save the current SP */ |
54 | mov x2, sp |
55 | str x2, [x0, oSP] |
56 | |
57 | /* Initialize the pstate. */ |
58 | str xzr, [x0, oPSTATE] |
59 | |
60 | /* Figure out where to place the first context extension |
61 | block. */ |
62 | add x2, x0, #oEXTENSION |
63 | |
64 | /* Write the context extension fpsimd header. */ |
65 | mov w3, #(FPSIMD_MAGIC & 0xffff) |
66 | movk w3, #(FPSIMD_MAGIC >> 16), lsl #16 |
67 | str w3, [x2, #oHEAD + oMAGIC] |
68 | mov w3, #FPSIMD_CONTEXT_SIZE |
69 | str w3, [x2, #oHEAD + oSIZE] |
70 | |
71 | /* Fill in the FP SIMD context. */ |
72 | add x3, x2, #oV0 + 8 * SZVREG |
73 | stp q8, q9, [x3], # 2 * SZVREG |
74 | stp q10, q11, [x3], # 2 * SZVREG |
75 | stp q12, q13, [x3], # 2 * SZVREG |
76 | stp q14, q15, [x3], # 2 * SZVREG |
77 | |
78 | add x3, x2, oFPSR |
79 | |
80 | mrs x4, fpsr |
81 | str w4, [x3] |
82 | |
83 | mrs x4, fpcr |
84 | str w4, [x3, oFPCR - oFPSR] |
85 | |
86 | /* Write the termination context extension header. */ |
87 | add x2, x2, #FPSIMD_CONTEXT_SIZE |
88 | |
89 | str xzr, [x2, #oHEAD + oMAGIC] |
90 | str xzr, [x2, #oHEAD + oSIZE] |
91 | |
92 | /* Grab the signal mask */ |
93 | /* rt_sigprocmask (SIG_BLOCK, NULL, &ucp->uc_sigmask, _NSIG8) */ |
94 | add PTR_REG (2), PTR_REG (0), #UCONTEXT_SIGMASK |
95 | mov x0, SIG_BLOCK |
96 | mov x1, 0 |
97 | mov x3, _NSIG8 |
98 | mov x8, SYS_ify (rt_sigprocmask) |
99 | svc 0 |
100 | cbnz x0, 1f |
101 | |
102 | /* Return 0 for success */ |
103 | mov x0, 0 |
104 | RET |
105 | 1: |
106 | b C_SYMBOL_NAME(__syscall_error) |
107 | |
108 | PSEUDO_END (__getcontext) |
109 | weak_alias (__getcontext, getcontext) |
110 | |