|
|
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) 1993 NeXT, Inc.
27: *
28: * HISTORY
29: * 23 Aug 93 Mac Gillon 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 <ppc/signal.h>
41: #import <sys/signalvar.h>
42: #import <kern/thread.h>
43: #import <mach/ppc/thread_status.h>
44: #import <machdep/ppc/proc_reg.h>
45: #import <machdep/ppc/fpu.h>
46:
47: #define C_REDZONE_LEN 224
48: #define C_STK_ALIGN 16
49: #define C_PARAMSAVE_LEN 64
50: #define C_LINKAGE_LEN 48
51: #define TRUNC_DOWN(a,b,c) (((((unsigned)a)-(b))/(c)) * (c))
52: #define NBITS (MASK(MSR_POW)|MASK(MSR_ILE)|MASK(MSR_IP)|MASK(MSR_LE))
53: #define RBITS (MASK(MSR_PR)|MASK(MSR_ME)|MASK(MSR_IR)|MASK(MSR_DR)|MASK(MSR_EE))
54:
55:
56: /*
57: * Arrange for this process to run a signal handler
58: */
59:
60:
61: struct sigregs {
62: struct ppc_saved_state ss;
63: struct ppc_float_state fs;
64: };
65:
66: void
67: sendsig(p, catcher, sig, mask, code)
68: struct proc *p;
69: sig_t catcher;
70: int sig, mask;
71: u_long code;
72: {
73: struct sigregs *p_regs;
74: struct sigcontext context, *p_context;
75: struct sigacts *ps = p->p_sigacts;
76: int framesize;
77: int oonstack;
78: unsigned long sp;
79: struct ppc_saved_state *statep;
80: struct thread *thread;
81: unsigned long paramp,linkp;
82:
83: thread = current_thread();
84:
85: statep = &(thread->pcb->ss);
86:
87: oonstack = ps->ps_sigstk.ss_flags & SA_ONSTACK;
88:
89: /* figure out where our new stack lives */
90: if ((ps->ps_flags & SAS_ALTSTACK) && !oonstack &&
91: (ps->ps_sigonstack & sigmask(sig))) {
92: sp = (unsigned long)(ps->ps_sigstk.ss_sp);
93: ps->ps_sigstk.ss_flags |= SA_ONSTACK;
94: }
95: else
96: sp = statep->r1;
97:
98: // preserve RED ZONE area
99: sp = TRUNC_DOWN(sp, C_REDZONE_LEN, C_STK_ALIGN);
100:
101: // context goes first on stack
102: sp -= sizeof(*p_context);
103: p_context = (struct sigcontext *) sp;
104:
105: // next are the saved registers
106: sp -= sizeof(*p_regs);
107: p_regs = (struct sigregs *)sp;
108:
109: // C calling conventions, create param save and linkage
110: // areas
111:
112: sp = TRUNC_DOWN(sp, C_PARAMSAVE_LEN, C_STK_ALIGN);
113: paramp = sp;
114: sp -= C_LINKAGE_LEN;
115: linkp = sp;
116:
117: /* flush fpu registers to pcb */
118: fp_state_save(thread);
119:
120: /* fill out sigcontext */
121: context.sc_onstack = oonstack;
122: context.sc_mask = mask;
123: context.sc_ir = statep->srr0;
124: context.sc_psw = statep->srr1;
125: context.sc_regs = p_regs;
126:
127: /* copy info out to user space */
128: if (copyout((caddr_t)&context, (caddr_t)p_context, sizeof(context)))
129: goto bad;
130: if (copyout((caddr_t)statep, (caddr_t)&p_regs->ss,
131: sizeof(struct ppc_saved_state)))
132: goto bad;
133: if (copyout((caddr_t)&thread->pcb->fs, (caddr_t)&p_regs->fs,
134: sizeof(struct ppc_float_state)))
135: goto bad;
136:
137: /* Place our arguments in arg registers: rtm dependent */
138:
139: statep->r3 = (unsigned long)sig;
140: statep->r4 = (unsigned long)code;
141: statep->r5 = (unsigned long)p_context;
142:
143: statep->srr0 = (unsigned long)catcher;
144: statep->srr1 = MSR_EXPORT_MASK_SET;
145: statep->r1 = sp;
146:
147: return;
148:
149: bad:
150: SIGACTION(p, SIGILL) = SIG_DFL;
151: sig = sigmask(SIGILL);
152: p->p_sigignore &= ~sig;
153: p->p_sigcatch &= ~sig;
154: p->p_sigmask &= ~sig;
155: psignal(p, SIGILL);
156: return;
157: }
158:
159: /*
160: * System call to cleanup state after a signal
161: * has been taken. Reset signal mask and
162: * stack state from context left by sendsig (above).
163: * Return to previous pc and psl as specified by
164: * context left by sendsig. Check carefully to
165: * make sure that the user has not modified the
166: * psl to gain improper priviledges or to cause
167: * a machine fault.
168: */
169: struct sigreturn_args {
170: struct sigcontext *sigcntxp;
171: };
172:
173: /* ARGSUSED */
174: int
175: sigreturn(p, uap, retval)
176: struct proc *p;
177: struct sigreturn_args *uap;
178: int *retval;
179: {
180: struct sigcontext context;
181: struct sigregs *p_regs;
182: int error;
183: struct thread *thread;
184:
185: thread = current_thread();
186:
187: if (error = copyin(uap->sigcntxp, &context, sizeof(context))) {
188: return(error);
189: }
190:
191: /* adjust the critical fields */
192: /* make sure naughty bits are off */
193: context.sc_psw &= ~(NBITS);
194: /* make sure necessary bits are on */
195: context.sc_psw |= (RBITS);
196:
197: // /* we return from sigreturns as if we faulted in */
198: // entry->es_flags = (entry->es_flags & ~ES_GATEWAY) | ES_TRAP;
199:
200: if (context.sc_regs) {
201: p_regs = (struct sigregs *)context.sc_regs;
202: if (error = copyin(&p_regs->ss, &thread->pcb->ss,
203: sizeof(struct ppc_saved_state)))
204: return(error);
205:
206: if (error = copyin(&p_regs->fs, &thread->pcb->fs,
207: sizeof(struct ppc_float_state)))
208: return(error);
209:
210: }
211: else {
212: thread->pcb->ss.r1 = context.sc_sp;
213: }
214: // entry->es_general.saved.stack_pointer = context.sc_sp;
215:
216: if (context.sc_onstack & 01)
217: p->p_sigacts->ps_sigstk.ss_flags |= SA_ONSTACK;
218: else
219: p->p_sigacts->ps_sigstk.ss_flags &= ~SA_ONSTACK;
220: p->p_sigmask = context.sc_mask &~ sigcantmask;
221: thread->pcb->ss.srr0 = context.sc_ir;
222: thread->pcb->ss.srr1 = context.sc_psw;
223:
224: return (EJUSTRETURN);
225: }
226:
227: /*
228: * machine_exception() performs MD translation
229: * of a mach exception to a unix signal and code.
230: */
231:
232: boolean_t
233: machine_exception(
234: int exception,
235: int code,
236: int subcode,
237: int *unix_signal,
238: int *unix_code
239: )
240: {
241: switch(exception) {
242:
243: case EXC_BAD_INSTRUCTION:
244: *unix_signal = SIGILL;
245: *unix_code = code;
246: break;
247:
248: case EXC_ARITHMETIC:
249: *unix_signal = SIGFPE;
250: *unix_code = code;
251: break;
252:
253: default:
254: return(FALSE);
255: }
256:
257: return(TRUE);
258: }
259:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.