Add ara command and fix RReg.arena.push/pop implementation

This commit is contained in:
pancake 2015-11-24 00:58:03 +01:00
parent b172333386
commit cffa44b2f7
7 changed files with 109 additions and 36 deletions

View File

@ -1097,6 +1097,7 @@ static void ar_show_help(RCore *core) {
"Usage: ar", "", "# Analysis Registers",
"ar", "", "Show 'gpr' registers",
"ar0", "", "Reset register arenas to 0",
"ara", "", "Manage register arenas",
"ar", " 16", "Show 16 bit registers",
"ar", " 32", "Show 32 bit registers",
"ar", " all", "Show all bit registers",
@ -1136,7 +1137,7 @@ void cmd_anal_reg(RCore *core, const char *str) {
use_color = NULL;
}
switch (str[0]) {
case 'l':
case 'l': // "arl"
{
RRegSet *rs = r_reg_regset_get (core->anal->reg, R_REG_TYPE_GPR);
if (rs) {
@ -1148,9 +1149,36 @@ void cmd_anal_reg(RCore *core, const char *str) {
}
}
break;
case '0':
case '0': // "ar"
r_reg_arena_zero (core->anal->reg);
break;
case 'a': // "ara"
switch (str[1]) {
case '+':
r_reg_arena_push (core->anal->reg);
break;
case '-':
r_reg_arena_pop (core->anal->reg);
break;
default:
{
int i, j;
RRegArena *a;
RListIter *iter;
for (i=0; i<R_REG_TYPE_LAST; i++) {
RRegSet *rs = &core->anal->reg->regset[i];
j = 0;
r_list_foreach (rs->pool, iter, a) {
r_cons_printf ("%s %p %d %d %s %d\n",
(a == rs->arena)? "*":".", a,
i, j, r_reg_get_type (i), a->size);
j++;
}
}
}
break;
}
break;
case '?':
if (str[1]) {
ut64 off = r_reg_getv (core->anal->reg, str+1);

View File

@ -992,8 +992,7 @@ static void handle_update_ref_lines (RCore *core, RDisasmState *ds) {
}
static int perform_disassembly(RCore *core, RDisasmState *ds, ut8 *buf, int len) {
int ret;
ret = r_asm_disassemble (core->assembler, &ds->asmop, buf, len);
int ret = r_asm_disassemble (core->assembler, &ds->asmop, buf, len);
if (ds->asmop.size < 1) ds->asmop.size = 1;
ds->oplen = ds->asmop.size;
@ -1609,13 +1608,12 @@ static void handle_print_core_vmode(RCore *core, RDisasmState *ds) {
}
}
// modifies anal register state
static void handle_print_cc_update (RCore *core, RDisasmState *ds) {
// declare static since this variable is reused locally, and needs to maintain
// state
static RAnalCC cc = {0};
if (!ds->show_comments)
return;
if (!ds->show_fcncalls)
if (!ds->show_comments || !ds->show_fcncalls)
return;
if (!r_anal_cc_update (core->anal, &cc, &ds->analop)) {
if (ds->show_functions) {
@ -2041,7 +2039,7 @@ static ut8 *regstate = NULL;
static void handle_print_esil_anal_init(RCore *core, RDisasmState *ds) {
const char *pc = r_reg_get_name (core->anal->reg, R_REG_NAME_PC);
opc = r_reg_getv (core->anal->reg, pc);
if (!opc) opc = core->offset;
if (!opc || opc==UT64_MAX) opc = core->offset;
if (!ds->show_emu) {
return;
}
@ -2055,11 +2053,13 @@ static void handle_print_esil_anal_init(RCore *core, RDisasmState *ds) {
}
static void handle_print_esil_anal_fini(RCore *core, RDisasmState *ds) {
const char *pc = r_reg_get_name (core->anal->reg, R_REG_NAME_PC);
r_reg_arena_poke (core->anal->reg, regstate);
r_reg_setv (core->anal->reg, pc, opc);
free (regstate);
regstate = NULL;
if (ds->show_emu && regstate) {
const char *pc = r_reg_get_name (core->anal->reg, R_REG_NAME_PC);
r_reg_arena_poke (core->anal->reg, regstate);
r_reg_setv (core->anal->reg, pc, opc);
free (regstate);
regstate = NULL;
}
}
static void handle_print_bbline(RCore *core, RDisasmState *ds) {
@ -2095,14 +2095,12 @@ static void handle_print_bbline(RCore *core, RDisasmState *ds) {
}
}
// modifies anal register state
static void handle_print_esil_anal(RCore *core, RDisasmState *ds) {
RAnalEsil *esil = core->anal->esil;
const char *pc;
int i, ioc, nargs;
if (!esil || !ds->show_comments) {
return;
}
if (!ds->show_emu) {
if (!esil || !ds->show_comments || !ds->show_emu) {
return;
}
ioc = r_config_get_i (core->config, "io.cache");
@ -2305,11 +2303,11 @@ R_API int r_core_print_disasm(RPrint *p, RCore *core, ut64 addr, ut8 *buf, int l
RAnalFunction *f = NULL;
ut8 *nbuf = NULL;
RDisasmState *ds;
r_reg_arena_push (core->anal->reg);
//r_cons_printf ("len =%d l=%d ib=%d limit=%d\n", len, l, invbreak, p->limit);
// TODO: import values from debugger is possible
// TODO: allow to get those register snapshots from traces
// TODO: per-function register state trace
// XXX - is there a better way to reset a the analysis counter so that
// when code is disassembled, it can actually find the correct offsets
if (core->anal->cur && core->anal->cur->reset_counter) {
@ -2370,7 +2368,6 @@ toro:
dorepeat = 0;
break;
}
r_core_seek_archbits (core, ds->at); // slow but safe
ds->hint = r_core_hint_begin (core, ds->hint, ds->at);
r_asm_set_pc (core->assembler, ds->at);
@ -2412,15 +2409,12 @@ toro:
if (core->inc == 0) {
core->inc = ds->oplen;
}
if (ds->analop.mnemonic) {
r_anal_op_fini (&ds->analop);
}
if (!ds->lastfail) {
r_anal_op (core->anal, &ds->analop, ds->at, buf+idx, (int)(len-idx));
}
if (ret < 1) {
r_strbuf_init (&ds->analop.esil);
ds->analop.type = R_ANAL_OP_TYPE_ILL;
@ -2447,7 +2441,6 @@ toro:
handle_print_pre (core, ds, false);
handle_print_lines_left (core, ds);
}
handle_print_offset (core, ds);
handle_print_op_size (core, ds);
handle_print_trace (core, ds);
@ -2455,7 +2448,6 @@ toro:
handle_print_family (core, ds);
handle_print_stackptr (core, ds);
ret = handle_print_meta_infos (core, ds, buf, len, idx);
if (!ds->mi_found) {
/* show cursor */
handle_print_show_cursor (core, ds);
@ -2548,6 +2540,7 @@ toro:
// TODO: this too (must review)
handle_print_esil_anal_fini (core, ds);
handle_deinit_ds (core, ds);
r_reg_arena_pop (core->anal->reg);
return idx; //-ds->lastfail;
}
@ -2562,6 +2555,7 @@ R_API int r_core_print_disasm_instructions (RCore *core, int nb_bytes, int nb_op
const ut64 old_offset = core->offset;
bool hasanal = false;
r_reg_arena_push (core->anal->reg);
if (!nb_bytes) {
nb_bytes = core->blocksize;
if (nb_opcodes < 0) {
@ -2729,6 +2723,7 @@ R_API int r_core_print_disasm_instructions (RCore *core, int nb_bytes, int nb_op
}
handle_deinit_ds (core, ds);
core->offset = old_offset;
r_reg_arena_pop (core->anal->reg);
return err;
}
@ -3025,7 +3020,6 @@ R_API int r_core_print_fcn_disasm(RPrint *p, RCore *core, ut64 addr, int l, int
core->cons->vline = r_config_get_i (core->config, "scr.utf8")?
r_vline_u: r_vline_a;
i = 0;
idx = 0;
r_cons_break (NULL, NULL);

View File

@ -85,6 +85,7 @@ R_API int r_list_del_n (RList *list, int n);
R_API void *r_list_get_top (const RList *list);
R_API void *r_list_get_bottom (const RList *list);
R_API void *r_list_pop (RList *list);
R_API void *r_list_pop_head (RList *list);
R_API void r_list_reverse (RList *list);
R_API RList *r_list_clone (RList *list);

View File

@ -112,7 +112,6 @@ typedef struct r_reg_flags_t {
bool p; // parity (lsb)
} RRegFlags;
#ifdef R_API
R_API void r_reg_free(RReg *reg);
R_API void r_reg_free_internal(RReg *reg);

View File

@ -182,12 +182,32 @@ R_API void r_reg_arena_free(RRegArena* ra) {
}
R_API void r_reg_arena_swap(RReg *reg, int copy) {
// XXX this api should be deprecated
int i;
for (i=0; i<R_REG_TYPE_LAST; i++) {
if (r_list_length (reg->regset[i].pool) > 1) {
RListIter *ia = reg->regset[i].pool->tail;
RListIter *ib = reg->regset[i].pool->tail->p;
void *tmp = ia->data;
ia->data = ib->data;
ib->data = tmp;
} else {
//eprintf ("Cannot pop more\n");
break;
}
}
#if 0
int index = (++reg->iters)%2;
r_reg_arena_set (reg, index, copy);
#endif
}
R_API int r_reg_arena_set(RReg *reg, int n, int copy) {
// XXX this api should be deprecated
return false;
#if 0
int i;
// XXX this shuoldnt be used at all
if (n>r_list_length (reg->regset[0].pool)) {
return R_FALSE;
}
@ -214,15 +234,19 @@ R_API int r_reg_arena_set(RReg *reg, int n, int copy) {
r_reg_set_bytes (reg, i, o->bytes, a->size);
}
return R_TRUE;
#endif
}
R_API void r_reg_arena_pop(RReg *reg) {
int i;
for (i=0; i<R_REG_TYPE_LAST; i++) {
if (r_list_length (reg->regset[i].pool)>0) {
RRegArena *arena = r_list_pop (reg->regset[i].pool);
//RRegArena *arena = (RRegArena*) r_list_head (reg->regset[i].pool);
reg->regset[i].arena = arena;
if (r_list_length (reg->regset[i].pool) > 1) {
RRegArena *a = r_list_pop (reg->regset[i].pool);
a = reg->regset[i].pool->tail->data;
if (a) {
reg->regset[i].arena = a;
//if (!i) { r_print_hexdump (NULL, 0, a->bytes, a->size, 16, 16); }
}
} else {
eprintf ("Cannot pop more\n");
break;
@ -233,9 +257,13 @@ R_API void r_reg_arena_pop(RReg *reg) {
R_API int r_reg_arena_push(RReg *reg) {
int i;
for (i=0; i<R_REG_TYPE_LAST; i++) {
if (!(reg->regset[i].arena = r_reg_arena_new (0)))
return 0;
r_list_push (reg->regset[i].pool, reg->regset[i].arena);
RRegArena *a = reg->regset[i].arena; // current arena
RRegArena *b = r_reg_arena_new (a->size); // new arena
if (!a || !b) continue;
// if (!i) { r_print_hexdump (NULL, 0, a->bytes, a->size, 16, 16); }
memcpy (b->bytes, a->bytes, a->size);
r_list_push (reg->regset[i].pool, b);
reg->regset[i].arena = b;
}
return r_list_length (reg->regset[0].pool);
}
@ -244,7 +272,7 @@ R_API void r_reg_arena_zero(RReg *reg) {
int i;
for (i=0; i<R_REG_TYPE_LAST; i++) {
RRegArena *a = reg->regset[i].arena;
if (a->size> 0)
if (a->size > 0)
memset (reg->regset[i].arena->bytes, 0, a->size);
}
}

View File

@ -137,11 +137,13 @@ R_API RReg *r_reg_new() {
reg->regset[i].pool = r_list_newf ((RListFree)r_reg_arena_free);
reg->regset[i].regs = r_list_newf ((RListFree)r_reg_item_free);
reg->regset[i].arena = arena;
//r_list_append (reg->regset[i].pool, arena);
}
r_reg_arena_push (reg);
#if 0
/* swap arena back and forth to avoid lost reg sets */
r_reg_arena_swap (reg, false);
r_reg_arena_swap (reg, false);
#endif
return reg;
}

View File

@ -226,7 +226,7 @@ R_API RListIter *r_list_insert(RList *list, int n, void *data) {
R_API void *r_list_pop(RList *list) {
void *data = NULL;
RListIter *iter;
if (list){
if (list) {
if (list->tail) {
iter = list->tail;
if (list->head == list->tail) {
@ -243,6 +243,26 @@ R_API void *r_list_pop(RList *list) {
return NULL;
}
R_API void *r_list_pop_head(RList *list) {
void *data = NULL;
RListIter *iter;
if (list) {
if (list->head) {
iter = list->head;
if (list->head == list->tail) {
list->head = list->tail = NULL;
} else {
list->head = iter->n;
list->head->p = NULL;
}
data = iter->data;
free (iter);
}
return data;
}
return NULL;
}
R_API int r_list_del_n(RList *list, int n) {
RListIter *it;
int i;
@ -274,6 +294,7 @@ R_API void *r_list_get_top(const RList *list) {
return list->tail->data;
return NULL;
}
R_API void *r_list_get_bottom(const RList *list) {
if (list && list->head)
return list->head->data;