mirror of
https://github.com/radareorg/radare2.git
synced 2024-12-01 09:00:46 +00:00
Add ara command and fix RReg.arena.push/pop implementation
This commit is contained in:
parent
b172333386
commit
cffa44b2f7
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user