[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     ! 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