Exemplo n.º 1
0
R_API ut64 r_reg_set_bvalue(RReg *reg, RRegItem *item, const char *str) {
	ut64 num;
	if (!item->flags)
		return UT64_MAX;
	num = r_str_bits_from_string (str, item->flags);
	if (num == UT64_MAX) 
		r_reg_set_value (reg, item, r_num_math (NULL, str));
	else r_reg_set_value (reg, item, num);
	return num;
}
Exemplo n.º 2
0
/* restore program counter after breakpoint hit */
static int r_debug_recoil(RDebug *dbg) {
	int recoil;
	RRegItem *ri;
	if (r_debug_is_dead (dbg))
		return R_FALSE;
	r_debug_reg_sync (dbg, R_REG_TYPE_GPR, R_FALSE);
	ri = r_reg_get (dbg->reg, dbg->reg->name[R_REG_NAME_PC], -1);
	dbg->reason.bpi = NULL;
	if (ri) {
		ut64 addr = r_reg_get_value (dbg->reg, ri);
		recoil = r_bp_recoil (dbg->bp, addr);
		//eprintf ("[R2] Breakpoint recoil at 0x%"PFMT64x" = %d\n", addr, recoil);
#if __arm__
		if (recoil<1) recoil = 0; // XXX Hack :D
#else
		if (recoil<1) recoil = 0; //1; // XXX Hack :D (x86 only?)
#endif
		if (recoil) {
			dbg->reason.type = R_DEBUG_REASON_BREAKPOINT;
			dbg->reason.bpi = r_bp_get_at (dbg->bp, addr-recoil);
			dbg->reason.addr = addr - recoil;
			r_reg_set_value (dbg->reg, ri, addr-recoil);
			if (r_reg_get_value (dbg->reg, ri) != (addr-recoil)) {
				eprintf ("r_debug_recoil: Cannot set program counter\n");
				return R_FALSE;
			}
			r_debug_reg_sync (dbg, R_REG_TYPE_GPR, R_TRUE);
			//eprintf ("[BP Hit] Setting pc to 0x%"PFMT64x"\n", (addr-recoil));
			return R_TRUE;
		}
	} else eprintf ("r_debug_recoil: Cannot get program counter\n");
	return R_FALSE;
}
Exemplo n.º 3
0
/* restore program counter after breakpoint hit */
static int r_debug_recoil(RDebug *dbg) {
	int recoil;
	RRegItem *ri;
	if (r_debug_is_dead (dbg)) {
		return false;
	}
	r_debug_reg_sync (dbg, R_REG_TYPE_GPR, false);
	ri = r_reg_get (dbg->reg, dbg->reg->name[R_REG_NAME_PC], -1);
	dbg->reason.bpi = NULL;
	if (ri) {
		ut64 addr = r_reg_get_value (dbg->reg, ri);
		recoil = r_bp_recoil (dbg->bp, addr - dbg->bpsize);
		//eprintf ("[R2] Breakpoint recoil at 0x%"PFMT64x" = %d\n", addr, recoil);
		if (recoil < 1)
			recoil = 0; // XXX Hack :D
		if (recoil) {
			dbg->in_recoil = true;
			dbg->reason.type = R_DEBUG_REASON_BREAKPOINT;
			dbg->reason.bpi = r_bp_get_at (dbg->bp, addr-recoil);
			dbg->reason.addr = addr - recoil;
			r_reg_set_value (dbg->reg, ri, addr-recoil);
			if (r_reg_get_value (dbg->reg, ri) != (addr-recoil)) {
				eprintf ("r_debug_recoil: Cannot set program counter\n");
				return false;
			}
			r_debug_reg_sync (dbg, R_REG_TYPE_GPR, true);
			//eprintf ("[BP Hit] Setting pc to 0x%"PFMT64x"\n", (addr-recoil));
			return true;
		}
	} else {
		eprintf ("r_debug_recoil: Cannot get program counter\n");
	}
	return false;
}
Exemplo n.º 4
0
/* 
 * Save 4096 bytes from %esp
 * TODO: Add support for reverse stack architectures
 * Also known as r_debug_inject()
 */
R_API ut64 r_debug_execute(RDebug *dbg, const ut8 *buf, int len, int restore) {
	int orig_sz;
	ut8 stackbackup[4096];
	ut8 *backup, *orig = NULL;
	RRegItem *ri, *risp, *ripc;
	ut64 rsp, rpc, ra0 = 0LL;
	if (r_debug_is_dead (dbg))
		return R_FALSE;
	ripc = r_reg_get (dbg->reg, dbg->reg->name[R_REG_NAME_PC], R_REG_TYPE_GPR);
	risp = r_reg_get (dbg->reg, dbg->reg->name[R_REG_NAME_SP], R_REG_TYPE_GPR);
	if (ripc) {
		r_debug_reg_sync (dbg, R_REG_TYPE_GPR, R_FALSE);
		orig = r_reg_get_bytes (dbg->reg, -1, &orig_sz);
		if (orig == NULL) {
			eprintf ("Cannot get register arena bytes\n");
			return 0LL;
		}
		rpc = r_reg_get_value (dbg->reg, ripc);
		rsp = r_reg_get_value (dbg->reg, risp);

		backup = malloc (len);
		if (backup == NULL) {
			free (orig);
			return 0LL;
		}
		dbg->iob.read_at (dbg->iob.io, rpc, backup, len);
		dbg->iob.read_at (dbg->iob.io, rsp, stackbackup, len);

		r_bp_add_sw (dbg->bp, rpc+len, dbg->bpsize, R_BP_PROT_EXEC);

		/* execute code here */
		dbg->iob.write_at (dbg->iob.io, rpc, buf, len);
	//r_bp_add_sw (dbg->bp, rpc+len, 4, R_BP_PROT_EXEC);
		r_debug_continue (dbg);
	//r_bp_del (dbg->bp, rpc+len);
		/* TODO: check if stopped in breakpoint or not */

		r_bp_del (dbg->bp, rpc+len);
		dbg->iob.write_at (dbg->iob.io, rpc, backup, len);
		if (restore) {
			dbg->iob.write_at (dbg->iob.io, rsp, stackbackup, len);
		}

		r_debug_reg_sync (dbg, R_REG_TYPE_GPR, R_FALSE);
		ri = r_reg_get (dbg->reg, dbg->reg->name[R_REG_NAME_A0], R_REG_TYPE_GPR);
		ra0 = r_reg_get_value (dbg->reg, ri);
		if (restore) {
			r_reg_set_bytes (dbg->reg, -1, orig, orig_sz);
		} else {
			r_reg_set_value (dbg->reg, ripc, rpc);
		}
		r_debug_reg_sync (dbg, R_REG_TYPE_GPR, R_TRUE);
		free (backup);
		free (orig);
		eprintf ("ra0=0x%08"PFMT64x"\n", ra0);
	} else eprintf ("r_debug_execute: Cannot get program counter\n");
	return (ra0);
}
Exemplo n.º 5
0
int reg_write(RAnalEsil *esil, const char *regname, ut64 num) {
	RRegItem *reg = r_reg_get (esil->anal->reg, regname, -1);
	if (reg) {
		if (num)
			r_reg_set_value (esil->anal->reg, reg,num);
		return 1;
	}
	return 0;
}
Exemplo n.º 6
0
int gb_write(emu *e, ut64 addr, ut8 *buf, ut32 len)
{
	if(0x2000 <= addr && addr < 0x4000) {
		if(buf[0] == 0x20 || buf[0] == 0x40 || buf[0] == 0x60)
			return r_reg_set_value(e->reg, r_reg_get(e->reg, "mbcrom", -1), 0);
		if(!buf[0])
			return r_reg_set_value(e->reg, r_reg_get(e->reg, "mbcrom", -1), 0);
		return r_reg_set_value(e->reg, r_reg_get(e->reg, "mbcrom", -1), buf[0]-1);
	}
	if(0x4000 <= addr && addr < 0x6000) {
		if(!buf[0])
			return r_reg_set_value(e->reg, r_reg_get(e->reg, "mbcram", -1), 0);
		return r_reg_set_value(e->reg, r_reg_get(e->reg, "mbcram", -1), buf[0]-1);
	}
	if(0xa000 <= addr && addr < 0xc000)
		return emu_write(e, addr + (r_reg_getv(e->reg, "mbcram") << 16), buf, len);
	return emu_write(e, addr, buf, len);
}
Exemplo n.º 7
0
static int esil_set (RAnalEsil *e, const char *s, ut64 n) {
	if (e->anal && e->anal->reg) {
		RRegItem *item;
		item = r_reg_get (e->anal->reg, s, 0); // GPR only wtf?
		eprintf ("SET (%p)\n", item);
		if (item) return r_reg_set_value (e->anal->reg, item, n);
	}
	return R_TRUE;
}
Exemplo n.º 8
0
R_API boolt r_anal_cc_update (RAnal *anal, RAnalCC *cc, RAnalOp *op) {
	RRegItem *it;
	cc->off = op->addr;
	switch (op->type) {
	case R_ANAL_OP_TYPE_CALL:
	case R_ANAL_OP_TYPE_UCALL:
		cc->type = R_ANAL_CC_TYPE_STDCALL;
		// TODO: check if next instruction after call is restoring stack
		cc->jump = op->jump;
		return R_FALSE;
	case R_ANAL_OP_TYPE_SWI: // syscall
		cc->type = R_ANAL_CC_TYPE_FASTCALL;
		cc->off = op->jump;
		cc->jump = op->val; // syscall number
		return R_FALSE;
	case R_ANAL_OP_TYPE_XOR:
		if (op->src[0] && op->src[0]->reg && op->dst && op->dst->reg && op->dst->reg->name) {
			char *n1 = op->dst->reg->name;
			char *n2 = op->src[0]->reg->name;
			// XXX: must handle XOR operation properly
			// if n1 == n2 then set to 0
			if (!strcmp (n1, n2)) {
				it = r_reg_get (anal->reg, n1, R_REG_TYPE_GPR);
				r_reg_set_value (anal->reg, it, 0);
			}
		}
		return R_TRUE;
	case R_ANAL_OP_TYPE_MOV:
		if (op->dst && op->dst->reg) {
			it = r_reg_get (anal->reg, op->dst->reg->name, R_REG_TYPE_GPR);
			if (it && op->src[0])
				r_reg_set_value (anal->reg, it, op->src[0]->imm);
		}
		return R_TRUE;
	case R_ANAL_OP_TYPE_PUSH:
	case R_ANAL_OP_TYPE_UPUSH: // add argument
		cc->nargs ++;
		if (cc->nargs>0 && cc->nargs < R_ANAL_CC_ARGS)
			cc->args[cc->nargs] = op->val;
		return R_TRUE;
	}
	// must update internal stuff to recognize parm
	return R_TRUE;
}
Exemplo n.º 9
0
static bool i8051_reg_write (RReg *reg, const char *regname, ut32 num) {
	if (reg) {
		RRegItem *item = r_reg_get (reg, regname, R_REG_TYPE_GPR);
		if (item) {
			r_reg_set_value (reg, item, num);
			return true;
		}
	}
	return false;
}
Exemplo n.º 10
0
R_API ut64 r_reg_set_bvalue(RReg *reg, RRegItem *item, const char *str) {
	ut64 num = UT64_MAX;
	if (item && item->flags && str) {
		num = r_str_bits_from_string (str, item->flags);
		if (num == UT64_MAX) {
			num = r_num_math (NULL, str);
		}
		r_reg_set_value (reg, item, num);
	}
	return num;
}
Exemplo n.º 11
0
R_API int r_anal_value_set_ut64(RAnal *anal, RAnalValue *val, ut64 num) {
	if (val->memref) {
		if (anal->iob.io) {
			ut8 data[8];
			ut64 addr = r_anal_value_to_ut64 (anal, val);
			r_mem_set_num (data, val->memref, num, anal->big_endian);
			anal->iob.write_at (anal->iob.io, addr, data, val->memref);
		} else eprintf ("No IO binded to r_anal\n");
	} else {
		if (val->reg)
			r_reg_set_value (anal->reg, val->reg, num);
	}
	return R_FALSE;							//is this necessary
}
Exemplo n.º 12
0
int gb_set_reg_profile(emu *e)
{
	int ret = r_anal_set_reg_profile (e->anal);
	e->reg = e->anal->reg;
	r_reg_set_value (e->reg, r_reg_get (e->reg,"mpc",-1), ((RBinAddr *) r_list_get_n (r_bin_get_entries (e->bin), 0))->offset);
	r_reg_set_value (e->reg, r_reg_get (e->reg,"sp",-1), 0xfffe);
	r_reg_set_value (e->reg, r_reg_get (e->reg,"af",-1), 0x01b0);
	r_reg_set_value (e->reg, r_reg_get (e->reg,"bc",-1), 0x0013);
	r_reg_set_value (e->reg, r_reg_get (e->reg,"de",-1), 0x00d8);
	r_reg_set_value (e->reg, r_reg_get (e->reg,"hl",-1), 0x014d);
	r_reg_set_value (e->reg, r_reg_get (e->reg,"ime",-1), R_TRUE);
	return ret;
}
Exemplo n.º 13
0
static int esil_6502_init (RAnalEsil *esil) {
	if (esil->anal && esil->anal->reg) {		//initial values
		r_reg_set_value (esil->anal->reg, r_reg_get (esil->anal->reg, "pc", -1), 0x0000);
		r_reg_set_value (esil->anal->reg, r_reg_get (esil->anal->reg, "sp", -1), 0xff);
		r_reg_set_value (esil->anal->reg, r_reg_get (esil->anal->reg, "a", -1), 0x00);
		r_reg_set_value (esil->anal->reg, r_reg_get (esil->anal->reg, "x", -1), 0x00);
		r_reg_set_value (esil->anal->reg, r_reg_get (esil->anal->reg, "y", -1), 0x00);
		r_reg_set_value (esil->anal->reg, r_reg_get (esil->anal->reg, "flags", -1), 0x00);
	}
	return true;
}
Exemplo n.º 14
0
/*
 * Recoiling after a breakpoint has two stages:
 * 1. remove the breakpoint and fix the program counter.
 * 2. on resume, single step once and then replace the breakpoint.
 *
 * Thus, we have two functions to handle these situations.
 * r_debug_bp_hit handles stage 1.
 * r_debug_recoil handles stage 2.
 */
static int r_debug_bp_hit(RDebug *dbg, RRegItem *pc_ri, ut64 pc, RBreakpointItem **pb) {
	RBreakpointItem *b;

	if (!pb) {
		eprintf ("BreakpointItem is NULL!\n");
		return false;
	}
	/* initialize the output parameter */
	*pb = NULL;

	/* if we are tracing, update the tracing data */
	if (dbg->trace->enabled) {
		r_debug_trace_pc (dbg, pc);
	}

	/* remove all sw breakpoints for now. we'll set them back in stage 2
	 *
	 * this is necessary because while stopped we don't want any breakpoints in
	 * the code messing up our analysis.
	 */
	if (!r_bp_restore (dbg->bp, false)) { // unset sw breakpoints
		return false;
	}

	/* if we are recoiling, tell r_debug_step that we ignored a breakpoint
	 * event */
	if (!dbg->swstep && dbg->recoil_mode != R_DBG_RECOIL_NONE) {
		dbg->reason.bp_addr = 0;
		return true;
	}

	/* The MIPS ptrace has a different behaviour */
# if __mips__
	/* see if we really have a breakpoint here... */
	b = r_bp_get_at (dbg->bp, pc);
	if (!b) { /* we don't. nothing left to do */
		return true;
	}
# else
	int pc_off = dbg->bpsize;
	/* see if we really have a breakpoint here... */
	b = r_bp_get_at (dbg->bp, pc - dbg->bpsize);
	if (!b) { /* we don't. nothing left to do */
		/* Some targets set pc to breakpoint */
		b = r_bp_get_at (dbg->bp, pc);
		if (!b) {
			return true;
		}
		pc_off = 0;
	}

	/* set the pc value back */
	if (pc_off) {
		pc -= pc_off;
		if (!r_reg_set_value (dbg->reg, pc_ri, pc)) {
			eprintf ("failed to set PC!\n");
			return false;
		}
		if (!r_debug_reg_sync (dbg, R_REG_TYPE_GPR, true)) {
			eprintf ("cannot set registers!\n");
			return false;
		}
	}
# endif

	*pb = b;

	/* if we are on a software stepping breakpoint, we hide what is going on... */
	if (b->swstep) {
		dbg->reason.bp_addr = 0;
		return true;
	}

	/* setup our stage 2 */
	dbg->reason.bp_addr = b->addr;

	/* inform the user of what happened */
	if (dbg->hitinfo) {
		eprintf ("hit %spoint at: %"PFMT64x "\n",
				b->trace ? "trace" : "break", pc);
	}

	/* now that we've cleaned up after the breakpoint, call the other
	 * potential breakpoint handlers
	 */
	if (dbg->corebind.core && dbg->corebind.bphit) {
		dbg->corebind.bphit (dbg->corebind.core, b);
	}
	return true;
}
Exemplo n.º 15
0
int gb_step (emu *e, ut8 *buf)
{
	int ret = R_FALSE;
	GBCpuStats *cpu = (GBCpuStats *)e->data;
	cpu->cycles += e->anop->cycles;
	r_reg_set_value (e->reg, r_reg_get (e->reg, "pc", -1), r_reg_getv(e->reg, "pc") + e->op->size);
	switch (e->anop->type) {
		case R_ANAL_OP_TYPE_NOP:
			ret = R_TRUE;
		case R_ANAL_OP_TYPE_TRAP:
		case R_ANAL_OP_TYPE_ILL:
			break;
		case R_ANAL_OP_TYPE_MOV:
			ret = gb_mov (e);
			break;
		case R_ANAL_OP_TYPE_PUSH:
			ret = gb_push (e);
			break;
		case R_ANAL_OP_TYPE_POP:
			ret = gb_pop (e);
			break;
		case R_ANAL_OP_TYPE_JMP:
			ret = gb_jmp (e);
			break;
		case R_ANAL_OP_TYPE_CJMP:
			ret = gb_cjmp (e);
			break;
		case R_ANAL_OP_TYPE_UJMP:
			ret = gb_ujmp (e);
			break;
		case R_ANAL_OP_TYPE_UCALL:
		case R_ANAL_OP_TYPE_CALL:
			ret = gb_call (e);
			break;
		case R_ANAL_OP_TYPE_CCALL:
			ret = gb_ccall (e);
			break;
		case R_ANAL_OP_TYPE_RET:
			ret = gb_ret (e);
			break;
		case R_ANAL_OP_TYPE_CRET:
			ret = gb_cret (e);
			break;
		case R_ANAL_OP_TYPE_CMP:
			ret = gb_cp (e);
			break;
		case R_ANAL_OP_TYPE_SUB:
			ret = gb_sub (e);
			break;
		case R_ANAL_OP_TYPE_ADD:
			ret = gb_add (e);
			break;
		case R_ANAL_OP_TYPE_XOR:
			ret = gb_xor (e);
			break;
		case R_ANAL_OP_TYPE_AND:
			ret = gb_and (e);
			break;
		case R_ANAL_OP_TYPE_OR:
			ret = gb_or (e);
			break;
		case R_ANAL_OP_TYPE_ACMP:
			ret = gb_bit (e);
			break;
		case R_ANAL_OP_TYPE_ROL:
			ret = gb_rol (e);
			break;
		case R_ANAL_OP_TYPE_STORE:
			ret = gb_store (e);
			break;
		case R_ANAL_OP_TYPE_LOAD:
			ret = gb_load (e);
			break;
	}
	gb_interrupts (e);
	cpu->cycles &= 0xffffff;	//prevent overflows
	cpu->prev_cycles = cpu->cycles;
	return ret;
}
Exemplo n.º 16
0
R_API bool r_reg_set_value_by_role(RReg *reg, RRegisterId role, ut64 val) {
	// TODO use mapping from RRegisterId to RRegItem (via RRegSet)
	RRegItem *r = r_reg_get (reg, r_reg_get_name (reg, role), -1);
	return r_reg_set_value (reg, r, val);
}
Exemplo n.º 17
0
int main() {
	int i;
	int foo[128];
	const char *type;
	struct r_reg_t *reg;

	for (i=0;i<128;i++)
		foo[i] = i;

	reg = r_reg_new ();
	r_reg_set_profile (reg, "./test.regs");
	r_reg_read_regs (reg, (const ut8 *)foo, sizeof(foo));
{
	ut64 a;
	RRegItem *item;
	item = r_reg_get (reg, "eflags", R_REG_TYPE_GPR);
	r_reg_set_value (reg, item, 0x00000346); //0xffffffffffff);
	a = r_reg_get_value (reg, item);
	eprintf ("A32 = 0x%x\n", (int)a);
	if ((int)a != -1) {
		eprintf ("1 FAIL\n");
	}

print_eflags_bits (reg);
	item = r_reg_get (reg, "zf", R_REG_TYPE_GPR);
	a = r_reg_get_value (reg, item);
	eprintf ("A = %d\n", (int)a);
	if (a != 1) {
		eprintf ("2 FAIL\n");
	}

	item = r_reg_get (reg, "zf", R_REG_TYPE_GPR);
	r_reg_set_value (reg, item, 1);
	a = r_reg_get_value (reg, item);
	eprintf ("A = %d\n", (int)a);
	if (a != 1) {
		eprintf ("3 FAIL\n");
	}
	r_reg_set_value (reg, item, 0);
	a = r_reg_get_value (reg, item);
	eprintf ("A = %d\n", (int)a);
	if (a != 0) {
		eprintf ("4 FAIL\n");
	}
}
	show_regs (reg, 1); //32);

exit (0);
	show_regs (reg, 32);
	/* --- */
	r_reg_set_profile(reg, "../p/x86-linux.regs");
	printf ("Program counter is named: %s\n", r_reg_get_name (reg, R_REG_NAME_PC));
	show_regs (reg, 32);
	r_reg_set_value(reg, r_reg_get(reg, "eax", -1), 0x414141);
	r_reg_set_value(reg, r_reg_get(reg, "ecx", -1), 666);
	show_regs(reg, 32);
	r_reg_set_value(reg, r_reg_get(reg, "al", -1), 0x22);
	show_regs(reg, 33);

	r_reg_set_value (reg, r_reg_get (reg, "zero", -1), 0);
	show_regs (reg, 1);
	r_reg_set_value (reg, r_reg_get (reg, "zero", -1), 1);
	show_regs (reg, 1);

	for (i=0; (type=r_reg_get_type (i));i++)
		printf (" - %s\n", type);

	r_reg_arena_push (reg);
	r_reg_arena_pop (reg);

	r_reg_arena_push (reg);
	r_reg_arena_push (reg);
	r_reg_arena_push (reg);
	r_reg_arena_pop (reg);
	r_reg_arena_pop (reg);
	r_reg_arena_push (reg);
	r_reg_arena_pop (reg);
	r_reg_arena_pop (reg);
/*
	r_reg_arena_pop(reg);
	r_reg_arena_pop(reg);
	r_reg_arena_pop(reg);
	r_reg_arena_pop(reg);
*/
	return 0;
}
Exemplo n.º 18
0
/*
 * Recoiling after a breakpoint has two stages:
 * 1. remove the breakpoint and fix the program counter.
 * 2. on resume, single step once and then replace the breakpoint.
 *
 * Thus, we have two functions to handle these situations.
 * r_debug_bp_hit handles stage 1.
 * r_debug_recoil handles stage 2.
 */
static int r_debug_bp_hit(RDebug *dbg, RRegItem *pc_ri, ut64 pc) {
	RBreakpointItem *b;

	/* if we are tracing, update the tracing data */
	if (dbg->trace->enabled) {
		r_debug_trace_pc (dbg, pc);
	}

	/* remove all sw breakpoints for now. we'll set them back in stage 2
	 *
	 * this is necessary because while stopped we don't want any breakpoints in
	 * the code messing up our analysis.
	 */
	if (!r_bp_restore (dbg->bp, false)) { // unset sw breakpoints
		return false;
	}

	/* if we are recoiling, tell r_debug_step that we ignored a breakpoint
	 * event */
	if (!dbg->swstep && dbg->recoil_mode != R_DBG_RECOIL_NONE) {
		dbg->reason.bp_addr = 0;
		return true;
	}

	/* see if we really have a breakpoint here... */
	b = r_bp_get_at (dbg->bp, pc - dbg->bpsize);
	if (!b) { /* we don't. nothing left to do */
		return true;
	}

	/* set the pc value back */
	pc -= b->size;
	if (!r_reg_set_value (dbg->reg, pc_ri, pc)) {
		eprintf ("failed to set PC!\n");
		return false;
	}
	if (!r_debug_reg_sync (dbg, R_REG_TYPE_GPR, true)) {
		eprintf ("cannot set registers!\n");
		return false;
	}

	/* if we are on a software stepping breakpoint, we hide what is going on... */
	if (b->swstep) {
		dbg->reason.bp_addr = 0;
		return true;
	}

	/* setup our stage 2 */
	dbg->reason.bp_addr = b->addr;

	/* inform the user of what happened */
	eprintf ("hit %spoint at: %"PFMT64x "\n",
			b->trace ? "trace" : "break", pc);

	/* now that we've cleaned up after the breakpoint, call the other
	 * potential breakpoint handlers
	 */
	if (dbg->corebind.core && dbg->corebind.bphit) {
		dbg->corebind.bphit (dbg->corebind.core, b);
	}

	/* XXX(jjd): i don't think this goes here...
	if (b->trace) {
		r_debug_step (dbg, 1);
		goto repeat;
	}
	 */
	return true;
}