From: deraadt Date: Tue, 9 Jan 1996 09:24:01 +0000 (+0000) Subject: from netbsd; Fix setcontext call and sendsig X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=bde4746f17cc3cf8e65fe2a19590c555d90ea227;p=openbsd from netbsd; Fix setcontext call and sendsig --- diff --git a/sys/arch/sparc/sparc/svr4_machdep.c b/sys/arch/sparc/sparc/svr4_machdep.c index 4d7ae0dfc37..5a572604c7b 100644 --- a/sys/arch/sparc/sparc/svr4_machdep.c +++ b/sys/arch/sparc/sparc/svr4_machdep.c @@ -1,4 +1,4 @@ -/* $NetBSD: svr4_machdep.c,v 1.12 1996/01/04 22:22:49 jtc Exp $ */ +/* $NetBSD: svr4_machdep.c,v 1.13 1996/01/07 19:47:27 christos Exp $ */ /* * Copyright (c) 1994 Christos Zoulas @@ -63,6 +63,50 @@ extern int sigpid; #define SDB_FPSTATE 0x04 #endif +#ifdef DEBUG_SVR4 +static void svr4_printcontext __P((const char *, struct svr4_ucontext *)); + +static void +svr4_printcontext(fun, uc) + const char *fun; + struct svr4_ucontext *uc; +{ + svr4_greg_t *r = uc->uc_mcontext.greg; + struct svr4_sigaltstack *s = &uc->uc_stack; + + printf("%s at %x\n", fun, uc); + + printf("Regs: "); + printf("PSR = %x ", r[SVR4_SPARC_PSR]); + printf("PC = %x ", r[SVR4_SPARC_PC]); + printf("nPC = %x ", r[SVR4_SPARC_nPC]); + printf("Y = %x ", r[SVR4_SPARC_Y]); + printf("G1 = %x ", r[SVR4_SPARC_G1]); + printf("G2 = %x ", r[SVR4_SPARC_G2]); + printf("G3 = %x ", r[SVR4_SPARC_G3]); + printf("G4 = %x ", r[SVR4_SPARC_G4]); + printf("G5 = %x ", r[SVR4_SPARC_G5]); + printf("G6 = %x ", r[SVR4_SPARC_G6]); + printf("G7 = %x ", r[SVR4_SPARC_G7]); + printf("O0 = %x ", r[SVR4_SPARC_O0]); + printf("O1 = %x ", r[SVR4_SPARC_O1]); + printf("O2 = %x ", r[SVR4_SPARC_O2]); + printf("O3 = %x ", r[SVR4_SPARC_O3]); + printf("O4 = %x ", r[SVR4_SPARC_O4]); + printf("O5 = %x ", r[SVR4_SPARC_O5]); + printf("O6 = %x ", r[SVR4_SPARC_O6]); + printf("O7 = %x ", r[SVR4_SPARC_O7]); + printf("\n"); + + printf("Signal Stack: sp %x, size %d, flags %x\n", + s->ss_sp, s->ss_size, s->ss_flags); + + printf("Signal mask: %x\n", uc->uc_sigmask); + + printf("Flags: %x\n", uc->uc_flags); +} +#endif + void svr4_getcontext(p, uc, mask, oonstack) struct proc *p; @@ -114,6 +158,10 @@ svr4_getcontext(p, uc, mask, oonstack) * Set the flags */ uc->uc_flags = SVR4_UC_ALL; + +#ifdef DEBUG_SVR4 + svr4_printcontext("getcontext", uc); +#endif } @@ -141,6 +189,9 @@ svr4_setcontext(p, uc) struct sigaltstack *sf = &psp->ps_sigstk; int mask; +#ifdef DEBUG_SVR4 + svr4_printcontext("setcontext", uc); +#endif /* * XXX: * Should we check the value of flags to determine what to restore? @@ -156,22 +207,8 @@ svr4_setcontext(p, uc) p->p_comm, p->p_pid, uc); #endif - if ((int)uc & 3 || useracc((caddr_t)uc, sizeof *uc, B_WRITE) == 0) - return EINVAL; - tf = (struct trapframe *)p->p_md.md_tf; - /* - * restore signal stack - */ - svr4_to_bsd_sigaltstack(s, sf); - - /* - * restore signal mask - */ - svr4_to_bsd_sigset(&uc->uc_sigmask, &mask); - p->p_sigmask = mask & ~sigcantmask; - /* * Restore register context. */ @@ -180,18 +217,18 @@ svr4_setcontext(p, uc) * verified. pc and npc must be multiples of 4. This is all * that is required; if it holds, just do it. */ - if (((r[SVR4_SPARC_PC] | r[SVR4_SPARC_nPC]) & 3) != 0) + if (((r[SVR4_SPARC_PC] | r[SVR4_SPARC_nPC]) & 3) != 0) { + printf("pc or npc are not multiples of 4!\n"); return EINVAL; + } /* take only psr ICC field */ tf->tf_psr = (tf->tf_psr & ~PSR_ICC) | (r[SVR4_SPARC_PSR] & PSR_ICC); tf->tf_pc = r[SVR4_SPARC_PC]; tf->tf_npc = r[SVR4_SPARC_nPC]; tf->tf_y = r[SVR4_SPARC_Y]; - tf->tf_out[0] = r[SVR4_SPARC_O0]; - tf->tf_out[6] = r[SVR4_SPARC_O6]; -#if 0 - /* I don't think that we need to restore those */ + + /* Restore everything */ tf->tf_global[1] = r[SVR4_SPARC_G1]; tf->tf_global[2] = r[SVR4_SPARC_G2]; tf->tf_global[3] = r[SVR4_SPARC_G3]; @@ -200,13 +237,25 @@ svr4_setcontext(p, uc) tf->tf_global[6] = r[SVR4_SPARC_G6]; tf->tf_global[7] = r[SVR4_SPARC_G7]; + tf->tf_out[0] = r[SVR4_SPARC_O0]; tf->tf_out[1] = r[SVR4_SPARC_O1]; tf->tf_out[2] = r[SVR4_SPARC_O2]; tf->tf_out[3] = r[SVR4_SPARC_O3]; tf->tf_out[4] = r[SVR4_SPARC_O4]; tf->tf_out[5] = r[SVR4_SPARC_O5]; + tf->tf_out[6] = r[SVR4_SPARC_O6]; tf->tf_out[7] = r[SVR4_SPARC_O7]; -#endif + + /* + * restore signal stack + */ + svr4_to_bsd_sigaltstack(s, sf); + + /* + * restore signal mask + */ + svr4_to_bsd_sigset(&uc->uc_sigmask, &mask); + p->p_sigmask = mask & ~sigcantmask; return EJUSTRETURN; } @@ -364,12 +413,17 @@ svr4_sendsig(catcher, sig, mask, code) if ((psp->ps_flags & SAS_ALTSTACK) && !oonstack && (psp->ps_sigonstack & sigmask(sig))) { fp = (struct svr4_sigframe *)(psp->ps_sigstk.ss_sp + - psp->ps_sigstk.ss_size - sizeof(struct svr4_sigframe)); + psp->ps_sigstk.ss_size); psp->ps_sigstk.ss_flags |= SS_ONSTACK; } else { fp = (struct svr4_sigframe *)oldsp; } + /* + * Subtract off one signal frame and align. + */ + fp = (struct svr4_sigframe *) ((int) (fp - 1) & ~7); + /* * Build the argument list for the signal handler. */ @@ -379,6 +433,10 @@ svr4_sendsig(catcher, sig, mask, code) frame.sf_sip = &fp->sf_si; frame.sf_ucp = &fp->sf_uc; frame.sf_handler = catcher; + + DPRINTF(("svr4_sendsig signum=%d si = %x uc = %x handler = %x\n", + frame.sf_signum, frame.sf_sip, + frame.sf_ucp, frame.sf_handler)); /* * Modify the signal context to be used by sigreturn. */ @@ -406,6 +464,7 @@ svr4_sendsig(catcher, sig, mask, code) */ addr = (int)PS_STRINGS - (svr4_esigcode - svr4_sigcode); tf->tf_global[1] = (int)catcher; + tf->tf_pc = addr; tf->tf_npc = addr + 4; tf->tf_out[6] = newsp;