Improve noreturn and aesu times, show it in afi & afij ##anal (#16324)

* Fix fcn->is_noreturn cache and add tests
This commit is contained in:
radare 2020-03-27 06:15:47 +01:00 committed by GitHub
parent 04e257bd47
commit 9f35d62018
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 61 additions and 43 deletions

View File

@ -52,7 +52,7 @@ int main(int argc, char **argv) {
}
atexit (r2r_subprocess_fini);
R2RState state = { 0 };
R2RState state = {{0}};
state.run_config.r2_cmd = "radare2";
state.run_config.rasm2_cmd = "rasm2";
state.verbose = verbose;

View File

@ -517,6 +517,10 @@ R_API bool r_anal_noreturn_add(RAnal *anal, const char *name, ut64 addr) {
char *fnl_name = NULL;
if (addr != UT64_MAX) {
if (sdb_bool_set (TDB, K_NORET_ADDR (addr), true, 0)) {
RAnalFunction *fcn = r_anal_get_function_at (anal, addr);
if (fcn) {
fcn->is_noreturn = true;
}
return true;
}
}
@ -530,6 +534,9 @@ R_API bool r_anal_noreturn_add(RAnal *anal, const char *name, ut64 addr) {
return false;
}
tmp_name = fcn ? fcn->name: fi->name;
if (fcn) {
fcn->is_noreturn = true;
}
}
if (r_type_func_exist (TDB, tmp_name)) {
fnl_name = strdup (tmp_name);

View File

@ -111,6 +111,7 @@ R_API bool r_anal_add_function(RAnal *anal, RAnalFunction *fcn) {
if (anal->flg_fcn_set) {
anal->flg_fcn_set (anal->flb.f, fcn->name, fcn->addr, r_anal_function_size_from_entry (fcn));
}
fcn->is_noreturn = r_anal_noreturn_at_addr (anal, fcn->addr);
r_list_append (anal->fcns, fcn);
ht_pp_insert (anal->ht_name_fun, fcn->name, fcn);
ht_up_insert (anal->ht_addr_fun, fcn->addr, fcn);

View File

@ -1,4 +1,4 @@
/* radare - LGPL - Copyright 2009-2019 - pancake, nibble */
/* radare - LGPL - Copyright 2009-2020 - pancake, nibble */
#include <r_types.h>
#include <r_list.h>
@ -2815,6 +2815,7 @@ static int fcn_print_json(RCore *core, RAnalFunction *fcn, PJ *pj) {
pj_kn (pj, "size", r_anal_function_linear_size (fcn));
pj_ks (pj, "is-pure", r_str_bool (r_anal_function_purity (fcn)));
pj_kn (pj, "realsz", r_anal_function_realsize (fcn));
pj_kb (pj, "noreturn", fcn->is_noreturn);
pj_ki (pj, "stackframe", fcn->maxstack);
if (fcn->cc) {
pj_ks (pj, "calltype", fcn->cc); // calling conventions
@ -3089,6 +3090,7 @@ static int fcn_print_legacy(RCore *core, RAnalFunction *fcn) {
refi->type == R_ANAL_REF_TYPE_CALL?'C':'J');
}
}
r_cons_printf ("\nnoreturn: %s", r_str_bool (fcn->is_noreturn));
r_cons_printf ("\nin-degree: %d", indegree);
r_cons_printf ("\nout-degree: %d", outdegree);
r_cons_printf ("\ndata-xrefs:");
@ -5537,35 +5539,33 @@ R_API void r_core_anal_inflags(RCore *core, const char *glob) {
free (anal_in);
}
static bool is_noreturn_function(RCore *core, RAnalFunction *f) {
static bool analyze_noreturn_function(RCore *core, RAnalFunction *f) {
RListIter *iter;
RAnalBlock *bb;
r_list_foreach (f->bbs, iter, bb) {
ut64 opaddr;
opaddr = r_anal_bb_opaddr_i (bb, bb->ninstr - 1);
ut64 opaddr = r_anal_bb_opaddr_i (bb, bb->ninstr - 1);
if (opaddr == UT64_MAX) {
return false;
}
// get last opcode
RAnalOp *op = r_core_op_anal (core, opaddr);
RAnalOp *op = r_core_op_anal (core, opaddr, R_ANAL_OP_MASK_HINT);
if (!op) {
eprintf ("Cannot analyze opcode at 0x%08" PFMT64x "\n", opaddr);
return false;
}
switch (op->type & R_ANAL_OP_TYPE_MASK) {
case R_ANAL_OP_TYPE_ILL:
case R_ANAL_OP_TYPE_RET:
case R_ANAL_OP_TYPE_ILL:
case R_ANAL_OP_TYPE_RET:
r_anal_op_free (op);
return false;
case R_ANAL_OP_TYPE_JMP:
if (!r_anal_function_contains (f, op->jump)) {
r_anal_op_free (op);
return false;
case R_ANAL_OP_TYPE_JMP:
if (!r_anal_function_contains (f, op->jump)) {
r_anal_op_free (op);
return false;
}
break;
}
break;
}
r_anal_op_free (op);
}
@ -5606,7 +5606,7 @@ R_API void r_core_anal_propagate_noreturn(RCore *core, ut64 addr) {
RList *xrefs = r_anal_xrefs_get (core->anal, noret_addr);
RAnalRef *xref;
r_list_foreach (xrefs, iter, xref) {
RAnalOp *xrefop = r_core_op_anal (core, xref->addr);
RAnalOp *xrefop = r_core_op_anal (core, xref->addr, R_ANAL_OP_MASK_ALL);
if (!xrefop) {
eprintf ("Cannot analyze opcode at 0x%08" PFMT64x "\n", xref->addr);
continue;
@ -5643,7 +5643,7 @@ R_API void r_core_anal_propagate_noreturn(RCore *core, ut64 addr) {
bool found = false;
found = ht_uu_find (done, f->addr, &found);
if (f->addr && !found && is_noreturn_function (core, f)) {
if (f->addr && !found && analyze_noreturn_function (core, f)) {
f->is_noreturn = true;
r_anal_noreturn_add (core->anal, NULL, f->addr);
ut64 *n = malloc (sizeof (ut64));

View File

@ -3617,7 +3617,7 @@ static int cmd_anal_fcn(RCore *core, const char *input) {
ptr = strchr (ptr + 1, ' ');
if (ptr) {
color = r_num_math (core->num, ptr + 1);
RAnalOp *op = r_core_op_anal (core, addr);
RAnalOp *op = r_core_op_anal (core, addr, R_ANAL_OP_MASK_ALL);
if (op) {
r_anal_colorize_bb (core->anal, addr, color);
r_anal_op_free (op);

View File

@ -812,21 +812,10 @@ static int step_until_esil(RCore *core, const char *esilstr) {
}
static bool is_repeatable_inst(RCore *core, ut64 addr) {
bool ret = false;
if (!r_str_startswith (r_config_get (core->config, "asm.arch"), "x86")) {
return false;
}
RAnalOp *op = r_core_op_anal (core, addr);
if (!op) {
eprintf ("Cannot analyze opcode at 0x%08" PFMT64x "\n", addr);
return false;
}
ret = (op->prefix & R_ANAL_OP_PREFIX_REP) || (op->prefix & R_ANAL_OP_PREFIX_REPNE);
r_anal_op_free (op);
// we have read the bytes already
RAnalOp *op = r_core_op_anal (core, addr, R_ANAL_OP_MASK_ALL);
bool ret = op && ((op->prefix & R_ANAL_OP_PREFIX_REP) || (op->prefix & R_ANAL_OP_PREFIX_REPNE));
r_anal_op_free (op);
return ret;
}
@ -835,6 +824,7 @@ static int step_until_inst(RCore *core, const char *instr, bool regex) {
ut8 buf[32];
ut64 pc;
int ret;
bool is_x86 = r_str_startswith (r_config_get (core->config, "asm.arch"), "x86");
instr = r_str_trim_head_ro (instr);
if (!core || !instr|| !core->dbg) {
@ -850,7 +840,7 @@ static int step_until_inst(RCore *core, const char *instr, bool regex) {
break;
}
pc = r_debug_reg_get (core->dbg, "PC");
if (is_repeatable_inst (core, pc)) {
if (is_x86 && is_repeatable_inst (core, pc)) {
r_debug_step_over (core->dbg, 1);
} else {
r_debug_step (core->dbg, 1);
@ -4897,7 +4887,7 @@ static int cmd_debug(void *data, const char *input) {
if (ptr) {
count = r_num_math (core->num, ptr + 1);
}
RAnalOp *op = r_core_op_anal (core, addr);
RAnalOp *op = r_core_op_anal (core, addr, R_ANAL_OP_MASK_HINT);
if (op) {
RDebugTracepoint *tp = r_debug_trace_add (core->dbg, addr, op->size);
if (!tp) {

View File

@ -3145,11 +3145,11 @@ R_API char *r_core_op_str(RCore *core, ut64 addr) {
return str;
}
R_API RAnalOp *r_core_op_anal(RCore *core, ut64 addr) {
R_API RAnalOp *r_core_op_anal(RCore *core, ut64 addr, RAnalOpMask mask) {
ut8 buf[64];
RAnalOp *op = R_NEW (RAnalOp);
r_io_read_at (core->io, addr, buf, sizeof (buf));
r_anal_op (core->anal, op, addr, buf, sizeof (buf), R_ANAL_OP_MASK_ALL);
r_anal_op (core->anal, op, addr, buf, sizeof (buf), mask);
return op;
}

View File

@ -1478,10 +1478,8 @@ R_API RAnalVar *get_link_var(RAnal *anal, ut64 faddr, RAnalVar *var);
R_API int r_anal_op_reg_delta(RAnal *anal, ut64 addr, const char *name);
R_API bool r_anal_op_is_eob(RAnalOp *op);
R_API RList *r_anal_op_list_new(void);
R_API int r_anal_op(RAnal *anal, RAnalOp *op, ut64 addr,
const ut8 *data, int len, RAnalOpMask mask);
R_API RAnalOp *r_anal_op_hexstr(RAnal *anal, ut64 addr,
const char *hexstr);
R_API int r_anal_op(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *data, int len, RAnalOpMask mask);
R_API RAnalOp *r_anal_op_hexstr(RAnal *anal, ut64 addr, const char *hexstr);
R_API char *r_anal_op_to_string(RAnal *anal, RAnalOp *op);
R_API RAnalEsil *r_anal_esil_new(int stacksize, int iotrap, unsigned int addrsize);

View File

@ -558,7 +558,7 @@ R_API char *r_core_cmd_str(RCore *core, const char *cmd);
R_API int r_core_cmd_foreach(RCore *core, const char *cmd, char *each);
R_API int r_core_cmd_foreach3(RCore *core, const char *cmd, char *each);
R_API char *r_core_op_str(RCore *core, ut64 addr);
R_API RAnalOp *r_core_op_anal(RCore *core, ut64 addr);
R_API RAnalOp *r_core_op_anal(RCore *core, ut64 addr, RAnalOpMask mask);
R_API char *r_core_disassemble_instr(RCore *core, ut64 addr, int l);
R_API char *r_core_disassemble_bytes(RCore *core, ut64 addr, int b);

View File

@ -43,6 +43,7 @@ end-bbs: 0
call-refs: 0x00004558 C 0x0000447a C 0x00004484 C 0x00004558 C 0x0000446a J 0x00004558 C 0x0000449c C 0x00004470 J
data-refs:
code-xrefs: 0x0000445c J 0x00004474 J
noreturn: false
in-degree: 2
out-degree: 6
data-xrefs:

16
test/new/db/anal/noreturn Normal file
View File

@ -0,0 +1,16 @@
NAME=noreturn 0
FILE=../bins/mach0/ls-osx-x86_64
CMDS=<<EOF
aaa
tn~0x
afi@0x1000013d8~noret[1]
afi@0x1000044bd~noret[1]
EOF
EXPECT=<<EOF
0x1000013d8
0x1000044bd
true
true
EOF
RUN

View File

@ -2424,6 +2424,7 @@ end-bbs: 0
call-refs:
data-refs:
code-xrefs:
noreturn: false
in-degree: 0
out-degree: 0
data-xrefs:
@ -2482,6 +2483,7 @@ end-bbs: 1
call-refs: 0x00000004 J
data-refs: 0x0000002c
code-xrefs: 0x00000005 J
noreturn: false
in-degree: 1
out-degree: 0
data-xrefs:
@ -2556,6 +2558,7 @@ end-bbs: 0
call-refs: 0x00000004 J 0x00000004 J
data-refs: 0x0000002c
code-xrefs: 0x00000005 J 0x0000000c J
noreturn: false
in-degree: 2
out-degree: 0
data-xrefs:
@ -2638,6 +2641,7 @@ end-bbs: 0
call-refs: 0x00000004 J 0x00000005 J
data-refs: 0x0000002c
code-xrefs: 0x00000005 J 0x0000000c J
noreturn: false
in-degree: 2
out-degree: 0
data-xrefs:
@ -2729,6 +2733,7 @@ end-bbs: 0
call-refs: 0x00000009 J 0x00000003 J
data-refs: 0x0000002c
code-xrefs: 0x00000011 J 0x0000000a J
noreturn: false
in-degree: 2
out-degree: 0
data-xrefs:

View File

@ -7,7 +7,7 @@ afi.
afb.
EOF
EXPECT=<<EOF
32
33
main
0x1000011e8 0x100001211 01:0899 41 j 0x100001216 f 0x100001211
EOF