Skip to content
Open

Bbsvec #25372

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 4 additions & 5 deletions libr/anal/block.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
#include <r_core.h>

R_VEC_TYPE(RVecAnalRef, RAnalRef);
R_VEC_TYPE(RVecAnalBlockPtr, RAnalBlock *);

typedef struct recurse_depth_first_ctx_t {
RAnalBlock *bb;
Expand Down Expand Up @@ -1046,10 +1045,10 @@ static bool automerge_get_predecessors_cb(void *user, ut64 k) {
return true;
}
AutomergeCtx *ctx = user;
const RAnalFunction *fcn = (const RAnalFunction *) (size_t)k;
RListIter *it;
RAnalBlock *block;
r_list_foreach (fcn->bbs, it, block) {
RAnalFunction *fcn = (RAnalFunction *) (size_t)k;
RAnalBlock **it;
R_VEC_FOREACH (&fcn->bbs, it) {
RAnalBlock *block = *it;
bool already_visited;
ht_up_find (ctx->visited_blocks, (ut64) (size_t)block, &already_visited);
if (already_visited) {
Expand Down
25 changes: 14 additions & 11 deletions libr/anal/diff.c
Original file line number Diff line number Diff line change
Expand Up @@ -79,9 +79,9 @@ R_API int r_anal_diff_fingerprint_bb(RAnal *anal, RAnalBlock *bb) {
return bb->size;
}

static int bb_sort_by_addr(const void *x, const void *y) {
ut64 a_addr = ((RAnalBlock *)x)->addr;
ut64 b_addr = ((RAnalBlock *)y)->addr;
static int bb_sort_by_addr(RAnalBlock * const *x, RAnalBlock * const *y) {
ut64 a_addr = (*x)->addr;
ut64 b_addr = (*y)->addr;
if (a_addr > b_addr) {
return 1;
}
Expand All @@ -93,17 +93,18 @@ static int bb_sort_by_addr(const void *x, const void *y) {

R_API size_t r_anal_diff_fingerprint_fcn(RAnal *anal, RAnalFunction *fcn) {
R_RETURN_VAL_IF_FAIL (anal && fcn, 0);
RAnalBlock **it;
RAnalBlock *bb;
RListIter *iter;

if (anal->cur && anal->cur->fingerprint_fcn) {
return (anal->cur->fingerprint_fcn (anal, fcn));
}

fcn->fingerprint = NULL;
fcn->fingerprint_size = 0;
r_list_sort (fcn->bbs, &bb_sort_by_addr);
r_list_foreach (fcn->bbs, iter, bb) {
RVecAnalBlockPtr_sort (&fcn->bbs, bb_sort_by_addr);
R_VEC_FOREACH (&fcn->bbs, it) {
bb = *it;
fcn->fingerprint_size += bb->size;
fcn->fingerprint = realloc (fcn->fingerprint, fcn->fingerprint_size + 1);
if (!fcn->fingerprint) {
Expand All @@ -117,22 +118,24 @@ R_API size_t r_anal_diff_fingerprint_fcn(RAnal *anal, RAnalFunction *fcn) {
R_API bool r_anal_diff_bb(RAnal *anal, RAnalFunction *fcn, RAnalFunction *fcn2) {
R_RETURN_VAL_IF_FAIL (anal && fcn && fcn2, false);
RAnalBlock *bb, *bb2, *mbb, *mbb2;
RListIter *iter, *iter2;
RAnalBlock **iter, **iter2;
double t, ot;

if (anal->cur && anal->cur->diff_bb) {
return (anal->cur->diff_bb (anal, fcn, fcn2));
}
fcn->diff->type = fcn2->diff->type = R_ANAL_DIFF_TYPE_MATCH;
r_list_sort (fcn->bbs, &bb_sort_by_addr);
r_list_foreach (fcn->bbs, iter, bb) {
RVecAnalBlockPtr_sort (&fcn->bbs, bb_sort_by_addr);
R_VEC_FOREACH (&fcn->bbs, iter) {
bb = *iter;
if (bb->diff && bb->diff->type != R_ANAL_DIFF_TYPE_NULL) {
continue;
}
ot = 0;
mbb = mbb2 = NULL;
r_list_sort (fcn2->bbs, &bb_sort_by_addr);
r_list_foreach (fcn2->bbs, iter2, bb2) {
RVecAnalBlockPtr_sort (&fcn2->bbs, bb_sort_by_addr);
R_VEC_FOREACH (&fcn2->bbs, iter2) {
bb2 = *iter2;
if (!bb2->diff || bb2->diff->type == R_ANAL_DIFF_TYPE_NULL) {
r_diff_buffers_distance (NULL, bb->fingerprint, bb->size,
bb2->fingerprint, bb2->size, NULL, &t);
Expand Down
107 changes: 68 additions & 39 deletions libr/anal/fcn.c
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,6 @@ static bool cond_is_inverse(RAnalCondType a, RAnalCondType b) {

R_API int r_anal_function_resize(RAnalFunction *fcn, int newsize) {
RAnal *anal = fcn->anal;
RAnalBlock *bb;
RListIter *iter, *iter2;

R_RETURN_VAL_IF_FAIL (fcn, false);

Expand All @@ -102,7 +100,9 @@ R_API int r_anal_function_resize(RAnalFunction *fcn, int newsize) {
}

ut64 eof = fcn->addr + newsize;
r_list_foreach_safe (fcn->bbs, iter, iter2, bb) {
size_t i;
for (i = RVecAnalBlockPtr_length (&fcn->bbs); i > 0; i--) {
RAnalBlock *bb = *RVecAnalBlockPtr_at (&fcn->bbs, i - 1);
if (bb->addr >= eof) {
r_anal_function_remove_block (fcn, bb);
continue;
Expand Down Expand Up @@ -293,10 +293,10 @@ static ut64 try_get_cmpval_from_parents(RAnal *anal, RAnalFunction *fcn, RAnalBl
R_LOG_DEBUG ("try_get_cmpval_from_parents: cmp_reg not defined");
return UT64_MAX;
}
R_RETURN_VAL_IF_FAIL (fcn && fcn->bbs, UT64_MAX);
RListIter *iter;
RAnalBlock *tmp_bb;
r_list_foreach (fcn->bbs, iter, tmp_bb) {
R_RETURN_VAL_IF_FAIL (fcn, UT64_MAX);
RAnalBlock **it;
R_VEC_FOREACH (&fcn->bbs, it) {
RAnalBlock *tmp_bb = *it;
if (tmp_bb->jump == my_bb->addr || tmp_bb->fail == my_bb->addr) {
if (tmp_bb->cmpreg == cmp_reg) {
if (tmp_bb->cond) {
Expand Down Expand Up @@ -2212,10 +2212,10 @@ R_API bool r_anal_function_add_bb(RAnal *a, RAnalFunction *fcn, ut64 addr, ut64
}

R_API int r_anal_function_loops(RAnalFunction *fcn) {
RListIter *iter;
RAnalBlock *bb;
RAnalBlock **it;
ut32 loops = 0;
r_list_foreach (fcn->bbs, iter, bb) {
R_VEC_FOREACH (&fcn->bbs, it) {
RAnalBlock *bb = *it;
if (bb->jump != UT64_MAX && bb->jump < bb->addr) {
loops ++;
}
Expand All @@ -2236,10 +2236,10 @@ R_API int r_anal_function_complexity(RAnalFunction *fcn) {
#endif
RAnal *anal = fcn->anal;
int E = 0, N = 0, P = 0;
RListIter *iter;
RAnalBlock *bb;
RAnalBlock **it;

r_list_foreach (fcn->bbs, iter, bb) {
R_VEC_FOREACH (&fcn->bbs, it) {
RAnalBlock *bb = *it;
N++; // nodes
if ((!anal || anal->verbose) && bb->jump == UT64_MAX && bb->fail != UT64_MAX) {
R_LOG_WARN ("invalid bb jump/fail pair at 0x%08"PFMT64x" (fcn 0x%08"PFMT64x, bb->addr, fcn->addr);
Expand Down Expand Up @@ -2421,10 +2421,10 @@ R_API RAnalBlock *r_anal_function_bbget_in(RAnal *anal, RAnalFunction *fcn, ut64
if (addr == UT64_MAX) {
return NULL;
}
RListIter *iter;
RAnalBlock *bb;
RAnalBlock **it;
const bool aligned = r_anal_is_aligned (anal, addr);
r_list_foreach (fcn->bbs, iter, bb) {
R_VEC_FOREACH (&fcn->bbs, it) {
RAnalBlock *bb = *it;
if (r_anal_block_contains (bb, addr)) {
if ((!anal->opt.jmpmid || !aligned || r_anal_block_op_starts_at (bb, addr))) {
// if (r_anal_block_op_starts_at (bb, addr)) {
Expand All @@ -2442,9 +2442,9 @@ R_API RAnalBlock *r_anal_function_bbget_at(RAnal *anal, RAnalFunction *fcn, ut64
if (b) {
return b;
}
RListIter *iter;
RAnalBlock *bb;
r_list_foreach (fcn->bbs, iter, bb) {
RAnalBlock **it;
R_VEC_FOREACH (&fcn->bbs, it) {
RAnalBlock *bb = *it;
if (addr == bb->addr) {
return bb;
}
Expand All @@ -2454,14 +2454,14 @@ R_API RAnalBlock *r_anal_function_bbget_at(RAnal *anal, RAnalFunction *fcn, ut64

// compute the cyclomatic cost
R_API ut32 r_anal_function_cost(RAnalFunction *fcn) {
RListIter *iter;
RAnalBlock *bb;
RAnalBlock **it;
ut32 totalCycles = 0;
if (!fcn) {
return 0;
}
RAnal *anal = fcn->anal;
r_list_foreach (fcn->bbs, iter, bb) {
R_VEC_FOREACH (&fcn->bbs, it) {
RAnalBlock *bb = *it;
RAnalOp op;
ut64 at, end = bb->addr + bb->size;
ut8 *buf = malloc (bb->size);
Expand All @@ -2488,13 +2488,13 @@ R_API ut32 r_anal_function_cost(RAnalFunction *fcn) {

R_API int r_anal_function_count_edges(const RAnalFunction *fcn, int * R_NULLABLE ebbs) {
R_RETURN_VAL_IF_FAIL (fcn, 0);
RListIter *iter;
RAnalBlock *bb;
RAnalBlock **it;
int edges = 0;
if (ebbs) {
*ebbs = 0;
}
r_list_foreach (fcn->bbs, iter, bb) {
R_VEC_FOREACH (&fcn->bbs, it) {
RAnalBlock *bb = *it;
if (ebbs && bb->jump == UT64_MAX && bb->fail == UT64_MAX) {
*ebbs = *ebbs + 1;
} else {
Expand Down Expand Up @@ -2545,7 +2545,7 @@ static bool can_affect_bp(RAnal *anal, RAnalOp* op) {
R_API void r_anal_function_check_bp_use(RAnalFunction *fcn) {
R_RETURN_IF_FAIL (fcn);
RAnal *anal = fcn->anal;
RListIter *iter;
RAnalBlock **iter;
RAnalBlock *bb;
char *pos;
// XXX omg this is one of the most awful things ive seen lately
Expand All @@ -2555,7 +2555,8 @@ R_API void r_anal_function_check_bp_use(RAnalFunction *fcn) {
snprintf (str_to_find, sizeof (str_to_find),
"\"type\":\"reg\",\"value\":\"%s", bpreg);
}
r_list_foreach (fcn->bbs, iter, bb) {
R_VEC_FOREACH (&fcn->bbs, iter) {
bb = *iter;
RAnalOp op;
RAnalValue *src = NULL;
ut64 at, end = bb->addr + bb->size;
Expand Down Expand Up @@ -2642,6 +2643,10 @@ typedef struct {
HtUP *visited;
} BlockRecurseCtx;

static int find_bb_cmp(RAnalBlock * const *a, const void *b) {
return (*a == b) ? 0 : 1;
}

static bool mark_as_visited(RAnalBlock *bb, void *user) {
BlockRecurseCtx *ctx = user;
ht_up_insert (ctx->visited, bb->addr, NULL);
Expand All @@ -2652,10 +2657,11 @@ static bool analize_addr_cb(ut64 addr, void *user) {
BlockRecurseCtx *ctx = user;
RAnal *anal = ctx->fcn->anal;
RAnalBlock *existing_bb = r_anal_get_block_at (anal, addr);
if (!existing_bb || !r_list_contains (ctx->fcn->bbs, existing_bb)) {
int old_len = r_list_length (ctx->fcn->bbs);
size_t idx = existing_bb ? RVecAnalBlockPtr_find_index (&ctx->fcn->bbs, existing_bb, find_bb_cmp) : SZT_MAX;
if (!existing_bb || idx == SZT_MAX) {
size_t old_len = RVecAnalBlockPtr_length (&ctx->fcn->bbs);
r_anal_function_bb (ctx->fcn->anal, ctx->fcn, addr, anal->opt.depth);
if (old_len != r_list_length (ctx->fcn->bbs)) {
if (old_len != RVecAnalBlockPtr_length (&ctx->fcn->bbs)) {
r_anal_block_recurse (r_anal_get_block_at (anal, addr), mark_as_visited, user);
}
}
Expand Down Expand Up @@ -2739,7 +2745,7 @@ static void clear_bb_vars(RAnalFunction *fcn, RAnalBlock *bb, ut64 from, ut64 to

static void update_analysis(RAnal *anal, RList *fcns, HtUP *reachable) {
// huge slowdown
RListIter *it, *it2, *tmp;
RListIter *it;
RAnalFunction *fcn;
bool old_jmpmid = anal->opt.jmpmid;
anal->opt.jmpmid = true;
Expand All @@ -2759,8 +2765,12 @@ static void update_analysis(RAnal *anal, RList *fcns, HtUP *reachable) {
BlockRecurseCtx ctx = { fcn, ht };
r_anal_block_recurse (bb, analize_descendents, &ctx);

// Remove non-reachable blocks
r_list_foreach_safe (fcn->bbs, it2, tmp, bb) {
// Remove non-reachable blocks - collect first, then remove
RVecAnalBlockPtr to_remove;
RVecAnalBlockPtr_init (&to_remove);
RAnalBlock **it2;
R_VEC_FOREACH (&fcn->bbs, it2) {
bb = *it2;
if (ht_up_find_kv (ht, bb->addr, NULL)) {
continue;
}
Expand All @@ -2769,11 +2779,20 @@ static void update_analysis(RAnal *anal, RList *fcns, HtUP *reachable) {
// Avoid removing blocks that were already not reachable
continue;
}
RVecAnalBlockPtr_push_back (&to_remove, &bb);
}
R_VEC_FOREACH (&to_remove, it2) {
bb = *it2;
fcn->ninstr -= bb->ninstr;
r_anal_function_remove_block (fcn, bb);
}
RVecAnalBlockPtr_fini (&to_remove);

RList *bbs = r_list_clone (fcn->bbs, NULL);
// Create temporary RList for r_anal_block_automerge
RList *bbs = r_list_new ();
R_VEC_FOREACH (&fcn->bbs, it2) {
r_list_append (bbs, *it2);
}
r_anal_block_automerge (bbs);
r_anal_function_delete_unused_vars (fcn);
r_list_free (bbs);
Expand Down Expand Up @@ -2838,18 +2857,28 @@ R_API void r_anal_update_analysis_range(RAnal *anal, ut64 addr, int size) {

R_API void r_anal_function_update_analysis(RAnalFunction *fcn) {
R_RETURN_IF_FAIL (fcn);
RListIter *it, *it2, *tmp, *tmp2;
RListIter *it2, *tmp2;
RAnalBlock *bb;
RAnalFunction *f;
RList *fcns = r_list_new ();
HtUP *reachable = ht_up_new (NULL, free_ht_up, NULL);
r_list_foreach_safe (fcn->bbs, it, tmp, bb) {
// Collect blocks to process first since we may modify during iteration
RVecAnalBlockPtr to_process;
RVecAnalBlockPtr_init (&to_process);
RAnalBlock **it;
R_VEC_FOREACH (&fcn->bbs, it) {
bb = *it;
if (r_anal_block_was_modified (bb)) {
r_list_foreach_safe (bb->fcns, it2, tmp2, f) {
calc_reachable_and_remove_block (fcns, f, bb, reachable);
}
RVecAnalBlockPtr_push_back (&to_process, &bb);
}
}
R_VEC_FOREACH (&to_process, it) {
bb = *it;
r_list_foreach_safe (bb->fcns, it2, tmp2, f) {
calc_reachable_and_remove_block (fcns, f, bb, reachable);
}
}
RVecAnalBlockPtr_fini (&to_process);
update_analysis (fcn->anal, fcns, reachable);
ht_up_free (reachable);
r_list_free (fcns);
Expand Down
6 changes: 3 additions & 3 deletions libr/anal/flirt.c
Original file line number Diff line number Diff line change
Expand Up @@ -576,9 +576,9 @@ static bool module_match_buffer(RAnal *anal, const RFlirtModule *module, ut8 *b,
if (fcn != next_module_function &&
fcn->addr >= next_module_function->addr + next_module_function_size &&
fcn->addr < next_module_function->addr + flirt_fcn_size) {
RListIter *iter_bb;
RAnalBlock *block;
r_list_foreach (fcn->bbs, iter_bb, block) {
RAnalBlock **it_bb;
R_VEC_FOREACH (&fcn->bbs, it_bb) {
RAnalBlock *block = *it_bb;
r_anal_function_add_block (next_module_function, block);
}
next_module_function->ninstr += fcn->ninstr;
Expand Down
Loading
Loading