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