1 | /* Set current context. |
2 | Copyright (C) 2009-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 | #include "ucontext-macros.h" |
20 | |
21 | /* int __setcontext (const ucontext_t *ucp) |
22 | |
23 | Restores the machine context in UCP and thereby resumes execution |
24 | in that context. |
25 | |
26 | This implementation is intended to be used for *synchronous* context |
27 | switches only. Therefore, it does not have to restore anything |
28 | other than the PRESERVED state. */ |
29 | |
30 | .text |
31 | LEAF (__setcontext) |
32 | |
33 | mv t0, a0 /* Save ucp into t0. */ |
34 | |
35 | /* rt_sigprocmask (SIG_SETMASK, &ucp->uc_sigmask, NULL, _NSIG8) */ |
36 | li a3, _NSIG8 |
37 | mv a2, zero |
38 | add a1, a0, UCONTEXT_SIGMASK |
39 | li a0, SIG_SETMASK |
40 | |
41 | li a7, SYS_ify (rt_sigprocmask) |
42 | scall |
43 | |
44 | bltz a0, 99f |
45 | |
46 | cfi_def_cfa (t0, 0) |
47 | |
48 | #ifndef __riscv_float_abi_soft |
49 | lw t1, MCONTEXT_FSR(t0) |
50 | |
51 | RESTORE_FP_REG_CFI (fs0, 8, t0) |
52 | RESTORE_FP_REG_CFI (fs1, 9, t0) |
53 | RESTORE_FP_REG_CFI (fs2, 18, t0) |
54 | RESTORE_FP_REG_CFI (fs3, 19, t0) |
55 | RESTORE_FP_REG_CFI (fs4, 20, t0) |
56 | RESTORE_FP_REG_CFI (fs5, 21, t0) |
57 | RESTORE_FP_REG_CFI (fs6, 22, t0) |
58 | RESTORE_FP_REG_CFI (fs7, 23, t0) |
59 | RESTORE_FP_REG_CFI (fs8, 24, t0) |
60 | RESTORE_FP_REG_CFI (fs9, 25, t0) |
61 | RESTORE_FP_REG_CFI (fs10, 26, t0) |
62 | RESTORE_FP_REG_CFI (fs11, 27, t0) |
63 | |
64 | fssr t1 |
65 | #endif /* __riscv_float_abi_soft */ |
66 | |
67 | /* Note the contents of argument registers will be random |
68 | unless makecontext() has been called. */ |
69 | RESTORE_INT_REG (t1, 0, t0) |
70 | RESTORE_INT_REG_CFI (ra, 1, t0) |
71 | RESTORE_INT_REG (sp, 2, t0) |
72 | RESTORE_INT_REG_CFI (s0, 8, t0) |
73 | RESTORE_INT_REG_CFI (s1, 9, t0) |
74 | RESTORE_INT_REG (a0, 10, t0) |
75 | RESTORE_INT_REG (a1, 11, t0) |
76 | RESTORE_INT_REG (a2, 12, t0) |
77 | RESTORE_INT_REG (a3, 13, t0) |
78 | RESTORE_INT_REG (a4, 14, t0) |
79 | RESTORE_INT_REG (a5, 15, t0) |
80 | RESTORE_INT_REG (a6, 16, t0) |
81 | RESTORE_INT_REG (a7, 17, t0) |
82 | RESTORE_INT_REG_CFI (s2, 18, t0) |
83 | RESTORE_INT_REG_CFI (s3, 19, t0) |
84 | RESTORE_INT_REG_CFI (s4, 20, t0) |
85 | RESTORE_INT_REG_CFI (s5, 21, t0) |
86 | RESTORE_INT_REG_CFI (s6, 22, t0) |
87 | RESTORE_INT_REG_CFI (s7, 23, t0) |
88 | RESTORE_INT_REG_CFI (s8, 24, t0) |
89 | RESTORE_INT_REG_CFI (s9, 25, t0) |
90 | RESTORE_INT_REG_CFI (s10, 26, t0) |
91 | RESTORE_INT_REG_CFI (s11, 27, t0) |
92 | |
93 | jr t1 |
94 | |
95 | 99: j __syscall_error |
96 | |
97 | END (__setcontext) |
98 | libc_hidden_def (__setcontext) |
99 | weak_alias (__setcontext, setcontext) |
100 | |
101 | LEAF (__start_context) |
102 | |
103 | /* Terminate call stack by noting ra == 0. Happily, s0 == 0 here. */ |
104 | cfi_register (ra, s0) |
105 | |
106 | /* Call the function passed to makecontext. */ |
107 | jalr s1 |
108 | |
109 | /* Invoke subsequent context if present, else exit(0). */ |
110 | mv a0, s2 |
111 | beqz s2, 1f |
112 | jal HIDDEN_JUMPTARGET (__setcontext) |
113 | 1: j HIDDEN_JUMPTARGET (exit) |
114 | |
115 | END (__start_context) |
116 | |