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

Annotation of sys/arch/m68k/m68k/sunos_machdep.c, Revision 1.1

1.1     ! nbrk        1: /*     $OpenBSD: sunos_machdep.c,v 1.18 2005/11/06 17:23:41 miod Exp $ */
        !             2: /*     $NetBSD: sunos_machdep.c,v 1.12 1996/10/13 03:19:22 christos Exp $      */
        !             3:
        !             4: /*
        !             5:  * Copyright (c) 1988 University of Utah.
        !             6:  * Copyright (c) 1982, 1986, 1990 The Regents of the University of California.
        !             7:  * All rights reserved.
        !             8:  *
        !             9:  * This code is derived from software contributed to Berkeley by
        !            10:  * the Systems Programming Group of the University of Utah Computer
        !            11:  * Science Department.
        !            12:  *
        !            13:  * Redistribution and use in source and binary forms, with or without
        !            14:  * modification, are permitted provided that the following conditions
        !            15:  * are met:
        !            16:  * 1. Redistributions of source code must retain the above copyright
        !            17:  *    notice, this list of conditions and the following disclaimer.
        !            18:  * 2. Redistributions in binary form must reproduce the above copyright
        !            19:  *    notice, this list of conditions and the following disclaimer in the
        !            20:  *    documentation and/or other materials provided with the distribution.
        !            21:  * 3. Neither the name of the University nor the names of its contributors
        !            22:  *    may be used to endorse or promote products derived from this software
        !            23:  *    without specific prior written permission.
        !            24:  *
        !            25:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
        !            26:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        !            27:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        !            28:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
        !            29:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        !            30:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        !            31:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        !            32:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        !            33:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        !            34:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        !            35:  * SUCH DAMAGE.
        !            36:  *
        !            37:  * from: Utah $Hdr: machdep.c 1.63 91/04/24$
        !            38:  *
        !            39:  *     @(#)machdep.c   7.16 (Berkeley) 6/3/91
        !            40:  */
        !            41:
        !            42: #include <sys/param.h>
        !            43: #include <sys/systm.h>
        !            44: #include <sys/namei.h>
        !            45: #include <sys/proc.h>
        !            46: #include <sys/user.h>
        !            47: #include <sys/filedesc.h>
        !            48: #include <sys/ioctl.h>
        !            49: #include <sys/mount.h>
        !            50: #include <sys/kernel.h>
        !            51: #include <sys/signal.h>
        !            52: #include <sys/signalvar.h>
        !            53: #include <sys/malloc.h>
        !            54: #include <sys/buf.h>
        !            55:
        !            56: #include <sys/syscallargs.h>
        !            57: #include <compat/sunos/sunos.h>
        !            58: #include <compat/sunos/sunos_syscallargs.h>
        !            59:
        !            60: #include <machine/reg.h>
        !            61:
        !            62: #ifdef DEBUG
        !            63: extern int sigdebug;
        !            64: extern int sigpid;
        !            65: #define SDB_FOLLOW      0x01
        !            66: #define SDB_KSTACK      0x02
        !            67: #define SDB_FPSTATE     0x04
        !            68: #endif
        !            69:
        !            70: /* sigh.. I guess it's too late to change now, but "our" sigcontext
        !            71:    is plain vax, not very 68000 (ap, for example..) */
        !            72: struct sunos_sigcontext {
        !            73:        int     sc_onstack;             /* sigstack state to restore */
        !            74:        int     sc_mask;                /* signal mask to restore */
        !            75:        int     sc_sp;                  /* sp to restore */
        !            76:        int     sc_pc;                  /* pc to restore */
        !            77:        int     sc_ps;                  /* psl to restore */
        !            78: };
        !            79: struct sunos_sigframe {
        !            80:        int     sf_signum;              /* signo for handler */
        !            81:        int     sf_code;                /* additional info for handler */
        !            82:        struct sunos_sigcontext *sf_scp;/* context pointer for handler */
        !            83:        u_int   sf_addr;                /* even more info for handler */
        !            84:        struct sunos_sigcontext sf_sc;  /* I don't know if that's what
        !            85:                                           comes here */
        !            86: };
        !            87: /*
        !            88:  * much simpler sendsig() for SunOS processes, as SunOS does the whole
        !            89:  * context-saving in usermode. For now, no hardware information (ie.
        !            90:  * frames for buserror etc) is saved. This could be fatal, so I take
        !            91:  * SIG_DFL for "dangerous" signals.
        !            92:  */
        !            93: void
        !            94: sunos_sendsig(catcher, sig, mask, code, type, val)
        !            95:        sig_t catcher;
        !            96:        int sig, mask;
        !            97:        u_long code;
        !            98:        int type;
        !            99:        union sigval val;
        !           100: {
        !           101:        register struct proc *p = curproc;
        !           102:        register struct sunos_sigframe *fp;
        !           103:        struct sunos_sigframe kfp;
        !           104:        register struct frame *frame;
        !           105:        register struct sigacts *psp = p->p_sigacts;
        !           106:        register short ft;
        !           107:        int oonstack, fsize;
        !           108:
        !           109:        frame = (struct frame *)p->p_md.md_regs;
        !           110:        ft = frame->f_format;
        !           111:        oonstack = psp->ps_sigstk.ss_flags & SS_ONSTACK;
        !           112:
        !           113:        /*
        !           114:         * if this is a hardware fault (ft >= FMT9), sunos_sendsig
        !           115:         * can't currently handle it. Reset signal actions and
        !           116:         * have the process die unconditionally.
        !           117:         */
        !           118:        if (ft >= FMT9) {
        !           119:                sigexit(p, sig);
        !           120:                /* NOTREACHED */
        !           121:        }
        !           122:
        !           123:        /*
        !           124:         * Allocate and validate space for the signal handler
        !           125:         * context. Note that if the stack is in P0 space, the
        !           126:         * call to grow() is a nop, and the useracc() check
        !           127:         * will fail if the process has not already allocated
        !           128:         * the space with a `brk'.
        !           129:         */
        !           130:        fsize = sizeof(struct sunos_sigframe);
        !           131:        if ((psp->ps_flags & SAS_ALTSTACK) && oonstack == 0 &&
        !           132:            (psp->ps_sigonstack & sigmask(sig))) {
        !           133:                fp = (struct sunos_sigframe *)(psp->ps_sigstk.ss_sp +
        !           134:                    psp->ps_sigstk.ss_size - sizeof(struct sunos_sigframe));
        !           135:                psp->ps_sigstk.ss_flags |= SS_ONSTACK;
        !           136:        } else
        !           137:                fp = (struct sunos_sigframe *)frame->f_regs[SP] - 1;
        !           138:        if ((vaddr_t)fp <= USRSTACK - ctob(p->p_vmspace->vm_ssize))
        !           139:                (void)uvm_grow(p, (unsigned)fp);
        !           140: #ifdef DEBUG
        !           141:        if ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid)
        !           142:                printf("sunos_sendsig(%d): sig %d ssp %p usp %p scp %p ft %d\n",
        !           143:                       p->p_pid, sig, &oonstack, fp, &fp->sf_sc, ft);
        !           144: #endif
        !           145:        /*
        !           146:         * Build the argument list for the signal handler.
        !           147:         */
        !           148:        kfp.sf_signum = sig;
        !           149:        kfp.sf_code = code;
        !           150:        kfp.sf_scp = &fp->sf_sc;
        !           151:        kfp.sf_addr = (u_int)val.sival_ptr;
        !           152:
        !           153:        /*
        !           154:         * Build the signal context to be used by sigreturn.
        !           155:         */
        !           156:        kfp.sf_sc.sc_onstack = oonstack;
        !           157:        kfp.sf_sc.sc_mask = mask;
        !           158:        kfp.sf_sc.sc_sp = frame->f_regs[SP];
        !           159:        kfp.sf_sc.sc_pc = frame->f_pc;
        !           160:        kfp.sf_sc.sc_ps = frame->f_sr;
        !           161:
        !           162:        if (copyout(&kfp, fp, fsize) != 0) {
        !           163: #ifdef DEBUG
        !           164:                if ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid)
        !           165:                        printf("sunos_sendsig(%d): copyout failed on sig %d\n",
        !           166:                               p->p_pid, sig);
        !           167: #endif
        !           168:                /*
        !           169:                 * Process has trashed its stack; give it an illegal
        !           170:                 * instruction to halt it in its tracks.
        !           171:                 */
        !           172:                sigexit(p, SIGILL);
        !           173:                /* NOTREACHED */
        !           174:        }
        !           175:
        !           176:        frame->f_regs[SP] = (int)fp;
        !           177: #ifdef DEBUG
        !           178:        if (sigdebug & SDB_FOLLOW)
        !           179:                printf("sunos_sendsig(%d): sig %d scp %p sc_sp %x\n",
        !           180:                       p->p_pid, sig, &fp->sf_sc,kfp.sf_sc.sc_sp);
        !           181: #endif
        !           182:
        !           183:        /* have the user-level trampoline code sort out what registers it
        !           184:           has to preserve. */
        !           185:        frame->f_pc = (u_int) catcher;
        !           186: #ifdef DEBUG
        !           187:        if ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid)
        !           188:                printf("sunos_sendsig(%d): sig %d returns\n",
        !           189:                       p->p_pid, sig);
        !           190: #endif
        !           191: }
        !           192:
        !           193:
        !           194: /*
        !           195:  * System call to cleanup state after a signal
        !           196:  * has been taken.  Reset signal mask and
        !           197:  * stack state from context left by sendsig (above).
        !           198:  * Return to previous pc and psl as specified by
        !           199:  * context left by sendsig. Check carefully to
        !           200:  * make sure that the user has not modified the
        !           201:  * psl to gain improper privileges or to cause
        !           202:  * a machine fault.
        !           203:  */
        !           204: int
        !           205: sunos_sys_sigreturn(p, v, retval)
        !           206:        struct proc *p;
        !           207:        void *v;
        !           208:        register_t *retval;
        !           209: {
        !           210:        struct sunos_sys_sigreturn_args *uap = v;
        !           211:        register struct sunos_sigcontext *scp;
        !           212:        register struct frame *frame;
        !           213:        struct sunos_sigcontext tsigc;
        !           214:
        !           215:        scp = (struct sunos_sigcontext *) SCARG(uap, sigcntxp);
        !           216: #ifdef DEBUG
        !           217:        if (sigdebug & SDB_FOLLOW)
        !           218:                printf("sunos_sigreturn: pid %d, scp %p\n", p->p_pid, scp);
        !           219: #endif
        !           220:        if ((int)scp & 1)
        !           221:                return (EINVAL);
        !           222:        /*
        !           223:         * Test and fetch the context structure.
        !           224:         * We grab it all at once for speed.
        !           225:         */
        !           226:        if (copyin((caddr_t)scp, (caddr_t)&tsigc, sizeof(tsigc)))
        !           227:                return (EINVAL);
        !           228:        scp = &tsigc;
        !           229:        if ((scp->sc_ps & PSL_USERCLR) != 0 ||
        !           230:            (scp->sc_ps & PSL_USERSET) != PSL_USERSET)
        !           231:                return (EINVAL);
        !           232:        /*
        !           233:         * Restore the user supplied information
        !           234:         */
        !           235:        if (scp->sc_onstack & 1)
        !           236:                p->p_sigacts->ps_sigstk.ss_flags |= SS_ONSTACK;
        !           237:        else
        !           238:                p->p_sigacts->ps_sigstk.ss_flags &= ~SS_ONSTACK;
        !           239:        p->p_sigmask = scp->sc_mask &~ sigcantmask;
        !           240:        frame = (struct frame *) p->p_md.md_regs;
        !           241:        frame->f_regs[SP] = scp->sc_sp;
        !           242:        frame->f_pc = scp->sc_pc;
        !           243:        frame->f_sr = scp->sc_ps;
        !           244:
        !           245:        return EJUSTRETURN;
        !           246: }

CVSweb