Annotation of sys/arch/mips64/mips64/sendsig.c, Revision 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