Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/netbsd-3]: src/sys/arch/sparc64/sparc64 Pull up revision 1.50 (requested...



details:   https://anonhg.NetBSD.org/src/rev/b74bddff279a
branches:  netbsd-3
changeset: 576558:b74bddff279a
user:      tron <tron%NetBSD.org@localhost>
date:      Mon Jul 11 11:36:16 2005 +0000

description:
Pull up revision 1.50 (requested by martin in ticket #571):
Add siginfo based signal delivery.

diffstat:

 sys/arch/sparc64/sparc64/netbsd32_machdep.c |  122 ++++++++++++++++++++++++++-
 1 files changed, 114 insertions(+), 8 deletions(-)

diffs (168 lines):

diff -r 07681c506992 -r b74bddff279a sys/arch/sparc64/sparc64/netbsd32_machdep.c
--- a/sys/arch/sparc64/sparc64/netbsd32_machdep.c       Mon Jul 11 11:34:56 2005 +0000
+++ b/sys/arch/sparc64/sparc64/netbsd32_machdep.c       Mon Jul 11 11:36:16 2005 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: netbsd32_machdep.c,v 1.44 2004/11/08 17:05:37 kleink Exp $     */
+/*     $NetBSD: netbsd32_machdep.c,v 1.44.10.1 2005/07/11 11:36:16 tron Exp $  */
 
 /*
  * Copyright (c) 1998, 2001 Matthew R. Green
@@ -29,7 +29,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: netbsd32_machdep.c,v 1.44 2004/11/08 17:05:37 kleink Exp $");
+__KERNEL_RCSID(0, "$NetBSD: netbsd32_machdep.c,v 1.44.10.1 2005/07/11 11:36:16 tron Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_compat_netbsd.h"
@@ -74,7 +74,6 @@
 #include <machine/reg.h>
 #include <machine/vmparam.h>
 #include <machine/vuid_event.h>
-
 #include <machine/netbsd32_machdep.h>
 
 /* Provide a the name of the architecture we're emulating */
@@ -145,6 +144,7 @@
        tf->tf_out[7] = 0;
 }
 
+#ifdef COMPAT_16
 /*
  * NB: since this is a 32-bit address world, sf_scp and sf_sc
  *     can't be a pointer since those are 64-bits wide.
@@ -162,15 +162,15 @@
 extern int sigdebug;
 #endif
 
-void
-netbsd32_sendsig(const ksiginfo_t *ksi, const sigset_t *mask)
+static void
+netbsd32_sendsig_sigcontext(const ksiginfo_t *ksi, const sigset_t *mask)
 {
        int sig = ksi->ksi_signo;
        register struct lwp *l = curlwp;
        struct proc *p = l->l_proc;
-       register struct sparc32_sigframe *fp;
-       register struct trapframe64 *tf;
-       register int addr, onstack; 
+       struct sparc32_sigframe *fp;
+       struct trapframe64 *tf;
+       int addr, onstack; 
        struct rwindow32 *kwin, *oldsp, *newsp;
        sig_t catcher = SIGACTION(p, sig).sa_handler;
        struct sparc32_sigframe sf;
@@ -286,6 +286,112 @@
        }
 #endif
 }
+#endif
+
+struct sparc32_sigframe_siginfo {
+       siginfo32_t sf_si;
+       ucontext32_t sf_uc;
+};
+
+static void
+netbsd32_sendsig_siginfo(const ksiginfo_t *ksi, const sigset_t *mask)
+{
+       struct lwp *l = curlwp;
+       struct proc *p = l->l_proc;
+       struct sigacts *ps = p->p_sigacts;
+       int onstack;
+       int sig = ksi->ksi_signo;
+       ucontext32_t uc;
+       struct sparc32_sigframe_siginfo *fp;
+       netbsd32_pointer_t catcher;
+       struct trapframe64 *tf = l->l_md.md_tf;
+       struct rwindow32 *oldsp, *newsp;
+       int ucsz;
+
+       /* Need to attempt to zero extend this 32-bit pointer */
+       oldsp = (struct rwindow32*)(u_long)(u_int)tf->tf_out[6];
+       /* 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. */
+       if (onstack)
+               fp = (struct sparc32_sigframe_siginfo *)
+                   ((caddr_t)p->p_sigctx.ps_sigstk.ss_sp +
+                                         p->p_sigctx.ps_sigstk.ss_size);
+       else
+               fp = (struct sparc32_sigframe_siginfo *)oldsp;
+       fp = (struct sparc32_sigframe_siginfo*)((u_long)(fp - 1) & ~7);
+       /*
+        * Build the signal context to be used by sigreturn.
+        */
+       uc.uc_flags = _UC_SIGMASK |
+               ((p->p_sigctx.ps_sigstk.ss_flags & SS_ONSTACK)
+                       ? _UC_SETSTACK : _UC_CLRSTACK);
+       uc.uc_sigmask = *mask;
+       uc.uc_link = 0;
+       memset(&uc.uc_stack, 0, sizeof(uc.uc_stack));
+       cpu_getmcontext32(l, &uc.uc_mcontext, &uc.uc_flags);
+       ucsz = (int)(intptr_t)&uc.__uc_pad - (int)(intptr_t)&uc;
+
+       /*
+        * Now copy the stack contents out to user space.
+        * We need to make sure that when we start the signal handler,
+        * its %i6 (%fp), which is loaded from the newly allocated stack area,
+        * joins seamlessly with the frame it was in when the signal occurred,
+        * so that the debugger and _longjmp code can back up through it.
+        * Since we're calling the handler directly, allocate a full size
+        * C stack frame.
+        */
+       newsp = (struct rwindow32*)((intptr_t)fp - sizeof(struct frame32));
+       if (copyout(&ksi->ksi_info, &fp->sf_si, sizeof ksi->ksi_info) ||
+           copyout(&uc, &fp->sf_uc, ucsz) ||
+           suword(&newsp->rw_in[6], (intptr_t)oldsp)) {
+               /*
+                * Process has trashed its stack; give it an illegal
+                * instruction to halt it in its tracks.
+                */
+               sigexit(l, SIGILL);
+               /* NOTREACHED */
+       }
+
+       switch (ps->sa_sigdesc[sig].sd_vers) {
+       default:
+               /* Unsupported trampoline version; kill the process. */
+               sigexit(l, SIGILL);
+       case 2:
+               /*
+                * Arrange to continue execution at the user's handler.
+                * It needs a new stack pointer, a return address and
+                * three arguments: (signo, siginfo *, ucontext *).
+                */
+               catcher = (intptr_t)SIGACTION(p, sig).sa_handler;
+               tf->tf_pc = catcher;
+               tf->tf_npc = catcher + 4;
+               tf->tf_out[0] = sig;
+               tf->tf_out[1] = (intptr_t)&fp->sf_si;
+               tf->tf_out[2] = (intptr_t)&fp->sf_uc;
+               tf->tf_out[6] = (intptr_t)newsp;
+               tf->tf_out[7] = (intptr_t)ps->sa_sigdesc[sig].sd_tramp - 8;
+               break;
+       }
+
+       /* Remember that we're now on the signal stack. */
+       if (onstack)
+               p->p_sigctx.ps_sigstk.ss_flags |= SS_ONSTACK;
+}
+
+void
+netbsd32_sendsig(const ksiginfo_t *ksi, const sigset_t *mask)
+{
+#ifdef COMPAT_16
+       if (curproc->p_sigacts->sa_sigdesc[ksi->ksi_signo].sd_vers < 2)
+               netbsd32_sendsig_sigcontext(ksi, mask);
+       else
+#endif
+               netbsd32_sendsig_siginfo(ksi, mask);
+}
 
 /*
  * Set the lwp to begin execution in the upcall handler.  The upcall



Home | Main Index | Thread Index | Old Index