|
|
1.1 root 1: /*
2: * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
3: *
4: * @APPLE_LICENSE_HEADER_START@
5: *
6: * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
7: * Reserved. This file contains Original Code and/or Modifications of
8: * Original Code as defined in and that are subject to the Apple Public
9: * Source License Version 1.1 (the "License"). You may not use this file
10: * except in compliance with the License. Please obtain a copy of the
11: * License at http://www.apple.com/publicsource and read it before using
12: * this file.
13: *
14: * The Original Code and all software distributed under the License are
15: * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
18: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
19: * License for the specific language governing rights and limitations
20: * under the License.
21: *
22: * @APPLE_LICENSE_HEADER_END@
23: */
24:
25: /*
26: * Copyright (c) 1992 NeXT, Inc.
27: *
28: * HISTORY
29: * 13 May 1992 ? at NeXT
30: * Created.
31: */
32:
33: #import <mach/mach_types.h>
34: #import <mach/exception.h>
35:
36: #import <sys/param.h>
37: #import <sys/proc.h>
38: #import <sys/user.h>
39:
40: #import <i386/psl.h>
41:
42: #import <machdep/i386/sel_inline.h>
43:
44: #import <pc_support.h>
45: #if PC_SUPPORT
46: #import <machdep/i386/pc_support/PCmiscInline.h>
47: #endif
48:
49: /*
50: * Send an interrupt to process.
51: *
52: * Stack is set up to allow sigcode stored
53: * in u. to call routine, followed by chmk
54: * to sigreturn routine below. After sigreturn
55: * resets the signal mask, the stack, the frame
56: * pointer, and the argument pointer, it returns
57: * to the user specified pc, psl.
58: */
59:
60: void
61: sendsig(p, catcher, sig, mask, code)
62: struct proc *p;
63: sig_t catcher;
64: int sig, mask;
65: u_long code;
66: {
67: struct sigframe {
68: int sig;
69: int code;
70: struct sigcontext * scp;
71: } frame, *fp;
72: struct sigcontext context, *scp;
73: struct sigacts *ps = p->p_sigacts;
74: int oonstack;
75: thread_t thread = current_thread();
76: thread_saved_state_t * saved_state = USER_REGS(thread);
77:
78: oonstack = ps->ps_sigstk.ss_flags & SA_ONSTACK;
79: if ((ps->ps_flags & SAS_ALTSTACK) && !oonstack &&
80: (ps->ps_sigonstack & sigmask(sig))) {
81: scp = (struct sigcontext *)(ps->ps_sigstk.ss_sp - 1);
82: ps->ps_sigstk.ss_flags |= SA_ONSTACK;
83: } else
84: scp = (struct sigcontext *)saved_state->frame.esp - 1;
85: fp = (struct sigframe *)scp - 1;
86:
87: /*
88: * Build the argument list for the signal handler.
89: */
90: frame.sig = sig;
91: if (sig == SIGILL || sig == SIGFPE) {
92: frame.code = code;
93: } else
94: frame.code = 0;
95: frame.scp = scp;
96: if (copyout((caddr_t)&frame, (caddr_t)fp, sizeof (frame)))
97: goto bad;
98: #if PC_SUPPORT
99: {
100: PCcontext_t context = threadPCContext(thread);
101:
102: if (context && context->running) {
103: oonstack |= 02;
104: context->running = FALSE;
105: }
106: }
107: #endif
108: /*
109: * Build the signal context to be used by sigreturn.
110: */
111: context.sc_onstack = oonstack;
112: context.sc_mask = mask;
113: context.sc_eax = saved_state->regs.eax;
114: context.sc_ebx = saved_state->regs.ebx;
115: context.sc_ecx = saved_state->regs.ecx;
116: context.sc_edx = saved_state->regs.edx;
117: context.sc_edi = saved_state->regs.edi;
118: context.sc_esi = saved_state->regs.esi;
119: context.sc_ebp = saved_state->regs.ebp;
120: context.sc_esp = saved_state->frame.esp;
121: context.sc_ss = sel_to_selector(saved_state->frame.ss);
122: context.sc_eflags = saved_state->frame.eflags;
123: context.sc_eip = saved_state->frame.eip;
124: context.sc_cs = sel_to_selector(saved_state->frame.cs);
125: if (saved_state->frame.eflags & EFL_VM) {
126: context.sc_ds = saved_state->frame.v_ds;
127: context.sc_es = saved_state->frame.v_es;
128: context.sc_fs = saved_state->frame.v_fs;
129: context.sc_gs = saved_state->frame.v_gs;
130:
131: saved_state->frame.eflags &= ~EFL_VM;
132: }
133: else {
134: context.sc_ds = sel_to_selector(saved_state->regs.ds);
135: context.sc_es = sel_to_selector(saved_state->regs.es);
136: context.sc_fs = sel_to_selector(saved_state->regs.fs);
137: context.sc_gs = sel_to_selector(saved_state->regs.gs);
138: }
139: if (copyout((caddr_t)&context, (caddr_t)scp, sizeof (context)))
140: goto bad;
141: saved_state->frame.eip = (unsigned int)catcher;
142: saved_state->frame.cs = UCODE_SEL;
143:
144: saved_state->frame.esp = (unsigned int)fp;
145: saved_state->frame.ss = UDATA_SEL;
146:
147: saved_state->regs.ds = UDATA_SEL;
148: saved_state->regs.es = UDATA_SEL;
149: saved_state->regs.fs = NULL_SEL;
150: saved_state->regs.gs = NULL_SEL;
151: return;
152:
153: bad:
154: SIGACTION(p, SIGILL) = SIG_DFL;
155: sig = sigmask(SIGILL);
156: p->p_sigignore &= ~sig;
157: p->p_sigcatch &= ~sig;
158: p->p_sigmask &= ~sig;
159: psignal(p, SIGILL);
160: return;
161: }
162:
163: /*
164: * System call to cleanup state after a signal
165: * has been taken. Reset signal mask and
166: * stack state from context left by sendsig (above).
167: * Return to previous pc and psl as specified by
168: * context left by sendsig. Check carefully to
169: * make sure that the user has not modified the
170: * psl to gain improper priviledges or to cause
171: * a machine fault.
172: */
173: struct sigreturn_args {
174: struct sigcontext *sigcntxp;
175: };
176: /* ARGSUSED */
177: int
178: sigreturn(p, uap, retval)
179: struct proc *p;
180: struct sigreturn_args *uap;
181: int *retval;
182: {
183: struct sigcontext context;
184: thread_t thread = current_thread();
185: int error;
186: thread_saved_state_t * saved_state = USER_REGS(thread);
187:
188: if (error = copyin((caddr_t)uap->sigcntxp, (caddr_t)&context,
189: sizeof (context)))
190: return(error);
191: if ((context.sc_eflags & EFL_VM) == 0 &&
192: (!valid_user_code_selector(context.sc_cs) ||
193: !valid_user_data_selector(context.sc_ds) ||
194: !valid_user_data_selector(context.sc_es) ||
195: !valid_user_data_selector(context.sc_fs) ||
196: !valid_user_data_selector(context.sc_gs) ||
197: !valid_user_stack_selector(context.sc_ss))
198: )
199: return(EINVAL);
200:
201: if (context.sc_onstack & 01)
202: p->p_sigacts->ps_sigstk.ss_flags |= SA_ONSTACK;
203: else
204: p->p_sigacts->ps_sigstk.ss_flags &= ~SA_ONSTACK;
205: p->p_sigmask = context.sc_mask &~ sigcantmask;
206: saved_state->regs.eax = context.sc_eax;
207: saved_state->regs.ebx = context.sc_ebx;
208: saved_state->regs.ecx = context.sc_ecx;
209: saved_state->regs.edx = context.sc_edx;
210: saved_state->regs.edi = context.sc_edi;
211: saved_state->regs.esi = context.sc_esi;
212: saved_state->regs.ebp = context.sc_ebp;
213: saved_state->frame.esp = context.sc_esp;
214: saved_state->frame.ss = selector_to_sel(context.sc_ss);
215: saved_state->frame.eflags = context.sc_eflags;
216: saved_state->frame.eflags &= ~EFL_USERCLR;
217: saved_state->frame.eflags |= EFL_USERSET;
218: saved_state->frame.eip = context.sc_eip;
219: saved_state->frame.cs = selector_to_sel(context.sc_cs);
220: if (context.sc_eflags & EFL_VM) {
221: saved_state->regs.ds = NULL_SEL;
222: saved_state->regs.es = NULL_SEL;
223: saved_state->regs.fs = NULL_SEL;
224: saved_state->regs.gs = NULL_SEL;
225: saved_state->frame.v_ds = context.sc_ds;
226: saved_state->frame.v_es = context.sc_es;
227: saved_state->frame.v_fs = context.sc_fs;
228: saved_state->frame.v_gs = context.sc_gs;
229:
230: saved_state->frame.eflags |= EFL_VM;
231: }
232: else {
233: saved_state->regs.ds = selector_to_sel(context.sc_ds);
234: saved_state->regs.es = selector_to_sel(context.sc_es);
235: saved_state->regs.fs = selector_to_sel(context.sc_fs);
236: saved_state->regs.gs = selector_to_sel(context.sc_gs);
237: }
238: #if PC_SUPPORT
239: if (context.sc_onstack & 02) {
240: PCcontext_t context = threadPCContext(thread);
241:
242: if (context)
243: context->running = TRUE;
244: }
245: #endif
246: return (EJUSTRETURN);
247: }
248:
249: /*
250: * machine_exception() performs MD translation
251: * of a mach exception to a unix signal and code.
252: */
253:
254: boolean_t
255: machine_exception(
256: int exception,
257: int code,
258: int subcode,
259: int *unix_signal,
260: int *unix_code
261: )
262: {
263: switch(exception) {
264:
265: case EXC_BAD_INSTRUCTION:
266: *unix_signal = SIGILL;
267: *unix_code = code;
268: break;
269:
270: case EXC_ARITHMETIC:
271: *unix_signal = SIGFPE;
272: *unix_code = code;
273: break;
274:
275: default:
276: return(FALSE);
277: }
278:
279: return(TRUE);
280: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.