summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiod Vallat <miod@cvs.openbsd.org>2005-12-04 12:14:11 +0000
committerMiod Vallat <miod@cvs.openbsd.org>2005-12-04 12:14:11 +0000
commit1a6b6052298833348054d8c0369aa3625e92782a (patch)
treefb419b7c5f6d4642f9a5ed077eec8390bdff3dd4
parent94996bfa764162035342c47b5c50a43f25ba97e7 (diff)
Simplify ptrace branch handling code.
-rw-r--r--sys/arch/m88k/m88k/trap.c148
1 files changed, 41 insertions, 107 deletions
diff --git a/sys/arch/m88k/m88k/trap.c b/sys/arch/m88k/m88k/trap.c
index bfcda591eb7..9919a23355b 100644
--- a/sys/arch/m88k/m88k/trap.c
+++ b/sys/arch/m88k/m88k/trap.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: trap.c,v 1.25 2005/12/03 14:30:06 miod Exp $ */
+/* $OpenBSD: trap.c,v 1.26 2005/12/04 12:14:10 miod Exp $ */
/*
* Copyright (c) 2004, Miodrag Vallat.
* Copyright (c) 1998 Steve Murphree, Jr.
@@ -107,6 +107,7 @@ const char *trap_type[] = {
};
const int trap_types = sizeof trap_type / sizeof trap_type[0];
+#ifdef M88100
const char *pbus_exception_type[] = {
"Success (No Fault)",
"unknown 1",
@@ -117,6 +118,7 @@ const char *pbus_exception_type[] = {
"Supervisor Violation",
"Write Violation",
};
+#endif
static inline void
userret(struct proc *p, struct trapframe *frame, u_quad_t oticks)
@@ -258,9 +260,6 @@ m88100_trap(unsigned type, struct trapframe *frame)
break;
case T_INT:
case T_INT+T_USER:
- /* This function pointer is set in machdep.c
- It calls m188_ext_int or sbc_ext_int depending
- on the value of brdtyp - smurph */
curcpu()->ci_intrdepth++;
md_interrupt_func(T_INT, frame);
curcpu()->ci_intrdepth--;
@@ -1111,15 +1110,6 @@ m88100_syscall(register_t code, struct trapframe *tf)
callp = p->p_emul->e_sysent;
nsys = p->p_emul->e_nsysent;
-#ifdef DIAGNOSTIC
- if (USERMODE(tf->tf_epsr) == 0)
- panic("syscall");
- if (curpcb != &p->p_addr->u_pcb)
- panic("syscall curpcb/ppcb");
- if (tf != (struct trapframe *)&curpcb->user_state)
- panic("syscall trapframe");
-#endif
-
sticks = p->p_sticks;
p->p_md.md_tf = tf;
@@ -1269,15 +1259,6 @@ m88110_syscall(register_t code, struct trapframe *tf)
callp = p->p_emul->e_sysent;
nsys = p->p_emul->e_nsysent;
-#ifdef DIAGNOSTIC
- if (USERMODE(tf->tf_epsr) == 0)
- panic("syscall");
- if (curpcb != &p->p_addr->u_pcb)
- panic("syscall curpcb/ppcb");
- if (tf != (struct trapframe *)&curpcb->user_state)
- panic("syscall trapframe");
-#endif
-
sticks = p->p_sticks;
p->p_md.md_tf = tf;
@@ -1363,13 +1344,6 @@ m88110_syscall(register_t code, struct trapframe *tf)
switch (error) {
case 0:
- /*
- * If fork succeeded and we are the child, our stack
- * has moved and the pointer tf is no longer valid,
- * and p is wrong. Compute the new trapframe pointer.
- * (The trap frame invariably resides at the
- * tippity-top of the u. area.)
- */
tf->tf_r[2] = rval[0];
tf->tf_r[3] = rval[1];
tf->tf_epsr &= ~PSR_C;
@@ -1467,12 +1441,9 @@ child_return(arg)
#include <sys/ptrace.h>
-vaddr_t ss_branch_taken(u_int, vaddr_t, u_int (*func)(u_int, struct reg *),
- struct reg *);
-u_int ss_getreg_val(u_int, struct reg *);
+vaddr_t ss_branch_taken(u_int, vaddr_t, struct reg *);
int ss_get_value(struct proc *, vaddr_t, u_int *);
-int ss_inst_branch(unsigned);
-int ss_inst_delayed(unsigned);
+int ss_inst_branch_or_call(u_int);
int ss_put_breakpoint(struct proc *, vaddr_t, vaddr_t *, u_int *);
#define SYSCALL_INSTR 0xf000d080 /* tb0 0,r0,128 */
@@ -1514,114 +1485,78 @@ ss_put_value(struct proc *p, vaddr_t addr, u_int value)
}
/*
- * ss_branch_taken(instruction, program counter, func, func_data)
+ * ss_branch_taken(instruction, pc, regs)
*
* instruction will be a control flow instruction location at address pc.
* Branch taken is supposed to return the address to which the instruction
- * would jump if the branch is taken. Func can be used to get the current
- * register values when invoked with a register number and func_data as
- * arguments.
+ * would jump if the branch is taken.
*
- * If the instruction is not a control flow instruction, panic.
+ * This is different from branch_taken() in ddb, as we also need to process
+ * system calls.
*/
vaddr_t
-ss_branch_taken(u_int inst, vaddr_t pc, u_int (*func)(u_int, struct reg *),
- struct reg *func_data)
+ss_branch_taken(u_int inst, vaddr_t pc, struct reg *regs)
{
- /* check for system call */
- if (inst == SYSCALL_INSTR) {
- /*
- * The regular (pc + 4) breakpoint will match the error
- * return. Successfull system calls return at (pc + 8),
- * so we'll set up a branch breakpoint there.
- */
- return (pc + 8);
- }
+ u_int regno;
- /* check if br/bsr */
- if ((inst & 0xf0000000) == 0xc0000000) {
- /* signed 26 bit pc relative displacement, shift left two bits */
+ /*
+ * Quick check of the instruction. Note that we know we are only
+ * invoked if ss_inst_branch_or_call() returns TRUE, so we do not
+ * need to repeat the jpm, jsr and syscall stricter checks here.
+ */
+ switch (inst >> (32 - 5)) {
+ case 0x18: /* br */
+ case 0x19: /* bsr */
+ /* signed 26 bit pc relative displacement, shift left 2 bits */
inst = (inst & 0x03ffffff) << 2;
/* check if sign extension is needed */
if (inst & 0x08000000)
inst |= 0xf0000000;
return (pc + inst);
- }
- /* check if bb0/bb1/bcnd case */
- switch (inst & 0xf8000000) {
- case 0xd0000000: /* bb0 */
- case 0xd8000000: /* bb1 */
- case 0xe8000000: /* bcnd */
- /* signed 16 bit pc relative displacement, shift left two bits */
+ case 0x1a: /* bb0 */
+ case 0x1b: /* bb1 */
+ case 0x1d: /* bcnd */
+ /* signed 16 bit pc relative displacement, shift left 2 bits */
inst = (inst & 0x0000ffff) << 2;
/* check if sign extension is needed */
if (inst & 0x00020000)
inst |= 0xfffc0000;
return (pc + inst);
- }
-
- /* check jmp/jsr case */
- /* check bits 5-31, skipping 10 & 11 */
- if ((inst & 0xfffff3e0) == 0xf400c000)
- return (*func)(inst & 0x1f, func_data); /* the register value */
- /* can't happen */
- return (0);
-}
+ case 0x1e: /* jmp or jsr */
+ regno = inst & 0x1f; /* get the register value */
+ return (regno == 0 ? 0 : regs->r[regno]);
-/*
- * ss_getreg_val - handed a register number and an exception frame.
- * Returns the value of the register in the specified
- * frame. Only makes sense for general registers.
- */
-u_int
-ss_getreg_val(u_int regno, struct reg *regs)
-{
- return (regno == 0 ? 0 : regs->r[regno]);
+ default: /* system call */
+ /*
+ * The regular (pc + 4) breakpoint will match the error
+ * return. Successfull system calls return at (pc + 8),
+ * so we'll set up a branch breakpoint there.
+ */
+ return (pc + 8);
+ }
}
int
-ss_inst_branch(u_int ins)
+ss_inst_branch_or_call(u_int ins)
{
/* check high five bits */
-
switch (ins >> (32 - 5)) {
case 0x18: /* br */
+ case 0x19: /* bsr */
case 0x1a: /* bb0 */
case 0x1b: /* bb1 */
case 0x1d: /* bcnd */
return (TRUE);
- break;
- case 0x1e: /* could be jmp */
- if ((ins & 0xfffffbe0) == 0xf400c000)
+ case 0x1e: /* could be jmp or jsr */
+ if ((ins & 0xfffff3e0) == 0xf400c000)
return (TRUE);
}
return (FALSE);
}
-/* ss_inst_delayed - this instruction is followed by a delay slot. Could be
- br.n, bsr.n bb0.n, bb1.n, bcnd.n or jmp.n or jsr.n */
-
-int
-ss_inst_delayed(u_int ins)
-{
- /* check the br, bsr, bb0, bb1, bcnd cases */
- switch ((ins & 0xfc000000) >> (32 - 6)) {
- case 0x31: /* br */
- case 0x33: /* bsr */
- case 0x35: /* bb0 */
- case 0x37: /* bb1 */
- case 0x3b: /* bcnd */
- return (TRUE);
- }
-
- /* check the jmp, jsr cases */
- /* mask out bits 0-4, bit 11 */
- return (((ins & 0xfffff7e0) == 0xf400c400) ? TRUE : FALSE);
-}
-
int
ss_put_breakpoint(struct proc *p, vaddr_t va, vaddr_t *bpva, u_int *bpsave)
{
@@ -1676,9 +1611,8 @@ process_sstep(struct proc *p, int sstep)
* Find if this instruction may cause a branch, and set up a breakpoint
* at the branch location.
*/
- if (ss_inst_branch(instr) || inst_call(instr) || inst_return(instr) ||
- instr == SYSCALL_INSTR) {
- brpc = ss_branch_taken(instr, pc, ss_getreg_val, sstf);
+ if (ss_inst_branch_or_call(instr) || instr == SYSCALL_INSTR) {
+ brpc = ss_branch_taken(instr, pc, sstf);
/* self-branches are hopeless */
if (brpc != pc && brpc != 0) {