summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkettenis <kettenis@openbsd.org>2010-05-09 17:14:20 +0000
committerkettenis <kettenis@openbsd.org>2010-05-09 17:14:20 +0000
commit85bd301422c8b4b2e14398a31d83a02fa14a0f35 (patch)
treed813686776b7b482f17f6cc5af7a662080d752e0
parent- audio/rio500 has been removed from ports, so refer to audio/rioutil instead (diff)
downloadwireguard-openbsd-85bd301422c8b4b2e14398a31d83a02fa14a0f35.tar.xz
wireguard-openbsd-85bd301422c8b4b2e14398a31d83a02fa14a0f35.zip
Make single stepping a system call work. Instead of single stepping through
the syscall gateway page, which doesn't work since that page is shared between processes, this makes us step over that bit by setting a breakpoint on the instruction where the system call returns. ok miod@, jsing@
-rw-r--r--sys/arch/hppa/hppa/trap.c21
1 files changed, 15 insertions, 6 deletions
diff --git a/sys/arch/hppa/hppa/trap.c b/sys/arch/hppa/hppa/trap.c
index 14cf4eb9bd7..8dd4ae2404b 100644
--- a/sys/arch/hppa/hppa/trap.c
+++ b/sys/arch/hppa/hppa/trap.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: trap.c,v 1.106 2010/03/30 14:57:02 kettenis Exp $ */
+/* $OpenBSD: trap.c,v 1.107 2010/05/09 17:14:20 kettenis Exp $ */
/*
* Copyright (c) 1998-2004 Michael Shalayeff
@@ -716,14 +716,19 @@ process_sstep(struct proc *p, int sstep)
ss_clear_breakpoints(p);
- /* Don't touch the syscall gateway page. */
- if (sstep == 0 ||
- (p->p_md.md_regs->tf_iioq_tail & ~PAGE_MASK) == SYSCALLGATE) {
+ if (sstep == 0) {
p->p_md.md_regs->tf_ipsw &= ~PSL_T;
return (0);
}
- p->p_md.md_bpva = p->p_md.md_regs->tf_iioq_tail & ~HPPA_PC_PRIV_MASK;
+ /*
+ * Don't touch the syscall gateway page. Instead, insert a
+ * breakpoint where we're supposed to return.
+ */
+ if ((p->p_md.md_regs->tf_iioq_tail & ~PAGE_MASK) == SYSCALLGATE)
+ p->p_md.md_bpva = p->p_md.md_regs->tf_r31 & ~HPPA_PC_PRIV_MASK;
+ else
+ p->p_md.md_bpva = p->p_md.md_regs->tf_iioq_tail & ~HPPA_PC_PRIV_MASK;
/*
* Insert two breakpoint instructions; the first one might be
@@ -745,7 +750,11 @@ process_sstep(struct proc *p, int sstep)
if (error)
return (error);
- p->p_md.md_regs->tf_ipsw |= PSL_T;
+ if ((p->p_md.md_regs->tf_iioq_tail & ~PAGE_MASK) != SYSCALLGATE)
+ p->p_md.md_regs->tf_ipsw |= PSL_T;
+ else
+ p->p_md.md_regs->tf_ipsw &= ~PSL_T;
+
return (0);
}