diff --git a/sys/arch/hppa/hppa/sig_machdep.c b/sys/arch/hppa/hppa/sig_machdep.c index ae3e4bc7e653..ae81ddaf44f9 100644 --- a/sys/arch/hppa/hppa/sig_machdep.c +++ b/sys/arch/hppa/hppa/sig_machdep.c @@ -1,4 +1,4 @@ -/* $NetBSD: sig_machdep.c,v 1.11 2004/07/24 19:04:53 chs Exp $ */ +/* $NetBSD: sig_machdep.c,v 1.12 2005/05/01 19:19:25 chs Exp $ */ /*- * Copyright (c) 2002 The NetBSD Foundation, Inc. @@ -111,7 +111,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: sig_machdep.c,v 1.11 2004/07/24 19:04:53 chs Exp $"); +__KERNEL_RCSID(0, "$NetBSD: sig_machdep.c,v 1.12 2005/05/01 19:19:25 chs Exp $"); #include "opt_compat_netbsd.h" @@ -141,147 +141,8 @@ int sigpid = 0; #define SDB_FPSTATE 0x04 #endif -void sendsig_sigcontext(const struct ksiginfo *, const sigset_t *); - -/* - * Send an interrupt to process. - */ -void -sendsig_sigcontext(const struct ksiginfo *ksi, const sigset_t *mask) -{ - int sig = ksi->ksi_signo; - u_long code = ksi->ksi_trap; - - struct lwp *l = curlwp; - struct proc *p = l->l_proc; - struct sigacts *ps = p->p_sigacts; - struct sigframe *fp, kf; - caddr_t sp; - struct trapframe *tf; - int onstack, fsize; - sig_t catcher = SIGACTION(p, sig).sa_handler; - - tf = (struct trapframe *)l->l_md.md_regs; - - /* Do we need to jump onto the signal stack? */ - onstack = - (p->p_sigctx.ps_sigstk.ss_flags & (SS_DISABLE | SS_ONSTACK)) == 0 && - (SIGACTION(p, sig).sa_flags & SA_ONSTACK) != 0; - - /* - * Allocate space for the signal handler context. - * The PA-RISC calling convention mandates that - * the stack pointer must always be 64-byte aligned, - * and points to the first *unused* byte. - */ - fsize = sizeof(struct sigframe); - sp = (onstack ? - (caddr_t)p->p_sigctx.ps_sigstk.ss_sp : - (caddr_t)tf->tf_sp); - sp = (caddr_t)(((u_int)(sp + fsize + 63)) & ~63); - fp = (struct sigframe *) (sp - fsize); - -#ifdef DEBUG - if ((sigdebug & SDB_FOLLOW) && (!sigpid || p->p_pid == sigpid)) - printf("sendsig: %s[%d] sig %d catcher %p\n", - p->p_comm, p->p_pid, sig, catcher); -#endif - - /* - * Save necessary hardware state. Currently this includes: - * - original exception frame - * - FP coprocessor state - */ - kf.sf_state.ss_flags = SS_USERREGS; - memcpy(&kf.sf_state.ss_frame, tf, sizeof(*tf)); - /* XXX FP state */ - - /* Build the signal context to be used by sigreturn. */ - kf.sf_sc.sc_sp = tf->tf_sp; - kf.sf_sc.sc_fp = tf->tf_sp; /* XXX fredette - is this right? */ - kf.sf_sc.sc_ap = (int)&fp->sf_state; - kf.sf_sc.sc_pcsqh = tf->tf_iisq_head; - kf.sf_sc.sc_pcoqh = tf->tf_iioq_head; - kf.sf_sc.sc_pcsqt = tf->tf_iisq_tail; - kf.sf_sc.sc_pcoqt = tf->tf_iioq_tail; - kf.sf_sc.sc_ps = tf->tf_ipsw; - - /* Save signal stack. */ - kf.sf_sc.sc_onstack = p->p_sigctx.ps_sigstk.ss_flags & SS_ONSTACK; - - /* Save signal mask. */ - kf.sf_sc.sc_mask = *mask; - - /* Fill the calling convention part of the signal frame. */ - kf.sf_psp = 0; - kf.sf_clup = 0; /* XXX fredette - is this right? */ - kf.sf_sl = 0; /* XXX fredette - is this right? */ - kf.sf_edp = 0; /* XXX fredette - is this right? */ - - /* Copy out the signal frame. */ - if (copyout(&kf, fp, fsize)) { -#ifdef DEBUG - if ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid) - printf("sendsig(%d): copyout failed on sig %d\n", - p->p_pid, sig); -#endif - /* - * Process has trashed its stack; give it an illegal - * instruction to halt it in its tracks. - */ - sigexit(l, SIGILL); - /* NOTREACHED */ - } -#ifdef DEBUG - if (sigdebug & SDB_FOLLOW) - printf("sendsig(%d): sig %d scp %p fp %p sc_sp %x sc_ap %x\n", - p->p_pid, sig, &fp->sf_sc, fp, - kf.sf_sc.sc_sp, kf.sf_sc.sc_ap); -#endif - - /* Set up the registers to return to sigcode. */ - switch (ps->sa_sigdesc[sig].sd_vers) { -#if 1 /* COMPAT_16 */ - case 0: /* legacy on-stack sigtramp */ - tf->tf_iioq_head = - (int)p->p_sigctx.ps_sigcode | HPPA_PC_PRIV_USER; - tf->tf_iioq_tail = tf->tf_iioq_head + 4; - break; -#endif - - case 1: - tf->tf_iioq_head = - (int)ps->sa_sigdesc[sig].sd_tramp | HPPA_PC_PRIV_USER; - tf->tf_iioq_tail = tf->tf_iioq_head + 4; - break; - - default: - /* Don't know what trampoline version; kill it. */ - sigexit(l, SIGILL); - } - - tf->tf_sp = (int)sp; - tf->tf_r3 = (int)&fp->sf_sc; - tf->tf_arg0 = sig; - tf->tf_arg1 = code; - tf->tf_arg2 = (int)&fp->sf_sc; - tf->tf_arg3 = (int)catcher; - - /* Remember that we're now on the signal stack. */ - if (onstack) - p->p_sigctx.ps_sigstk.ss_flags |= SS_ONSTACK; - -#ifdef DEBUG - if ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid) - printf("sendsig(%d): sig %d returns\n", - p->p_pid, sig); -#endif -} - -void *getframe(struct lwp *, int, int *); -void sendsig_siginfo(const struct ksiginfo *, const sigset_t *); - -void * +static void *getframe(struct lwp *, int, int *); +static void * getframe(struct lwp *l, int sig, int *onstack) { struct proc *p = l->l_proc; @@ -303,7 +164,7 @@ struct sigframe_siginfo { }; void -sendsig_siginfo(const struct ksiginfo *ksi, const sigset_t *mask) +sendsig(const struct ksiginfo *ksi, const sigset_t *mask) { struct lwp *l = curlwp; struct proc *p = l->l_proc; @@ -365,173 +226,3 @@ sendsig_siginfo(const struct ksiginfo *ksi, const sigset_t *mask) if (onstack) p->p_sigctx.ps_sigstk.ss_flags |= SS_ONSTACK; } - -void -sendsig(const ksiginfo_t *ksi, const sigset_t *mask) -{ - if (curproc->p_sigacts->sa_sigdesc[ksi->ksi_signo].sd_vers < 2) - sendsig_sigcontext(ksi, mask); - else - sendsig_siginfo(ksi, mask); -} - -int -compat_16_sys___sigreturn14(struct lwp *l, void *v, register_t *retval) -{ - struct compat_16_sys___sigreturn14_args /* { - syscallarg(struct sigcontext *) sigcntxp; - } */ *uap = v; - struct proc *p = l->l_proc; - struct sigcontext *scp; - struct trapframe *tf; - struct sigcontext tsigc; - struct sigstate tstate; - int rf, flags; - - /* - * The trampoline code hands us the context. - * It is unsafe to keep track of it ourselves, in the event that a - * program jumps out of a signal handler. - */ - scp = SCARG(uap, sigcntxp); -#ifdef DEBUG - if (sigdebug & SDB_FOLLOW) - printf("sigreturn: pid %d, scp %p\n", p->p_pid, scp); -#endif - if ((int)scp & 3) - return (EINVAL); - - if (copyin(scp, &tsigc, sizeof(tsigc)) != 0) - return (EFAULT); - scp = &tsigc; - - /* Make sure the user isn't pulling a fast one on us! */ - /* XXX fredette - until this is done, huge security hole here. */ - /* XXX fredette - requiring that PSL_R be zero will hurt debuggers. */ - if ((scp->sc_ps & (PSW_MBS|PSW_MBZ)) != PSW_MBS) - return (EINVAL); - - /* Restore register context. */ - tf = (struct trapframe *)l->l_md.md_regs; - - /* - * Grab pointer to hardware state information. - * If zero, the user is probably doing a longjmp. - */ - if ((rf = scp->sc_ap) == 0) - goto restore; - - /* - * See if there is anything to do before we go to the - * expense of copying in the trapframe - */ - flags = fuword((caddr_t)rf); -#ifdef DEBUG - if (sigdebug & SDB_FOLLOW) - printf("sigreturn(%d): sc_ap %x flags %x\n", - p->p_pid, rf, flags); -#endif - /* fuword failed (bogus sc_ap value). */ - if (flags == -1) - return (EINVAL); - - if (flags == 0 || copyin((caddr_t)rf, &tstate, sizeof(tstate)) != 0) - goto restore; -#ifdef DEBUG - if ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid) - printf("sigreturn(%d): ssp %p usp %x scp %p\n", - p->p_pid, &flags, scp->sc_sp, SCARG(uap, sigcntxp)); -#endif - - /* - * Restore most of the users registers except for those - * in the sigcontext; they will be handled below. - */ - if (flags & SS_USERREGS) { - - /* - * There are more registers that the user can tell - * us to bash than registers that, for security - * or other reasons, we must protect. So it's - * easier (but not faster), to copy these sensitive - * register values into the user-provided frame, - * then bulk-copy the user-provided frame into - * the process' frame. - */ -#define SIG_PROTECT(r) tstate.ss_frame.r = tf->r - /* SRs 5,6,7 must be protected. */ - SIG_PROTECT(tf_sr5); - SIG_PROTECT(tf_sr6); - SIG_PROTECT(tf_sr7); - - /* all CRs except CR11 must be protected. */ - SIG_PROTECT(tf_rctr); /* CR0 */ - /* CRs 1-8 are reserved */ - SIG_PROTECT(tf_pidr1); /* CR8 */ - SIG_PROTECT(tf_pidr2); /* CR9 */ - SIG_PROTECT(tf_ccr); /* CR10 */ - SIG_PROTECT(tf_pidr3); /* CR12 */ - SIG_PROTECT(tf_pidr4); /* CR14 */ - SIG_PROTECT(tf_eiem); /* CR15 */ - /* CR17 is the IISQ head */ - /* CR18 is the IIOQ head */ - SIG_PROTECT(tf_iir); /* CR19 */ - SIG_PROTECT(tf_isr); /* CR20 */ - SIG_PROTECT(tf_ior); /* CR21 */ - /* CR22 is the IPSW */ - SIG_PROTECT(tf_eirr); /* CR23 */ - SIG_PROTECT(tf_hptm); /* CR24 */ - SIG_PROTECT(tf_vtop); /* CR25 */ - /* XXX where are CR26, CR27, CR29, CR31? */ - SIG_PROTECT(tf_cr28); /* CR28 */ - SIG_PROTECT(tf_cr30); /* CR30 */ -#undef SIG_PROTECT - - /* The bulk copy. */ - *tf = tstate.ss_frame; - } - - /* - * Restore the original FP context - */ - /* XXX fredette */ - - restore: - /* - * Restore the user supplied information. - * This should be at the last so that the error (EINVAL) - * is reported to the sigreturn caller, not to the - * jump destination. - */ - - tf->tf_sp = scp->sc_sp; - /* XXX should we be doing the space registers? */ - tf->tf_iisq_head = scp->sc_pcsqh; - tf->tf_iioq_head = scp->sc_pcoqh | HPPA_PC_PRIV_USER; - tf->tf_iisq_tail = scp->sc_pcsqt; - tf->tf_iioq_tail = scp->sc_pcoqt | HPPA_PC_PRIV_USER; - tf->tf_ipsw = scp->sc_ps; - - /* Restore signal stack. */ - if (scp->sc_onstack & SS_ONSTACK) - p->p_sigctx.ps_sigstk.ss_flags |= SS_ONSTACK; - else - p->p_sigctx.ps_sigstk.ss_flags &= ~SS_ONSTACK; - - /* Restore signal mask. */ - (void) sigprocmask1(p, SIG_SETMASK, &scp->sc_mask, 0); - -#ifdef DEBUG -#if 0 /* XXX FP state */ - if ((sigdebug & SDB_FPSTATE) && *(char *)&tstate.ss_fpstate) - printf("sigreturn(%d): copied in FP state (%x) at %p\n", - p->p_pid, *(u_int *)&tstate.ss_fpstate, - &tstate.ss_fpstate); -#endif - if ((sigdebug & SDB_FOLLOW) || - ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid)) - printf("sigreturn(%d): returns\n", p->p_pid); -#endif - return (EJUSTRETURN); -} -