Enscript Output

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.