[BACK]Return to sendsig.c CVS log [TXT][DIR] Up to [local] / sys / arch / mips64 / mips64

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)&regs->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)&regs->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