7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 */
26
27 .file "getcontext.s"
28
29 #include <sys/asm_linkage.h>
30
31 ANSI_PRAGMA_WEAK(getcontext,function)
32 ANSI_PRAGMA_WEAK(swapcontext,function)
33
34 #include "SYS.h"
35 #include <assym.h>
36
37 /*
38 * getcontext() and swapcontext() are written in assembler since it has to
39 * capture the correct machine state of the caller, including
40 * the registers: %edi, %esi and %ebx.
41 *
42 * As swapcontext() is actually equivalent to getcontext() + setcontext(),
43 * swapcontext() shares the most code with getcontext().
44 */
45
46
47 #define GETCONTEXT_IMPL \
48 movl 4(%esp), %eax; /* %eax <-- first arg: ucp */ \
49 pushl %eax; /* push ucp for system call */ \
50 call __getcontext; /* call getcontext: syscall */ \
51 addl $4, %esp; /* pop arg */ \
52 andl %eax, %eax; /* if (err_ret_from_syscall) */ \
53 je 1f; \
54 ret; /* then return */ \
55 1: \
56 movl 4(%esp), %eax; /* recompute first arg */ \
57 /* \
58 * fix up %esp and %eip \
59 */ \
60 leal UC_MCONTEXT_GREGS (%eax), %edx; \
61 /* %edx <-- &ucp->uc_mcontext.gregs */ \
62 movl 0(%esp), %eax; /* read return PC from stack */ \
63 movl %eax, EIP_OFF (%edx); \
64 /* store ret PC in EIP of env var */ \
65 leal 4(%esp), %eax; /* get caller's sp at time of call */ \
66 movl %eax, UESP_OFF (%edx); \
67 /* store the sp into UESP of env var */ \
68 xorl %eax, %eax; /* return 0 */ \
69 movl %eax, EAX_OFF (%edx); \
70 /* getcontext returns 0 after a setcontext */
71
72 /*
73 * getcontext(ucontext_t *ucp)
74 */
75 ENTRY(getcontext)
76 GETCONTEXT_IMPL
77 ret
78 SET_SIZE(getcontext)
79
80
81 /*
82 * swapcontext(ucontext_t *oucp, const ucontext_t *ucp)
83 */
84 ENTRY(swapcontext)
85 GETCONTEXT_IMPL
86 / call setcontext
87 movl 8(%esp), %eax /* %eax <-- second arg: ucp */
88 pushl %eax /* push ucp for setcontext */
89 call setcontext
90 addl $4, %esp /* pop arg: just in case */
91 ret
92 SET_SIZE(swapcontext)
|
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 */
26
27 /*
28 * Copyright 2023 Oxide Computer Company
29 */
30
31 .file "getcontext.s"
32
33 #include <sys/asm_linkage.h>
34
35 ANSI_PRAGMA_WEAK(getcontext,function)
36 ANSI_PRAGMA_WEAK(swapcontext,function)
37
38 #include "SYS.h"
39 #include <assym.h>
40
41 /*
42 * getcontext() and swapcontext() are written in assembler since it has to
43 * capture the correct machine state of the caller, including
44 * the registers: %edi, %esi and %ebx.
45 *
46 * As swapcontext() is actually equivalent to getcontext() + setcontext(),
47 * swapcontext() shares the most code with getcontext().
48 */
49
50
51 #define GETCONTEXT_IMPL(func) \
52 movl 4(%esp), %eax; /* %eax <-- first arg: ucp */ \
53 pushl %eax; /* push ucp for system call */ \
54 call func; /* call getcontext: syscall */ \
55 addl $4, %esp; /* pop arg */ \
56 andl %eax, %eax; /* if (err_ret_from_syscall) */ \
57 je 1f; \
58 ret; /* then return */ \
59 1: \
60 movl 4(%esp), %eax; /* recompute first arg */ \
61 /* \
62 * fix up %esp and %eip \
63 */ \
64 leal UC_MCONTEXT_GREGS (%eax), %edx; \
65 /* %edx <-- &ucp->uc_mcontext.gregs */ \
66 movl 0(%esp), %eax; /* read return PC from stack */ \
67 movl %eax, EIP_OFF (%edx); \
68 /* store ret PC in EIP of env var */ \
69 leal 4(%esp), %eax; /* get caller's sp at time of call */ \
70 movl %eax, UESP_OFF (%edx); \
71 /* store the sp into UESP of env var */ \
72 xorl %eax, %eax; /* return 0 */ \
73 movl %eax, EAX_OFF (%edx); \
74 /* getcontext returns 0 after a setcontext */
75
76 /*
77 * int getcontext(ucontext_t *ucp)
78 */
79 ENTRY(getcontext)
80 GETCONTEXT_IMPL(__getcontext)
81 ret
82 SET_SIZE(getcontext)
83
84
85 /*
86 * int swapcontext(ucontext_t *oucp, const ucontext_t *ucp)
87 */
88 ENTRY(swapcontext)
89 GETCONTEXT_IMPL(__getcontext)
90 /* call setcontext */
91 movl 8(%esp), %eax /* %eax <-- second arg: ucp */
92 pushl %eax /* push ucp for setcontext */
93 call setcontext
94 addl $4, %esp /* pop arg: just in case */
95 ret
96 SET_SIZE(swapcontext)
97
98 /*
99 * int getcontext_extd(ucontext_t *ucp, uint32_t flags)
100 */
101 ENTRY(getcontext_extd)
102 movl 8(%esp), %eax
103 cmpl $0, %eax /* if (flags != 0) */
104 jne 2f
105 GETCONTEXT_IMPL(__getcontext_extd)
106 ret
107 2:
108 movl $EINVAL, %eax /* errno = EINVAL; */
109 jmp __cerror /* return (-1) */
110 SET_SIZE(getcontext_extd)
111
112
113 /*
114 * int swapcontext_extd(ucontext_t *oucp, const ucontext_t *ucp)
115 */
116 ENTRY(swapcontext_extd)
117 movl 8(%esp), %eax
118 cmpl $0, %eax /* if (flags != 0) */
119 jne 2f
120 GETCONTEXT_IMPL(__getcontext_extd)
121 /* call setcontext */
122 movl 12(%esp), %eax /* %eax <-- second arg: ucp */
123 pushl %eax /* push ucp for setcontext */
124 call setcontext
125 addl $4, %esp /* pop arg: just in case */
126 ret
127 2:
128 movl $EINVAL, %eax /* errno = EINVAL; */
129 jmp __cerror /* return (-1) */
130 SET_SIZE(swapcontext_extd)
|