diff options
author | Mark Kettenis <kettenis@cvs.openbsd.org> | 2010-05-09 17:14:21 +0000 |
---|---|---|
committer | Mark Kettenis <kettenis@cvs.openbsd.org> | 2010-05-09 17:14:21 +0000 |
commit | c66c771560a1325641de98c3c58bbcf0ec513a0f (patch) | |
tree | f901a737db79075df4a7806c320719cc63660dbe | |
parent | 2d078b27472b1f231d414b6ddf26224d13c81129 (diff) |
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.c | 21 |
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); } |