extractedLnx/linux-2.6.27/arch/mn10300/kernel/gdb-stub.c_gdbstub_single_step.c
static int gdbstub_single_step(struct pt_regs *regs)
{
unsigned size;
uint32_t x;
uint8_t cur, *pc, *sp;
step_bp[0].addr = NULL;
step_bp[0].opcode[0] = 0;
step_bp[0].opcode[1] = 0;
step_bp[1].addr = NULL;
step_bp[1].opcode[0] = 0;
step_bp[1].opcode[1] = 0;
x = 0;
pc = (u8 *) regs->pc;
sp = (u8 *) (regs + 1);
if (gdbstub_read_byte(pc, &cur) < 0)
return -EFAULT;
gdbstub_bkpt("Single Step from %p { %02x }\n", pc, cur);
gdbstub_flush_caches = 1;
size = gdbstub_insn_sizes[cur];
if (size > 0) {
if (!__gdbstub_mark_bp(pc + size, 0))
goto fault;
} else {
switch (cur) {
/* Bxx (d8,PC) */
case 0xc0:
case 0xc1:
case 0xc2:
case 0xc3:
case 0xc4:
case 0xc5:
case 0xc6:
case 0xc7:
case 0xc8:
case 0xc9:
case 0xca:
if (gdbstub_read_byte(pc + 1, (u8 *) &x) < 0)
goto fault;
if (!__gdbstub_mark_bp(pc + 2, 0))
goto fault;
if ((x < 0 || x > 2) &&
!__gdbstub_mark_bp(pc + (s8) x, 1))
goto fault;
break;
/* LXX (d8,PC) */
case 0xd0:
case 0xd1:
case 0xd2:
case 0xd3:
case 0xd4:
case 0xd5:
case 0xd6:
case 0xd7:
case 0xd8:
case 0xd9:
case 0xda:
if (!__gdbstub_mark_bp(pc + 1, 0))
goto fault;
if (regs->pc != regs->lar &&
!__gdbstub_mark_bp((u8 *) regs->lar, 1))
goto fault;
break;
/* SETLB - loads the next for bytes into the LIR
* register */
case 0xdb:
if (!__gdbstub_mark_bp(pc + 1, 0))
goto fault;
break;
/* JMP (d16,PC) or CALL (d16,PC) */
case 0xcc:
case 0xcd:
if (gdbstub_read_byte(pc + 1, ((u8 *) &x) + 0) < 0 ||
gdbstub_read_byte(pc + 2, ((u8 *) &x) + 1) < 0)
goto fault;
if (!__gdbstub_mark_bp(pc + (s16) x, 0))
goto fault;
break;
/* JMP (d32,PC) or CALL (d32,PC) */
case 0xdc:
case 0xdd:
if (gdbstub_read_byte(pc + 1, ((u8 *) &x) + 0) < 0 ||
gdbstub_read_byte(pc + 2, ((u8 *) &x) + 1) < 0 ||
gdbstub_read_byte(pc + 3, ((u8 *) &x) + 2) < 0 ||
gdbstub_read_byte(pc + 4, ((u8 *) &x) + 3) < 0)
goto fault;
if (!__gdbstub_mark_bp(pc + (s32) x, 0))
goto fault;
break;
/* RETF */
case 0xde:
if (!__gdbstub_mark_bp((u8 *) regs->mdr, 0))
goto fault;
break;
/* RET */
case 0xdf:
if (gdbstub_read_byte(pc + 2, (u8 *) &x) < 0)
goto fault;
sp += (s8)x;
if (gdbstub_read_byte(sp + 0, ((u8 *) &x) + 0) < 0 ||
gdbstub_read_byte(sp + 1, ((u8 *) &x) + 1) < 0 ||
gdbstub_read_byte(sp + 2, ((u8 *) &x) + 2) < 0 ||
gdbstub_read_byte(sp + 3, ((u8 *) &x) + 3) < 0)
goto fault;
if (!__gdbstub_mark_bp((u8 *) x, 0))
goto fault;
break;
case 0xf0:
if (gdbstub_read_byte(pc + 1, &cur) < 0)
goto fault;
if (cur >= 0xf0 && cur <= 0xf7) {
/* JMP (An) / CALLS (An) */
switch (cur & 3) {
case 0: x = regs->a0; break;
case 1: x = regs->a1; break;
case 2: x = regs->a2; break;
case 3: x = regs->a3; break;
}
if (!__gdbstub_mark_bp((u8 *) x, 0))
goto fault;
} else if (cur == 0xfc) {
/* RETS */
if (gdbstub_read_byte(
sp + 0, ((u8 *) &x) + 0) < 0 ||
gdbstub_read_byte(
sp + 1, ((u8 *) &x) + 1) < 0 ||
gdbstub_read_byte(
sp + 2, ((u8 *) &x) + 2) < 0 ||
gdbstub_read_byte(
sp + 3, ((u8 *) &x) + 3) < 0)
goto fault;
if (!__gdbstub_mark_bp((u8 *) x, 0))
goto fault;
} else if (cur == 0xfd) {
/* RTI */
if (gdbstub_read_byte(
sp + 4, ((u8 *) &x) + 0) < 0 ||
gdbstub_read_byte(
sp + 5, ((u8 *) &x) + 1) < 0 ||
gdbstub_read_byte(
sp + 6, ((u8 *) &x) + 2) < 0 ||
gdbstub_read_byte(
sp + 7, ((u8 *) &x) + 3) < 0)
goto fault;
if (!__gdbstub_mark_bp((u8 *) x, 0))
goto fault;
} else {
if (!__gdbstub_mark_bp(pc + 2, 0))
goto fault;
}
break;
/* potential 3-byte conditional branches */
case 0xf8:
if (gdbstub_read_byte(pc + 1, &cur) < 0)
goto fault;
if (!__gdbstub_mark_bp(pc + 3, 0))
goto fault;
if (cur >= 0xe8 && cur <= 0xeb) {
if (gdbstub_read_byte(
pc + 2, ((u8 *) &x) + 0) < 0)
goto fault;
if ((x < 0 || x > 3) &&
!__gdbstub_mark_bp(pc + (s8) x, 1))
goto fault;
}
break;
case 0xfa:
if (gdbstub_read_byte(pc + 1, &cur) < 0)
goto fault;
if (cur == 0xff) {
/* CALLS (d16,PC) */
if (gdbstub_read_byte(
pc + 2, ((u8 *) &x) + 0) < 0 ||
gdbstub_read_byte(
pc + 3, ((u8 *) &x) + 1) < 0)
goto fault;
if (!__gdbstub_mark_bp(pc + (s16) x, 0))
goto fault;
} else {
if (!__gdbstub_mark_bp(pc + 4, 0))
goto fault;
}
break;
case 0xfc:
if (gdbstub_read_byte(pc + 1, &cur) < 0)
goto fault;
if (cur == 0xff) {
/* CALLS (d32,PC) */
if (gdbstub_read_byte(
pc + 2, ((u8 *) &x) + 0) < 0 ||
gdbstub_read_byte(
pc + 3, ((u8 *) &x) + 1) < 0 ||
gdbstub_read_byte(
pc + 4, ((u8 *) &x) + 2) < 0 ||
gdbstub_read_byte(
pc + 5, ((u8 *) &x) + 3) < 0)
goto fault;
if (!__gdbstub_mark_bp(
pc + (s32) x, 0))
goto fault;
} else {
if (!__gdbstub_mark_bp(
pc + 6, 0))
goto fault;
}
break;
}
}
gdbstub_bkpt("Step: %02x at %p; %02x at %p\n",
step_bp[0].opcode[0], step_bp[0].addr,
step_bp[1].opcode[0], step_bp[1].addr);
if (step_bp[0].addr) {
#ifdef GDBSTUB_USE_F7F7_AS_BREAKPOINT
if (gdbstub_write_byte(0xF7, step_bp[0].addr + 0) < 0 ||
gdbstub_write_byte(0xF7, step_bp[0].addr + 1) < 0)
goto fault;
#else
if (gdbstub_write_byte(0xFF, step_bp[0].addr + 0) < 0)
goto fault;
#endif
}
if (step_bp[1].addr) {
#ifdef GDBSTUB_USE_F7F7_AS_BREAKPOINT
if (gdbstub_write_byte(0xF7, step_bp[1].addr + 0) < 0 ||
gdbstub_write_byte(0xF7, step_bp[1].addr + 1) < 0)
goto fault;
#else
if (gdbstub_write_byte(0xFF, step_bp[1].addr + 0) < 0)
goto fault;
#endif
}
return 0;
fault:
/* uh-oh - silly address alert, try and restore things */
__gdbstub_restore_bp();
return -EFAULT;
}
Generated by GNU enscript 1.6.4.