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:
parent
04e257bd47
commit
9f35d62018
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
|
|
@ -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:
|
||||
|
|
|
@ -7,7 +7,7 @@ afi.
|
|||
afb.
|
||||
EOF
|
||||
EXPECT=<<EOF
|
||||
32
|
||||
33
|
||||
main
|
||||
0x1000011e8 0x100001211 01:0899 41 j 0x100001216 f 0x100001211
|
||||
EOF
|
||||
|
|
Loading…
Reference in New Issue