Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/arch/usermode/usermode Make signals work for NetBSD/user...
details: https://anonhg.NetBSD.org/src/rev/7bb5ecb38140
branches: trunk
changeset: 772210:7bb5ecb38140
user: reinoud <reinoud%NetBSD.org@localhost>
date: Sat Dec 24 12:26:58 2011 +0000
description:
Make signals work for NetBSD/usermode[i386] !
diffstat:
sys/arch/usermode/usermode/machdep.c | 131 +++++++++++++++++++++++++++++-----
1 files changed, 112 insertions(+), 19 deletions(-)
diffs (170 lines):
diff -r 20d3545d8090 -r 7bb5ecb38140 sys/arch/usermode/usermode/machdep.c
--- a/sys/arch/usermode/usermode/machdep.c Sat Dec 24 12:23:24 2011 +0000
+++ b/sys/arch/usermode/usermode/machdep.c Sat Dec 24 12:26:58 2011 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: machdep.c,v 1.41 2011/12/20 22:48:59 jmcneill Exp $ */
+/* $NetBSD: machdep.c,v 1.42 2011/12/24 12:26:58 reinoud Exp $ */
/*-
* Copyright (c) 2011 Reinoud Zandijk <reinoud%netbsd.org@localhost>
@@ -27,11 +27,18 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
+/*
+ * Note that this machdep.c uses the `dummy' mcontext_t defined for usermode.
+ * This is basicly a blob of PAGE_SIZE big. We might want to switch over to
+ * non-generic mcontext_t's one day, but will this break non-NetBSD hosts?
+ */
+
+
#include "opt_memsize.h"
#include "opt_sdl.h"
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.41 2011/12/20 22:48:59 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.42 2011/12/24 12:26:58 reinoud Exp $");
#include <sys/types.h>
#include <sys/param.h>
@@ -141,22 +148,6 @@
printf("NetBSD/usermode startup\n");
}
-void
-sendsig_siginfo(const ksiginfo_t *ksi, const sigset_t *mask)
-{
-#if 1
- printf("%s: ", __func__);
- printf("flags %d, ", (int) ksi->ksi_flags);
- printf("to lwp %d, signo %d, code %d, errno %d\n",
- (int) ksi->ksi_lid,
- ksi->ksi_signo,
- ksi->ksi_code,
- ksi->ksi_errno);
-#endif
-
- panic("%s not implemented", __func__);
-}
-
int
mm_md_physacc(paddr_t pa, vm_prot_t prog)
{
@@ -184,6 +175,108 @@
}
#endif
+
+/* from sys/arch/i386/include/frame.h : KEEP IN SYNC */
+
+/*
+ * New-style signal frame
+ */
+struct sigframe_siginfo {
+ int sf_ra; /* return address for handler */
+ int sf_signum; /* "signum" argument for handler */
+ siginfo_t *sf_sip; /* "sip" argument for handler */
+ ucontext_t *sf_ucp; /* "ucp" argument for handler */
+ siginfo_t sf_si; /* actual saved siginfo */
+ ucontext_t sf_uc; /* actual saved ucontext */
+};
+
+
+/*
+ * mcontext extensions to handle signal delivery.
+ */
+#define _UC_SETSTACK 0x00010000
+#define _UC_CLRSTACK 0x00020000
+#define _UC_VM 0x00040000
+#define _UC_TLSBASE 0x00080000
+
+
+void
+sendsig_siginfo(const ksiginfo_t *ksi, const sigset_t *mask)
+{
+ struct lwp *l = curlwp;
+ struct proc *p = l->l_proc;
+ struct pcb *pcb = lwp_getpcb(l);
+ struct sigacts *ps = p->p_sigacts;
+ struct sigframe_siginfo *fp, frame;
+ int sig = ksi->ksi_signo;
+ sig_t catcher = SIGACTION(p, sig).sa_handler;
+ ucontext_t *ucp = &pcb->pcb_userret_ucp;
+ register_t *reg = (register_t *) &ucp->uc_mcontext;
+ int onstack, error;
+
+ KASSERT(mutex_owned(p->p_lock));
+
+#if 0
+ printf("%s: ", __func__);
+ printf("flags %d, ", (int) ksi->ksi_flags);
+ printf("to lwp %d, signo %d, code %d, errno %d\n",
+ (int) ksi->ksi_lid,
+ ksi->ksi_signo,
+ ksi->ksi_code,
+ ksi->ksi_errno);
+#endif
+
+ /* do we need to jump onto the signal stack? */
+ onstack = (l->l_sigstk.ss_flags & (SS_DISABLE | SS_ONSTACK)) == 0
+ && (SIGACTION(p, sig).sa_flags & SA_ONSTACK) != 0;
+
+ fp = (void *) reg[17]; /* ESP */
+ if (onstack)
+ fp = (void *)
+ ((char *) l->l_sigstk.ss_sp + l->l_sigstk.ss_size);
+
+ fp--;
+
+ /* set up stack frame */
+ frame.sf_ra = (int)ps->sa_sigdesc[sig].sd_tramp;
+ frame.sf_signum = sig;
+ frame.sf_sip = &fp->sf_si;
+ frame.sf_ucp = &fp->sf_uc;
+ frame.sf_si._info = ksi->ksi_info;
+
+ /* copy our userret context into sf_uc */
+ memcpy(&frame.sf_uc, ucp, sizeof(ucontext_t));
+ frame.sf_uc.uc_sigmask = *mask;
+ frame.sf_uc.uc_link = l->l_ctxlink; /* XXX ??? */
+ frame.sf_uc.uc_flags |= (l->l_sigstk.ss_flags & SS_ONSTACK)
+ ? _UC_SETSTACK : _UC_CLRSTACK;
+ memset(&frame.sf_uc.uc_stack, 0, sizeof(frame.sf_uc.uc_stack));
+
+ sendsig_reset(l, sig);
+
+ /* copyout our frame to the stackframe */
+ mutex_exit(p->p_lock);
+ error = copyout(&frame, fp, sizeof(frame));
+ mutex_enter(p->p_lock);
+
+ if (error != 0) {
+ /*
+ * Process has trashed its stack; give it an illegal
+ * instruction to halt it in its tracks.
+ */
+ sigexit(l, SIGILL);
+ /* NOTREACHED */
+ }
+
+ /* set catcher and the new stack pointer */
+ reg[17] = (register_t) fp; /* ESP */
+ reg[14] = (register_t) catcher; /* EIP */
+
+ /* Remember that we're now on the signal stack. */
+ if (onstack)
+ l->l_sigstk.ss_flags |= SS_ONSTACK;
+}
+
void
setregs(struct lwp *l, struct exec_package *pack, vaddr_t stack)
{
@@ -298,7 +391,7 @@
{
register_t *reg = (register_t *) &ucp->uc_mcontext;
// uint8_t *p8 = (uint8_t *) (reg[14]);
- uint16_t *p16 = (uint16_t*) (reg[14]);
+ uint16_t *p16 = (uint16_t*) (reg[14]); /* EIP */
switch (*p16) {
case 0xff0f: /* UD1 */
Home |
Main Index |
Thread Index |
Old Index