1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
7 * with the License.
8 *
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 */
22 /* Copyright (c) 1988 AT&T */
23 /* All Rights Reserved */
24
25
26 /*
27 * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
28 * Use is subject to license terms.
29 */
30
31 #pragma ident "%Z%%M% %I% %E% SMI"
32
33
34 #include <sys/setjmp.h>
35 #include "ucontext.h"
36
37 int _getsp();
38
39 int
sigsetjmp(env,savemask)40 sigsetjmp(env, savemask)
41 sigjmp_buf env;
42 int savemask;
43 {
44 register o_setjmp_struct_t *bp = (o_setjmp_struct_t *)env;
45 register int sp = _getsp();
46 ucontext_t uc;
47
48 /*
49 * Get the current machine context.
50 */
51 uc.uc_flags = UC_STACK | UC_SIGMASK;
52 __getcontext(&uc);
53
54 /*
55 * Note that the pc and former sp (fp) from the stack are valid
56 * because the call to __getcontext must flush the user windows
57 * to the stack.
58 */
59 bp->sjs_flags = 0;
60 bp->sjs_sp = *((int *)sp+14);
61 bp->sjs_pc = *((int *)sp+15) + 0x8;
62 bp->sjs_stack = uc.uc_stack;
63
64 if (savemask) {
65 /* save the mask */
66 bp->sjs_flags |= JB_SAVEMASK;
67 memcpy(bp->sjs_sigmask, &(uc.uc_sigmask), 3 * sizeof (int));
68 } else {
69 memset(bp->sjs_sigmask, 0, 3 * sizeof (int));
70 }
71
72 return (0);
73 }
74
75
76 void
siglongjmp(env,val)77 siglongjmp(env, val)
78 sigjmp_buf env;
79 int val;
80 {
81 o_setjmp_struct_t *bp = (o_setjmp_struct_t *)env;
82 setjmp_struct_t sjmp, *sp;
83
84 sp = &sjmp;
85 sp->sjs_flags = bp->sjs_flags;
86 sp->sjs_sp = bp->sjs_sp;
87 sp->sjs_pc = bp->sjs_pc;
88 sp->sjs_fp = 0;
89 sp->sjs_i7 = 0;
90 sp->sjs_uclink = 0;
91 sp->sjs_sigmask[0] = bp->sjs_sigmask[0];
92 sp->sjs_sigmask[1] = bp->sjs_sigmask[1];
93 sp->sjs_sigmask[2] = bp->sjs_sigmask[2];
94 sp->sjs_sigmask[3] = 0;
95 sp->sjs_stack = bp->sjs_stack;
96
97 _siglongjmp(sjmp, val);
98 }
99
100 int
_setjmp(env)101 _setjmp(env)
102 jmp_buf env;
103 {
104 register o_setjmp_struct_t *bp = (o_setjmp_struct_t *)env;
105 register int sp = _getsp();
106 ucontext_t uc;
107
108 /*
109 * Get the current machine context.
110 */
111 uc.uc_flags = UC_STACK;
112 __getcontext(&uc);
113
114 /*
115 * Note that the pc and former sp (fp) from the stack are valid
116 * because the call to __getcontext must flush the user windows
117 * to the stack.
118 */
119 bp->sjs_flags = 0;
120 bp->sjs_sp = *((int *)sp+14);
121 bp->sjs_pc = *((int *)sp+15) + 0x8;
122 bp->sjs_sigmask[0] = 0;
123 bp->sjs_sigmask[1] = 0;
124 bp->sjs_sigmask[2] = 0;
125 bp->sjs_stack = uc.uc_stack;
126
127 return (0);
128 }
129
130
131 void
_longjmp(env,val)132 _longjmp(env, val)
133 jmp_buf env;
134 int val;
135 {
136 o_setjmp_struct_t *bp = (o_setjmp_struct_t *)env;
137 setjmp_struct_t sjmp, *sp;
138
139 sp = &sjmp;
140 sp->sjs_flags = bp->sjs_flags;
141 sp->sjs_sp = bp->sjs_sp;
142 sp->sjs_pc = bp->sjs_pc;
143 sp->sjs_fp = 0;
144 sp->sjs_i7 = 0;
145 sp->sjs_uclink = 0;
146 sp->sjs_sigmask[0] = bp->sjs_sigmask[0];
147 sp->sjs_sigmask[1] = bp->sjs_sigmask[1];
148 sp->sjs_sigmask[2] = bp->sjs_sigmask[2];
149 sp->sjs_sigmask[3] = 0;
150 sp->sjs_stack = bp->sjs_stack;
151
152 _siglongjmp(sjmp, val);
153 }
154