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

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