Annotation of sys/arch/m68k/m68k/sig_machdep.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: sig_machdep.c,v 1.18 2006/06/11 20:48:13 miod Exp $ */
2: /* $NetBSD: sig_machdep.c,v 1.3 1997/04/30 23:28:03 gwr Exp $ */
3:
4: /*
5: * Copyright (c) 1997 Theo de Raadt
6: *
7: * Redistribution and use in source and binary forms, with or without
8: * modification, are permitted provided that the following conditions
9: * are met:
10: * 1. Redistributions of source code must retain the above copyright
11: * notice, this list of conditions and the following disclaimer.
12: * 2. Redistributions in binary form must reproduce the above copyright
13: * notice, this list of conditions and the following disclaimer in the
14: * documentation and/or other materials provided with the distribution.
15: *
16: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
17: * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18: * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19: * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
20: * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26: * SUCH DAMAGE.
27: *
28: * Copyright (c) 1988 University of Utah.
29: * Copyright (c) 1982, 1986, 1990, 1993
30: * The Regents of the University of California. All rights reserved.
31: *
32: * This code is derived from software contributed to Berkeley by
33: * the Systems Programming Group of the University of Utah Computer
34: * Science Department.
35: *
36: * Redistribution and use in source and binary forms, with or without
37: * modification, are permitted provided that the following conditions
38: * are met:
39: * 1. Redistributions of source code must retain the above copyright
40: * notice, this list of conditions and the following disclaimer.
41: * 2. Redistributions in binary form must reproduce the above copyright
42: * notice, this list of conditions and the following disclaimer in the
43: * documentation and/or other materials provided with the distribution.
44: * 3. Neither the name of the University nor the names of its contributors
45: * may be used to endorse or promote products derived from this software
46: * without specific prior written permission.
47: *
48: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
49: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
50: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
51: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
52: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
53: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
54: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
55: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
56: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
57: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
58: * SUCH DAMAGE.
59: *
60: * from: Utah Hdr: machdep.c 1.74 92/12/20
61: * from: @(#)machdep.c 8.10 (Berkeley) 4/20/94
62: */
63:
64: #include <sys/param.h>
65: #include <sys/systm.h>
66: #include <sys/kernel.h>
67: #include <sys/proc.h>
68: #include <sys/user.h>
69: #include <sys/exec.h>
70: #include <sys/ioctl.h>
71: #include <sys/mount.h>
72: #include <sys/signal.h>
73: #include <sys/signalvar.h>
74: #include <sys/malloc.h>
75: #include <sys/buf.h>
76:
77: #include <uvm/uvm_extern.h>
78:
79: #include <sys/syscallargs.h>
80:
81: #include <machine/cpu.h>
82: #include <machine/reg.h>
83:
84: extern short exframesize[];
85:
86: #define SS_RTEFRAME 1
87: #define SS_FPSTATE 2
88: #define SS_USERREGS 4
89:
90: struct sigstate {
91: int ss_flags; /* which of the following are valid */
92: struct frame ss_frame; /* original exception frame */
93: struct fpframe ss_fpstate; /* 68881/68882 state info */
94: };
95:
96: /*
97: * WARNING: code in locore.s assumes the layout shown for sf_signum
98: * thru sf_handler so... don't screw with them!
99: */
100: struct sigframe {
101: int sf_signum; /* signo for handler */
102: siginfo_t *sf_sip; /* pointer to siginfo_t */
103: struct sigcontext *sf_scp; /* context ptr for handler */
104: sig_t sf_handler; /* handler addr for u_sigc */
105: struct sigstate sf_state; /* state of the hardware */
106: struct sigcontext sf_sc; /* actual context */
107: siginfo_t sf_si;
108: };
109:
110: #ifdef DEBUG
111: int sigdebug = 0;
112: int sigpid = 0;
113: #define SDB_FOLLOW 0x01
114: #define SDB_KSTACK 0x02
115: #define SDB_FPSTATE 0x04
116: #endif
117:
118: /*
119: * Send an interrupt to process.
120: */
121: void
122: sendsig(catcher, sig, mask, code, type, val)
123: sig_t catcher;
124: int sig, mask;
125: u_long code;
126: int type;
127: union sigval val;
128: {
129: struct proc *p = curproc;
130: struct sigframe *fp, *kfp;
131: struct frame *frame;
132: struct sigacts *psp = p->p_sigacts;
133: short ft;
134: int oonstack, fsize;
135:
136: frame = (struct frame *)p->p_md.md_regs;
137: ft = frame->f_format;
138: oonstack = psp->ps_sigstk.ss_flags & SS_ONSTACK;
139:
140: /*
141: * Allocate and validate space for the signal handler
142: * context. Note that if the stack is in P0 space, the
143: * call to grow() is a nop, and the useracc() check
144: * will fail if the process has not already allocated
145: * the space with a `brk'.
146: */
147: fsize = sizeof(struct sigframe);
148: if ((psp->ps_flags & SAS_ALTSTACK) && !oonstack &&
149: (psp->ps_sigonstack & sigmask(sig))) {
150: fp = (struct sigframe *)(psp->ps_sigstk.ss_sp +
151: psp->ps_sigstk.ss_size - fsize);
152: psp->ps_sigstk.ss_flags |= SS_ONSTACK;
153: } else
154: fp = (struct sigframe *)(frame->f_regs[SP] - fsize);
155: if ((unsigned)fp <= USRSTACK - ctob(p->p_vmspace->vm_ssize))
156: (void)uvm_grow(p, (unsigned)fp);
157: #ifdef DEBUG
158: if ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid)
159: printf("sendsig(%d): sig %d ssp %p usp %p scp %p ft %d\n",
160: p->p_pid, sig, &oonstack, fp, &fp->sf_sc, ft);
161: #endif
162: kfp = (struct sigframe *)malloc((u_long)fsize, M_TEMP,
163: M_WAITOK | M_CANFAIL);
164: if (kfp == NULL) {
165: /* Better halt the process in its track than panicing */
166: sigexit(p, SIGILL);
167: /* NOTREACHED */
168: }
169:
170: /*
171: * Build the argument list for the signal handler.
172: */
173: kfp->sf_signum = sig;
174: kfp->sf_sip = NULL;
175: kfp->sf_scp = &fp->sf_sc;
176: kfp->sf_handler = catcher;
177:
178: /*
179: * Save necessary hardware state. Currently this includes:
180: * - general registers
181: * - original exception frame (if not a "normal" frame)
182: * - FP coprocessor state
183: */
184: kfp->sf_state.ss_flags = SS_USERREGS;
185: bcopy((caddr_t)frame->f_regs,
186: (caddr_t)kfp->sf_state.ss_frame.f_regs, sizeof frame->f_regs);
187: if (ft >= FMT7) {
188: #ifdef DEBUG
189: if (ft > 15 || exframesize[ft] < 0)
190: panic("sendsig: bogus frame type");
191: #endif
192: kfp->sf_state.ss_flags |= SS_RTEFRAME;
193: kfp->sf_state.ss_frame.f_format = frame->f_format;
194: kfp->sf_state.ss_frame.f_vector = frame->f_vector;
195: bcopy((caddr_t)&frame->F_u,
196: (caddr_t)&kfp->sf_state.ss_frame.F_u, exframesize[ft]);
197: /*
198: * Leave an indicator that we need to clean up the kernel
199: * stack. We do this by setting the "pad word" above the
200: * hardware stack frame to the amount the stack must be
201: * adjusted by.
202: *
203: * N.B. we increment rather than just set f_stackadj in
204: * case we are called from syscall when processing a
205: * sigreturn. In that case, f_stackadj may be non-zero.
206: */
207: frame->f_stackadj += exframesize[ft];
208: frame->f_format = frame->f_vector = 0;
209: #ifdef DEBUG
210: if (sigdebug & SDB_FOLLOW)
211: printf("sendsig(%d): copy out %d of frame %d\n",
212: p->p_pid, exframesize[ft], ft);
213: #endif
214: }
215:
216: if (fputype) {
217: kfp->sf_state.ss_flags |= SS_FPSTATE;
218: m68881_save(&kfp->sf_state.ss_fpstate);
219: }
220: #ifdef DEBUG
221: if ((sigdebug & SDB_FPSTATE) && *(char *)&kfp->sf_state.ss_fpstate)
222: printf("sendsig(%d): copy out FP state (%x) to %p\n",
223: p->p_pid, *(u_int *)&kfp->sf_state.ss_fpstate,
224: &kfp->sf_state.ss_fpstate);
225: #endif
226: /*
227: * Build the signal context to be used by sigreturn.
228: */
229: kfp->sf_sc.sc_onstack = oonstack;
230: kfp->sf_sc.sc_mask = mask;
231: kfp->sf_sc.sc_sp = frame->f_regs[SP];
232: kfp->sf_sc.sc_fp = frame->f_regs[A6];
233: kfp->sf_sc.sc_ap = (int)&fp->sf_state;
234: kfp->sf_sc.sc_pc = frame->f_pc;
235: kfp->sf_sc.sc_ps = frame->f_sr;
236:
237: if (psp->ps_siginfo & sigmask(sig)) {
238: kfp->sf_sip = &fp->sf_si;
239: initsiginfo(&kfp->sf_si, sig, code, type, val);
240: }
241:
242: /* XXX do not copy out siginfo if not needed */
243: if (copyout((caddr_t)kfp, (caddr_t)fp, fsize) != 0) {
244: #ifdef DEBUG
245: if ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid)
246: printf("sendsig(%d): copyout failed on sig %d\n",
247: p->p_pid, sig);
248: #endif
249: /*
250: * Process has trashed its stack; give it an illegal
251: * instruction to halt it in its tracks.
252: */
253: free((caddr_t)kfp, M_TEMP);
254: sigexit(p, SIGILL);
255: /* NOTREACHED */
256: }
257: frame->f_regs[SP] = (int)fp;
258: #ifdef DEBUG
259: if (sigdebug & SDB_FOLLOW)
260: printf("sendsig(%d): sig %d scp %p fp %p sc_sp %x sc_ap %x\n",
261: p->p_pid, sig, kfp->sf_scp, fp,
262: kfp->sf_sc.sc_sp, kfp->sf_sc.sc_ap);
263: #endif
264: /*
265: * Signal trampoline code is at base of user stack.
266: */
267: frame->f_pc = p->p_sigcode;
268: #ifdef DEBUG
269: if ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid)
270: printf("sendsig(%d): sig %d returns\n",
271: p->p_pid, sig);
272: #endif
273: free((caddr_t)kfp, M_TEMP);
274: }
275:
276: /*
277: * System call to cleanup state after a signal
278: * has been taken. Reset signal mask and
279: * stack state from context left by sendsig (above).
280: * Return to previous pc and psl as specified by
281: * context left by sendsig. Check carefully to
282: * make sure that the user has not modified the
283: * psl to gain improper privileges or to cause
284: * a machine fault.
285: */
286: int
287: sys_sigreturn(p, v, retval)
288: struct proc *p;
289: void *v;
290: register_t *retval;
291: {
292: struct sys_sigreturn_args /* {
293: syscallarg(struct sigcontext *) sigcntxp;
294: } */ *uap = v;
295: register struct sigcontext *scp;
296: register struct frame *frame;
297: register int rf;
298: struct sigcontext tsigc;
299: struct sigstate tstate;
300: int flags;
301:
302: scp = SCARG(uap, sigcntxp);
303: #ifdef DEBUG
304: if (sigdebug & SDB_FOLLOW)
305: printf("sigreturn: pid %d, scp %p\n", p->p_pid, scp);
306: #endif
307: if ((int)scp & 1)
308: return (EINVAL);
309:
310: /*
311: * Test and fetch the context structure.
312: * We grab it all at once for speed.
313: */
314: if (copyin((caddr_t)scp, (caddr_t)&tsigc, sizeof tsigc))
315: return (EINVAL);
316: scp = &tsigc;
317: if ((scp->sc_ps & PSL_USERCLR) != 0 ||
318: (scp->sc_ps & PSL_USERSET) != PSL_USERSET)
319: return (EINVAL);
320: /*
321: * Restore the user supplied information
322: */
323: if (scp->sc_onstack & 1)
324: p->p_sigacts->ps_sigstk.ss_flags |= SS_ONSTACK;
325: else
326: p->p_sigacts->ps_sigstk.ss_flags &= ~SS_ONSTACK;
327: p->p_sigmask = scp->sc_mask &~ sigcantmask;
328: frame = (struct frame *) p->p_md.md_regs;
329: frame->f_regs[SP] = scp->sc_sp;
330: frame->f_regs[A6] = scp->sc_fp;
331: frame->f_pc = scp->sc_pc;
332: frame->f_sr = scp->sc_ps;
333:
334: /*
335: * Grab pointer to hardware state information.
336: * If zero, the user is probably doing a longjmp.
337: */
338: if ((rf = scp->sc_ap) == 0)
339: return (EJUSTRETURN);
340: /*
341: * See if there is anything to do before we go to the
342: * expense of copying in close to 1/2K of data
343: */
344: if (copyin((caddr_t)rf, &flags, sizeof(int)) != 0)
345: return (EINVAL);
346: #ifdef DEBUG
347: if (sigdebug & SDB_FOLLOW)
348: printf("sigreturn(%d): sc_ap %x flags %x\n",
349: p->p_pid, rf, flags);
350: #endif
351: if (flags == 0 || copyin((caddr_t)rf, (caddr_t)&tstate, sizeof tstate))
352: return (EJUSTRETURN);
353: #ifdef DEBUG
354: if ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid)
355: printf("sigreturn(%d): ssp %p usp %x scp %p ft %d\n",
356: p->p_pid, &flags, scp->sc_sp, SCARG(uap, sigcntxp),
357: (flags&SS_RTEFRAME) ? tstate.ss_frame.f_format : -1);
358: #endif
359: /*
360: * Restore most of the users registers except for A6 and SP
361: * which were handled above.
362: */
363: if (flags & SS_USERREGS)
364: bcopy((caddr_t)tstate.ss_frame.f_regs,
365: (caddr_t)frame->f_regs, sizeof(frame->f_regs)-2*NBPW);
366: /*
367: * Restore long stack frames. Note that we do not copy
368: * back the saved SR or PC, they were picked up above from
369: * the sigcontext structure.
370: */
371: if (flags & SS_RTEFRAME) {
372: register int sz;
373:
374: /* grab frame type and validate */
375: sz = tstate.ss_frame.f_format;
376: if (sz > 15 || (sz = exframesize[sz]) < 0)
377: return (EINVAL);
378: frame->f_stackadj -= sz;
379: frame->f_format = tstate.ss_frame.f_format;
380: frame->f_vector = tstate.ss_frame.f_vector;
381: bcopy((caddr_t)&tstate.ss_frame.F_u, (caddr_t)&frame->F_u, sz);
382: #ifdef DEBUG
383: if (sigdebug & SDB_FOLLOW)
384: printf("sigreturn(%d): copy in %d of frame type %d\n",
385: p->p_pid, sz, tstate.ss_frame.f_format);
386: #endif
387: }
388: /*
389: * Finally we restore the original FP context
390: */
391: if (fputype && (flags & SS_FPSTATE))
392: m68881_restore(&tstate.ss_fpstate);
393: #ifdef DEBUG
394: if ((sigdebug & SDB_FPSTATE) && *(char *)&tstate.ss_fpstate)
395: printf("sigreturn(%d): copied in FP state (%x) at %p\n",
396: p->p_pid, *(u_int *)&tstate.ss_fpstate,
397: &tstate.ss_fpstate);
398: if ((sigdebug & SDB_FOLLOW) ||
399: ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid))
400: printf("sigreturn(%d): returns\n", p->p_pid);
401: #endif
402: return (EJUSTRETURN);
403: }
CVSweb