Fix #6473 - Show function cost information in afi, aflj and afll

This commit is contained in:
pancake 2017-01-13 23:08:37 +01:00
parent c646b99724
commit 7bb7ec1e42
4 changed files with 50 additions and 34 deletions

View File

@ -1740,3 +1740,32 @@ R_API ut32 r_anal_fcn_contsize(const RAnalFunction *fcn) {
}
return sz;
}
// compute the cyclomatic cost
R_API ut32 r_anal_fcn_cost(RAnal *anal, RAnalFunction *fcn) {
RListIter *iter;
RAnalBlock *bb;
ut32 totalCycles = 0;
if (!fcn) {
return 0;
}
r_list_foreach (fcn->bbs, iter, bb) {
RAnalOp op;
ut64 at, end = bb->addr + bb->size;
ut8 *buf = malloc (bb->size);
anal->iob.read_at (anal->iob.io, bb->addr, (ut8 *)buf, bb->size);
int idx = 0;
for (at = bb->addr; at < end; ) {
memset (&op, 0, sizeof (op));
(void)r_anal_op (anal, &op, at, buf + idx, bb->size - idx);
if (op.size < 1) {
op.size = 1;
}
idx += op.size;
at += op.size;
totalCycles += op.cycles;
}
free (buf);
}
return totalCycles;
}

View File

@ -1738,7 +1738,7 @@ static int count_edges(RAnalFunction *fcn, int *ebbs) {
return edges;
}
#define FCN_LIST_VERBOSE_ENTRY "%s0x%08"PFMT64x" %4d %5d %5d %4d 0x%08"PFMT64x" %5d 0x%08"PFMT64x" %5d %4d %6d %4d %5d %s%s\n"
#define FCN_LIST_VERBOSE_ENTRY "%s0x%08"PFMT64x" %4d %5d %5d %5d %4d 0x%08"PFMT64x" %5d 0x%08"PFMT64x" %5d %4d %6d %4d %5d %s%s\n"
static int fcn_print_verbose(RCore *core, RAnalFunction *fcn, bool use_color) {
char *name = get_fcn_name(core, fcn);
int ebbs = 0;
@ -1761,6 +1761,7 @@ static int fcn_print_verbose(RCore *core, RAnalFunction *fcn, bool use_color) {
r_list_length (fcn->bbs),
count_edges (fcn, &ebbs),
r_anal_fcn_cc (fcn),
r_anal_fcn_cost (core->anal, fcn),
fcn->meta.min,
r_anal_fcn_size (fcn),
fcn->meta.max,
@ -1782,11 +1783,11 @@ static int fcn_print_verbose(RCore *core, RAnalFunction *fcn, bool use_color) {
static int fcn_list_verbose(RCore *core, RList *fcns) {
bool use_color = r_config_get_i (core->config, "scr.color");
r_cons_printf ("%-11s %4s %5s %5s %4s %11s range %-11s %s %s %s %s %s %s\n",
"address", "size", "nbbs", "edges", "cc", "min bound", "max bound",
r_cons_printf ("%-11s %4s %5s %5s %5s %4s %11s range %-11s %s %s %s %s %s %s\n",
"address", "size", "nbbs", "edges", "cc", "cost", "min bound", "max bound",
"calls", "locals", "args", "xref", "frame", "name");
r_cons_printf ("%-11s %-4s %-5s %-5s %-4s %-11s ===== %-11s %s %s %s %s %s %s\n",
"===========", "====", "=====", "=====", "====", "===========", "===========",
r_cons_printf ("%-11s %-4s %-5s %-5s %-5s %-4s %-11s ===== %-11s %s %s %s %s %s %s\n",
"===========", "====", "=====", "=====", "=====", "====", "===========", "===========",
"=====", "======", "====", "====", "=====", "====");
RListIter *iter;
@ -1840,6 +1841,7 @@ static int fcn_print_json(RCore *core, RAnalFunction *fcn) {
fcn->addr, name, r_anal_fcn_size (fcn));
r_cons_printf (",\"realsz\":%d", r_anal_fcn_realsize (fcn));
r_cons_printf (",\"cc\":%d", r_anal_fcn_cc (fcn));
r_cons_printf (",\"cost\":%d", r_anal_fcn_cost (core->anal, fcn));
r_cons_printf (",\"nbbs\":%d", r_list_length (fcn->bbs));
r_cons_printf (",\"edges\":%d", count_edges (fcn, &ebbs));
r_cons_printf (",\"ebbs\":%d", ebbs);
@ -1984,6 +1986,7 @@ static int fcn_print_legacy(RCore *core, RAnalFunction *fcn) {
r_cons_printf ("\n realsz: %d", r_anal_fcn_realsize (fcn));
r_cons_printf ("\n stackframe: %d", fcn->maxstack);
r_cons_printf ("\n call-convention: %s", fcn->cc);
r_cons_printf ("\n cyclomatic-cost : %d", r_anal_fcn_cost (core->anal, fcn));
r_cons_printf ("\n cyclomatic-complexity: %d", r_anal_fcn_cc (fcn));
r_cons_printf ("\n bits: %d", fcn->bits);
r_cons_printf ("\n type: %s", r_anal_fcn_type_tostring (fcn->type));

View File

@ -361,9 +361,11 @@ static int var_cmd (RCore *core, const char *str) {
r_anal_var_add (core->anal, fcn->addr,
scope, delta, type,
vartype, size, name);
} else eprintf ("Missing name\n");
} else {
eprintf ("Missing name\n");
}
}
break;
}
};
free (ostr);
@ -376,10 +378,11 @@ static void print_trampolines(RCore *core, ut64 a, ut64 b, size_t element_size)
ut32 n;
memcpy (&n, core->block + i, sizeof (ut32));
if (n >= a && n <= b) {
if (element_size == 4)
if (element_size == 4) {
r_cons_printf ("f trampoline.%x @ 0x%" PFMT64x "\n", n, core->offset + i);
else r_cons_printf ("f trampoline.%" PFMT64x " @ 0x%" PFMT64x "\n", n, core->offset + i);
} else {
r_cons_printf ("f trampoline.%" PFMT64x " @ 0x%" PFMT64x "\n", n, core->offset + i);
}
r_cons_printf ("Cd %u @ 0x%" PFMT64x ":%u\n", element_size, core->offset + i, element_size);
// TODO: add data xrefs
}
@ -1141,27 +1144,7 @@ static void afcc(RCore *core, const char *input) {
fcn = r_anal_get_fcn_in (core->anal, addr, R_ANAL_FCN_TYPE_NULL);
}
if (fcn) {
RListIter *iter;
RAnalBlock *bb;
ut32 totalCycles = 0;
r_list_foreach (fcn->bbs, iter, bb) {
RAnalOp op;
ut64 at, end = bb->addr + bb->size;
ut8 *buf = malloc (bb->size);
r_io_read_at (core->io, bb->addr, (ut8 *)buf, bb->size);
int idx = 0;
for (at = bb->addr; at < end; ) {
memset (&op, 0, sizeof (op));
(void)r_anal_op (core->anal, &op, at, buf + idx, bb->size - idx);
if (op.size < 1) {
op.size = 1;
}
idx += op.size;
at += op.size;
totalCycles += op.cycles;
}
free (buf);
}
ut32 totalCycles = r_anal_fcn_cost (core->anal, fcn);
r_cons_printf ("%d\n", totalCycles);
} else {
eprintf ("Cannot find function\n");
@ -1180,9 +1163,9 @@ static int cmd_anal_fcn(RCore *core, const char *input) {
r_anal_fcn_del_locs (core->anal, UT64_MAX);
r_anal_fcn_del (core->anal, UT64_MAX);
} else {
ut64 addr = input[2] ?
r_num_math (core->num, input + 2) :
core->offset;
ut64 addr = input[2]
? r_num_math (core->num, input + 2)
: core->offset;
r_anal_fcn_del_locs (core->anal, addr);
r_anal_fcn_del (core->anal, addr);
}

View File

@ -1255,6 +1255,7 @@ R_API int r_anal_pin_call(RAnal *a, ut64 addr);
R_API void r_anal_pin_list(RAnal *a);
/* fcn.c */
R_API ut32 r_anal_fcn_cost(RAnal *anal, RAnalFunction *fcn);
R_API RAnalFunction *r_anal_fcn_new(void);
R_API int r_anal_fcn_is_in_offset (RAnalFunction *fcn, ut64 addr);
R_API bool r_anal_fcn_in(RAnalFunction *fcn, ut64 addr);