From 711bc0e2f27aeb66bf0a2487dfdef613a32c9eb4 Mon Sep 17 00:00:00 2001 From: HN026 Date: Wed, 3 Jan 2024 13:32:15 +0530 Subject: [PATCH 1/8] rzanalysisblock_rzlist_to_rzpvector --- librz/analysis/analysis.c | 5 +- librz/analysis/block.c | 5 +- librz/analysis/fcn.c | 76 ++++++++++++++++-------- librz/analysis/function.c | 28 +++++---- librz/analysis/jmptbl.c | 5 +- librz/analysis/serialize_analysis.c | 4 +- librz/analysis/similarity.c | 29 +++++++-- librz/analysis/xrefs.c | 5 +- librz/core/agraph.c | 20 ++++--- librz/core/analysis_tp.c | 7 ++- librz/core/canalysis.c | 49 +++++++++------ librz/core/cfile.c | 6 +- librz/core/cgraph.c | 5 +- librz/core/cil.c | 10 +++- librz/core/cmd/cmd.c | 26 ++++---- librz/core/cmd/cmd_analysis.c | 61 +++++++++++-------- librz/core/cmd/cmd_meta.c | 5 +- librz/core/cmd/cmd_print.c | 26 ++++---- librz/core/cmd/cmd_search.c | 5 +- librz/core/core.c | 25 ++++---- librz/core/cprint.c | 8 ++- librz/core/ctypes.c | 7 ++- librz/core/disasm.c | 8 +-- librz/core/golang.c | 6 +- librz/core/tui/panels.c | 2 +- librz/core/tui/visual.c | 2 +- librz/include/rz_analysis.h | 2 +- librz/main/rz-diff.c | 5 +- librz/sign/flirt.c | 5 +- test/unit/test_analysis_block.c | 12 ++-- test/unit/test_analysis_block_invars.inl | 45 +++++++++----- test/unit/test_serialize_analysis.c | 14 ++--- 32 files changed, 323 insertions(+), 195 deletions(-) diff --git a/librz/analysis/analysis.c b/librz/analysis/analysis.c index 1f89bffeb34..de54cf0e751 100644 --- a/librz/analysis/analysis.c +++ b/librz/analysis/analysis.c @@ -412,10 +412,11 @@ RZ_API ut8 *rz_analysis_mask(RzAnalysis *analysis, ut32 size, const ut8 *data, u RZ_API void rz_analysis_trace_bb(RzAnalysis *analysis, ut64 addr) { RzAnalysisBlock *bbi; RzAnalysisFunction *fcni; - RzListIter *iter2; + void **iter2; fcni = rz_analysis_get_fcn_in(analysis, addr, 0); if (fcni) { - rz_list_foreach (fcni->bbs, iter2, bbi) { + rz_pvector_foreach (fcni->bbs, iter2) { + bbi = *iter2; if (addr >= bbi->addr && addr < (bbi->addr + bbi->size)) { bbi->traced = true; break; diff --git a/librz/analysis/block.c b/librz/analysis/block.c index e50fd2f0c89..07151ba3016 100644 --- a/librz/analysis/block.c +++ b/librz/analysis/block.c @@ -874,9 +874,10 @@ static bool automerge_predecessor_successor_cb(ut64 addr, void *user) { static bool automerge_get_predecessors_cb(void *user, const ut64 k, const void *v) { AutomergeCtx *ctx = user; const RzAnalysisFunction *fcn = (const RzAnalysisFunction *)(size_t)k; - RzListIter *it; + void **it; RzAnalysisBlock *block; - rz_list_foreach (fcn->bbs, it, block) { + rz_pvector_foreach (fcn->bbs, it) { + block = *it; bool already_visited; ht_up_find(ctx->visited_blocks, (ut64)(size_t)block, &already_visited); if (already_visited) { diff --git a/librz/analysis/fcn.c b/librz/analysis/fcn.c index a76f2335746..765a231c72f 100644 --- a/librz/analysis/fcn.c +++ b/librz/analysis/fcn.c @@ -90,7 +90,7 @@ RZ_API void rz_analysis_fcn_invalidate_read_ahead_cache(void) { RZ_API int rz_analysis_function_resize(RzAnalysisFunction *fcn, int newsize) { RzAnalysis *analysis = fcn->analysis; RzAnalysisBlock *bb; - RzListIter *iter, *iter2; + void **iter; rz_return_val_if_fail(fcn, false); @@ -105,7 +105,8 @@ RZ_API int rz_analysis_function_resize(RzAnalysisFunction *fcn, int newsize) { } ut64 eof = fcn->addr + newsize; - rz_list_foreach_safe (fcn->bbs, iter, iter2, bb) { + rz_pvector_foreach (fcn->bbs, iter) { + bb = *iter; if (bb->addr >= eof) { rz_analysis_function_remove_block(fcn, bb); continue; @@ -260,9 +261,10 @@ static bool is_delta_pointer_table(RzAnalysis *analysis, ut64 addr, ut64 lea_ptr static ut64 try_get_cmpval_from_parents(RzAnalysis *analysis, RzAnalysisFunction *fcn, RzAnalysisBlock *my_bb, const char *cmp_reg) { rz_return_val_if_fail(fcn && fcn->bbs && cmp_reg, UT64_MAX); - RzListIter *iter; + void **iter; RzAnalysisBlock *tmp_bb; - rz_list_foreach (fcn->bbs, iter, tmp_bb) { + rz_pvector_foreach (fcn->bbs, iter) { + tmp_bb = *iter; if (tmp_bb->jump == my_bb->addr || tmp_bb->fail == my_bb->addr) { if (tmp_bb->cmpreg == cmp_reg) { if (tmp_bb->cond) { @@ -1767,10 +1769,11 @@ RZ_API bool rz_analysis_fcn_add_bb(RzAnalysis *a, RzAnalysisFunction *fcn, ut64 * \brief Returns the amount of loops located in the \p fcn function */ RZ_API int rz_analysis_function_loops(RzAnalysisFunction *fcn) { - RzListIter *iter; + void **iter; RzAnalysisBlock *bb; ut32 loops = 0; - rz_list_foreach (fcn->bbs, iter, bb) { + rz_pvector_foreach (fcn->bbs, iter) { + bb = *iter; if (bb->jump != UT64_MAX && bb->jump < bb->addr) { loops++; } @@ -1796,10 +1799,11 @@ RZ_API int rz_analysis_function_loops(RzAnalysisFunction *fcn) { RZ_API int rz_analysis_function_complexity(RzAnalysisFunction *fcn) { RzAnalysis *analysis = fcn->analysis; int E = 0, N = 0, P = 0; - RzListIter *iter; + void **iter; RzAnalysisBlock *bb; - rz_list_foreach (fcn->bbs, iter, bb) { + rz_pvector_foreach (fcn->bbs, iter) { + bb = *iter; N++; // nodes if (!analysis && bb->jump == UT64_MAX && bb->fail != UT64_MAX) { RZ_LOG_DEBUG("invalid bb jump/fail pair at 0x%08" PFMT64x " (fcn 0x%08" PFMT64x "\n", bb->addr, fcn->addr); @@ -2034,9 +2038,10 @@ RZ_API RzAnalysisBlock *rz_analysis_fcn_bbget_in(const RzAnalysis *analysis, RzA bool is_dalvik = !strncmp(analysis->cur->arch, "dalvik", 6); can_jmpmid = analysis->opt.jmpmid && (is_dalvik || is_x86); } - RzListIter *iter; + void **iter; RzAnalysisBlock *bb; - rz_list_foreach (fcn->bbs, iter, bb) { + rz_pvector_foreach (fcn->bbs, iter) { + bb = *iter; if (addr >= bb->addr && addr < (bb->addr + bb->size) && (!can_jmpmid || rz_analysis_block_op_starts_at(bb, addr))) { return bb; } @@ -2050,9 +2055,10 @@ RZ_API RzAnalysisBlock *rz_analysis_fcn_bbget_at(RzAnalysis *analysis, RzAnalysi if (b) { return b; } - RzListIter *iter; + void **iter; RzAnalysisBlock *bb; - rz_list_foreach (fcn->bbs, iter, bb) { + rz_pvector_foreach (fcn->bbs, iter) { + bb = *iter; if (addr == bb->addr) { return bb; } @@ -2062,14 +2068,15 @@ RZ_API RzAnalysisBlock *rz_analysis_fcn_bbget_at(RzAnalysis *analysis, RzAnalysi // compute the cyclomatic cost RZ_API ut32 rz_analysis_function_cost(RzAnalysisFunction *fcn) { - RzListIter *iter; + void **iter; RzAnalysisBlock *bb; ut32 totalCycles = 0; if (!fcn) { return 0; } RzAnalysis *analysis = fcn->analysis; - rz_list_foreach (fcn->bbs, iter, bb) { + rz_pvector_foreach (fcn->bbs, iter) { + bb = *iter; RzAnalysisOp op; ut64 at, end = bb->addr + bb->size; ut8 *buf = malloc(bb->size); @@ -2096,13 +2103,14 @@ RZ_API ut32 rz_analysis_function_cost(RzAnalysisFunction *fcn) { RZ_API int rz_analysis_function_count_edges(const RzAnalysisFunction *fcn, RZ_NULLABLE int *ebbs) { rz_return_val_if_fail(fcn, 0); - RzListIter *iter; + void **iter; RzAnalysisBlock *bb; int edges = 0; if (ebbs) { *ebbs = 0; } - rz_list_foreach (fcn->bbs, iter, bb) { + rz_pvector_foreach (fcn->bbs, iter) { + bb = *iter; if (ebbs && bb->jump == UT64_MAX && bb->fail == UT64_MAX) { *ebbs = *ebbs + 1; } else { @@ -2150,12 +2158,13 @@ static bool can_affect_bp(RzAnalysis *analysis, RzAnalysisOp *op) { * and "pop bp" at the end). */ static void __analysis_fcn_check_bp_use(RzAnalysis *analysis, RzAnalysisFunction *fcn) { - RzListIter *iter; + void **iter; RzAnalysisBlock *bb; if (!fcn) { return; } - rz_list_foreach (fcn->bbs, iter, bb) { + rz_pvector_foreach (fcn->bbs, iter) { + bb = *iter; RzAnalysisOp op; ut64 at, end = bb->addr + bb->size; ut8 *buf = malloc(bb->size); @@ -2236,10 +2245,10 @@ static bool analize_addr_cb(ut64 addr, void *user) { BlockRecurseCtx *ctx = user; RzAnalysis *analysis = ctx->fcn->analysis; RzAnalysisBlock *existing_bb = rz_analysis_get_block_at(analysis, addr); - if (!existing_bb || !rz_list_contains(ctx->fcn->bbs, existing_bb)) { - int old_len = rz_list_length(ctx->fcn->bbs); + if (!existing_bb || !rz_pvector_contains(ctx->fcn->bbs, existing_bb)) { + int old_len = rz_pvector_len(ctx->fcn->bbs); analyze_function_locally(ctx->fcn->analysis, ctx->fcn, addr); - if (old_len != rz_list_length(ctx->fcn->bbs)) { + if (old_len != rz_pvector_len(ctx->fcn->bbs)) { rz_analysis_block_recurse(rz_analysis_get_block_at(analysis, addr), mark_as_visited, user); } } @@ -2313,7 +2322,8 @@ static void clear_bb_vars(RzAnalysisFunction *fcn, RzAnalysisBlock *bb, ut64 fro } static void update_analysis(RzAnalysis *analysis, RzList /**/ *fcns, HtUP *reachable) { - RzListIter *it, *it2, *tmp; + RzListIter *it; + void **it2; RzAnalysisFunction *fcn; bool old_jmpmid = analysis->opt.jmpmid; analysis->opt.jmpmid = true; @@ -2335,7 +2345,8 @@ static void update_analysis(RzAnalysis *analysis, RzList /*bbs, it2, tmp, bb) { + rz_pvector_foreach (fcn->bbs, it2) { + bb = *it2; if (ht_up_find_kv(ht, bb->addr, NULL)) { continue; } @@ -2347,8 +2358,19 @@ static void update_analysis(RzAnalysis *analysis, RzList /*ninstr -= bb->ninstr; rz_analysis_function_remove_block(fcn, bb); } + RzList *bbs_temp = rz_list_new(); + if (!bbs_temp) { + // If memory allocation failed, print an error message and return from the function + eprintf("Failed to allocate memory for bbs.\n"); + return; + } - RzList *bbs = rz_list_clone(fcn->bbs); + void **it; + rz_pvector_foreach (fcn->bbs, it) { + rz_list_append(bbs_temp, *it); + } + + RzList *bbs = rz_list_clone(bbs_temp); rz_analysis_block_automerge(bbs); rz_analysis_function_delete_unused_vars(fcn); rz_list_free(bbs); @@ -2412,12 +2434,14 @@ RZ_API void rz_analysis_update_analysis_range(RzAnalysis *analysis, ut64 addr, i RZ_API void rz_analysis_function_update_analysis(RzAnalysisFunction *fcn) { rz_return_if_fail(fcn); - RzListIter *it, *it2, *tmp, *tmp2; + void **it; + RzListIter *it2, *tmp2; RzAnalysisBlock *bb; RzAnalysisFunction *f; RzList *fcns = rz_list_new(); HtUP *reachable = ht_up_new(NULL, free_ht_up, NULL); - rz_list_foreach_safe (fcn->bbs, it, tmp, bb) { + rz_pvector_foreach (fcn->bbs, it) { + bb = *it; if (rz_analysis_block_was_modified(bb)) { rz_list_foreach_safe (bb->fcns, it2, tmp2, f) { calc_reachable_and_remove_block(fcns, f, bb, reachable); diff --git a/librz/analysis/function.c b/librz/analysis/function.c index a1fdcee8f76..35545fced51 100644 --- a/librz/analysis/function.c +++ b/librz/analysis/function.c @@ -74,7 +74,7 @@ RZ_API RzAnalysisFunction *rz_analysis_function_new(RzAnalysis *analysis) { fcn->addr = UT64_MAX; fcn->cc = rz_str_constpool_get(&analysis->constpool, rz_analysis_cc_default(analysis)); fcn->bits = analysis->bits; - fcn->bbs = rz_list_new(); + fcn->bbs = rz_pvector_new(NULL); fcn->has_changed = true; fcn->bp_frame = true; fcn->is_noreturn = false; @@ -93,12 +93,13 @@ RZ_API void rz_analysis_function_free(void *_fcn) { } RzAnalysisBlock *block; - RzListIter *iter; - rz_list_foreach (fcn->bbs, iter, block) { + void **iter; + rz_pvector_foreach (fcn->bbs, iter) { + block = *iter; rz_list_delete_data(block->fcns, fcn); rz_analysis_block_unref(block); } - rz_list_free(fcn->bbs); + rz_pvector_free(fcn->bbs); RzAnalysis *analysis = fcn->analysis; if (ht_up_find(analysis->ht_addr_fun, fcn->addr, NULL) == _fcn) { @@ -259,7 +260,7 @@ RZ_API void rz_analysis_function_add_block(RzAnalysisFunction *fcn, RzAnalysisBl } rz_list_append(bb->fcns, fcn); // associate the given fcn with this bb rz_analysis_block_ref(bb); - rz_list_append(fcn->bbs, bb); + rz_pvector_push(fcn->bbs, bb); if (fcn->meta._min != UT64_MAX) { if (bb->addr + bb->size > fcn->meta._max) { @@ -283,7 +284,7 @@ RZ_API void rz_analysis_function_remove_block(RzAnalysisFunction *fcn, RzAnalysi fcn->meta._min = UT64_MAX; } - rz_list_delete_data(fcn->bbs, bb); + rz_pvector_remove_data(fcn->bbs, bb); rz_analysis_block_unref(bb); } @@ -294,8 +295,9 @@ static void ensure_fcn_range(RzAnalysisFunction *fcn) { ut64 minval = UT64_MAX; ut64 maxval = UT64_MIN; RzAnalysisBlock *block; - RzListIter *iter; - rz_list_foreach (fcn->bbs, iter, block) { + void **iter; + rz_pvector_foreach (fcn->bbs, iter) { + block = *iter; if (block->addr < minval) { minval = block->addr; } @@ -328,11 +330,12 @@ RZ_API ut64 rz_analysis_function_size_from_entry(RzAnalysisFunction *fcn) { } RZ_API ut64 rz_analysis_function_realsize(const RzAnalysisFunction *fcn) { - RzListIter *iter; + void **iter; RzAnalysisBlock *bb; ut64 sz = 0; if (!sz) { - rz_list_foreach (fcn->bbs, iter, bb) { + rz_pvector_foreach (fcn->bbs, iter) { + bb = *iter; sz += bb->size; } } @@ -357,9 +360,10 @@ RZ_API bool rz_analysis_function_contains(RzAnalysisFunction *fcn, ut64 addr) { RZ_API bool rz_analysis_function_was_modified(RzAnalysisFunction *fcn) { rz_return_val_if_fail(fcn, false); - RzListIter *it; + void **it; RzAnalysisBlock *bb; - rz_list_foreach (fcn->bbs, it, bb) { + rz_pvector_foreach (fcn->bbs, it) { + bb = *it; if (rz_analysis_block_was_modified(bb)) { return true; } diff --git a/librz/analysis/jmptbl.c b/librz/analysis/jmptbl.c index 9152c2520c2..0ae5b693e69 100644 --- a/librz/analysis/jmptbl.c +++ b/librz/analysis/jmptbl.c @@ -445,7 +445,7 @@ RZ_API bool rz_analysis_get_jmptbl_info(RZ_NONNULL RzAnalysis *analysis, RZ_NONN rz_return_val_if_fail(analysis && fcn && params && block, false); bool isValid = false; int i; - RzListIter *iter; + void **iter; RzAnalysisBlock *tmp_bb, *prev_bb; prev_bb = 0; if (!fcn->bbs) { @@ -468,7 +468,8 @@ RZ_API bool rz_analysis_get_jmptbl_info(RZ_NONNULL RzAnalysis *analysis, RZ_NONN } // search for the predecessor bb - rz_list_foreach (fcn->bbs, iter, tmp_bb) { + rz_pvector_foreach (fcn->bbs, iter) { + tmp_bb = *iter; if (tmp_bb->jump == block->addr || tmp_bb->fail == block->addr) { prev_bb = tmp_bb; break; diff --git a/librz/analysis/serialize_analysis.c b/librz/analysis/serialize_analysis.c index 2eed2cd5916..ca336876265 100644 --- a/librz/analysis/serialize_analysis.c +++ b/librz/analysis/serialize_analysis.c @@ -1110,8 +1110,10 @@ static void function_store(RZ_NONNULL Sdb *db, const char *key, RzAnalysisFuncti pj_ka(j, "bbs"); RzListIter *it; + void **iter; RzAnalysisBlock *block; - rz_list_foreach (function->bbs, it, block) { + rz_pvector_foreach (function->bbs, iter) { + block = *iter; pj_n(j, block->addr); } pj_end(j); diff --git a/librz/analysis/similarity.c b/librz/analysis/similarity.c index bb722955672..975cd697cfc 100644 --- a/librz/analysis/similarity.c +++ b/librz/analysis/similarity.c @@ -120,9 +120,10 @@ static bool function_data_new(RzAnalysis *analysis, RzAnalysisFunction *fcn, ut8 size_t size = 0, current = 0; ut8 *data = NULL; RzAnalysisBlock *bb = NULL; - RzListIter *iter = NULL; + void **iter = NULL; - rz_list_foreach (fcn->bbs, iter, bb) { + rz_pvector_foreach (fcn->bbs, iter) { + bb = *iter; size += bb->size; } @@ -131,7 +132,8 @@ static bool function_data_new(RzAnalysis *analysis, RzAnalysisFunction *fcn, ut8 } current = 0; - rz_list_foreach (fcn->bbs, iter, bb) { + rz_pvector_foreach (fcn->bbs, iter) { + bb = *iter; if (bb->size > 0 && !iob_read_at(bb->addr, data + current, bb->size)) { goto fail; } @@ -420,7 +422,26 @@ static void *analysis_match_basic_blocks(SharedContext *shared) { */ RZ_API RZ_OWN RzAnalysisMatchResult *rz_analysis_match_basic_blocks(RZ_NONNULL RzAnalysisFunction *fcn_a, RZ_NONNULL RzAnalysisFunction *fcn_b, RZ_NONNULL RzAnalysisMatchOpt *opt) { rz_return_val_if_fail(opt && opt->analysis_a && opt->analysis_b && fcn_a && fcn_b, NULL); - return analysis_match_result_new(opt, fcn_a->bbs, fcn_b->bbs, (RzThreadFunction)analysis_match_basic_blocks, (AllocateBuffer)basic_block_data_new); + + RzList *bbs_list_a = rz_list_new(); + RzList *bbs_list_b = rz_list_new(); + if (!bbs_list_a || !bbs_list_b) { + // If memory allocation failed, print an error message and return NULL + eprintf("Failed to allocate memory for bbs_list_a or bbs_list_b.\n"); + rz_list_free(bbs_list_a); // It's safe to call rz_list_free with NULL + rz_list_free(bbs_list_b); + return NULL; + } + + void **it; + rz_pvector_foreach (fcn_a->bbs, it) { + rz_list_append(bbs_list_a, *it); + } + rz_pvector_foreach (fcn_b->bbs, it) { + rz_list_append(bbs_list_b, *it); + } + + return analysis_match_result_new(opt, bbs_list_a, bbs_list_b, (RzThreadFunction)analysis_match_basic_blocks, (AllocateBuffer)basic_block_data_new); } static bool function_name_cmp(RzAnalysisFunction *fcn_a, RzAnalysisFunction *fcn_b) { diff --git a/librz/analysis/xrefs.c b/librz/analysis/xrefs.c index cd4f6f1c09c..f1deac9c436 100644 --- a/librz/analysis/xrefs.c +++ b/librz/analysis/xrefs.c @@ -275,13 +275,14 @@ RZ_API ut64 rz_analysis_xrefs_count(RzAnalysis *analysis) { } static RZ_OWN RzList /**/ *fcn_get_refs(const RzAnalysisFunction *fcn, HtUP *ht) { - RzListIter *iter; + void **iter; RzAnalysisBlock *bb; RzList *list = rz_analysis_xref_list_new(); if (!list) { return NULL; } - rz_list_foreach (fcn->bbs, iter, bb) { + rz_pvector_foreach (fcn->bbs, iter) { + bb = *iter; int i; for (i = 0; i < bb->ninstr; i++) { diff --git a/librz/core/agraph.c b/librz/core/agraph.c index 8be6f287095..c5b4eb45286 100644 --- a/librz/core/agraph.c +++ b/librz/core/agraph.c @@ -2224,7 +2224,7 @@ static int bbcmp(RzAnalysisBlock *a, RzAnalysisBlock *b) { static void get_bbupdate(RzAGraph *g, RzCore *core, RzAnalysisFunction *fcn) { RzAnalysisBlock *bb; - RzListIter *iter; + void **iter; bool emu = rz_config_get_i(core->config, "asm.emu"); ut64 saved_gp = core->analysis->gp; ut8 *saved_arena = NULL; @@ -2239,10 +2239,11 @@ static void get_bbupdate(RzAGraph *g, RzCore *core, RzAnalysisFunction *fcn) { RZ_FREE(saved_arena); return; } - rz_list_sort(fcn->bbs, (RzListComparator)bbcmp); + rz_pvector_sort(fcn->bbs, (RzListComparator)bbcmp); shortcuts = rz_config_get_i(core->config, "graph.nodejmps"); - rz_list_foreach (fcn->bbs, iter, bb) { + rz_pvector_foreach (fcn->bbs, iter) { + bb = *iter; if (bb->addr == UT64_MAX) { continue; } @@ -2339,7 +2340,7 @@ static bool isbbfew(RzAnalysisBlock *curbb, RzAnalysisBlock *bb) { /* build the RzGraph inside the RzAGraph g, starting from the Basic Blocks */ static int get_bbnodes(RzAGraph *g, RzCore *core, RzAnalysisFunction *fcn) { RzAnalysisBlock *bb; - RzListIter *iter; + void **iter; bool emu = rz_config_get_i(core->config, "asm.emu"); bool few = rz_config_get_i(core->config, "graph.few"); int ret = false; @@ -2353,10 +2354,11 @@ static int get_bbnodes(RzAGraph *g, RzCore *core, RzAnalysisFunction *fcn) { if (emu) { saved_arena = rz_reg_arena_peek(core->analysis->reg); } - rz_list_sort(fcn->bbs, (RzListComparator)bbcmp); + rz_pvector_sort(fcn->bbs, (RzListComparator)bbcmp); RzAnalysisBlock *curbb = NULL; if (few) { - rz_list_foreach (fcn->bbs, iter, bb) { + rz_pvector_foreach (fcn->bbs, iter) { + bb = *iter; if (!curbb) { curbb = bb; } @@ -2369,7 +2371,8 @@ static int get_bbnodes(RzAGraph *g, RzCore *core, RzAnalysisFunction *fcn) { core->keep_asmqjmps = false; bool shortcuts = rz_core_agraph_is_shortcuts(core, g); - rz_list_foreach (fcn->bbs, iter, bb) { + rz_pvector_foreach (fcn->bbs, iter) { + bb = *iter; if (bb->addr == UT64_MAX) { continue; } @@ -2391,7 +2394,8 @@ static int get_bbnodes(RzAGraph *g, RzCore *core, RzAnalysisFunction *fcn) { core->keep_asmqjmps = true; } - rz_list_foreach (fcn->bbs, iter, bb) { + rz_pvector_foreach (fcn->bbs, iter) { + bb = *iter; if (bb->addr == UT64_MAX) { continue; } diff --git a/librz/core/analysis_tp.c b/librz/core/analysis_tp.c index d0a6f4fbaaf..8269efc724c 100644 --- a/librz/core/analysis_tp.c +++ b/librz/core/analysis_tp.c @@ -812,7 +812,7 @@ void propagate_types_among_used_variables(RzCore *core, HtUP *op_cache, RzAnalys #define OP_CACHE_LIMIT 8192 RZ_API void rz_core_analysis_type_match(RzCore *core, RzAnalysisFunction *fcn, HtUU *loop_table) { - RzListIter *it; + void **it; rz_return_if_fail(core && core->analysis && fcn); @@ -868,10 +868,11 @@ RZ_API void rz_core_analysis_type_match(RzCore *core, RzAnalysisFunction *fcn, H goto out_function; } rz_cons_break_push(NULL, NULL); - rz_list_sort(fcn->bbs, bb_cmpaddr); + rz_pvector_sort(fcn->bbs, bb_cmpaddr); // TODO: The algorithm can be more accurate if blocks are followed by their jmp/fail, not just by address RzAnalysisBlock *bb; - rz_list_foreach (fcn->bbs, it, bb) { + rz_pvector_foreach (fcn->bbs, it) { + bb = *it; ut64 addr = bb->addr; rz_reg_set_value(reg, r, addr); ht_up_free(op_cache); diff --git a/librz/core/canalysis.c b/librz/core/canalysis.c index 5b049b35330..453719ad239 100644 --- a/librz/core/canalysis.c +++ b/librz/core/canalysis.c @@ -314,9 +314,10 @@ RZ_IPI void rz_core_analysis_bbs_asciiart(RzCore *core, RzAnalysisFunction *fcn) if (!flist) { return; } - RzListIter *iter; + void **iter; RzAnalysisBlock *b; - rz_list_foreach (fcn->bbs, iter, b) { + rz_pvector_foreach (fcn->bbs, iter) { + b = *iter; RzInterval inter = (RzInterval){ b->addr, b->size }; RzListInfo *info = rz_listinfo_new(NULL, inter, inter, -1, NULL); if (!info) { @@ -333,9 +334,10 @@ RZ_IPI void rz_core_analysis_bbs_asciiart(RzCore *core, RzAnalysisFunction *fcn) } RZ_IPI void rz_core_analysis_fcn_returns(RzCore *core, RzAnalysisFunction *fcn) { - RzListIter *iter; + void **iter; RzAnalysisBlock *b; - rz_list_foreach (fcn->bbs, iter, b) { + rz_pvector_foreach (fcn->bbs, iter) { + b = *iter; if (b->jump == UT64_MAX) { ut64 retaddr = rz_analysis_block_get_op_addr(b, b->ninstr - 1); if (retaddr == UT64_MAX) { @@ -370,11 +372,12 @@ static ut64 __opaddr(RzAnalysisBlock *b, ut64 addr) { static void bb_info_print(RzCore *core, RzAnalysisFunction *fcn, RzAnalysisBlock *bb, ut64 addr, RzOutputMode mode, PJ *pj, RzTable *t) { RzDebugTracepoint *tp = NULL; - RzListIter *iter; + void **iter; RzAnalysisBlock *bb2; int outputs = (bb->jump != UT64_MAX) + (bb->fail != UT64_MAX); int inputs = 0; - rz_list_foreach (fcn->bbs, iter, bb2) { + rz_pvector_foreach (fcn->bbs, iter) { + bb2 = *iter; inputs += (bb2->jump == bb->addr) + (bb2->fail == bb->addr); } if (bb->switch_op) { @@ -484,7 +487,7 @@ static int bb_cmp(const void *a, const void *b) { RZ_IPI void rz_core_analysis_bbs_info_print(RzCore *core, RzAnalysisFunction *fcn, RzCmdStateOutput *state) { rz_return_if_fail(core && fcn && state); - RzListIter *iter; + void **iter; RzAnalysisBlock *bb; rz_cmd_state_output_array_start(state); rz_cmd_state_output_set_columnsf(state, "xdxx", "addr", "size", "jump", "fail"); @@ -492,8 +495,9 @@ RZ_IPI void rz_core_analysis_bbs_info_print(RzCore *core, RzAnalysisFunction *fc rz_cons_printf("fs blocks\n"); } - rz_list_sort(fcn->bbs, bb_cmp); - rz_list_foreach (fcn->bbs, iter, bb) { + rz_pvector_sort(fcn->bbs, bb_cmp); + rz_pvector_foreach (fcn->bbs, iter) { + bb = *iter; bb_info_print(core, fcn, bb, bb->addr, state->mode, state->d.pj, state->d.t); } @@ -781,7 +785,7 @@ static void function_rename(RzFlag *flags, RzAnalysisFunction *fcn) { } static void autoname_imp_trampoline(RzCore *core, RzAnalysisFunction *fcn) { - if (rz_list_length(fcn->bbs) == 1 && ((RzAnalysisBlock *)rz_list_first(fcn->bbs))->ninstr == 1) { + if (rz_pvector_len(fcn->bbs) == 1 && ((RzAnalysisBlock *)rz_pvector_at(fcn->bbs, 0))->ninstr == 1) { RzList *xrefs = rz_analysis_function_get_xrefs_from(fcn); if (xrefs && rz_list_length(xrefs) == 1) { RzAnalysisXRef *xref = rz_list_first(xrefs); @@ -2535,7 +2539,8 @@ RZ_API RZ_OWN RzCoreAnalysisStats *rz_core_analysis_get_stats(RZ_NONNULL RzCore RzAnalysisFunction *F; RzAnalysisBlock *B; RzBinSymbol *S; - RzListIter *iter, *iter2; + RzListIter *iter; + void **iter2; ut64 at; RzCoreAnalysisStats *as = RZ_NEW0(RzCoreAnalysisStats); if (!as) { @@ -2584,7 +2589,8 @@ RZ_API RZ_OWN RzCoreAnalysisStats *rz_core_analysis_get_stats(RZ_NONNULL RzCore blocks[piece].in_functions++; } // iter all basic blocks - rz_list_foreach (F->bbs, iter2, B) { + rz_pvector_foreach (F->bbs, iter2) { + B = *iter2; if (B->addr < from || B->addr > to) { continue; } @@ -2851,7 +2857,7 @@ RZ_API void rz_core_analysis_undefine(RzCore *core, ut64 off) { /* Join function at addr2 into function at addr */ // addr use to be core->offset RZ_API void rz_core_analysis_fcn_merge(RzCore *core, ut64 addr, ut64 addr2) { - RzListIter *iter; + void **iter; ut64 min = 0; ut64 max = 0; int first = 1; @@ -2868,7 +2874,8 @@ RZ_API void rz_core_analysis_fcn_merge(RzCore *core, ut64 addr, ut64 addr2) { // join all basic blocks from f1 into f2 if they are not // delete f2 RZ_LOG_WARN("core: merging 0x%08" PFMT64x " into 0x%08" PFMT64x "\n", addr, addr2); - rz_list_foreach (f1->bbs, iter, bb) { + rz_pvector_foreach (f1->bbs, iter) { + bb = *iter; if (first) { min = bb->addr; max = bb->addr + bb->size; @@ -2882,7 +2889,8 @@ RZ_API void rz_core_analysis_fcn_merge(RzCore *core, ut64 addr, ut64 addr2) { } } } - rz_list_foreach (f2->bbs, iter, bb) { + rz_pvector_foreach (f2->bbs, iter) { + bb = *iter; if (first) { min = bb->addr; max = bb->addr + bb->size; @@ -3227,9 +3235,10 @@ RZ_API void rz_core_analysis_paths(RzCore *core, ut64 from, ut64 to, bool follow } static bool analyze_noreturn_function(RzCore *core, RzAnalysisFunction *f) { - RzListIter *iter; + void **iter; RzAnalysisBlock *bb; - rz_list_foreach (f->bbs, iter, bb) { + rz_pvector_foreach (f->bbs, iter) { + bb = *iter; ut64 opaddr = rz_analysis_block_get_op_addr(bb, bb->ninstr - 1); if (opaddr == UT64_MAX) { return false; @@ -3864,7 +3873,8 @@ RZ_IPI void rz_core_analysis_resolve_pointers_to_data(RzCore *core) { return; } - RzListIter *it, *it2; + RzListIter *it; + void **it2; RzAnalysisFunction *func = NULL; RzAnalysisBlock *block = NULL; ut8 *bytes = NULL; @@ -3880,7 +3890,8 @@ RZ_IPI void rz_core_analysis_resolve_pointers_to_data(RzCore *core) { if (rz_cons_is_breaked()) { break; } - rz_list_foreach (func->bbs, it2, block) { + rz_pvector_foreach (func->bbs, it2) { + block = *it2; if (block->size < 1) { continue; } diff --git a/librz/core/cfile.c b/librz/core/cfile.c index 34f8076c2ad..38a0f8c7c16 100644 --- a/librz/core/cfile.c +++ b/librz/core/cfile.c @@ -121,7 +121,8 @@ static bool __rebase_xrefs(void *user, const ut64 k, const void *v) { } static void __rebase_everything(RzCore *core, RzList /**/ *old_sections, ut64 old_base) { - RzListIter *it, *itit, *ititit; + RzListIter *it, *itit; + void **it3; RzAnalysisFunction *fcn; ut64 new_base = core->bin->cur->o->baddr_shift; RzBinSection *old_section; @@ -138,7 +139,8 @@ static void __rebase_everything(RzCore *core, RzList /**/ *old_s rz_analysis_function_relocate(fcn, fcn->addr + diff); RzAnalysisBlock *bb; ut64 new_sec_addr = new_base + old_section->vaddr; - rz_list_foreach (fcn->bbs, ititit, bb) { + rz_pvector_foreach (fcn->bbs, it3) { + bb = *it3; if (bb->addr >= new_sec_addr && bb->addr <= new_sec_addr + old_section->vsize) { // Todo: Find better way to check if bb was already rebased continue; diff --git a/librz/core/cgraph.c b/librz/core/cgraph.c index 5448e7f3fa9..b3a82ddfd3c 100644 --- a/librz/core/cgraph.c +++ b/librz/core/cgraph.c @@ -283,9 +283,10 @@ static void core_graph_fn_bbs(RzCore *core, RzAnalysisFunction *fcn, RzGraph /*< return; } - RzListIter *iter; + void **iter; RzAnalysisBlock *bbi; - rz_list_foreach (fcn->bbs, iter, bbi) { + rz_pvector_foreach (fcn->bbs, iter) { + bbi = *iter; if (bbi->addr == UT64_MAX) { continue; } diff --git a/librz/core/cil.c b/librz/core/cil.c index 2a8c1623f12..a85840ed527 100644 --- a/librz/core/cil.c +++ b/librz/core/cil.c @@ -1087,7 +1087,15 @@ static inline bool get_next_i(IterCtx *ctx, size_t *next_i) { if (!ctx->cur_bb) { ctx->path = rz_list_new(); ctx->switch_path = rz_list_new(); - ctx->bbl = rz_list_clone(ctx->fcn->bbs); + ctx->bbl = rz_list_new(); + if (!ctx->bbl) { + eprintf("Failed to allocate memory for ctx->bbl list.\n"); + return false; + } + void **it; + rz_pvector_foreach (ctx->fcn->bbs, it) { + rz_list_append(ctx->bbl, *it); + } ctx->cur_bb = rz_analysis_get_block_at(ctx->fcn->analysis, ctx->fcn->addr); rz_list_push(ctx->path, ctx->cur_bb); } diff --git a/librz/core/cmd/cmd.c b/librz/core/cmd/cmd.c index 42f49d6170c..035f92c53e9 100644 --- a/librz/core/cmd/cmd.c +++ b/librz/core/cmd/cmd.c @@ -2753,9 +2753,10 @@ RZ_API int rz_core_cmd_foreach3(RzCore *core, const char *cmd, char *each) { // ut64 offorig = core->offset; ut64 obs = core->blocksize; if (fcn) { - RzListIter *iter; + void **iter; RzAnalysisBlock *bb; - rz_list_foreach (fcn->bbs, iter, bb) { + rz_pvector_foreach (fcn->bbs, iter) { + bb = *iter; rz_core_seek(core, bb->addr, true); rz_core_block_size(core, bb->size); rz_core_cmd0(core, cmd); @@ -2861,13 +2862,14 @@ RZ_API int rz_core_cmd_foreach(RzCore *core, const char *cmd, char *each) { break; case 'b': // "@@b" - function basic blocks { - RzListIter *iter; + void **iter; RzAnalysisBlock *bb; RzAnalysisFunction *fcn = rz_analysis_get_function_at(core->analysis, core->offset); int bs = core->blocksize; if (fcn) { - rz_list_sort(fcn->bbs, bb_cmp); - rz_list_foreach (fcn->bbs, iter, bb) { + rz_pvector_sort(fcn->bbs, bb_cmp); + rz_pvector_foreach (fcn->bbs, iter) { + bb = *iter; rz_core_block_size(core, bb->size); rz_core_seek(core, bb->addr, true); rz_core_cmd(core, cmd, 0); @@ -2905,13 +2907,14 @@ RZ_API int rz_core_cmd_foreach(RzCore *core, const char *cmd, char *each) { } break; case 'i': // "@@i" - function instructions { - RzListIter *iter; + void **iter; RzAnalysisBlock *bb; int i; RzAnalysisFunction *fcn = rz_analysis_get_function_at(core->analysis, core->offset); if (fcn) { - rz_list_sort(fcn->bbs, bb_cmp); - rz_list_foreach (fcn->bbs, iter, bb) { + rz_pvector_sort(fcn->bbs, bb_cmp); + rz_pvector_foreach (fcn->bbs, iter) { + bb = *iter; for (i = 0; i < bb->op_pos_size; i++) { ut64 addr = bb->addr + bb->op_pos[i]; rz_core_seek(core, addr, true); @@ -4676,11 +4679,12 @@ DEFINE_HANDLE_TS_FCN_AND_SYMBOL(iter_bbs_stmt) { return RZ_CMD_STATUS_INVALID; } - RzListIter *iter; + void **iter; RzAnalysisBlock *bb; RzCmdStatus ret = RZ_CMD_STATUS_OK; - rz_list_sort(fcn->bbs, bb_cmp); - rz_list_foreach (fcn->bbs, iter, bb) { + rz_pvector_sort(fcn->bbs, bb_cmp); + rz_pvector_foreach (fcn->bbs, iter) { + bb = *iter; rz_core_seek(core, bb->addr, true); rz_core_block_size(core, bb->size); RzCmdStatus cmd_res = handle_ts_stmt_tmpseek(state, command); diff --git a/librz/core/cmd/cmd_analysis.c b/librz/core/cmd/cmd_analysis.c index ba24d4a5c70..fb03d54f929 100644 --- a/librz/core/cmd/cmd_analysis.c +++ b/librz/core/cmd/cmd_analysis.c @@ -1394,7 +1394,7 @@ static void rz_analysis_aefa(RzCore *core, const char *arg) { } static void __analysis_esil_function(RzCore *core, ut64 addr) { - RzListIter *iter; + void **iter; RzAnalysisBlock *bb; if (!core->analysis->esil) { rz_core_analysis_esil_init_mem(core, NULL, UT64_MAX, UT32_MAX); @@ -1403,7 +1403,8 @@ static void __analysis_esil_function(RzCore *core, ut64 addr) { addr, RZ_ANALYSIS_FCN_TYPE_FCN | RZ_ANALYSIS_FCN_TYPE_SYM); if (fcn) { // emulate every instruction in the function recursively across all the basic blocks - rz_list_foreach (fcn->bbs, iter, bb) { + rz_pvector_foreach (fcn->bbs, iter) { + bb = *iter; ut64 pc = bb->addr; ut64 end = bb->addr + bb->size; RzAnalysisOp op; @@ -2103,8 +2104,8 @@ RZ_IPI RzCmdStatus rz_analysis_function_blocks_del_all_handler(RzCore *core, int if (!fcn) { return RZ_CMD_STATUS_ERROR; } - while (!rz_list_empty(fcn->bbs)) { - rz_analysis_function_remove_block(fcn, rz_list_first(fcn->bbs)); + while (!rz_pvector_empty(fcn->bbs)) { + rz_analysis_function_remove_block(fcn, rz_pvector_at(fcn->bbs, 0)); } return RZ_CMD_STATUS_OK; } @@ -2213,9 +2214,10 @@ RZ_IPI RzCmdStatus rz_analysis_function_setbits_handler(RzCore *core, int argc, if (!fcn) { return RZ_CMD_STATUS_ERROR; } - RzListIter *iter; + void **iter; RzAnalysisBlock *bb; - rz_list_foreach (fcn->bbs, iter, bb) { + rz_pvector_foreach (fcn->bbs, iter) { + bb = *iter; rz_analysis_hint_set_bits(core->analysis, bb->addr, bits); rz_analysis_hint_set_bits(core->analysis, bb->addr + bb->size, core->analysis->bits); } @@ -2227,9 +2229,10 @@ static bool function_byte_signature(RzCore *core, RzAnalysisFunction *fcn, ut8 * size_t size = 0, current = 0; ut8 *data = NULL; RzAnalysisBlock *bb = NULL; - RzListIter *iter = NULL; + void **iter = NULL; - rz_list_foreach (fcn->bbs, iter, bb) { + rz_pvector_foreach (fcn->bbs, iter) { + bb = *iter; size += bb->size; } @@ -2239,7 +2242,8 @@ static bool function_byte_signature(RzCore *core, RzAnalysisFunction *fcn, ut8 * } current = 0; - rz_list_foreach (fcn->bbs, iter, bb) { + rz_pvector_foreach (fcn->bbs, iter) { + bb = *iter; if (bb->size > 0 && !rz_io_read_at(core->io, bb->addr, data + current, bb->size)) { RZ_LOG_ERROR("core: failed to read at %" PFMT64x "\n", bb->addr); goto fail; @@ -3572,7 +3576,7 @@ static void function_list_print_to_table(RzCore *core, RzList /*addr, fcn->name, rz_analysis_function_realsize(fcn), xref_to_num, xref_from_num, calls_num, - rz_list_length(fcn->bbs), rz_analysis_function_count_edges(fcn, NULL), + rz_pvector_len(fcn->bbs), rz_analysis_function_count_edges(fcn, NULL), rz_analysis_function_complexity(fcn), rz_analysis_function_cost(fcn), fcn->is_noreturn, rz_analysis_function_min_addr(fcn), rz_analysis_function_linear_size(fcn), rz_analysis_function_max_addr(fcn), @@ -3581,7 +3585,7 @@ static void function_list_print_to_table(RzCore *core, RzList /*addr, fcn->name, rz_analysis_function_realsize(fcn), xref_to_num, xref_from_num, calls_num, - rz_list_length(fcn->bbs), rz_analysis_function_count_edges(fcn, NULL), + rz_pvector_len(fcn->bbs), rz_analysis_function_count_edges(fcn, NULL), rz_analysis_function_complexity(fcn), rz_analysis_function_cost(fcn), fcn->is_noreturn, NULL); } @@ -3600,8 +3604,8 @@ static void function_list_print(RzCore *core, RzList /**/ } else { msg = rz_str_newf("%-4" PFMT64u " -> %-4" PFMT64u, size, realsize); } - rz_cons_printf("0x%08" PFMT64x " %4d %4s %s\n", - fcn->addr, rz_list_length(fcn->bbs), msg, fcn->name); + rz_cons_printf("0x%08" PFMT64x " %4ld %4s %s\n", + fcn->addr, rz_pvector_len(fcn->bbs), msg, fcn->name); free(msg); } } @@ -3630,9 +3634,10 @@ static char function_type_to_char(RzAnalysisFunction *fcn) { static void fcn_list_bbs(RzAnalysisFunction *fcn) { RzAnalysisBlock *bbi; - RzListIter *iter; + void **iter; - rz_list_foreach (fcn->bbs, iter, bbi) { + rz_pvector_foreach (fcn->bbs, iter) { + bbi = *iter; rz_cons_printf("afb+ 0x%08" PFMT64x " 0x%08" PFMT64x " %" PFMT64u " ", fcn->addr, bbi->addr, bbi->size); rz_cons_printf("0x%08" PFMT64x " ", bbi->jump); @@ -3692,7 +3697,7 @@ static void function_print_to_json(RzCore *core, RzAnalysisFunction *fcn, RzCmdS pj_ki(state->d.pj, "loops", rz_analysis_function_loops(fcn)); pj_ki(state->d.pj, "bits", fcn->bits); pj_ks(state->d.pj, "type", rz_analysis_fcntype_tostring(fcn->type)); - pj_ki(state->d.pj, "nbbs", rz_list_length(fcn->bbs)); + pj_ki(state->d.pj, "nbbs", rz_pvector_len(fcn->bbs)); pj_ki(state->d.pj, "edges", rz_analysis_function_count_edges(fcn, &ebbs)); pj_ki(state->d.pj, "ebbs", ebbs); { @@ -3995,7 +4000,7 @@ static void fcn_print_info(RzCore *core, RzAnalysisFunction *fcn, RzCmdStateOutp rz_cons_printf("loops: %d\n", rz_analysis_function_loops(fcn)); rz_cons_printf("bits: %d\n", fcn->bits); rz_cons_printf("type: %s\n", rz_analysis_fcntype_tostring(fcn->type)); - rz_cons_printf("num-bbs: %d\n", rz_list_length(fcn->bbs)); + rz_cons_printf("num-bbs: %ld\n", rz_pvector_len(fcn->bbs)); rz_cons_printf("edges: %d\n", rz_analysis_function_count_edges(fcn, &ebbs)); rz_cons_printf("end-bbs: %d\n", ebbs); rz_cons_printf("call-refs:"); @@ -4172,8 +4177,9 @@ static void update_stat_for_op(RzCore *core, HtPU *ht, ut64 addr, int mode) { static void gather_opcode_stat_for_fcn(RzCore *core, HtPU *ht, RzAnalysisFunction *fcn, int mode) { RzAnalysisBlock *bb; - RzListIter *iter; - rz_list_foreach (fcn->bbs, iter, bb) { + void **iter; + rz_pvector_foreach (fcn->bbs, iter) { + bb = *iter; update_stat_for_op(core, ht, bb->addr, mode); for (int i = 0; i < bb->op_pos_size; i++) { ut16 op_pos = bb->op_pos[i]; @@ -4373,13 +4379,15 @@ RZ_IPI RzCmdStatus rz_analysis_functions_map_handler(RzCore *core, int argc, con return RZ_CMD_STATUS_ERROR; } - RzListIter *iter, *iter2; + RzListIter *iter; + void **iter2; RzAnalysisFunction *fcn; RzAnalysisBlock *b; // for each function rz_list_foreach (core->analysis->fcns, iter, fcn) { // for each basic block in the function - rz_list_foreach (fcn->bbs, iter2, b) { + rz_pvector_foreach (fcn->bbs, iter2) { + b = *iter2; // if it is not within range, continue if ((fcn->addr < base_addr) || (fcn->addr >= base_addr + code_size)) continue; @@ -6350,7 +6358,8 @@ RZ_IPI RzCmdStatus rz_print_areas_no_functions_handler(RzCore *core, int argc, c ut64 code_size = rz_num_get(core->num, "$SS"); ut64 base_addr = rz_num_get(core->num, "$S"); ut64 chunk_size, chunk_offset, i; - RzListIter *iter, *iter2; + RzListIter *iter; + void **iter2; RzAnalysisFunction *fcn; RzAnalysisBlock *b; char *bitmap; @@ -6370,7 +6379,8 @@ RZ_IPI RzCmdStatus rz_print_areas_no_functions_handler(RzCore *core, int argc, c // for each function rz_list_foreach (core->analysis->fcns, iter, fcn) { // for each basic block in the function - rz_list_foreach (fcn->bbs, iter2, b) { + rz_pvector_foreach (fcn->bbs, iter2) { + b = *iter2; // if it is not withing range, continue if ((fcn->addr < base_addr) || (fcn->addr >= base_addr + code_size)) continue; @@ -6483,8 +6493,9 @@ RZ_IPI RzCmdStatus rz_analysis_data_function_handler(RzCore *core, int argc, con char *bitmap = calloc(1, fcn_size); if (bitmap) { RzAnalysisBlock *b; - RzListIter *iter; - rz_list_foreach (fcn->bbs, iter, b) { + void **iter; + rz_pvector_foreach (fcn->bbs, iter) { + b = *iter; int f = b->addr - fcn->addr; int t = RZ_MIN(f + b->size, fcn_size); if (f >= 0) { diff --git a/librz/core/cmd/cmd_meta.c b/librz/core/cmd/cmd_meta.c index a5cf7b86d88..37069bfc54b 100644 --- a/librz/core/cmd/cmd_meta.c +++ b/librz/core/cmd/cmd_meta.c @@ -270,8 +270,9 @@ RZ_IPI RzCmdStatus rz_comment_function_list_handler(RzCore *core, int argc, cons static void meta_function_comment_remove(RzAnalysis *analysis, RzAnalysisFunction *fcn) { RzAnalysisBlock *bb; - RzListIter *iter; - rz_list_foreach (fcn->bbs, iter, bb) { + void **iter; + rz_pvector_foreach (fcn->bbs, iter) { + bb = *iter; int i; for (i = 0; i < bb->size; i++) { ut64 addr = bb->addr + i; diff --git a/librz/core/cmd/cmd_print.c b/librz/core/cmd/cmd_print.c index afbee0625a4..b149905ad5e 100644 --- a/librz/core/cmd/cmd_print.c +++ b/librz/core/cmd/cmd_print.c @@ -2246,14 +2246,15 @@ static void func_walk_blocks(RzCore *core, RzAnalysisFunction *f, bool fromHere, const bool orig_bb_middle = rz_config_get_b(core->config, "asm.bb.middle"); rz_config_set_b(core->config, "asm.bb.middle", false); - rz_list_sort(f->bbs, (RzListComparator)bbcmp); + rz_pvector_sort(f->bbs, (RzListComparator)bbcmp); RzAnalysisBlock *b; - RzListIter *iter; + void **iter; if (state->mode == RZ_OUTPUT_MODE_JSON) { rz_cmd_state_output_array_start(state); - rz_list_foreach (f->bbs, iter, b) { + rz_pvector_foreach (f->bbs, iter) { + b = *iter; if (fromHere) { if (b->addr < core->offset) { core->cons->null = true; @@ -2282,7 +2283,8 @@ static void func_walk_blocks(RzCore *core, RzAnalysisFunction *f, bool fromHere, } rz_config_set_i(core->config, "asm.lines.bb", 0); - rz_list_foreach (f->bbs, iter, b) { + rz_pvector_foreach (f->bbs, iter) { + b = *iter; pr_bb(core, f, b, emu, saved_gp, saved_arena, 'I', fromHere); } if (emu) { @@ -4320,22 +4322,23 @@ RZ_IPI RzCmdStatus rz_cmd_disassemble_ropchain_handler(RzCore *core, int argc, c } static bool core_walk_function_blocks(RzCore *core, RzAnalysisFunction *f, RzCmdStateOutput *state, char type_print, bool fromHere) { - RzListIter *iter; + void **iter; RzAnalysisBlock *b = NULL; const bool orig_bb_middle = rz_config_get_b(core->config, "asm.bb.middle"); rz_config_set_b(core->config, "asm.bb.middle", false); - if (rz_list_length(f->bbs) >= 1) { + if (rz_pvector_len(f->bbs) >= 1) { ut32 fcn_size = rz_analysis_function_realsize(f); - b = rz_list_get_top(f->bbs); + b = rz_pvector_at(f->bbs, 0); if (b->size > fcn_size) { b->size = fcn_size; } } - rz_list_sort(f->bbs, (RzListComparator)bbcmp); + rz_pvector_sort(f->bbs, (RzListComparator)bbcmp); if (state->mode == RZ_OUTPUT_MODE_JSON) { - rz_list_foreach (f->bbs, iter, b) { + rz_pvector_foreach (f->bbs, iter) { + b = *iter; ut8 *buf = malloc(b->size); if (!buf) { RZ_LOG_ERROR("cannot allocate %" PFMT64u " byte(s)\n", b->size); @@ -4355,7 +4358,8 @@ static bool core_walk_function_blocks(RzCore *core, RzAnalysisFunction *f, RzCmd saved_arena = rz_reg_arena_peek(core->analysis->reg); } rz_config_set_i(core->config, "asm.lines.bb", 0); - rz_list_foreach (f->bbs, iter, b) { + rz_pvector_foreach (f->bbs, iter) { + b = *iter; pr_bb(core, f, b, emu, saved_gp, saved_arena, type_print, fromHere); } if (emu) { @@ -5950,7 +5954,7 @@ static ut8 *analysis_histogram_data(RzCore *core, CoreBlockRange *brange, CoreAn if (hist_type == HISTOGRAM_ANALYSIS_BASIC_BLOCKS) { RzAnalysisFunction *fcn = rz_analysis_get_fcn_in(core->analysis, off + j, 0); if (fcn) { - data[i] = rz_list_length(fcn->bbs); + data[i] = rz_pvector_len(fcn->bbs); } continue; } diff --git a/librz/core/cmd/cmd_search.c b/librz/core/cmd/cmd_search.c index ebcf854bddd..004d9d1bd79 100644 --- a/librz/core/cmd/cmd_search.c +++ b/librz/core/cmd/cmd_search.c @@ -824,10 +824,11 @@ RZ_API RZ_OWN RzList /**/ *rz_core_get_boundaries_prot(RzCore *core, /* Search only inside the basic block */ if (!strcmp(mode, "analysis.bb")) { - RzListIter *iter; + void **iter; RzAnalysisBlock *bb; - rz_list_foreach (f->bbs, iter, bb) { + rz_pvector_foreach (f->bbs, iter) { + bb = *iter; ut64 at = core->offset; if ((at >= bb->addr) && (at < (bb->addr + bb->size))) { from = bb->addr; diff --git a/librz/core/core.c b/librz/core/core.c index 613b4606a17..8d64b4a7eae 100644 --- a/librz/core/core.c +++ b/librz/core/core.c @@ -427,9 +427,10 @@ static ut64 getref(RzCore *core, int n, char t, int type) { } static ut64 bbInstructions(RzAnalysisFunction *fcn, ut64 addr) { - RzListIter *iter; + void **iter; RzAnalysisBlock *bb; - rz_list_foreach (fcn->bbs, iter, bb) { + rz_pvector_foreach (fcn->bbs, iter) { + bb = *iter; if (RZ_BETWEEN(bb->addr, addr, bb->addr + bb->size - 1)) { return bb->ninstr; } @@ -438,9 +439,10 @@ static ut64 bbInstructions(RzAnalysisFunction *fcn, ut64 addr) { } static ut64 bbBegin(RzAnalysisFunction *fcn, ut64 addr) { - RzListIter *iter; + void **iter; RzAnalysisBlock *bb; - rz_list_foreach (fcn->bbs, iter, bb) { + rz_pvector_foreach (fcn->bbs, iter) { + bb = *iter; if (RZ_BETWEEN(bb->addr, addr, bb->addr + bb->size - 1)) { return bb->addr; } @@ -449,9 +451,10 @@ static ut64 bbBegin(RzAnalysisFunction *fcn, ut64 addr) { } static ut64 bbJump(RzAnalysisFunction *fcn, ut64 addr) { - RzListIter *iter; + void **iter; RzAnalysisBlock *bb; - rz_list_foreach (fcn->bbs, iter, bb) { + rz_pvector_foreach (fcn->bbs, iter) { + bb = *iter; if (RZ_BETWEEN(bb->addr, addr, bb->addr + bb->size - 1)) { return bb->jump; } @@ -460,9 +463,10 @@ static ut64 bbJump(RzAnalysisFunction *fcn, ut64 addr) { } static ut64 bbFail(RzAnalysisFunction *fcn, ut64 addr) { - RzListIter *iter; + void **iter; RzAnalysisBlock *bb; - rz_list_foreach (fcn->bbs, iter, bb) { + rz_pvector_foreach (fcn->bbs, iter) { + bb = *iter; if (RZ_BETWEEN(bb->addr, addr, bb->addr + bb->size - 1)) { return bb->fail; } @@ -471,9 +475,10 @@ static ut64 bbFail(RzAnalysisFunction *fcn, ut64 addr) { } static ut64 bbSize(RzAnalysisFunction *fcn, ut64 addr) { - RzListIter *iter; + void **iter; RzAnalysisBlock *bb; - rz_list_foreach (fcn->bbs, iter, bb) { + rz_pvector_foreach (fcn->bbs, iter) { + bb = *iter; if (RZ_BETWEEN(bb->addr, addr, bb->addr + bb->size - 1)) { return bb->size; } diff --git a/librz/core/cprint.c b/librz/core/cprint.c index eebceeb5db7..7f4f35a4899 100644 --- a/librz/core/cprint.c +++ b/librz/core/cprint.c @@ -822,8 +822,9 @@ RZ_API RZ_OWN char *rz_core_print_disasm_strings(RZ_NONNULL RzCore *core, RzCore bool label = false; /* show labels, basic blocks and (conditional) branches */ RzAnalysisBlock *bb; - RzListIter *iterb; - rz_list_foreach (fcn->bbs, iterb, bb) { + void **iterb; + rz_pvector_foreach (fcn->bbs, iterb) { + bb = *iterb; if (addr == bb->jump) { if (show_offset) { rz_strbuf_appendf(sb, "%s0x%08" PFMT64x ":\n", use_color ? Color_YELLOW : "", addr); @@ -836,7 +837,8 @@ RZ_API RZ_OWN char *rz_core_print_disasm_strings(RZ_NONNULL RzCore *core, RzCore rz_strbuf_appendf(sb, "%s0x%08" PFMT64x ":\n", use_color ? Color_YELLOW : "", addr); } if (strstr(line, "=<")) { - rz_list_foreach (fcn->bbs, iterb, bb) { + rz_pvector_foreach (fcn->bbs, iterb) { + bb = *iterb; if (addr >= bb->addr && addr < bb->addr + bb->size) { const char *op; if (use_color) { diff --git a/librz/core/ctypes.c b/librz/core/ctypes.c index 23200e90d8b..c4e593cbfac 100644 --- a/librz/core/ctypes.c +++ b/librz/core/ctypes.c @@ -716,7 +716,7 @@ static void resolve_global_var_types(RzCore *core, ut64 at, struct GVTAnalysisCo RZ_API void rz_core_global_vars_propagate_types(RzCore *core, RzAnalysisFunction *fcn) { rz_return_if_fail(core && core->analysis && fcn); RzAnalysisBlock *bb; - RzListIter *it; + void **it; RzAnalysisOp aop = { 0 }; bool ioCache = rz_config_get_i(core->config, "io.cache"); bool stack_set = false; @@ -766,8 +766,9 @@ RZ_API void rz_core_global_vars_propagate_types(RzCore *core, RzAnalysisFunction ut64 oldoff = core->offset; rz_cons_break_push(NULL, NULL); // TODO: The algorithm can be more accurate if blocks are followed by their jmp/fail, not just by address - rz_list_sort(fcn->bbs, bb_cmpaddr); - rz_list_foreach (fcn->bbs, it, bb) { + rz_pvector_sort(fcn->bbs, bb_cmpaddr); + rz_pvector_foreach (fcn->bbs, it) { + bb = *it; ut64 at = bb->addr; ut64 to = bb->addr + bb->size; rz_reg_set_value(esil->analysis->reg, pc, at); diff --git a/librz/core/disasm.c b/librz/core/disasm.c index 4b09311ae88..2d778c43b82 100644 --- a/librz/core/disasm.c +++ b/librz/core/disasm.c @@ -6559,7 +6559,7 @@ RZ_API int rz_core_disasm_pde(RzCore *core, int nb_opcodes, RzCmdStateOutput *st RZ_API bool rz_core_print_function_disasm_json(RzCore *core, RzAnalysisFunction *fcn, PJ *pj) { RzAnalysisBlock *b; - RzListIter *locs_it = NULL; + void **locs_it = NULL; ut32 fcn_size = rz_analysis_function_realsize(fcn); const char *orig_bb_middle = rz_config_get(core->config, "asm.bb.middle"); rz_config_set_i(core->config, "asm.bb.middle", false); @@ -6569,9 +6569,9 @@ RZ_API bool rz_core_print_function_disasm_json(RzCore *core, RzAnalysisFunction pj_kn(pj, "addr", fcn->addr); pj_k(pj, "ops"); pj_a(pj); - rz_list_sort(fcn->bbs, bb_cmpaddr); - rz_list_foreach (fcn->bbs, locs_it, b) { - + rz_pvector_sort(fcn->bbs, bb_cmpaddr); + rz_pvector_foreach (fcn->bbs, locs_it) { + b = *locs_it; ut8 *buf = malloc(b->size); if (buf) { rz_io_read_at(core->io, b->addr, buf, b->size); diff --git a/librz/core/golang.c b/librz/core/golang.c index 42c41cff88b..be073ef8936 100644 --- a/librz/core/golang.c +++ b/librz/core/golang.c @@ -1733,7 +1733,8 @@ RZ_API void rz_core_analysis_resolve_golang_strings(RzCore *core) { const char *asm_arch = rz_config_get(core->config, "asm.arch"); ut32 asm_bits = rz_config_get_i(core->config, "asm.bits"); - RzListIter *it, *it2; + RzListIter *it; + void **it2; RzAnalysisFunction *func; RzAnalysisBlock *block; GoStrRecoverCb recover_cb = NULL; @@ -1811,7 +1812,8 @@ RZ_API void rz_core_analysis_resolve_golang_strings(RzCore *core) { if (rz_cons_is_breaked()) { break; } - rz_list_foreach (func->bbs, it2, block) { + rz_pvector_foreach (func->bbs, it2) { + block = *it2; bytes = malloc(block->size); if (!bytes) { RZ_LOG_ERROR("Failed allocate basic block bytes buffer\n"); diff --git a/librz/core/tui/panels.c b/librz/core/tui/panels.c index 48257d1c7b5..bc8bb66c772 100644 --- a/librz/core/tui/panels.c +++ b/librz/core/tui/panels.c @@ -2892,7 +2892,7 @@ bool __check_func(RzCore *core) { rz_cons_message("Not in a function. Type 'df' to define it here"); return false; } - if (rz_list_empty(fun->bbs)) { + if (rz_pvector_empty(fun->bbs)) { rz_cons_message("No basic blocks in this function. You may want to use 'afb+'."); return false; } diff --git a/librz/core/tui/visual.c b/librz/core/tui/visual.c index 149ba06498e..f59fdc9c5a9 100644 --- a/librz/core/tui/visual.c +++ b/librz/core/tui/visual.c @@ -2544,7 +2544,7 @@ RZ_IPI int rz_core_visual_cmd(RzCore *core, const char *arg) { if (!fun) { rz_cons_message("Not in a function. Type 'df' to define it here"); break; - } else if (rz_list_empty(fun->bbs)) { + } else if (rz_pvector_empty(fun->bbs)) { rz_cons_message("No basic blocks in this function. You may want to use 'afb+'."); break; } diff --git a/librz/include/rz_analysis.h b/librz/include/rz_analysis.h index 6408a328133..5b129209ca9 100644 --- a/librz/include/rz_analysis.h +++ b/librz/include/rz_analysis.h @@ -170,7 +170,7 @@ typedef struct rz_analysis_function_t { bool bp_frame : 1; bool is_noreturn : 1; // true if function does not return int argnum; // number of arguments; - RzList /**/ *bbs; // TODO: should be RzPVector + RzPVector /**/ *bbs; RzAnalysisFcnMeta meta; RzList /**/ *imports; // maybe bound to class? struct rz_analysis_t *analysis; // this function is associated with this instance diff --git a/librz/main/rz-diff.c b/librz/main/rz-diff.c index afd3272f387..5dce5544455 100644 --- a/librz/main/rz-diff.c +++ b/librz/main/rz-diff.c @@ -1617,9 +1617,10 @@ static void graphviz_dot_nodes(RzCore *core_a, RzAnalysisFunction *fcn_a, RzCore #define PAL_TRUE "#13a10e" static void graphviz_dot_edges(RzCore *core, RzAnalysisFunction *fcn) { RzAnalysisBlock *bbi; - RzListIter *iter; + void **iter; - rz_list_foreach (fcn->bbs, iter, bbi) { + rz_pvector_foreach (fcn->bbs, iter) { + bbi = *iter; if (bbi->jump != UT64_MAX) { rz_cons_printf("\t\"0x%08" PFMT64x "\" -> \"0x%08" PFMT64x "\" [color=\"%s\"];\n", bbi->addr, bbi->jump, diff --git a/librz/sign/flirt.c b/librz/sign/flirt.c index e81754260df..45c8438ecbd 100644 --- a/librz/sign/flirt.c +++ b/librz/sign/flirt.c @@ -428,9 +428,10 @@ static int module_match_buffer(RzAnalysis *analysis, const RzFlirtModule *module if (fcn != next_module_function && fcn->addr >= next_module_function->addr + next_module_function_size && fcn->addr < next_module_function->addr + flirt_fcn_size) { - RzListIter *iter_bb; + void **iter_bb; RzAnalysisBlock *block; - rz_list_foreach (fcn->bbs, iter_bb, block) { + rz_pvector_foreach (fcn->bbs, iter_bb) { + block = *iter_bb; rz_analysis_function_add_block(next_module_function, block); } next_module_function->ninstr += fcn->ninstr; diff --git a/test/unit/test_analysis_block.c b/test/unit/test_analysis_block.c index 9d9e439dffb..a712374fa1d 100644 --- a/test/unit/test_analysis_block.c +++ b/test/unit/test_analysis_block.c @@ -314,8 +314,8 @@ bool test_rz_analysis_block_split_in_function() { mu_assert_eq(block->ref, 2, "first block refs after adding to function"); mu_assert_eq(second->ref, 2, "second block refs after adding to function"); - mu_assert("function has first block after split", rz_list_contains(fcn->bbs, block)); - mu_assert("function has second block after split", rz_list_contains(fcn->bbs, second)); + mu_assert("function has first block after split", rz_pvector_contains(fcn->bbs, block)); + mu_assert("function has second block after split", rz_pvector_contains(fcn->bbs, second)); mu_assert("second block is in function after split", rz_list_contains(block->fcns, fcn)); mu_assert("second block is in function after split", rz_list_contains(second->fcns, fcn)); @@ -395,9 +395,9 @@ bool test_rz_analysis_block_merge_in_function() { assert_block_invariants(analysis); mu_assert("merge success", success); mu_assert_eq(blocks_count(analysis), 1, "count after merge"); - mu_assert_eq(rz_list_length(fcn->bbs), 1, "fcn bbs after merge"); + mu_assert_eq(rz_pvector_len(fcn->bbs), 1, "fcn bbs after merge"); mu_assert_eq(rz_list_length(first->fcns), 1, "bb functions after merge"); - mu_assert("function has merged block", rz_list_contains(fcn->bbs, first)); + mu_assert("function has merged block", rz_pvector_contains(fcn->bbs, first)); mu_assert("merged block is in function", rz_list_contains(first->fcns, fcn)); rz_analysis_block_unref(first); @@ -421,13 +421,13 @@ bool test_rz_analysis_block_delete() { rz_analysis_function_add_block(fcn, block); assert_block_invariants(analysis); mu_assert_eq(block->ref, 2, "refs after adding"); - mu_assert_eq(rz_list_length(fcn->bbs), 1, "fcn bbs after add"); + mu_assert_eq(rz_pvector_len(fcn->bbs), 1, "fcn bbs after add"); mu_assert_eq(rz_list_length(block->fcns), 1, "bb fcns after add"); rz_analysis_delete_block(block); assert_block_invariants(analysis); mu_assert_eq(block->ref, 1, "refs after delete"); - mu_assert_eq(rz_list_length(fcn->bbs), 0, "fcn bbs after delete"); + mu_assert_eq(rz_pvector_len(fcn->bbs), 0, "fcn bbs after delete"); mu_assert_eq(rz_list_length(block->fcns), 0, "bb fcns after delete"); rz_analysis_block_unref(block); diff --git a/test/unit/test_analysis_block_invars.inl b/test/unit/test_analysis_block_invars.inl index 719e70ef5e0..026de7ca230 100644 --- a/test/unit/test_analysis_block_invars.inl +++ b/test/unit/test_analysis_block_invars.inl @@ -7,13 +7,13 @@ static bool block_check_invariants(RzAnalysis *analysis) { ut64 last_start = UT64_MAX; rz_rbtree_foreach (analysis->bb_tree, iter, block, RzAnalysisBlock, _rb) { if (last_start != UT64_MAX) { - mu_assert ("corrupted binary tree", block->addr >= last_start); - mu_assert_neq (block->addr, last_start, "double blocks"); + mu_assert("corrupted binary tree", block->addr >= last_start); + mu_assert_neq(block->addr, last_start, "double blocks"); } last_start = block->addr; - mu_assert ("block->ref < 1, but it is still in the tree", block->ref >= 1); - mu_assert ("block->ref < rz_list_length (block->fcns)", block->ref >= rz_list_length (block->fcns)); + mu_assert("block->ref < 1, but it is still in the tree", block->ref >= 1); + mu_assert("block->ref < rz_list_length (block->fcns)", block->ref >= rz_list_length(block->fcns)); RzListIter *fcniter; RzAnalysisFunction *fcn; @@ -21,9 +21,9 @@ static bool block_check_invariants(RzAnalysis *analysis) { RzListIter *fcniter2; RzAnalysisFunction *fcn2; rz_list_foreach_iter(rz_list_iter_get_next(fcniter), fcniter2, fcn2) { - mu_assert_ptrneq (fcn, fcn2, "duplicate function in basic block"); + mu_assert_ptrneq(fcn, fcn2, "duplicate function in basic block"); } - mu_assert ("block references function, but function does not reference block", rz_list_contains (fcn->bbs, block)); + mu_assert("block references function, but function does not reference block", rz_pvector_contains(fcn->bbs, block)); } } @@ -31,10 +31,13 @@ static bool block_check_invariants(RzAnalysis *analysis) { RzAnalysisFunction *fcn; rz_list_foreach (analysis->fcns, fcniter, fcn) { RzListIter *blockiter; + void **iter; ut64 min = UT64_MAX; ut64 max = UT64_MIN; ut64 realsz = 0; - rz_list_foreach (fcn->bbs, blockiter, block) { + rz_pvector_foreach (fcn->bbs, iter) { + block = *iter; + blockiter = *iter; RzListIter *blockiter2; RzAnalysisBlock *block2; if (block->addr < min) { @@ -45,17 +48,17 @@ static bool block_check_invariants(RzAnalysis *analysis) { } realsz += block->size; rz_list_foreach_iter(rz_list_iter_get_next(blockiter), blockiter2, block2) { - mu_assert_ptrneq (block, block2, "duplicate basic block in function"); + mu_assert_ptrneq(block, block2, "duplicate basic block in function"); } - mu_assert ("function references block, but block does not reference function", rz_list_contains (block->fcns, fcn)); + mu_assert("function references block, but block does not reference function", rz_list_contains(block->fcns, fcn)); } if (fcn->meta._min != UT64_MAX) { - mu_assert_eq (fcn->meta._min, min, "function min wrong"); - mu_assert_eq (fcn->meta._max, max, "function max wrong"); + mu_assert_eq(fcn->meta._min, min, "function min wrong"); + mu_assert_eq(fcn->meta._max, max, "function max wrong"); } - mu_assert_eq (rz_analysis_function_realsize (fcn), realsz, "realsize wrong"); + mu_assert_eq(rz_analysis_function_realsize(fcn), realsz, "realsize wrong"); } return true; } @@ -64,12 +67,22 @@ static bool block_check_leaks(RzAnalysis *analysis) { RBIter iter; RzAnalysisBlock *block; rz_rbtree_foreach (analysis->bb_tree, iter, block, RzAnalysisBlock, _rb) { - if (block->ref != rz_list_length (block->fcns)) { - mu_assert ("leaked basic block", false); + if (block->ref != rz_list_length(block->fcns)) { + mu_assert("leaked basic block", false); } } return true; } -#define assert_block_invariants(analysis) do { if (!block_check_invariants (analysis)) { return false; } } while (0) -#define assert_block_leaks(analysis) do { if (!block_check_leaks (analysis)) { return false; } } while (0) +#define assert_block_invariants(analysis) \ + do { \ + if (!block_check_invariants(analysis)) { \ + return false; \ + } \ + } while (0) +#define assert_block_leaks(analysis) \ + do { \ + if (!block_check_leaks(analysis)) { \ + return false; \ + } \ + } while (0) diff --git a/test/unit/test_serialize_analysis.c b/test/unit/test_serialize_analysis.c index efaa9aa4794..f7eefbc088f 100644 --- a/test/unit/test_serialize_analysis.c +++ b/test/unit/test_serialize_analysis.c @@ -264,9 +264,9 @@ bool test_analysis_function_load() { mu_assert_notnull(f, "function"); mu_assert_streq(f->name, "hirsch", "name"); mu_assert_eq(f->type, RZ_ANALYSIS_FCN_TYPE_NULL, "type"); - mu_assert_eq(rz_list_length(f->bbs), 2, "bbs count"); - mu_assert("bb", rz_list_contains(f->bbs, ba)); - mu_assert("bb", rz_list_contains(f->bbs, bb)); + mu_assert_eq(rz_pvector_len(f->bbs), 2, "bbs count"); + mu_assert("bb", rz_pvector_contains(f->bbs, ba)); + mu_assert("bb", rz_pvector_contains(f->bbs, bb)); mu_assert_eq(f->bits, 16, "bits"); mu_assert_ptreq(f->cc, rz_str_constpool_get(&analysis->constpool, "fancycall"), "cc"); mu_assert_eq(f->stack, 42, "stack"); @@ -289,8 +289,8 @@ bool test_analysis_function_load() { mu_assert_notnull(f, "function"); mu_assert_streq(f->name, "effekt", "name"); mu_assert_eq(f->type, RZ_ANALYSIS_FCN_TYPE_FCN, "type"); - mu_assert_eq(rz_list_length(f->bbs), 1, "bbs count"); - mu_assert("bb", rz_list_contains(f->bbs, ba)); + mu_assert_eq(rz_pvector_len(f->bbs), 1, "bbs count"); + mu_assert("bb", rz_pvector_contains(f->bbs, ba)); mu_assert_eq(f->bits, 0, "bits"); mu_assert_null(f->cc, "cc"); mu_assert_eq(f->stack, 0, "stack"); @@ -307,7 +307,7 @@ bool test_analysis_function_load() { mu_assert_notnull(f, "function"); mu_assert_streq(f->name, "hiberno", "name"); mu_assert_eq(f->type, RZ_ANALYSIS_FCN_TYPE_LOC, "type"); - mu_assert_eq(rz_list_length(f->bbs), 0, "bbs count"); + mu_assert_eq(rz_pvector_len(f->bbs), 0, "bbs count"); mu_assert_eq(f->bits, 32, "bits"); mu_assert_null(f->cc, "cc"); mu_assert_eq(f->stack, 0, "stack"); @@ -323,7 +323,7 @@ bool test_analysis_function_load() { mu_assert_notnull(f, "function"); mu_assert_streq(f->name, "anamnesis", "name"); mu_assert_eq(f->type, RZ_ANALYSIS_FCN_TYPE_SYM, "type"); - mu_assert_eq(rz_list_length(f->bbs), 0, "bbs count"); + mu_assert_eq(rz_pvector_len(f->bbs), 0, "bbs count"); mu_assert_eq(f->bits, 32, "bits"); mu_assert_null(f->cc, "cc"); mu_assert_eq(f->stack, 0, "stack"); From 2287827a787a721495491b04d3cbd238c5897400 Mon Sep 17 00:00:00 2001 From: HN026 Date: Sat, 6 Jan 2024 20:51:30 +0530 Subject: [PATCH 2/8] freed list memory --- librz/analysis/fcn.c | 3 +++ librz/analysis/similarity.c | 4 +++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/librz/analysis/fcn.c b/librz/analysis/fcn.c index 765a231c72f..540d98453e5 100644 --- a/librz/analysis/fcn.c +++ b/librz/analysis/fcn.c @@ -107,6 +107,9 @@ RZ_API int rz_analysis_function_resize(RzAnalysisFunction *fcn, int newsize) { ut64 eof = fcn->addr + newsize; rz_pvector_foreach (fcn->bbs, iter) { bb = *iter; + if(!bb) { + continue; + } if (bb->addr >= eof) { rz_analysis_function_remove_block(fcn, bb); continue; diff --git a/librz/analysis/similarity.c b/librz/analysis/similarity.c index 5e53bc95b9a..d241cfd606a 100644 --- a/librz/analysis/similarity.c +++ b/librz/analysis/similarity.c @@ -339,6 +339,8 @@ static RZ_OWN RzAnalysisMatchResult *analysis_match_result_new(RZ_NONNULL RzAnal return result; fail: + rz_list_free(list_a); + rz_list_free(list_b); rz_th_pool_free(pool); shared_context_fini(&shared); rz_list_free(unmatch_a); @@ -427,7 +429,7 @@ RZ_API RZ_OWN RzAnalysisMatchResult *rz_analysis_match_basic_blocks(RZ_NONNULL R RzList *bbs_list_b = rz_list_new(); if (!bbs_list_a || !bbs_list_b) { // If memory allocation failed, print an error message and return NULL - eprintf("Failed to allocate memory for bbs_list_a or bbs_list_b.\n"); + RZ_LOG_ERROR("Failed to allocate memory for bbs_list_a or bbs_list_b.\n"); rz_list_free(bbs_list_a); // It's safe to call rz_list_free with NULL rz_list_free(bbs_list_b); return NULL; From 82101e418d512af203ad9440fc3b5f262c0e4c96 Mon Sep 17 00:00:00 2001 From: HN026 Date: Sat, 6 Jan 2024 20:59:29 +0530 Subject: [PATCH 3/8] eprintf removed --- librz/analysis/fcn.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/librz/analysis/fcn.c b/librz/analysis/fcn.c index 540d98453e5..1b64b5a3f03 100644 --- a/librz/analysis/fcn.c +++ b/librz/analysis/fcn.c @@ -107,7 +107,7 @@ RZ_API int rz_analysis_function_resize(RzAnalysisFunction *fcn, int newsize) { ut64 eof = fcn->addr + newsize; rz_pvector_foreach (fcn->bbs, iter) { bb = *iter; - if(!bb) { + if (!bb) { continue; } if (bb->addr >= eof) { @@ -2364,7 +2364,7 @@ static void update_analysis(RzAnalysis *analysis, RzList /* Date: Sat, 6 Jan 2024 21:26:54 +0530 Subject: [PATCH 4/8] refactor --- test/unit/test_analysis_block_invars.inl | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/test/unit/test_analysis_block_invars.inl b/test/unit/test_analysis_block_invars.inl index 026de7ca230..94ff0b57555 100644 --- a/test/unit/test_analysis_block_invars.inl +++ b/test/unit/test_analysis_block_invars.inl @@ -37,7 +37,6 @@ static bool block_check_invariants(RzAnalysis *analysis) { ut64 realsz = 0; rz_pvector_foreach (fcn->bbs, iter) { block = *iter; - blockiter = *iter; RzListIter *blockiter2; RzAnalysisBlock *block2; if (block->addr < min) { @@ -47,8 +46,11 @@ static bool block_check_invariants(RzAnalysis *analysis) { max = block->addr + block->size; } realsz += block->size; - rz_list_foreach_iter(rz_list_iter_get_next(blockiter), blockiter2, block2) { - mu_assert_ptrneq(block, block2, "duplicate basic block in function"); + rz_list_foreach (block->fcns, blockiter, block2) { + RzListIter *next_iter = rz_list_iter_get_next(blockiter); + rz_list_foreach_iter(next_iter, blockiter2, block2) { + mu_assert_ptrneq(block, block2, "duplicate basic block in function"); + } } mu_assert("function references block, but block does not reference function", rz_list_contains(block->fcns, fcn)); } From baab1d89a993d14ce0ada40d0870eda8fcf5faa9 Mon Sep 17 00:00:00 2001 From: HN026 Date: Sat, 6 Jan 2024 21:38:12 +0530 Subject: [PATCH 5/8] changes test_analysis_block_invars undone --- test/unit/test_analysis_block_invars.inl | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/test/unit/test_analysis_block_invars.inl b/test/unit/test_analysis_block_invars.inl index 94ff0b57555..026de7ca230 100644 --- a/test/unit/test_analysis_block_invars.inl +++ b/test/unit/test_analysis_block_invars.inl @@ -37,6 +37,7 @@ static bool block_check_invariants(RzAnalysis *analysis) { ut64 realsz = 0; rz_pvector_foreach (fcn->bbs, iter) { block = *iter; + blockiter = *iter; RzListIter *blockiter2; RzAnalysisBlock *block2; if (block->addr < min) { @@ -46,11 +47,8 @@ static bool block_check_invariants(RzAnalysis *analysis) { max = block->addr + block->size; } realsz += block->size; - rz_list_foreach (block->fcns, blockiter, block2) { - RzListIter *next_iter = rz_list_iter_get_next(blockiter); - rz_list_foreach_iter(next_iter, blockiter2, block2) { - mu_assert_ptrneq(block, block2, "duplicate basic block in function"); - } + rz_list_foreach_iter(rz_list_iter_get_next(blockiter), blockiter2, block2) { + mu_assert_ptrneq(block, block2, "duplicate basic block in function"); } mu_assert("function references block, but block does not reference function", rz_list_contains(block->fcns, fcn)); } From 47c1a3cd349f895a9cd6a7b70506cfc7283d1473 Mon Sep 17 00:00:00 2001 From: HN026 Date: Sat, 6 Jan 2024 22:32:32 +0530 Subject: [PATCH 6/8] rzpvectorsort refactor --- librz/core/agraph.c | 4 ++-- librz/core/analysis_tp.c | 2 +- librz/core/canalysis.c | 2 +- librz/core/cmd/cmd.c | 6 +++--- librz/core/cmd/cmd_print.c | 4 ++-- librz/core/ctypes.c | 2 +- librz/core/disasm.c | 2 +- 7 files changed, 11 insertions(+), 11 deletions(-) diff --git a/librz/core/agraph.c b/librz/core/agraph.c index c5b4eb45286..0df2d723a28 100644 --- a/librz/core/agraph.c +++ b/librz/core/agraph.c @@ -2239,7 +2239,7 @@ static void get_bbupdate(RzAGraph *g, RzCore *core, RzAnalysisFunction *fcn) { RZ_FREE(saved_arena); return; } - rz_pvector_sort(fcn->bbs, (RzListComparator)bbcmp); + rz_pvector_sort(fcn->bbs, (RzPVectorComparator)bbcmp, NULL); shortcuts = rz_config_get_i(core->config, "graph.nodejmps"); rz_pvector_foreach (fcn->bbs, iter) { @@ -2354,7 +2354,7 @@ static int get_bbnodes(RzAGraph *g, RzCore *core, RzAnalysisFunction *fcn) { if (emu) { saved_arena = rz_reg_arena_peek(core->analysis->reg); } - rz_pvector_sort(fcn->bbs, (RzListComparator)bbcmp); + rz_pvector_sort(fcn->bbs, (RzPVectorComparator)bbcmp, NULL); RzAnalysisBlock *curbb = NULL; if (few) { rz_pvector_foreach (fcn->bbs, iter) { diff --git a/librz/core/analysis_tp.c b/librz/core/analysis_tp.c index 8269efc724c..9f8eaf94d7e 100644 --- a/librz/core/analysis_tp.c +++ b/librz/core/analysis_tp.c @@ -868,7 +868,7 @@ RZ_API void rz_core_analysis_type_match(RzCore *core, RzAnalysisFunction *fcn, H goto out_function; } rz_cons_break_push(NULL, NULL); - rz_pvector_sort(fcn->bbs, bb_cmpaddr); + rz_pvector_sort(fcn->bbs, (RzPVectorComparator)bb_cmpaddr, NULL); // TODO: The algorithm can be more accurate if blocks are followed by their jmp/fail, not just by address RzAnalysisBlock *bb; rz_pvector_foreach (fcn->bbs, it) { diff --git a/librz/core/canalysis.c b/librz/core/canalysis.c index 47dc025d083..aad74f9641a 100644 --- a/librz/core/canalysis.c +++ b/librz/core/canalysis.c @@ -495,7 +495,7 @@ RZ_IPI void rz_core_analysis_bbs_info_print(RzCore *core, RzAnalysisFunction *fc rz_cons_printf("fs blocks\n"); } - rz_pvector_sort(fcn->bbs, bb_cmp); + rz_pvector_sort(fcn->bbs, (RzPVectorComparator)bb_cmp, NULL); rz_pvector_foreach (fcn->bbs, iter) { bb = *iter; bb_info_print(core, fcn, bb, bb->addr, state->mode, state->d.pj, state->d.t); diff --git a/librz/core/cmd/cmd.c b/librz/core/cmd/cmd.c index ce9eea8efea..1b6b7f5ae88 100644 --- a/librz/core/cmd/cmd.c +++ b/librz/core/cmd/cmd.c @@ -2873,7 +2873,7 @@ RZ_API int rz_core_cmd_foreach(RzCore *core, const char *cmd, char *each) { RzAnalysisFunction *fcn = rz_analysis_get_function_at(core->analysis, core->offset); int bs = core->blocksize; if (fcn) { - rz_pvector_sort(fcn->bbs, bb_cmp); + rz_pvector_sort(fcn->bbs, (RzPVectorComparator)bb_cmp, NULL); rz_pvector_foreach (fcn->bbs, iter) { bb = *iter; rz_core_block_size(core, bb->size); @@ -2918,7 +2918,7 @@ RZ_API int rz_core_cmd_foreach(RzCore *core, const char *cmd, char *each) { int i; RzAnalysisFunction *fcn = rz_analysis_get_function_at(core->analysis, core->offset); if (fcn) { - rz_pvector_sort(fcn->bbs, bb_cmp); + rz_pvector_sort(fcn->bbs, (RzPVectorComparator)bb_cmp, NULL); rz_pvector_foreach (fcn->bbs, iter) { bb = *iter; for (i = 0; i < bb->op_pos_size; i++) { @@ -4688,7 +4688,7 @@ DEFINE_HANDLE_TS_FCN_AND_SYMBOL(iter_bbs_stmt) { void **iter; RzAnalysisBlock *bb; RzCmdStatus ret = RZ_CMD_STATUS_OK; - rz_pvector_sort(fcn->bbs, bb_cmp); + rz_pvector_sort(fcn->bbs, (RzPVectorComparator)bb_cmp, NULL); rz_pvector_foreach (fcn->bbs, iter) { bb = *iter; rz_core_seek(core, bb->addr, true); diff --git a/librz/core/cmd/cmd_print.c b/librz/core/cmd/cmd_print.c index ca1c1a7f336..0971b0e3846 100644 --- a/librz/core/cmd/cmd_print.c +++ b/librz/core/cmd/cmd_print.c @@ -2245,7 +2245,7 @@ static void func_walk_blocks(RzCore *core, RzAnalysisFunction *f, bool fromHere, const bool orig_bb_middle = rz_config_get_b(core->config, "asm.bb.middle"); rz_config_set_b(core->config, "asm.bb.middle", false); - rz_pvector_sort(f->bbs, (RzListComparator)bbcmp); + rz_pvector_sort(f->bbs, (RzPVectorComparator)bbcmp, NULL); RzAnalysisBlock *b; void **iter; @@ -4338,7 +4338,7 @@ static bool core_walk_function_blocks(RzCore *core, RzAnalysisFunction *f, RzCmd } } - rz_pvector_sort(f->bbs, (RzListComparator)bbcmp); + rz_pvector_sort(f->bbs, (RzPVectorComparator)bbcmp, NULL); if (state->mode == RZ_OUTPUT_MODE_JSON) { rz_pvector_foreach (f->bbs, iter) { b = *iter; diff --git a/librz/core/ctypes.c b/librz/core/ctypes.c index c4e593cbfac..39887686bc7 100644 --- a/librz/core/ctypes.c +++ b/librz/core/ctypes.c @@ -766,7 +766,7 @@ RZ_API void rz_core_global_vars_propagate_types(RzCore *core, RzAnalysisFunction ut64 oldoff = core->offset; rz_cons_break_push(NULL, NULL); // TODO: The algorithm can be more accurate if blocks are followed by their jmp/fail, not just by address - rz_pvector_sort(fcn->bbs, bb_cmpaddr); + rz_pvector_sort(fcn->bbs, (RzPVectorComparator)bb_cmpaddr, NULL); rz_pvector_foreach (fcn->bbs, it) { bb = *it; ut64 at = bb->addr; diff --git a/librz/core/disasm.c b/librz/core/disasm.c index 81949690538..d9941600956 100644 --- a/librz/core/disasm.c +++ b/librz/core/disasm.c @@ -6564,7 +6564,7 @@ RZ_API bool rz_core_print_function_disasm_json(RzCore *core, RzAnalysisFunction pj_kn(pj, "addr", fcn->addr); pj_k(pj, "ops"); pj_a(pj); - rz_pvector_sort(fcn->bbs, bb_cmpaddr); + rz_pvector_sort(fcn->bbs, (RzPVectorComparator)bb_cmpaddr, NULL); rz_pvector_foreach (fcn->bbs, locs_it) { b = *locs_it; ut8 *buf = malloc(b->size); From f5947f949eab0beb821105e8729cfe8935fdcede Mon Sep 17 00:00:00 2001 From: HN026 Date: Mon, 8 Jan 2024 23:31:52 +0530 Subject: [PATCH 7/8] RZ_NONNULL ADDED --- librz/analysis/analysis.c | 3 ++- librz/analysis/fcn.c | 13 ++++++------- librz/analysis/similarity.c | 2 -- librz/core/analysis_tp.c | 8 ++++---- librz/core/canalysis.c | 5 +++-- librz/core/cmd/cmd_analysis.c | 2 +- librz/core/core_private.h | 2 +- librz/include/rz_analysis.h | 8 ++++---- librz/include/rz_core.h | 2 +- test/unit/test_analysis_block_invars.inl | 13 +++++++------ 10 files changed, 29 insertions(+), 29 deletions(-) diff --git a/librz/analysis/analysis.c b/librz/analysis/analysis.c index da61d0f7301..7f2d292ce65 100644 --- a/librz/analysis/analysis.c +++ b/librz/analysis/analysis.c @@ -411,7 +411,8 @@ RZ_API ut8 *rz_analysis_mask(RzAnalysis *analysis, ut32 size, const ut8 *data, u return ret; } -RZ_API void rz_analysis_trace_bb(RzAnalysis *analysis, ut64 addr) { +RZ_API void rz_analysis_trace_bb(RZ_NONNULL RzAnalysis *analysis, ut64 addr) { + rz_return_if_fail(analysis); RzAnalysisBlock *bbi; RzAnalysisFunction *fcni; void **iter2; diff --git a/librz/analysis/fcn.c b/librz/analysis/fcn.c index b426ba65323..bf18f27dc00 100644 --- a/librz/analysis/fcn.c +++ b/librz/analysis/fcn.c @@ -78,7 +78,7 @@ static int read_ahead(ReadAhead *ra, RzAnalysis *analysis, ut64 addr, ut8 *buf, return -1; } -RZ_API int rz_analysis_function_resize(RzAnalysisFunction *fcn, int newsize) { +RZ_API int rz_analysis_function_resize(RZ_NONNULL RzAnalysisFunction *fcn, int newsize) { RzAnalysis *analysis = fcn->analysis; RzAnalysisBlock *bb; void **iter; @@ -1763,7 +1763,7 @@ RZ_API bool rz_analysis_fcn_add_bb(RzAnalysis *a, RzAnalysisFunction *fcn, ut64 /** * \brief Returns the amount of loops located in the \p fcn function */ -RZ_API int rz_analysis_function_loops(RzAnalysisFunction *fcn) { +RZ_API int rz_analysis_function_loops(RZ_NONNULL RzAnalysisFunction *fcn) { void **iter; RzAnalysisBlock *bb; ut32 loops = 0; @@ -2062,7 +2062,7 @@ RZ_API RzAnalysisBlock *rz_analysis_fcn_bbget_at(RzAnalysis *analysis, RzAnalysi } // compute the cyclomatic cost -RZ_API ut32 rz_analysis_function_cost(RzAnalysisFunction *fcn) { +RZ_API ut32 rz_analysis_function_cost(RZ_NONNULL RzAnalysisFunction *fcn) { void **iter; RzAnalysisBlock *bb; ut32 totalCycles = 0; @@ -2352,8 +2352,8 @@ static void update_analysis(RzAnalysis *analysis, RzList /*ninstr -= bb->ninstr; rz_analysis_function_remove_block(fcn, bb); } - RzList *bbs_temp = rz_list_new(); - if (!bbs_temp) { + RzList *bbs = rz_list_new(); + if (!bbs) { // If memory allocation failed, print an error message and return from the function RZ_LOG_ERROR("Failed to allocate memory for bbs.\n"); return; @@ -2361,10 +2361,9 @@ static void update_analysis(RzAnalysis *analysis, RzList /*bbs, it) { - rz_list_append(bbs_temp, *it); + rz_list_append(bbs, *it); } - RzList *bbs = rz_list_clone(bbs_temp); rz_analysis_block_automerge(bbs); rz_analysis_function_delete_unused_vars(fcn); rz_list_free(bbs); diff --git a/librz/analysis/similarity.c b/librz/analysis/similarity.c index d241cfd606a..40590e5d047 100644 --- a/librz/analysis/similarity.c +++ b/librz/analysis/similarity.c @@ -339,8 +339,6 @@ static RZ_OWN RzAnalysisMatchResult *analysis_match_result_new(RZ_NONNULL RzAnal return result; fail: - rz_list_free(list_a); - rz_list_free(list_b); rz_th_pool_free(pool); shared_context_fini(&shared); rz_list_free(unmatch_a); diff --git a/librz/core/analysis_tp.c b/librz/core/analysis_tp.c index 9f8eaf94d7e..00fba71c517 100644 --- a/librz/core/analysis_tp.c +++ b/librz/core/analysis_tp.c @@ -524,7 +524,8 @@ static void type_match(RzCore *core, char *fcn_name, ut64 addr, ut64 baddr, cons } static int bb_cmpaddr(const void *_a, const void *_b) { - const RzAnalysisBlock *a = _a, *b = _b; + const RzAnalysisBlock *a = *(const RzAnalysisBlock **)_a; + const RzAnalysisBlock *b = *(const RzAnalysisBlock **)_b; return a->addr > b->addr ? 1 : (a->addr < b->addr ? -1 : 0); } @@ -811,10 +812,9 @@ void propagate_types_among_used_variables(RzCore *core, HtUP *op_cache, RzAnalys #define OP_CACHE_LIMIT 8192 -RZ_API void rz_core_analysis_type_match(RzCore *core, RzAnalysisFunction *fcn, HtUU *loop_table) { - void **it; - +RZ_API void rz_core_analysis_type_match(RZ_NONNULL RzCore *core, RZ_NONNULL RzAnalysisFunction *fcn, HtUU *loop_table) { rz_return_if_fail(core && core->analysis && fcn); + void **it; if (!core->analysis->esil) { RZ_LOG_ERROR("core: please run aeim first.\n"); diff --git a/librz/core/canalysis.c b/librz/core/canalysis.c index aad74f9641a..3ee3106585a 100644 --- a/librz/core/canalysis.c +++ b/librz/core/canalysis.c @@ -333,7 +333,8 @@ RZ_IPI void rz_core_analysis_bbs_asciiart(RzCore *core, RzAnalysisFunction *fcn) rz_list_free(flist); } -RZ_IPI void rz_core_analysis_fcn_returns(RzCore *core, RzAnalysisFunction *fcn) { +RZ_IPI void rz_core_analysis_fcn_returns(RZ_NONNULL RzCore *core, RZ_NONNULL RzAnalysisFunction *fcn) { + rz_return_if_fail(core && fcn); void **iter; RzAnalysisBlock *b; rz_pvector_foreach (fcn->bbs, iter) { @@ -785,7 +786,7 @@ static void function_rename(RzFlag *flags, RzAnalysisFunction *fcn) { } static void autoname_imp_trampoline(RzCore *core, RzAnalysisFunction *fcn) { - if (rz_pvector_len(fcn->bbs) == 1 && ((RzAnalysisBlock *)rz_pvector_at(fcn->bbs, 0))->ninstr == 1) { + if (rz_pvector_len(fcn->bbs) == 1 && ((RzAnalysisBlock *)rz_pvector_head(fcn->bbs))->ninstr == 1) { RzList *xrefs = rz_analysis_function_get_xrefs_from(fcn); if (xrefs && rz_list_length(xrefs) == 1) { RzAnalysisXRef *xref = rz_list_first(xrefs); diff --git a/librz/core/cmd/cmd_analysis.c b/librz/core/cmd/cmd_analysis.c index abc4ef4ca30..7a4707bf00a 100644 --- a/librz/core/cmd/cmd_analysis.c +++ b/librz/core/cmd/cmd_analysis.c @@ -2095,7 +2095,7 @@ RZ_IPI RzCmdStatus rz_analysis_function_blocks_del_all_handler(RzCore *core, int return RZ_CMD_STATUS_ERROR; } while (!rz_pvector_empty(fcn->bbs)) { - rz_analysis_function_remove_block(fcn, rz_pvector_at(fcn->bbs, 0)); + rz_analysis_function_remove_block(fcn, rz_pvector_head(fcn->bbs)); } return RZ_CMD_STATUS_OK; } diff --git a/librz/core/core_private.h b/librz/core/core_private.h index 1c477d1e724..bd9ff04de49 100644 --- a/librz/core/core_private.h +++ b/librz/core/core_private.h @@ -43,7 +43,7 @@ RZ_IPI bool rz_core_analysis_types_propagation(RzCore *core); RZ_IPI bool rz_core_analysis_function_set_signature(RzCore *core, RzAnalysisFunction *fcn, const char *newsig); RZ_IPI void rz_core_analysis_function_signature_editor(RzCore *core, ut64 addr); RZ_IPI void rz_core_analysis_bbs_asciiart(RzCore *core, RzAnalysisFunction *fcn); -RZ_IPI void rz_core_analysis_fcn_returns(RzCore *core, RzAnalysisFunction *fcn); +RZ_IPI void rz_core_analysis_fcn_returns(RZ_NONNULL RzCore *core, RZ_NONNULL RzAnalysisFunction *fcn); RZ_IPI void rz_core_analysis_bbs_info_print(RzCore *core, RzAnalysisFunction *fcn, RzCmdStateOutput *state); RZ_IPI void rz_core_analysis_bb_info_print(RzCore *core, RzAnalysisBlock *bb, ut64 addr, RzCmdStateOutput *state); RZ_IPI void rz_core_analysis_function_until(RzCore *core, ut64 addr_end); diff --git a/librz/include/rz_analysis.h b/librz/include/rz_analysis.h index 1928e0460e7..dcadde3c1ed 100644 --- a/librz/include/rz_analysis.h +++ b/librz/include/rz_analysis.h @@ -1576,7 +1576,7 @@ RZ_API bool rz_analysis_set_os(RzAnalysis *analysis, const char *os); RZ_API void rz_analysis_set_cpu(RzAnalysis *analysis, const char *cpu); RZ_API int rz_analysis_set_big_endian(RzAnalysis *analysis, int boolean); RZ_API ut8 *rz_analysis_mask(RzAnalysis *analysis, ut32 size, const ut8 *data, ut64 at); -RZ_API void rz_analysis_trace_bb(RzAnalysis *analysis, ut64 addr); +RZ_API void rz_analysis_trace_bb(RZ_NONNULL RzAnalysis *analysis, ut64 addr); RZ_API const char *rz_analysis_fcntype_tostring(int type); RZ_API void rz_analysis_bind(RzAnalysis *b, RzAnalysisBind *bnd); RZ_API bool rz_analysis_set_triplet(RzAnalysis *analysis, const char *os, const char *arch, int bits); @@ -1716,7 +1716,7 @@ RZ_API void rz_analysis_rzil_trace_op(RzAnalysis *analysis, RZ_NONNULL RzAnalysi RZ_API bool rz_analysis_add_device_peripheral_map(RzBinObject *o, RzAnalysis *analysis); /* fcn.c */ -RZ_API ut32 rz_analysis_function_cost(RzAnalysisFunction *fcn); +RZ_API ut32 rz_analysis_function_cost(RZ_NONNULL RzAnalysisFunction *fcn); RZ_API int rz_analysis_function_count_edges(const RzAnalysisFunction *fcn, RZ_NULLABLE int *ebbs); // Use rz_analysis_get_functions_in¿() instead @@ -1739,7 +1739,7 @@ RZ_API bool rz_analysis_task_item_new(RZ_NONNULL RzAnalysis *analysis, RZ_NONNUL RZ_API int rz_analysis_run_tasks(RZ_NONNULL RzVector /**/ *tasks); RZ_API int rz_analysis_function_complexity(RzAnalysisFunction *fcn); -RZ_API int rz_analysis_function_loops(RzAnalysisFunction *fcn); +RZ_API int rz_analysis_function_loops(RZ_NONNULL RzAnalysisFunction *fcn); RZ_API void rz_analysis_trim_jmprefs(RzAnalysis *analysis, RzAnalysisFunction *fcn); RZ_API void rz_analysis_del_jmprefs(RzAnalysis *analysis, RzAnalysisFunction *fcn); RZ_API char *rz_analysis_function_get_json(RzAnalysisFunction *function); @@ -1750,7 +1750,7 @@ RZ_API bool rz_analysis_function_set_type_str(RzAnalysis *a, RZ_NONNULL RzAnalys RZ_API int rz_analysis_fcn_count(RzAnalysis *a, ut64 from, ut64 to); RZ_API RzAnalysisBlock *rz_analysis_fcn_bbget_in(const RzAnalysis *analysis, RzAnalysisFunction *fcn, ut64 addr); RZ_API RzAnalysisBlock *rz_analysis_fcn_bbget_at(RzAnalysis *analysis, RzAnalysisFunction *fcn, ut64 addr); -RZ_API int rz_analysis_function_resize(RzAnalysisFunction *fcn, int newsize); +RZ_API int rz_analysis_function_resize(RZ_NONNULL RzAnalysisFunction *fcn, int newsize); RZ_API bool rz_analysis_function_purity(RzAnalysisFunction *fcn); typedef bool (*RzAnalysisRefCmp)(RzAnalysisXRef *ref, void *data); diff --git a/librz/include/rz_core.h b/librz/include/rz_core.h index d7c7753a733..7a96e3bcb42 100644 --- a/librz/include/rz_core.h +++ b/librz/include/rz_core.h @@ -794,7 +794,7 @@ RZ_API RZ_OWN char *rz_core_graph_to_dot_str(RZ_NONNULL RzCore *core, RZ_NONNULL RZ_API RZ_OWN char *rz_core_graph_to_sdb_str(RZ_NONNULL RzCore *core, RZ_NONNULL RzGraph /**/ *graph); /*tp.c*/ -RZ_API void rz_core_analysis_type_match(RzCore *core, RzAnalysisFunction *fcn, HtUU *addr_loop_table); +RZ_API void rz_core_analysis_type_match(RZ_NONNULL RzCore *core, RZ_NONNULL RzAnalysisFunction *fcn, HtUU *addr_loop_table); /* asm.c */ #define RZ_MIDFLAGS_HIDE 0 diff --git a/test/unit/test_analysis_block_invars.inl b/test/unit/test_analysis_block_invars.inl index 026de7ca230..55b368c45d4 100644 --- a/test/unit/test_analysis_block_invars.inl +++ b/test/unit/test_analysis_block_invars.inl @@ -30,16 +30,12 @@ static bool block_check_invariants(RzAnalysis *analysis) { RzListIter *fcniter; RzAnalysisFunction *fcn; rz_list_foreach (analysis->fcns, fcniter, fcn) { - RzListIter *blockiter; void **iter; ut64 min = UT64_MAX; ut64 max = UT64_MIN; ut64 realsz = 0; rz_pvector_foreach (fcn->bbs, iter) { - block = *iter; - blockiter = *iter; - RzListIter *blockiter2; - RzAnalysisBlock *block2; + block = (RzAnalysisBlock *)*iter; if (block->addr < min) { min = block->addr; } @@ -47,7 +43,12 @@ static bool block_check_invariants(RzAnalysis *analysis) { max = block->addr + block->size; } realsz += block->size; - rz_list_foreach_iter(rz_list_iter_get_next(blockiter), blockiter2, block2) { + void **iter2; + rz_pvector_foreach (fcn->bbs, iter2) { + if (*iter == *iter2) { + continue; + } + RzAnalysisBlock *block2 = (RzAnalysisBlock *)*iter2; mu_assert_ptrneq(block, block2, "duplicate basic block in function"); } mu_assert("function references block, but block does not reference function", rz_list_contains(block->fcns, fcn)); From c8a4db654714bd23f7d475ff9b44cd5ddf59595f Mon Sep 17 00:00:00 2001 From: HN026 Date: Fri, 12 Jan 2024 23:19:45 +0530 Subject: [PATCH 8/8] fixed broken tests --- librz/analysis/fcn.c | 4 +++- librz/analysis/function.c | 5 +++-- librz/core/analysis_tp.c | 8 ++++++++ librz/core/cfile.c | 3 ++- librz/core/cgraph.c | 4 +--- librz/include/rz_analysis.h | 6 +++--- test/integration/test_analysis_graph.c | 11 ++++++++++- 7 files changed, 30 insertions(+), 11 deletions(-) diff --git a/librz/analysis/fcn.c b/librz/analysis/fcn.c index bf18f27dc00..c75408dfc5d 100644 --- a/librz/analysis/fcn.c +++ b/librz/analysis/fcn.c @@ -1764,6 +1764,7 @@ RZ_API bool rz_analysis_fcn_add_bb(RzAnalysis *a, RzAnalysisFunction *fcn, ut64 * \brief Returns the amount of loops located in the \p fcn function */ RZ_API int rz_analysis_function_loops(RZ_NONNULL RzAnalysisFunction *fcn) { + rz_return_val_if_fail(fcn, 0); void **iter; RzAnalysisBlock *bb; ut32 loops = 0; @@ -2063,6 +2064,7 @@ RZ_API RzAnalysisBlock *rz_analysis_fcn_bbget_at(RzAnalysis *analysis, RzAnalysi // compute the cyclomatic cost RZ_API ut32 rz_analysis_function_cost(RZ_NONNULL RzAnalysisFunction *fcn) { + rz_return_val_if_fail(fcn, 0); void **iter; RzAnalysisBlock *bb; ut32 totalCycles = 0; @@ -2425,7 +2427,7 @@ RZ_API void rz_analysis_update_analysis_range(RzAnalysis *analysis, ut64 addr, i rz_list_free(fcns); } -RZ_API void rz_analysis_function_update_analysis(RzAnalysisFunction *fcn) { +RZ_API void rz_analysis_function_update_analysis(RZ_NONNULL RzAnalysisFunction *fcn) { rz_return_if_fail(fcn); void **it; RzListIter *it2, *tmp2; diff --git a/librz/analysis/function.c b/librz/analysis/function.c index 35545fced51..95bf2bfd08f 100644 --- a/librz/analysis/function.c +++ b/librz/analysis/function.c @@ -329,7 +329,8 @@ RZ_API ut64 rz_analysis_function_size_from_entry(RzAnalysisFunction *fcn) { return fcn->meta._min == UT64_MAX ? 0 : fcn->meta._max - fcn->addr; } -RZ_API ut64 rz_analysis_function_realsize(const RzAnalysisFunction *fcn) { +RZ_API ut64 rz_analysis_function_realsize(RZ_NONNULL const RzAnalysisFunction *fcn) { + rz_return_val_if_fail(fcn, 0); void **iter; RzAnalysisBlock *bb; ut64 sz = 0; @@ -358,7 +359,7 @@ RZ_API bool rz_analysis_function_contains(RzAnalysisFunction *fcn, ut64 addr) { return !rz_analysis_blocks_foreach_in(fcn->analysis, addr, fcn_in_cb, fcn); } -RZ_API bool rz_analysis_function_was_modified(RzAnalysisFunction *fcn) { +RZ_API bool rz_analysis_function_was_modified(RZ_NONNULL RzAnalysisFunction *fcn) { rz_return_val_if_fail(fcn, false); void **it; RzAnalysisBlock *bb; diff --git a/librz/core/analysis_tp.c b/librz/core/analysis_tp.c index 00fba71c517..e93d6249c68 100644 --- a/librz/core/analysis_tp.c +++ b/librz/core/analysis_tp.c @@ -524,8 +524,16 @@ static void type_match(RzCore *core, char *fcn_name, ut64 addr, ut64 baddr, cons } static int bb_cmpaddr(const void *_a, const void *_b) { + if (!_a || !_b) { + return 0; + } const RzAnalysisBlock *a = *(const RzAnalysisBlock **)_a; const RzAnalysisBlock *b = *(const RzAnalysisBlock **)_b; + + if (!a || !b) { + return 0; + } + return a->addr > b->addr ? 1 : (a->addr < b->addr ? -1 : 0); } diff --git a/librz/core/cfile.c b/librz/core/cfile.c index a5e79d507c6..a8565cdd55a 100644 --- a/librz/core/cfile.c +++ b/librz/core/cfile.c @@ -124,7 +124,8 @@ static bool __rebase_xrefs(void *user, const ut64 k, const void *v) { } static void __rebase_everything(RzCore *core, RzPVector /**/ *old_sections, ut64 old_base) { - RzListIter *it, *ititit; + RzListIter *it; + void **it3; RzAnalysisFunction *fcn; ut64 new_base = core->bin->cur->o->baddr_shift; RzBinSection *old_section; diff --git a/librz/core/cgraph.c b/librz/core/cgraph.c index b3a82ddfd3c..bee197dca90 100644 --- a/librz/core/cgraph.c +++ b/librz/core/cgraph.c @@ -279,9 +279,7 @@ static inline RzGraphNode *graph_add_cached(RzCore *core, HtUP *cache, RzAnalysi } static void core_graph_fn_bbs(RzCore *core, RzAnalysisFunction *fcn, RzGraph /**/ *graph, HtUP *cache, GraphBodyFn body_fn) { - if (!(fcn && fcn->bbs)) { - return; - } + rz_return_if_fail(core && fcn && graph && cache); void **iter; RzAnalysisBlock *bbi; diff --git a/librz/include/rz_analysis.h b/librz/include/rz_analysis.h index dcadde3c1ed..0c6ab17304d 100644 --- a/librz/include/rz_analysis.h +++ b/librz/include/rz_analysis.h @@ -1549,14 +1549,14 @@ RZ_API ut64 rz_analysis_function_size_from_entry(RzAnalysisFunction *fcn); // the "real" size of the function, that is the sum of the size of the // basicblocks this function is composed of -RZ_API ut64 rz_analysis_function_realsize(const RzAnalysisFunction *fcn); +RZ_API ut64 rz_analysis_function_realsize(RZ_NONNULL const RzAnalysisFunction *fcn); // returns whether the function contains a basic block that contains addr // This is completely independent of fcn->addr, which is only the entrypoint! RZ_API bool rz_analysis_function_contains(RzAnalysisFunction *fcn, ut64 addr); // returns true if function bytes were modified -RZ_API bool rz_analysis_function_was_modified(RzAnalysisFunction *fcn); +RZ_API bool rz_analysis_function_was_modified(RZ_NONNULL RzAnalysisFunction *fcn); RZ_API bool rz_analysis_function_is_autonamed(RZ_NONNULL char *name); RZ_API RZ_OWN char *rz_analysis_function_name_guess(RzTypeDB *typedb, RZ_NONNULL char *name); @@ -1733,7 +1733,7 @@ RZ_API bool rz_analysis_check_fcn(RzAnalysis *analysis, ut8 *buf, ut16 bufsz, ut RZ_API void rz_analysis_function_check_bp_use(RzAnalysisFunction *fcn); RZ_API void rz_analysis_update_analysis_range(RzAnalysis *analysis, ut64 addr, int size); -RZ_API void rz_analysis_function_update_analysis(RzAnalysisFunction *fcn); +RZ_API void rz_analysis_function_update_analysis(RZ_NONNULL RzAnalysisFunction *fcn); RZ_API bool rz_analysis_task_item_new(RZ_NONNULL RzAnalysis *analysis, RZ_NONNULL RzVector /**/ *tasks, RZ_NONNULL RzAnalysisFunction *fcn, RZ_NULLABLE RzAnalysisBlock *block, ut64 address, RzStackAddr sp); RZ_API int rz_analysis_run_tasks(RZ_NONNULL RzVector /**/ *tasks); diff --git a/test/integration/test_analysis_graph.c b/test/integration/test_analysis_graph.c index 6d2f763c422..be9e2c84201 100644 --- a/test/integration/test_analysis_graph.c +++ b/test/integration/test_analysis_graph.c @@ -117,7 +117,16 @@ bool test_analysis_graph_more() { mu_assert_eq(g->n_nodes, 3, "data graph node count"); mu_assert_eq(g->n_edges, 3, "data graph edge count"); - RzGraphNode *n = rz_graph_get_node(g, 0); + RzGraphNode *n = NULL; + RzListIter *it; + RzGraphNode *node; + rz_list_foreach (g->nodes, it, node) { + RzGraphNodeInfo *info = node->data; + if (strcmp(info->title, "0x8048be4") == 0) { + n = node; + break; + } + } mu_assert_notnull(n, "graph node"); RzGraphNodeInfo *ni = n->data;