Ejemplo n.º 1
0
/*
 * Singlestep is implemented by disabling the current kprobe and setting one
 * on the next instruction, following branches. Two probes are set if the
 * branch is conditional.
 */
static void __kprobes prepare_singlestep(struct kprobe *p, struct pt_regs *regs)
{
	kprobe_opcode_t *addr = NULL;
	saved_current_opcode.addr = (kprobe_opcode_t *) (regs->pc);
	addr = saved_current_opcode.addr;

	if (p != NULL) {
		arch_disarm_kprobe(p);

		if (OPCODE_JSR(p->opcode) || OPCODE_JMP(p->opcode)) {
			unsigned int reg_nr = ((p->opcode >> 8) & 0x000F);
			saved_next_opcode.addr =
			    (kprobe_opcode_t *) regs->regs[reg_nr];
		} else if (OPCODE_BRA(p->opcode) || OPCODE_BSR(p->opcode)) {
Ejemplo n.º 2
0
static void __kprobes prepare_singlestep(struct kprobe *p, struct pt_regs *regs)
{
	__get_cpu_var(saved_current_opcode).addr = (kprobe_opcode_t *)regs->pc;

	if (p != NULL) {
		struct kprobe *op1, *op2;

		arch_disarm_kprobe(p);

		op1 = &__get_cpu_var(saved_next_opcode);
		op2 = &__get_cpu_var(saved_next_opcode2);

		if (OPCODE_JSR(p->opcode) || OPCODE_JMP(p->opcode)) {
			unsigned int reg_nr = ((p->opcode >> 8) & 0x000F);
			op1->addr = (kprobe_opcode_t *) regs->regs[reg_nr];
		} else if (OPCODE_BRA(p->opcode) || OPCODE_BSR(p->opcode)) {
Ejemplo n.º 3
0
/*
  Analyzes the next instruction, to see where the program
  will go to when it runs.  Returns the destination address.
*/
static long get_stepi_dest (void)
	{
	short op = *(short*)register_file.pc;
	long addr = register_file.pc + 2;


	/* BT, BT/S (untested!), BF and BF/S (untested!)
	   TODO: test delay-slot branches */
	if (((OPCODE_BT(op) || OPCODE_BTS(op))
		 && (register_file.sr & SR_T_BIT_MASK))
		|| ((OPCODE_BF(op) || OPCODE_BFS(op))
			&& !(register_file.sr & SR_T_BIT_MASK)))
		{
    
		/* we're taking the branch */
    
		/* per 6.12 of the SH1/SH2 programming manual,
		   PC+disp is address of the second instruction
		   after the branch instruction, so we have to add 4 */
		/* TODO: spend more time understanding this magic */ 
		addr = register_file.pc + 4 + OPCODE_BTF_DISP(op);
		}
  
	/* BRA */
	else if (OPCODE_BRA(op))
		addr = register_file.pc + 4 + OPCODE_BRA_DISP(op);
  
	/* BRAF */
	else if (OPCODE_BRAF(op))
		addr = register_file.pc + 4
		  + register_file.r[OPCODE_BRAF_REG(op)];
  
	/* BSR */
	else if (OPCODE_BSR(op))
		addr = register_file.pc + 4 + OPCODE_BSR_DISP(op);
  
	/* BSRF */
	else if (OPCODE_BSRF(op))
		addr = register_file.pc + 4
		  + register_file.r[OPCODE_BSRF_REG(op)];

	/* JMP */
	else if (OPCODE_JMP(op))
		addr = register_file.r[OPCODE_JMP_REG(op)];

	/* JSR */
	else if (OPCODE_JSR(op))
		addr = register_file.r[OPCODE_JSR_REG(op)];
  
	/* RTS */
	else if (OPCODE_RTS(op))
		addr = register_file.pr;

	/* RTE */
	else if (OPCODE_RTE(op))
		addr = *(unsigned long*)(register_file.r[15]);

	/* TRAPA */
	else if (OPCODE_TRAPA(op))
		addr = register_file.vbr[OPCODE_TRAPA_DISP(op)];

	return addr;
	}