summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorTheo de Raadt <deraadt@cvs.openbsd.org>1996-01-09 09:24:02 +0000
committerTheo de Raadt <deraadt@cvs.openbsd.org>1996-01-09 09:24:02 +0000
commitaeca999f3986210c2a53e038b73f040e7e946ac8 (patch)
tree3a4f09c6590c21db7aa0d2e25d83477cc6b7ecc0 /sys
parent39ee86d7b1f8b143fe5fcb99f4ec32ee247852f4 (diff)
from netbsd; Fix setcontext call and sendsig
Diffstat (limited to 'sys')
-rw-r--r--sys/arch/sparc/sparc/svr4_machdep.c103
1 files changed, 81 insertions, 22 deletions
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,23 +207,9 @@ 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;