Initial support for fold/unfold functions with afF and Vz

This commit is contained in:
pancake 2015-12-14 10:19:07 +01:00
parent 71536f3fd9
commit db5a76f8b3
4 changed files with 97 additions and 26 deletions

View File

@ -984,6 +984,16 @@ static int cmd_anal_fcn(RCore *core, const char *input) {
case 'g': // "afg" - non-interactive VV
r_core_visual_graph (core, NULL, false);
break;
case 'F':// "afF"
{
RAnalFunction *fcn;
int val = input[2] && r_num_math (core->num, input+2);
fcn = r_anal_get_fcn_in (core->anal, core->offset, R_ANAL_FCN_TYPE_NULL);
if (fcn) {
fcn->folded = input[2]? val: !fcn->folded;
}
}
break;
case '?':{ // "af?"
const char* help_msg[] = {
"Usage:", "af", "",
@ -999,6 +1009,7 @@ static int cmd_anal_fcn(RCore *core, const char *input) {
"afc", "@[addr]", "calculate the Cyclomatic Complexity (starting at addr)",
"afC[a]", " type @[addr]", "set calling convention for function (afC?=list cc types)",
"aff", "", "re-adjust function boundaries to fit",
"afF", "[1|0|]", "fold/unfold/toggle",
"afg", "", "non-interactive ascii-art basic-block graph (See VV)",
"afi", " [addr|fcn.name]", "show function(s) information (verbose afl)",
"afl", "[*] [fcn name]", "list functions (addr, size, bbs, name)",

View File

@ -2306,22 +2306,13 @@ static void handle_print_refptr (RCore *core, RDisasmState *ds) {
// int l is for lines
R_API int r_core_print_disasm(RPrint *p, RCore *core, ut64 addr, ut8 *buf, int len, int l, int invbreak, int cbytes) {
int ret, idx = 0, i;
int continueoninvbreak = (len == l) && invbreak;
int dorepeat = 1;
RAnalFunction *of = NULL;
RAnalFunction *f = NULL;
int ret, idx = 0, i;
int dorepeat = 1;
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) {
core->anal->cur->reset_counter (core->anal, addr);
}
// TODO: All those ds must be print flags
ds = handle_init_ds (core);
@ -2332,6 +2323,19 @@ r_reg_arena_push (core->anal->reg);
ds->len = len;
ds->addr = addr;
ds->hint = NULL;
//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 (ds->show_emu) {
r_reg_arena_push (core->anal->reg);
}
if (core->anal->cur && core->anal->cur->reset_counter) {
core->anal->cur->reset_counter (core->anal, addr);
}
handle_reflines_init (core->anal, ds);
core->inc = 0;
@ -2385,6 +2389,28 @@ toro:
r_core_cmdf (core, "tf 0x%08"PFMT64x, ds->at);
f = r_anal_get_fcn_in (core->anal, ds->at, R_ANAL_FCN_TYPE_NULL);
if (f && f->folded && ds->at >= f->addr && ds->at < f->addr+f->size) {
int delta = (ds->addr <= f->addr)? (ds->addr - f->addr + f->size): 0;
if (of != f) {
r_cons_printf ("%s%s%s (fcn) %s%s\n", COLOR (ds, color_fline), core->cons->vline[RUP_CORNER], COLOR (ds, color_fname), f->name, COLOR_RESET (ds));
handle_print_pre (core, ds, false);
handle_print_lines_left (core, ds);
handle_print_offset (core, ds);
r_cons_printf ("(%d byte folded function)\n", f->size);
r_cons_printf ("%s%s%s\n", COLOR (ds, color_fline), core->cons->vline[RDWN_CORNER], COLOR_RESET (ds));
ds->addr += delta;
r_io_read_at (core->io, ds->addr, buf, len);
inc = 0; //delta;
idx = 0;
of = f;
continue;
} else {
ds->lines--;
// r_cons_printf ("delta %d fsize %d\n", delta, f->size);
inc = 1;
continue;
}
}
if (!ds->hint || !ds->hint->bits) {
if (f) {
if (f->bits) {
@ -2549,7 +2575,9 @@ 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);
if (ds->show_emu) {
r_reg_arena_pop (core->anal->reg);
}
return idx; //-ds->lastfail;
}

View File

@ -1193,7 +1193,7 @@ R_API int r_core_visual_cmd(RCore *core, int ch) {
cursor += cols;
ocursor = -1;
offscreen = (core->cons->rows - 3) * cols;
if (cursor > offscreen ) {
if (cursor > offscreen) {
r_core_seek (core, core->offset+cols, 1);
cursor-=cols;
}
@ -1203,12 +1203,23 @@ R_API int r_core_visual_cmd(RCore *core, int ch) {
if (times<1) times = 1;
while (times--) {
if (core->printidx == 1 || core->printidx == 2) {
cols = r_asm_disassemble (core->assembler,
&op, core->block, 32);
RAnalFunction *f = NULL;
if (true) {
f = r_anal_get_fcn_in (core->anal, core->offset, R_ANAL_FCN_TYPE_NULL);
}
if (f && f->folded) {
if (core->offset <= f->addr) {
cols = core->offset - f->addr + f->size;
} else cols = 1;
} else {
r_asm_set_pc (core->assembler, core->offset);
cols = r_asm_disassemble (core->assembler,
&op, core->block, 32);
}
if (cols<1) cols = op.size;
if (cols<1) cols = 1;
}
r_core_seek (core, core->offset+cols, 1);
r_core_seek (core, core->offset + cols, 1);
}
}
break;
@ -1242,12 +1253,12 @@ R_API int r_core_visual_cmd(RCore *core, int ch) {
case 'k':
if (curset) {
if (core->printidx == 1 || core->printidx == 2)
cols = prevopsz (core, core->offset+cursor);
cols = prevopsz (core, core->offset + cursor);
cursor -= cols;
ocursor = -1;
if (cursor<0) {
if (core->offset>=cols) {
r_core_seek (core, core->offset-cols, 1);
if (core->offset >= cols) {
r_core_seek (core, core->offset - cols, 1);
cursor += cols;
}
}
@ -1256,11 +1267,17 @@ R_API int r_core_visual_cmd(RCore *core, int ch) {
if (times<1) times = 1;
while (times--) {
if (core->printidx == 1 || core->printidx == 2) {
cols = prevopsz (core, core->offset);
}
if (core->offset >= cols)
r_core_seek (core, core->offset-cols, 1);
else r_core_seek (core, 0, 1);
RAnalFunction *f = r_anal_get_fcn_in (core->anal, core->offset, R_ANAL_FCN_TYPE_NULL);
if (f && f->folded) {
cols = core->offset - f->addr; // + f->size;
if (cols<1) {
cols = 4;
}
} else {
cols = prevopsz (core, core->offset);
}
} else cols = 1;
r_core_seek (core, core->offset - cols, 1);
}
}
break;
@ -1539,7 +1556,21 @@ R_API int r_core_visual_cmd(RCore *core, int ch) {
}
break;
case 'z':
r_config_toggle (core->config, "asm.cmtfold");
{
RAnalFunction *fcn;
if (curset) {
fcn = r_anal_get_fcn_in (core->anal,
core->offset+cursor, R_ANAL_FCN_TYPE_NULL);
} else {
fcn = r_anal_get_fcn_in (core->anal,
core->offset, R_ANAL_FCN_TYPE_NULL);
}
if (fcn) {
fcn->folded = !fcn->folded;
} else {
r_config_toggle (core->config, "asm.cmtfold");
}
}
break;
case 'Z':
if (zoom && cursor) {

View File

@ -295,6 +295,7 @@ typedef struct r_anal_type_function_t {
int ninstr;
int nargs; // Function arguments counter
int depth;
bool folded;
RAnalType *args; // list of arguments
#if USE_VARSUBS
RAnalVarSub varsubs[R_ANAL_VARSUBS];