Annotation of sys/arch/mips64/mips64/sendsig.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: sendsig.c,v 1.9 2006/03/04 19:33:21 miod Exp $ */
2:
3: /*
4: * Copyright (c) 1990 The Regents of the University of California.
5: * All rights reserved.
6: *
7: * This code is derived from software contributed to Berkeley by
8: * William Jolitz and Don Ahn.
9: *
10: * Redistribution and use in source and binary forms, with or without
11: * modification, are permitted provided that the following conditions
12: * are met:
13: * 1. Redistributions of source code must retain the above copyright
14: * notice, this list of conditions and the following disclaimer.
15: * 2. Redistributions in binary form must reproduce the above copyright
16: * notice, this list of conditions and the following disclaimer in the
17: * documentation and/or other materials provided with the distribution.
18: * 3. All advertising materials mentioning features or use of this software
19: * must display the following acknowledgement:
20: * This product includes software developed by the University of
21: * California, Berkeley and its contributors.
22: * 4. Neither the name of the University nor the names of its contributors
23: * may be used to endorse or promote products derived from this software
24: * without specific prior written permission.
25: *
26: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
27: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
30: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36: * SUCH DAMAGE.
37: *
38: */
39: /*
40: * Copyright (c) 2001 Opsycon AB (www.opsycon.se)
41: *
42: * Redistribution and use in source and binary forms, with or without
43: * modification, are permitted provided that the following conditions
44: * are met:
45: * 1. Redistributions of source code must retain the above copyright
46: * notice, this list of conditions and the following disclaimer.
47: * 2. Redistributions in binary form must reproduce the above copyright
48: * notice, this list of conditions and the following disclaimer in the
49: * documentation and/or other materials provided with the distribution.
50: *
51: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
52: * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
53: * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
54: * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
55: * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
56: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
57: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
58: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
59: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
60: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
61: * SUCH DAMAGE.
62: *
63: */
64:
65: #include <sys/param.h>
66: #include <sys/systm.h>
67: #include <sys/signalvar.h>
68: #include <sys/user.h>
69: #include <sys/exec.h>
70: #include <sys/mount.h>
71: #include <sys/syscallargs.h>
72:
73: #include <machine/regnum.h>
74:
75: /*
76: * WARNING: code in locore.s assumes the layout shown for sf_signum
77: * thru sf_handler so... don't screw with them!
78: */
79: struct sigframe {
80: int sf_signum; /* signo for handler */
81: siginfo_t *sf_sip; /* pointer to siginfo_t */
82: struct sigcontext *sf_scp; /* context ptr for handler */
83: sig_t sf_handler; /* handler addr for u_sigc */
84: struct sigcontext sf_sc; /* actual context */
85: siginfo_t sf_si;
86: };
87:
88: #ifdef DEBUG
89: int sigdebug = 0;
90: int sigpid = 0;
91: #define SDB_FOLLOW 0x01
92: #define SDB_KSTACK 0x02
93: #define SDB_FPSTATE 0x04
94: #endif
95:
96: /*
97: * Send an interrupt to process.
98: */
99: void
100: sendsig(catcher, sig, mask, code, type, val)
101: sig_t catcher;
102: int sig, mask;
103: u_long code;
104: int type;
105: union sigval val;
106: {
107: struct proc *p = curproc;
108: struct sigframe *fp;
109: struct trap_frame *regs;
110: struct sigacts *psp = p->p_sigacts;
111: int oonstack, fsize;
112: struct sigcontext ksc;
113:
114: regs = p->p_md.md_regs;
115: oonstack = psp->ps_sigstk.ss_flags & SA_ONSTACK;
116: /*
117: * Allocate and validate space for the signal handler
118: * context. Note that if the stack is in data space, the
119: * call to grow() is a nop, and the copyout()
120: * will fail if the process has not already allocated
121: * the space with a `brk'.
122: */
123: fsize = sizeof(struct sigframe);
124: if (!(psp->ps_siginfo & sigmask(sig)))
125: fsize -= sizeof(siginfo_t);
126: if ((psp->ps_flags & SAS_ALTSTACK) &&
127: (psp->ps_sigstk.ss_flags & SA_ONSTACK) == 0 &&
128: (psp->ps_sigonstack & sigmask(sig))) {
129: fp = (struct sigframe *)(psp->ps_sigstk.ss_sp +
130: psp->ps_sigstk.ss_size - fsize);
131: psp->ps_sigstk.ss_flags |= SA_ONSTACK;
132: } else
133: fp = (struct sigframe *)(regs->sp - fsize);
134: if ((vaddr_t)fp <= USRSTACK - ctob(p->p_vmspace->vm_ssize))
135: (void)uvm_grow(p, (vaddr_t)fp);
136: #ifdef DEBUG
137: if ((sigdebug & SDB_FOLLOW) ||
138: ((sigdebug & SDB_KSTACK) && (p->p_pid == sigpid)))
139: printf("sendsig(%d): sig %d ssp %x usp %x scp %x\n",
140: p->p_pid, sig, &oonstack, fp, &fp->sf_sc);
141: #endif
142: /*
143: * Build the signal context to be used by sigreturn.
144: */
145: ksc.sc_onstack = oonstack;
146: ksc.sc_mask = mask;
147: ksc.sc_pc = regs->pc;
148: ksc.mullo = regs->mullo;
149: ksc.mulhi = regs->mulhi;
150: ksc.sc_regs[ZERO] = 0xACEDBADE; /* magic number */
151: bcopy((caddr_t)®s->ast, (caddr_t)&ksc.sc_regs[1],
152: sizeof(ksc.sc_regs) - sizeof(register_t));
153: ksc.sc_fpused = p->p_md.md_flags & MDP_FPUSED;
154: if (ksc.sc_fpused) {
155: extern struct proc *machFPCurProcPtr;
156:
157: /* if FPU has current state, save it first */
158: if (p == machFPCurProcPtr) {
159: if (regs->sr & SR_FR_32)
160: MipsSaveCurFPState(p);
161: else
162: MipsSaveCurFPState16(p);
163: }
164: bcopy((caddr_t)&p->p_md.md_regs->f0, (caddr_t)ksc.sc_fpregs,
165: sizeof(ksc.sc_fpregs));
166: }
167:
168: if (psp->ps_siginfo & sigmask(sig)) {
169: siginfo_t si;
170:
171: initsiginfo(&si, sig, code, type, val);
172: if (copyout((caddr_t)&si, (caddr_t)&fp->sf_si, sizeof si))
173: goto bail;
174: }
175:
176: if (copyout((caddr_t)&ksc, (caddr_t)&fp->sf_sc, sizeof(ksc))) {
177: bail:
178: /*
179: * Process has trashed its stack; give it an illegal
180: * instruction to halt it in its tracks.
181: */
182: sigexit(p, SIGILL);
183: /* NOTREACHED */
184: }
185: /*
186: * Build the argument list for the signal handler.
187: */
188: regs->a0 = sig;
189: regs->a1 = (psp->ps_siginfo & sigmask(sig)) ? (register_t)&fp->sf_si : NULL;
190: regs->a2 = (register_t)&fp->sf_sc;
191: regs->a3 = (register_t)catcher;
192:
193: regs->pc = (register_t)catcher;
194: regs->t9 = (register_t)catcher;
195: regs->sp = (register_t)fp;
196:
197: regs->ra = p->p_sigcode;
198: #ifdef DEBUG
199: if ((sigdebug & SDB_FOLLOW) ||
200: ((sigdebug & SDB_KSTACK) && (p->p_pid == sigpid)))
201: printf("sendsig(%d): sig %d returns\n",
202: p->p_pid, sig);
203: #endif
204: }
205:
206: /*
207: * System call to cleanup state after a signal
208: * has been taken. Reset signal mask and
209: * stack state from context left by sendsig (above).
210: * Return to previous pc and psl as specified by
211: * context left by sendsig. Check carefully to
212: * make sure that the user has not modified the
213: * psl to gain improper privileges or to cause
214: * a machine fault.
215: */
216: /* ARGSUSED */
217: int
218: sys_sigreturn(p, v, retval)
219: struct proc *p;
220: void *v;
221: register_t *retval;
222: {
223: struct sys_sigreturn_args /* {
224: syscallarg(struct sigcontext *) sigcntxp;
225: } */ *uap = v;
226: struct sigcontext *scp;
227: struct trap_frame *regs;
228: struct sigcontext ksc;
229: int error;
230: extern struct proc *machFPCurProcPtr;
231:
232: scp = SCARG(uap, sigcntxp);
233: #ifdef DEBUG
234: if (sigdebug & SDB_FOLLOW)
235: printf("sigreturn: pid %d, scp %x\n", p->p_pid, scp);
236: #endif
237: regs = p->p_md.md_regs;
238: /*
239: * Test and fetch the context structure.
240: * We grab it all at once for speed.
241: */
242: error = copyin((caddr_t)scp, (caddr_t)&ksc, sizeof(ksc));
243: if (error || ksc.sc_regs[ZERO] != 0xACEDBADE) {
244: #ifdef DEBUG
245: if (!(sigdebug & SDB_FOLLOW))
246: printf("sigreturn: pid %d, scp %x\n", p->p_pid, scp);
247: printf(" old sp %x ra %x pc %x\n",
248: regs->sp, regs->ra, regs->pc);
249: printf(" new sp %x ra %x pc %x err %d z %x\n",
250: ksc.sc_regs[SP], ksc.sc_regs[RA], ksc.sc_regs[PC],
251: error, ksc.sc_regs[ZERO]);
252: #endif
253: return (EINVAL);
254: }
255: scp = &ksc;
256: /*
257: * Restore the user supplied information
258: */
259: if (scp->sc_onstack & SA_ONSTACK)
260: p->p_sigacts->ps_sigstk.ss_flags |= SA_ONSTACK;
261: else
262: p->p_sigacts->ps_sigstk.ss_flags &= ~SA_ONSTACK;
263: p->p_sigmask = scp->sc_mask &~ sigcantmask;
264: regs->pc = scp->sc_pc;
265: regs->mullo = scp->mullo;
266: regs->mulhi = scp->mulhi;
267: regs->sr &= ~SR_COP_1_BIT; /* Zap current FP state */
268: if (p == machFPCurProcPtr)
269: machFPCurProcPtr = NULL;
270: bcopy((caddr_t)&scp->sc_regs[1], (caddr_t)®s->ast,
271: sizeof(scp->sc_regs) - sizeof(register_t));
272: if (scp->sc_fpused)
273: bcopy((caddr_t)scp->sc_fpregs, (caddr_t)&p->p_md.md_regs->f0,
274: sizeof(scp->sc_fpregs));
275: return (EJUSTRETURN);
276: }
CVSweb