From 2efd34a305c16705ddc972ed1203e262d8feb523 Mon Sep 17 00:00:00 2001 From: Khairul Azhar Kasmiran Date: Mon, 6 May 2024 21:10:43 +0800 Subject: [PATCH 1/6] rz_core_task_join: Return true on join (#4474) --- librz/core/task.c | 21 ++++++++++++++------- librz/include/rz_core.h | 2 +- test/unit/test_core_task.c | 3 ++- 3 files changed, 17 insertions(+), 9 deletions(-) diff --git a/librz/core/task.c b/librz/core/task.c index cd91025c1f9..f42adb2546c 100644 --- a/librz/core/task.c +++ b/librz/core/task.c @@ -83,29 +83,33 @@ RZ_API int rz_core_task_running_tasks_count(RzCoreTaskScheduler *scheduler) { return count; } -static void task_join(RzCoreTask *task) { +static bool task_join(RzCoreTask *task) { RzThreadSemaphore *sem = task->running_sem; if (!sem) { - return; + return false; } rz_th_sem_wait(sem); rz_th_sem_post(sem); + return true; } -RZ_API void rz_core_task_join(RzCoreTaskScheduler *scheduler, RzCoreTask *current, int id) { +RZ_API bool rz_core_task_join(RzCoreTaskScheduler *scheduler, RzCoreTask *current, int id) { + bool ret = true; if (current && id == current->id) { - return; + return false; } if (id >= 0) { RzCoreTask *task = rz_core_task_get_incref(scheduler, id); if (!task) { - return; + return false; } if (current) { rz_core_task_sleep_begin(current); } - task_join(task); + if (!task_join(task)) { + ret = false; + } if (current) { rz_core_task_sleep_end(current); } @@ -131,7 +135,9 @@ RZ_API void rz_core_task_join(RzCoreTaskScheduler *scheduler, RzCoreTask *curren if (current) { rz_core_task_sleep_begin(current); } - task_join(task); + if (!task_join(task)) { + ret = false; + } if (current) { rz_core_task_sleep_end(current); } @@ -139,6 +145,7 @@ RZ_API void rz_core_task_join(RzCoreTaskScheduler *scheduler, RzCoreTask *curren } rz_list_free(tasks); } + return ret; } static void task_free(RzCoreTask *task) { diff --git a/librz/include/rz_core.h b/librz/include/rz_core.h index 2bed94ef9c8..0e43e8deb41 100644 --- a/librz/include/rz_core.h +++ b/librz/include/rz_core.h @@ -1191,7 +1191,7 @@ RZ_API void rz_core_task_break(RzCoreTaskScheduler *scheduler, int id); RZ_API void rz_core_task_break_all(RzCoreTaskScheduler *scheduler); RZ_API int rz_core_task_del(RzCoreTaskScheduler *scheduler, int id); RZ_API RzCoreTask *rz_core_task_self(RzCoreTaskScheduler *scheduler); -RZ_API void rz_core_task_join(RzCoreTaskScheduler *scheduler, RzCoreTask *current, int id); +RZ_API bool rz_core_task_join(RzCoreTaskScheduler *scheduler, RzCoreTask *current, int id); typedef void (*inRangeCb)(RzCore *core, ut64 from, ut64 to, int vsize, void *cb_user); RZ_API int rz_core_search_value_in_range(RzCore *core, RzInterval search_itv, ut64 vmin, ut64 vmax, int vsize, inRangeCb cb, void *cb_user); diff --git a/test/unit/test_core_task.c b/test/unit/test_core_task.c index 46aa246bae1..fbc6255ffd0 100644 --- a/test/unit/test_core_task.c +++ b/test/unit/test_core_task.c @@ -69,7 +69,8 @@ static bool test_core_task_finished_cb(void) { RzCoreTask *a = rz_core_cmd_task_new(core, "echo amor; echo vincit; echo omnia", finished_cb, &res_indir); rz_core_task_enqueue(&core->tasks, a); - rz_core_task_join(&core->tasks, rz_core_task_self(&core->tasks), a->id); + bool task_joined = rz_core_task_join(&core->tasks, rz_core_task_self(&core->tasks), a->id); + mu_assert_true(task_joined, "task joined"); const char *cmd_result = rz_core_cmd_task_get_result(a); mu_assert_streq(cmd_result, "amor\nvincit\nomnia\n", "cmd result"); From f818ca42961b88cae9517160418a1319212ed73c Mon Sep 17 00:00:00 2001 From: pelijah Date: Tue, 7 May 2024 02:57:52 +0300 Subject: [PATCH 2/6] Refactor sdb_foreach and related APIs (#4471) * Refactor sdb_foreach and related APIs * Strengthen bounds check in sdb_dump_next() * Switch to RzPVector * Use length info in filter_noreturn() * Fix cmp function * Remove unused sdb_like() API * Pass SdbKv to SdbForeachCallback * Add sdbkv_dup_value() helper --- librz/arch/analysis.c | 47 ++- librz/arch/cc.c | 18 +- librz/arch/class.c | 36 +-- librz/arch/platform_profile.c | 19 +- librz/arch/platform_target_index.c | 16 +- librz/arch/serialize_analysis.c | 38 +-- librz/bp/serialize_bp.c | 6 +- librz/config/config.c | 6 +- librz/config/serialize_config.c | 8 +- librz/core/cbin.c | 27 +- librz/core/cdebug.c | 28 +- librz/core/cmd/cmd.c | 4 +- librz/core/cmd/cmd_analysis.c | 34 ++- librz/core/cmd/cmd_search.c | 30 +- librz/core/project_migrate.c | 20 +- librz/core/serialize_core.c | 18 +- librz/core/tui/classes.c | 31 +- librz/debug/dsession.c | 19 +- librz/flag/serialize_flag.c | 12 +- librz/flag/tags.c | 10 +- librz/include/rz_analysis.h | 2 +- librz/syscall/syscall.c | 29 +- librz/type/serialize_functions.c | 17 +- librz/type/serialize_types.c | 10 +- librz/util/sdb/src/diff.c | 8 +- librz/util/sdb/src/main.c | 8 +- librz/util/sdb/src/query.c | 38 +-- librz/util/sdb/src/sdb.c | 454 ++++++++++++---------------- librz/util/sdb/src/sdb.h | 24 +- librz/util/sdb/src/sdbht.h | 11 +- librz/util/sdb/src/text.c | 18 +- librz/util/serialize_spaces.c | 4 +- test/unit/test_analysis_function.c | 37 +++ test/unit/test_sdb_sdb.c | 172 +++++++---- test/unit/test_serialize_analysis.c | 20 +- 35 files changed, 663 insertions(+), 616 deletions(-) diff --git a/librz/arch/analysis.c b/librz/arch/analysis.c index 664c03f44db..521fbbdc980 100644 --- a/librz/arch/analysis.c +++ b/librz/arch/analysis.c @@ -712,41 +712,38 @@ RZ_API bool rz_analysis_noreturn_at(RzAnalysis *analysis, ut64 addr) { return false; } +static bool filter_noreturn(void *user, const SdbKv *kv) { + ut32 klen = sdbkv_key_len(kv); + ut32 vlen = sdbkv_value_len(kv); + return vlen == 4 && !strcmp(sdbkv_value(kv), "true") && klen > 9 && !strcmp(sdbkv_key(kv) + (klen - 9), ".noreturn"); +} + RZ_API RzList /**/ *rz_analysis_noreturn_functions(RzAnalysis *analysis) { rz_return_val_if_fail(analysis, NULL); + // At first we read all noreturn functions from the Types DB RzList *noretl = rz_type_noreturn_function_names(analysis->typedb); // Then we propagate all noreturn functions that were inferred by // the analysis process - SdbKv *kv; - SdbListIter *iter; - SdbList *l = sdb_foreach_list(analysis->sdb_noret, true); - ls_foreach (l, iter, kv) { + void **iter; + RzPVector *items = sdb_get_items_filter(analysis->sdb_noret, filter_noreturn, NULL, false); + rz_pvector_foreach (items, iter) { + SdbKv *kv = *iter; const char *k = sdbkv_key(kv); - if (!strncmp(k, "func.", 5) && strstr(k, ".noreturn")) { - char *s = strdup(k + 5); - char *d = strchr(s, '.'); - if (d) { - *d = 0; - } - rz_list_append(noretl, strdup(s)); - free(s); + const ut32 klen = sdbkv_key_len(kv); + // strlen("func." ".noreturn") = 14 + if (klen > 14 && !strncmp(k, "func.", 5)) { + rz_list_append(noretl, rz_str_ndup(k + 5, klen - 14)); } - if (!strncmp(k, "addr.", 5)) { - char *off; - if (!(off = strdup(k + 5))) { - break; - } - char *ptr = strstr(off, ".noreturn"); - if (ptr) { - *ptr = 0; - char *addr = rz_str_newf("0x%s", off); - rz_list_append(noretl, addr); - } - free(off); + // strlen("addr." ".noreturn") = 14 + if (RZ_BETWEEN(15, klen, 30) && !strncmp(k, "addr.", 5)) { + char addr[17]; + memcpy(addr, k + 5, klen - 14); + addr[klen - 14] = '\0'; + rz_list_append(noretl, rz_str_newf("0x%s", addr)); } } - ls_free(l); + rz_pvector_free(items); return noretl; } diff --git a/librz/arch/cc.c b/librz/arch/cc.c index be0ffc19deb..1a75f30dee3 100644 --- a/librz/arch/cc.c +++ b/librz/arch/cc.c @@ -265,16 +265,18 @@ RZ_API const char *rz_analysis_cc_func(RzAnalysis *analysis, const char *func_na return cc ? cc : rz_analysis_cc_default(analysis); } +static bool filter_cc(void *user, const SdbKv *kv) { + return sdbkv_value_len(kv) == 2 && !strcmp(sdbkv_value(kv), "cc"); +} + RZ_API RzList /**/ *rz_analysis_calling_conventions(RzAnalysis *analysis) { RzList *ccl = rz_list_new(); - SdbKv *kv; - SdbListIter *iter; - SdbList *l = sdb_foreach_list(analysis->sdb_cc, true); - ls_foreach (l, iter, kv) { - if (!strcmp(sdbkv_value(kv), "cc")) { - rz_list_append(ccl, strdup(sdbkv_key(kv))); - } + void **iter; + RzPVector *items = sdb_get_items_filter(analysis->sdb_cc, filter_cc, NULL, true); + rz_pvector_foreach (items, iter) { + SdbKv *kv = *iter; + rz_list_append(ccl, strdup(sdbkv_key(kv))); } - ls_free(l); + rz_pvector_free(items); return ccl; } diff --git a/librz/arch/class.c b/librz/arch/class.c index c9c7322946a..387a856341e 100644 --- a/librz/arch/class.c +++ b/librz/arch/class.c @@ -184,8 +184,8 @@ RZ_API bool rz_analysis_class_exists(RzAnalysis *analysis, const char *name) { return r; } -RZ_API SdbList *rz_analysis_class_get_all(RzAnalysis *analysis, bool sorted) { - return sdb_foreach_list(analysis->sdb_classes, sorted); +RZ_API RZ_OWN RzPVector /**/ *rz_analysis_class_get_all(RzAnalysis *analysis, bool sorted) { + return sdb_get_items(analysis->sdb_classes, sorted); } RZ_API void rz_analysis_class_foreach(RzAnalysis *analysis, SdbForeachCallback cb, void *user) { @@ -1031,14 +1031,13 @@ typedef struct { const char *class_name; } DeleteClassCtx; -static bool rz_analysis_class_base_delete_class_cb(void *user, const char *k, const char *v) { - (void)v; +static bool rz_analysis_class_base_delete_class_cb(void *user, const SdbKv *kv) { DeleteClassCtx *ctx = user; - RzVector *bases = rz_analysis_class_base_get_all(ctx->analysis, k); + RzVector *bases = rz_analysis_class_base_get_all(ctx->analysis, sdbkv_key(kv)); RzAnalysisBaseClass *base; rz_vector_foreach (bases, base) { if (base->class_name && strcmp(base->class_name, ctx->class_name) == 0) { - rz_analysis_class_base_delete(ctx->analysis, k, base->id); + rz_analysis_class_base_delete(ctx->analysis, sdbkv_key(kv), base->id); } } rz_vector_free(bases); @@ -1056,18 +1055,17 @@ typedef struct { const char *class_name_new; } RenameClassCtx; -static bool rz_analysis_class_base_rename_class_cb(void *user, const char *k, const char *v) { - (void)v; +static bool rz_analysis_class_base_rename_class_cb(void *user, const SdbKv *kv) { RenameClassCtx *ctx = user; - RzVector *bases = rz_analysis_class_base_get_all(ctx->analysis, k); + RzVector *bases = rz_analysis_class_base_get_all(ctx->analysis, sdbkv_key(kv)); RzAnalysisBaseClass *base; rz_vector_foreach (bases, base) { if (base->class_name && strcmp(base->class_name, ctx->class_name_old) == 0) { - rz_analysis_class_base_set_raw(ctx->analysis, k, base, ctx->class_name_new); + rz_analysis_class_base_set_raw(ctx->analysis, sdbkv_key(kv), base, ctx->class_name_new); } } rz_vector_free(bases); - return 1; + return true; } static void rz_analysis_class_base_rename_class(RzAnalysis *analysis, const char *class_name_old, const char *class_name_new) { @@ -1279,21 +1277,19 @@ RZ_API RzGraph /**/ *rz_analysis_class_get_inheritance_graph( if (!class_graph) { return NULL; } - SdbList *classes = rz_analysis_class_get_all(analysis, true); + RzPVector *classes = rz_analysis_class_get_all(analysis, true); if (!classes) { rz_graph_free(class_graph); return NULL; } HtSP /**/ *hashmap = ht_sp_new(HT_STR_DUP, NULL, NULL); if (!hashmap) { - rz_graph_free(class_graph); - ls_free(classes); - return NULL; + goto failure; } - SdbListIter *iter; - SdbKv *kv; + void **iter; // Traverse each class and create a node and edges - ls_foreach (classes, iter, kv) { + rz_pvector_foreach (classes, iter) { + SdbKv *kv = *iter; const char *name = sdbkv_key(kv); // create nodes RzGraphNode *curr_node = ht_sp_find(hashmap, name, NULL); @@ -1322,12 +1318,12 @@ RZ_API RzGraph /**/ *rz_analysis_class_get_inheritance_graph( } rz_vector_free(bases); } - ls_free(classes); + rz_pvector_free(classes); ht_sp_free(hashmap); return class_graph; failure: - ls_free(classes); + rz_pvector_free(classes); ht_sp_free(hashmap); rz_graph_free(class_graph); return NULL; diff --git a/librz/arch/platform_profile.c b/librz/arch/platform_profile.c index 94f718d1221..0687aa37a9f 100644 --- a/librz/arch/platform_profile.c +++ b/librz/arch/platform_profile.c @@ -99,14 +99,15 @@ static inline bool cpu_reload_needed(RzPlatformTarget *c, const char *cpu, const static bool sdb_load_arch_profile(RzPlatformTarget *t, Sdb *sdb) { rz_return_val_if_fail(t && sdb, false); - SdbKv *kv; - SdbListIter *iter; + RzPlatformProfile *c = rz_platform_profile_new(); if (!c) { return false; } - SdbList *l = sdb_foreach_list(sdb, false); - ls_foreach (l, iter, kv) { + void **iter; + RzPVector *items = sdb_get_items(sdb, false); + rz_pvector_foreach (items, iter) { + SdbKv *kv = *iter; if (!strcmp(sdbkv_key(kv), "PC")) { c->pc = rz_num_math(NULL, sdbkv_value(kv)); } else if (!strcmp(sdbkv_key(kv), "EEPROM_SIZE")) { @@ -127,21 +128,21 @@ static bool sdb_load_arch_profile(RzPlatformTarget *t, Sdb *sdb) { c->ram_size = rz_num_math(NULL, sdbkv_value(kv)); } if (!strcmp(sdbkv_value(kv), "io")) { - char *io_name = sdbkv_key(kv); + const char *io_name = sdbkv_key(kv); char *argument_key = rz_str_newf("%s.address", io_name); ut64 io_address = sdb_num_get(sdb, argument_key, NULL); free(argument_key); - ht_up_insert(c->registers_mmio, io_address, io_name); + ht_up_insert(c->registers_mmio, io_address, (char *)io_name); } if (!strcmp(sdbkv_value(kv), "ext_io")) { - char *ext_io_name = sdbkv_key(kv); + const char *ext_io_name = sdbkv_key(kv); char *argument_key = rz_str_newf("%s.address", ext_io_name); ut64 ext_io_address = sdb_num_get(sdb, argument_key, NULL); free(argument_key); - ht_up_insert(c->registers_extended, ext_io_address, ext_io_name); + ht_up_insert(c->registers_extended, ext_io_address, (char *)ext_io_name); } } - ls_free(l); + rz_pvector_free(items); rz_platform_profile_free(t->profile); t->profile = c; return true; diff --git a/librz/arch/platform_target_index.c b/librz/arch/platform_target_index.c index d6de9f07db9..1537da5919d 100644 --- a/librz/arch/platform_target_index.c +++ b/librz/arch/platform_target_index.c @@ -59,17 +59,17 @@ RZ_API void rz_platform_item_free(RzPlatformItem *item) { static bool sdb_load_platform_profile(RZ_NONNULL RzPlatformTargetIndex *t, RZ_NONNULL Sdb *sdb) { rz_return_val_if_fail(t && sdb, false); - SdbKv *kv; - SdbListIter *iter; - SdbList *l = sdb_foreach_list(sdb, false); - char *argument_key, *comment, *name; - ls_foreach (l, iter, kv) { + + void **iter; + RzPVector *items = sdb_get_items(sdb, false); + rz_pvector_foreach (items, iter) { + SdbKv *kv = *iter; if (!strcmp(sdbkv_value(kv), "name")) { - name = sdbkv_key(kv); + const char *name = sdbkv_key(kv); RzPlatformItem *item = rz_platform_item_new(name); - argument_key = rz_str_newf("%s.address", item->name); + char *argument_key = rz_str_newf("%s.address", item->name); if (!argument_key) { rz_platform_item_free(item); return false; @@ -81,7 +81,7 @@ static bool sdb_load_platform_profile(RZ_NONNULL RzPlatformTargetIndex *t, RZ_NO } argument_key = rz_str_newf("%s.comment", item->name); - comment = sdb_get(sdb, argument_key, NULL); + char *comment = sdb_get(sdb, argument_key, NULL); if (comment) { item->comment = comment; } diff --git a/librz/arch/serialize_analysis.c b/librz/arch/serialize_analysis.c index 9f0b0343b0d..637dafb64cc 100644 --- a/librz/arch/serialize_analysis.c +++ b/librz/arch/serialize_analysis.c @@ -235,10 +235,10 @@ typedef struct { RzKeyParser *parser; } BlockLoadCtx; -static bool block_load_cb(void *user, const char *k, const char *v) { +static bool block_load_cb(void *user, const SdbKv *kv) { BlockLoadCtx *ctx = user; - char *json_str = strdup(v); + char *json_str = sdbkv_dup_value(kv); if (!json_str) { return true; } @@ -359,7 +359,7 @@ static bool block_load_cb(void *user, const char *k, const char *v) { free(json_str); errno = 0; - ut64 addr = strtoull(k, NULL, 0); + ut64 addr = strtoull(sdbkv_key(kv), NULL, 0); if (errno || proto.size == UT64_MAX || (proto.op_pos && proto.op_pos_size != proto.ninstr - 1)) { // op_pos_size > ninstr - 1 is legal but we require the format to be like this. goto error; } @@ -953,10 +953,10 @@ typedef struct { RzKeyParser *parser; } GlobalVarCtx; -static bool global_var_load_cb(void *user, const char *k, const char *v) { +static bool global_var_load_cb(void *user, const SdbKv *kv) { GlobalVarCtx *ctx = user; - char *json_str = strdup(v); + char *json_str = sdbkv_dup_value(kv); if (!json_str) { return true; } @@ -1182,10 +1182,10 @@ enum { FUNCTION_FIELD_LABELS }; -static bool function_load_cb(void *user, const char *k, const char *v) { +static bool function_load_cb(void *user, const SdbKv *kv) { RzSerializeAnalysisFunctionLoadCtx *ctx = user; - char *json_str = strdup(v); + char *json_str = sdbkv_dup_value(kv); if (!json_str) { return true; } @@ -1338,7 +1338,7 @@ static bool function_load_cb(void *user, const char *k, const char *v) { bool ret = true; errno = 0; - function->addr = strtoull(k, NULL, 0); + function->addr = strtoull(sdbkv_key(kv), NULL, 0); if (errno || !function->name || !rz_analysis_add_function(ctx->analysis, function)) { rz_analysis_function_free(function); ret = false; @@ -1443,16 +1443,16 @@ RZ_API void rz_serialize_analysis_xrefs_save(RZ_NONNULL Sdb *db, RZ_NONNULL RzAn ht_up_foreach(analysis->ht_xrefs_from, store_xrefs_list_cb, db); } -static bool xrefs_load_cb(void *user, const char *k, const char *v) { +static bool xrefs_load_cb(void *user, const SdbKv *kv) { RzAnalysis *analysis = user; errno = 0; - ut64 from = strtoull(k, NULL, 0); + ut64 from = strtoull(sdbkv_key(kv), NULL, 0); if (errno) { return false; } - char *json_str = strdup(v); + char *json_str = sdbkv_dup_value(kv); if (!json_str) { return true; } @@ -1606,16 +1606,16 @@ RZ_API void rz_serialize_analysis_meta_save(RZ_NONNULL Sdb *db, RZ_NONNULL RzAna pj_free(j); } -static bool meta_load_cb(void *user, const char *k, const char *v) { +static bool meta_load_cb(void *user, const SdbKv *kv) { RzAnalysis *analysis = user; errno = 0; - ut64 addr = strtoull(k, NULL, 0); + ut64 addr = strtoull(sdbkv_key(kv), NULL, 0); if (errno) { return false; } - char *json_str = strdup(v); + char *json_str = sdbkv_dup_value(kv); if (!json_str) { return true; } @@ -1920,17 +1920,17 @@ typedef struct { RzKeyParser *parser; } HintsLoadCtx; -static bool hints_load_cb(void *user, const char *k, const char *v) { +static bool hints_load_cb(void *user, const SdbKv *kv) { HintsLoadCtx *ctx = user; RzAnalysis *analysis = ctx->analysis; errno = 0; - ut64 addr = strtoull(k, NULL, 0); + ut64 addr = strtoull(sdbkv_key(kv), NULL, 0); if (errno) { return false; } - char *json_str = strdup(v); + char *json_str = sdbkv_dup_value(kv); if (!json_str) { return true; } @@ -2130,8 +2130,8 @@ RZ_API void rz_serialize_analysis_imports_save(RZ_NONNULL Sdb *db, RZ_NONNULL Rz } } -static bool import_load_cb(void *user, const char *k, const char *v) { - rz_analysis_add_import(user, k); +static bool import_load_cb(void *user, const SdbKv *kv) { + rz_analysis_add_import(user, sdbkv_key(kv)); return true; } diff --git a/librz/bp/serialize_bp.c b/librz/bp/serialize_bp.c index ebe5e7ffe57..8bf0cff8fc4 100644 --- a/librz/bp/serialize_bp.c +++ b/librz/bp/serialize_bp.c @@ -119,10 +119,10 @@ typedef struct { RzSerializeBpParser parser; } BpLoadCtx; -static bool bp_load_cb(void *user, const char *k, const char *v) { +static bool bp_load_cb(void *user, const SdbKv *kv) { bool ret = false; BpLoadCtx *ctx = user; - char *json_str = strdup(v); + char *json_str = sdbkv_dup_value(kv); if (!json_str) { return true; } @@ -131,7 +131,7 @@ static bool bp_load_cb(void *user, const char *k, const char *v) { goto heaven; } RzBreakpointItem bp_item_temp = { 0 }; - bp_item_temp.addr = strtoull(k, NULL, 0); + bp_item_temp.addr = strtoull(sdbkv_key(kv), NULL, 0); RZ_KEY_PARSER_JSON(ctx->parser, json, child, { case BP_FIELD_NAME: diff --git a/librz/config/config.c b/librz/config/config.c index 265e012c03e..5c19b059ed0 100644 --- a/librz/config/config.c +++ b/librz/config/config.c @@ -552,11 +552,11 @@ RZ_API void rz_config_serialize(RZ_NONNULL RzConfig *config, RZ_NONNULL Sdb *db) } } -static bool load_config_cb(void *user, const char *k, const char *v) { +static bool load_config_cb(void *user, const SdbKv *kv) { RzConfig *config = user; - RzConfigNode *node = rz_config_node_get(config, k); + RzConfigNode *node = rz_config_node_get(config, sdbkv_key(kv)); if (node) { - rz_config_set(config, k, v); + rz_config_set(config, sdbkv_key(kv), sdbkv_value(kv)); } return true; } diff --git a/librz/config/serialize_config.c b/librz/config/serialize_config.c index dc70b592e1d..0048796102e 100644 --- a/librz/config/serialize_config.c +++ b/librz/config/serialize_config.c @@ -29,16 +29,16 @@ typedef struct load_config_ctx_t { HtSP *exclude; } LoadConfigCtx; -static bool load_config_cb(void *user, const char *k, const char *v) { +static bool load_config_cb(void *user, const SdbKv *kv) { LoadConfigCtx *ctx = user; - if (ctx->exclude && ht_sp_find_kv(ctx->exclude, k, NULL)) { + if (ctx->exclude && ht_sp_find_kv(ctx->exclude, sdbkv_key(kv), NULL)) { return true; } - RzConfigNode *node = rz_config_node_get(ctx->config, k); + RzConfigNode *node = rz_config_node_get(ctx->config, sdbkv_key(kv)); if (!node) { return 1; } - rz_config_set(ctx->config, k, v); + rz_config_set(ctx->config, sdbkv_key(kv), sdbkv_value(kv)); return 1; } diff --git a/librz/core/cbin.c b/librz/core/cbin.c index fd56a960e8a..84d12c9a1d8 100644 --- a/librz/core/cbin.c +++ b/librz/core/cbin.c @@ -91,18 +91,18 @@ RZ_API void rz_core_bin_export_info(RzCore *core, int mode) { if (!db) { return; } - SdbListIter *iter; - SdbKv *kv; if (IS_MODE_RZCMD(mode)) { rz_cons_printf("fs format\n"); } else if (IS_MODE_SET(mode)) { rz_flag_space_push(core->flags, "format"); } // iterate over all keys - SdbList *ls = sdb_foreach_list(db, false); - ls_foreach (ls, iter, kv) { - char *k = sdbkv_key(kv); - char *v = sdbkv_value(kv); + void **iter; + RzPVector *items = sdb_get_items(db, false); + rz_pvector_foreach (items, iter) { + SdbKv *kv = *iter; + const char *k = sdbkv_key(kv); + const char *v = sdbkv_value(kv); char *dup = strdup(k); if ((flagname = strstr(dup, ".offset"))) { *flagname = 0; @@ -134,9 +134,10 @@ RZ_API void rz_core_bin_export_info(RzCore *core, int mode) { free(dup); } RZ_FREE(offset); - ls_foreach (ls, iter, kv) { - char *k = sdbkv_key(kv); - char *v = sdbkv_value(kv); + rz_pvector_foreach (items, iter) { + SdbKv *kv = *iter; + const char *k = sdbkv_key(kv); + const char *v = sdbkv_value(kv); char *dup = strdup(k); if ((flagname = strstr(dup, ".format"))) { *flagname = 0; @@ -152,9 +153,10 @@ RZ_API void rz_core_bin_export_info(RzCore *core, int mode) { } free(dup); } - ls_foreach (ls, iter, kv) { - char *k = sdbkv_key(kv); - char *v = sdbkv_value(kv); + rz_pvector_foreach (items, iter) { + SdbKv *kv = *iter; + const char *k = sdbkv_key(kv); + const char *v = sdbkv_value(kv); char *dup = strdup(k); if ((flagname = strstr(dup, ".format"))) { *flagname = 0; @@ -204,6 +206,7 @@ RZ_API void rz_core_bin_export_info(RzCore *core, int mode) { free(dup); } free(offset); + rz_pvector_free(items); if (IS_MODE_SET(mode)) { rz_flag_space_pop(core->flags); } diff --git a/librz/core/cdebug.c b/librz/core/cdebug.c index bf24af2ed2e..b17ff4b67e4 100644 --- a/librz/core/cdebug.c +++ b/librz/core/cdebug.c @@ -1200,37 +1200,37 @@ static const char *signal_option(int opt) { return NULL; } -static bool siglistcb(void *p, const char *k, const char *v) { +static bool siglistcb(void *p, const SdbKv *kv) { char key[32] = "cfg."; struct RzCoreDebugState *ds = p; int opt; - if (atoi(k) > 0) { - strncpy(key + 4, k, 20); + if (atoi(sdbkv_key(kv)) > 0) { + strncpy(key + 4, sdbkv_key(kv), 20); opt = sdb_num_get(ds->dbg->sgnls, key, 0); if (opt && ds->state->mode == RZ_OUTPUT_MODE_STANDARD) { - rz_cons_printf("%s %s", k, v); + rz_cons_printf("%s %s", sdbkv_key(kv), sdbkv_value(kv)); const char *optstr = signal_option(opt); if (optstr) { rz_cons_printf(" %s", optstr); } rz_cons_newline(); } else { - rz_cons_printf("%s %s\n", k, v); + rz_cons_printf("%s %s\n", sdbkv_key(kv), sdbkv_value(kv)); } } return true; } -static bool siglistjsoncb(void *p, const char *k, const char *v) { +static bool siglistjsoncb(void *p, const SdbKv *kv) { char key[32] = "cfg."; struct RzCoreDebugState *ds = p; int opt; - if (atoi(k) > 0) { - strncpy(key + 4, k, 20); + if (atoi(sdbkv_key(kv)) > 0) { + strncpy(key + 4, sdbkv_key(kv), 20); opt = (int)sdb_num_get(ds->dbg->sgnls, key, 0); pj_o(ds->state->d.pj); - pj_ks(ds->state->d.pj, "signum", k); - pj_ks(ds->state->d.pj, "name", v); + pj_ks(ds->state->d.pj, "signum", sdbkv_key(kv)); + pj_ks(ds->state->d.pj, "name", sdbkv_value(kv)); const char *optstr = signal_option(opt); if (optstr) { pj_ks(ds->state->d.pj, "option", optstr); @@ -1242,15 +1242,15 @@ static bool siglistjsoncb(void *p, const char *k, const char *v) { return true; } -static bool siglisttblcb(void *p, const char *k, const char *v) { +static bool siglisttblcb(void *p, const SdbKv *kv) { char key[32] = "cfg."; struct RzCoreDebugState *ds = p; int opt; - if (atoi(k) > 0) { - strncpy(key + 4, k, 20); + if (atoi(sdbkv_key(kv)) > 0) { + strncpy(key + 4, sdbkv_key(kv), 20); opt = (int)sdb_num_get(ds->dbg->sgnls, key, 0); const char *optstr = signal_option(opt); - rz_table_add_rowf(ds->state->d.t, "sss", k, v, rz_str_get(optstr)); + rz_table_add_rowf(ds->state->d.t, "sss", sdbkv_key(kv), sdbkv_value(kv), rz_str_get(optstr)); } return true; } diff --git a/librz/core/cmd/cmd.c b/librz/core/cmd/cmd.c index 4c57f00a207..30cc13091ca 100644 --- a/librz/core/cmd/cmd.c +++ b/librz/core/cmd/cmd.c @@ -432,8 +432,8 @@ RZ_API bool rz_core_run_script(RzCore *core, RZ_NONNULL const char *file) { return ret; } -static bool callback_foreach_kv(void *user, const char *k, const char *v) { - rz_cons_printf("%s=%s\n", k, v); +static bool callback_foreach_kv(void *user, const SdbKv *kv) { + rz_cons_printf("%s=%s\n", sdbkv_key(kv), sdbkv_value(kv)); return true; } diff --git a/librz/core/cmd/cmd_analysis.c b/librz/core/cmd/cmd_analysis.c index 567f33dacef..def8b9875e3 100644 --- a/librz/core/cmd/cmd_analysis.c +++ b/librz/core/cmd/cmd_analysis.c @@ -205,8 +205,8 @@ static int cmpaddr(const void *_a, const void *_b, void *user) { : 0; } -static bool listOpDescriptions(void *_core, const char *k, const char *v) { - rz_cons_printf("%s=%s\n", k, v); +static bool listOpDescriptions(void *_core, const SdbKv *kv) { + rz_cons_printf("%s=%s\n", sdbkv_key(kv), sdbkv_value(kv)); return true; } @@ -5159,9 +5159,9 @@ typedef struct { PJ *pj; } ListJsonCtx; -static bool analysis_class_print_to_json_cb(void *user, const char *k, const char *v) { +static bool analysis_class_print_to_json_cb(void *user, const SdbKv *kv) { ListJsonCtx *ctx = user; - analysis_class_print_to_json(ctx->analysis, ctx->pj, k); + analysis_class_print_to_json(ctx->analysis, ctx->pj, sdbkv_key(kv)); return true; } @@ -5210,23 +5210,25 @@ RZ_IPI RzCmdStatus rz_analysis_class_list_handler(RzCore *core, int argc, const return RZ_CMD_STATUS_OK; } - SdbList *classes = rz_analysis_class_get_all(core->analysis, state->mode != RZ_OUTPUT_MODE_RIZIN); - SdbListIter *iter; - SdbKv *kv; + RzPVector *classes = rz_analysis_class_get_all(core->analysis, state->mode != RZ_OUTPUT_MODE_RIZIN); + void **iter; if (state->mode == RZ_OUTPUT_MODE_RIZIN) { - ls_foreach (classes, iter, kv) { + rz_pvector_foreach (classes, iter) { + SdbKv *kv = *iter; // need to create all classes first, so they can be referenced rz_cons_printf("ac %s\n", sdbkv_key(kv)); } - ls_foreach (classes, iter, kv) { + rz_pvector_foreach (classes, iter) { + SdbKv *kv = *iter; analysis_class_print_as_cmd(core->analysis, sdbkv_key(kv)); } } else { - ls_foreach (classes, iter, kv) { + rz_pvector_foreach (classes, iter) { + SdbKv *kv = *iter; analysis_class_print(core->analysis, sdbkv_key(kv), state->mode == RZ_OUTPUT_MODE_LONG); } } - ls_free(classes); + rz_pvector_free(classes); return RZ_CMD_STATUS_OK; } @@ -5505,14 +5507,14 @@ RZ_IPI RzCmdStatus rz_analysis_class_vtable_lookup_handler(RzCore *core, int arg list_all_functions_at_vtable_offset(core->analysis, class_name, offset); return RZ_CMD_STATUS_OK; } - SdbList *classes = rz_analysis_class_get_all(core->analysis, true); - SdbListIter *iter; - SdbKv *kv; - ls_foreach (classes, iter, kv) { + RzPVector *classes = rz_analysis_class_get_all(core->analysis, true); + void **iter; + rz_pvector_foreach (classes, iter) { + SdbKv *kv = *iter; const char *name = sdbkv_key(kv); list_all_functions_at_vtable_offset(core->analysis, name, offset); } - ls_free(classes); + rz_pvector_free(classes); return RZ_CMD_STATUS_OK; } diff --git a/librz/core/cmd/cmd_search.c b/librz/core/cmd/cmd_search.c index b46309427ae..d995c1e324a 100644 --- a/librz/core/cmd/cmd_search.c +++ b/librz/core/cmd/cmd_search.c @@ -2455,10 +2455,9 @@ static void do_string_search(RzCore *core, RzInterval search_itv, struct search_ static void rop_kuery(void *data, const char *input, PJ *pj) { RzCore *core = (RzCore *)data; Sdb *db_rop = sdb_ns(core->sdb, "rop", false); - SdbListIter *sdb_iter, *it; - SdbList *sdb_list; + SdbListIter *it; + void **items_iter; SdbNs *ns; - SdbKv *kv; char *out; if (!db_rop) { @@ -2469,19 +2468,22 @@ static void rop_kuery(void *data, const char *input, PJ *pj) { switch (*input) { case 'q': ls_foreach (db_rop->ns, it, ns) { - sdb_list = sdb_foreach_list(ns->sdb, false); - ls_foreach (sdb_list, sdb_iter, kv) { + RzPVector *items = sdb_get_items(ns->sdb, false); + rz_pvector_foreach (items, items_iter) { + SdbKv *kv = *items_iter; rz_cons_printf("%s ", sdbkv_key(kv)); } + rz_pvector_free(items); } break; case 'j': pj_o(pj); pj_ka(pj, "gadgets"); ls_foreach (db_rop->ns, it, ns) { - sdb_list = sdb_foreach_list(ns->sdb, false); - ls_foreach (sdb_list, sdb_iter, kv) { - char *dup = strdup(sdbkv_value(kv)); + RzPVector *items = sdb_get_items(ns->sdb, false); + rz_pvector_foreach (items, items_iter) { + SdbKv *kv = *items_iter; + char *dup = sdbkv_dup_value(kv); bool flag = false; // to free tok when doing strdup char *size = strtok(dup, " "); char *tok = strtok(NULL, "{}"); @@ -2500,6 +2502,7 @@ static void rop_kuery(void *data, const char *input, PJ *pj) { free(tok); } } + rz_pvector_free(items); } pj_end(pj); pj_end(pj); @@ -3087,17 +3090,17 @@ RZ_IPI int rz_cmd_search(void *data, const char *input) { if (!gadgetSdb) { rz_core_search_rop(core, search_itv, 0, input + 1, 0, ¶m); } else { - SdbKv *kv; - SdbListIter *sdb_iter; - SdbList *sdb_list = sdb_foreach_list(gadgetSdb, true); + void **iter; + RzPVector *items = sdb_get_items(gadgetSdb, true); - ls_foreach (sdb_list, sdb_iter, kv) { + rz_pvector_foreach (items, iter) { + SdbKv *kv = *iter; RzList *hitlist = rz_core_asm_hit_list_new(); if (!hitlist) { goto beach; } - char *s = sdbkv_value(kv); + const char *s = sdbkv_value(kv); ut64 addr; int opsz; int mode = 0; @@ -3122,6 +3125,7 @@ RZ_IPI int rz_cmd_search(void *data, const char *input) { print_rop(core, hitlist, param.pj, mode); rz_list_free(hitlist); } + rz_pvector_free(items); } } goto beach; diff --git a/librz/core/project_migrate.c b/librz/core/project_migrate.c index 553930004cd..ebe468f1086 100644 --- a/librz/core/project_migrate.c +++ b/librz/core/project_migrate.c @@ -41,7 +41,9 @@ typedef struct { Sdb *noreturn_db; } V1V2TypesCtx; -bool v1_v2_types_foreach_cb(void *user, const char *k, const char *v) { +bool v1_v2_types_foreach_cb(void *user, const SdbKv *kv) { + const char *k = sdbkv_key(kv); + const char *v = sdbkv_value(kv); if (!rz_str_startswith(k, "addr.") || !rz_str_endswith(k, ".noreturn")) { return true; } @@ -92,8 +94,10 @@ typedef struct { Sdb *typelinks_db; } V2V3TypesCtx; -bool v2_v3_types_foreach_cb(void *user, const char *k, const char *v) { +bool v2_v3_types_foreach_cb(void *user, const SdbKv *kv) { V2V3TypesCtx *ctx = user; + const char *k = sdbkv_key(kv); + const char *v = sdbkv_value(kv); if (rz_str_startswith(k, "func.") || !strcmp(v, "func")) { sdb_set(ctx->callables_db, k, v, 0); rz_list_push(ctx->moved_keys, strdup(k)); @@ -371,7 +375,9 @@ bool v10_v11_migrate_variable(const RzJson *var, st64 maxstack, PJ *pj, RzSerial return false; } -bool v10_v11_functions_foreach_cb(void *user, const char *k, const char *v) { +bool v10_v11_functions_foreach_cb(void *user, const SdbKv *kv) { + const char *k = sdbkv_key(kv); + const char *v = sdbkv_value(kv); V10V11FunctionsCtx *ctx = user; char *json_str = strdup(v); RzJson *j = rz_json_parse(json_str); @@ -487,7 +493,9 @@ typedef struct { Sdb *global_vars_db; } V12V13TypesCtx; -bool v12_v13_types_foreach_cb(void *user, const char *k, const char *v) { +bool v12_v13_types_foreach_cb(void *user, const SdbKv *kv) { + const char *k = sdbkv_key(kv); + const char *v = sdbkv_value(kv); V12V13TypesCtx *ctx = user; if (rz_str_startswith(k, "0x")) { char name[32]; @@ -537,7 +545,9 @@ RZ_API bool rz_project_migrate_v12_v13(RzProject *prj, RzSerializeResultInfo *re // Removed {stack,reg} from "/core/analysis/functions/vars" // and converted into storage object { ..., storage: { type: ... } } -bool v13_v14_foreach_cb(void *user, const char *k, const char *v) { +bool v13_v14_foreach_cb(void *user, const SdbKv *kv) { + const char *k = sdbkv_key(kv); + const char *v = sdbkv_value(kv); static const char *types[] = { "stack", "reg" }; Sdb *fn_db = user; if (rz_str_startswith(k, "0x")) { diff --git a/librz/core/serialize_core.c b/librz/core/serialize_core.c index 8abb2a7e07a..c758932d23b 100644 --- a/librz/core/serialize_core.c +++ b/librz/core/serialize_core.c @@ -388,12 +388,12 @@ static bool seek_load_item(SeekLoadCtx *ctx, const char *k, const char *v) { return ret; } -static int __cmp_num_asc(const void *a, const void *b) { +static int __cmp_num_asc(const void *a, const void *b, RZ_UNUSED void *user) { const SdbKv *ka = a, *kb = b; // Parse as signed ints but don't bother witb error detection, it'll sort bad and that's it long ia = strtol(sdbkv_key(ka), NULL, 10); long ib = strtol(sdbkv_key(kb), NULL, 10); - return ia > ib; + return RZ_NUM_CMP(ia, ib); } /** @@ -414,19 +414,17 @@ RZ_API bool rz_serialize_core_seek_load(RZ_NONNULL Sdb *db, RZ_NONNULL RzCore *c } // Sort by (numeric) key - SdbList *db_list = sdb_foreach_list(db, false); - if (!db_list) { + RzPVector *db_items = sdb_get_items(db, false); + if (!db_items) { ret = false; goto out_free_parser; } - ls_sort(db_list, __cmp_num_asc); + rz_pvector_sort(db_items, __cmp_num_asc, NULL); // Clear the current history rz_core_seek_reset(core); core->seek_history.saved_set = false; - SdbKv *kv; - SdbListIter *it; SeekLoadCtx ctx = { .core = core, .parser = seek_parser, @@ -434,7 +432,9 @@ RZ_API bool rz_serialize_core_seek_load(RZ_NONNULL Sdb *db, RZ_NONNULL RzCore *c .vec = &core->seek_history.undos, }; bool parsed = true; - ls_foreach (db_list, it, kv) { + void **it; + rz_pvector_foreach (db_items, it) { + SdbKv *kv = *it; parsed &= seek_load_item(&ctx, sdbkv_key(kv), sdbkv_value(kv)); } ret &= parsed; @@ -471,7 +471,7 @@ RZ_API bool rz_serialize_core_seek_load(RZ_NONNULL Sdb *db, RZ_NONNULL RzCore *c out_free_list: free(ctx.current_key); - ls_free(db_list); + rz_pvector_free(db_items); out_free_parser: rz_key_parser_free(seek_parser); return ret; diff --git a/librz/core/tui/classes.c b/librz/core/tui/classes.c index 0e34faa3bc7..8952fd48d0a 100644 --- a/librz/core/tui/classes.c +++ b/librz/core/tui/classes.c @@ -435,11 +435,8 @@ static void analysis_class_print(RzAnalysis *analysis, const char *class_name) { } } -static const char *show_analysis_classes(RzCore *core, char mode, int *idx, SdbList *list, const char *class_name) { +static const char *show_analysis_classes(RzCore *core, char mode, int *idx, RzPVector /**/ *classes, const char *class_name) { bool show_color = rz_config_get_i(core->config, "scr.color"); - SdbListIter *iter; - SdbKv *kv; - int i = 0; int skip = *idx - 10; const char *cur_class = NULL; rz_cons_printf("[hjkl_/Cfm]> analysis classes:\n\n"); @@ -449,11 +446,13 @@ static const char *show_analysis_classes(RzCore *core, char mode, int *idx, SdbL return class_name; } - ls_foreach (list, iter, kv) { + int i; + void **iter; + rz_pvector_enumerate (classes, iter, i) { + SdbKv *kv = *iter; if (*idx > 10) { skip--; if (skip > 0) { - i++; continue; } } @@ -474,8 +473,6 @@ static const char *show_analysis_classes(RzCore *core, char mode, int *idx, SdbL } else { rz_cons_printf("%s %02d %s\n", (i == *idx) ? ">>" : "- ", i, class_name); } - - i++; } return cur_class; @@ -487,13 +484,13 @@ static const char *show_analysis_classes(RzCore *core, char mode, int *idx, SdbL RZ_IPI int rz_core_visual_analysis_classes(RzCore *core) { int ch, index = 0; char command[1024]; - SdbList *list = rz_analysis_class_get_all(core->analysis, true); + RzPVector *classes = rz_analysis_class_get_all(core->analysis, true); int oldcur = 0; char mode = ' '; const char *class_name = ""; RzLine *line = core->cons->line; - if (rz_list_empty(list)) { + if (rz_pvector_empty(classes)) { rz_cons_message("No Classes"); goto cleanup; } @@ -501,7 +498,7 @@ RZ_IPI int rz_core_visual_analysis_classes(RzCore *core) { int cols; rz_cons_clear00(); - class_name = show_analysis_classes(core, mode, &index, list, class_name); + class_name = show_analysis_classes(core, mode, &index, classes, class_name); /* update terminal size */ (void)rz_cons_get_size(&cols); @@ -518,18 +515,18 @@ RZ_IPI int rz_core_visual_analysis_classes(RzCore *core) { break; case 'J': index += 10; - if (index >= list->length) { - index = list->length - 1; + if (index >= rz_pvector_len(classes)) { + index = rz_pvector_len(classes) - 1; } break; case 'j': - if (++index >= list->length) { + if (++index >= rz_pvector_len(classes)) { index = 0; } break; case 'k': if (--index < 0) { - index = list->length - 1; + index = rz_pvector_len(classes) - 1; } break; case 'K': @@ -542,7 +539,7 @@ RZ_IPI int rz_core_visual_analysis_classes(RzCore *core) { index = 0; break; case 'G': - index = list->length - 1; + index = rz_pvector_len(classes) - 1; break; case 'h': case 127: // backspace @@ -596,6 +593,6 @@ RZ_IPI int rz_core_visual_analysis_classes(RzCore *core) { } } cleanup: - ls_free(list); + rz_pvector_free(classes); return true; } diff --git a/librz/debug/dsession.c b/librz/debug/dsession.c index 5ffc0b3fda9..e0035d1ef30 100644 --- a/librz/debug/dsession.c +++ b/librz/debug/dsession.c @@ -460,9 +460,9 @@ RZ_API bool rz_debug_session_save(RzDebugSession *session, const char *path) { if (!v || v->type != t) \ continue -static bool deserialize_memory_cb(void *user, const char *addr, const char *v) { +static bool deserialize_memory_cb(void *user, const SdbKv *kv) { RzJson *child; - char *json_str = strdup(v); + char *json_str = sdbkv_dup_value(kv); if (!json_str) { return true; } @@ -474,6 +474,7 @@ static bool deserialize_memory_cb(void *user, const char *addr, const char *v) { HtUP *memory = user; // Insert a new vector into `memory` HtUP at `addr` + ut64 addr = sdb_atoi(sdbkv_key(kv)); RzVector *vmem = rz_vector_new(sizeof(RzDebugChangeMem), NULL, NULL); if (!vmem) { eprintf("Error: failed to allocate RzVector vmem.\n"); @@ -481,7 +482,7 @@ static bool deserialize_memory_cb(void *user, const char *addr, const char *v) { rz_json_free(reg_json); return false; } - ht_up_insert(memory, sdb_atoi(addr), vmem); + ht_up_insert(memory, addr, vmem); // Extract 's into the new vector for (child = reg_json->children.first; child; child = child->next) { @@ -509,9 +510,9 @@ static void deserialize_memory(Sdb *db, HtUP *memory) { sdb_foreach(db, deserialize_memory_cb, memory); } -static bool deserialize_registers_cb(void *user, const char *addr, const char *v) { +static bool deserialize_registers_cb(void *user, const SdbKv *kv) { RzJson *child; - char *json_str = strdup(v); + char *json_str = sdbkv_dup_value(kv); if (!json_str) { return true; } @@ -530,7 +531,7 @@ static bool deserialize_registers_cb(void *user, const char *addr, const char *v free(json_str); return true; } - ht_up_insert(registers, sdb_atoi(addr), vreg); + ht_up_insert(registers, sdb_atoi(sdbkv_key(kv)), vreg); // Extract 's into the new vector for (child = reg_json->children.first; child; child = child->next) { @@ -558,9 +559,9 @@ static void deserialize_registers(Sdb *db, HtUP *registers) { sdb_foreach(db, deserialize_registers_cb, registers); } -static bool deserialize_checkpoints_cb(void *user, const char *cnum, const char *v) { +static bool deserialize_checkpoints_cb(void *user, const SdbKv *kv) { const RzJson *child; - char *json_str = strdup(v); + char *json_str = sdbkv_dup_value(kv); if (!json_str) { return true; } @@ -572,7 +573,7 @@ static bool deserialize_checkpoints_cb(void *user, const char *cnum, const char RzVector *checkpoints = user; RzDebugCheckpoint checkpoint = { 0 }; - checkpoint.cnum = (int)sdb_atoi(cnum); + checkpoint.cnum = (int)sdb_atoi(sdbkv_key(kv)); // Extract RzRegArena's from "registers" const RzJson *regs_json = rz_json_get(chkpt_json, "registers"); diff --git a/librz/flag/serialize_flag.c b/librz/flag/serialize_flag.c index fce4d7b9ea8..fb4621a5c53 100644 --- a/librz/flag/serialize_flag.c +++ b/librz/flag/serialize_flag.c @@ -36,9 +36,9 @@ RZ_API void rz_serialize_flag_zones_save(RZ_NONNULL Sdb *db, RZ_NONNULL RzList / } } -static bool zone_load_cb(void *user, const char *k, const char *v) { +static bool zone_load_cb(void *user, const SdbKv *kv) { RzList *list = user; - char *json_str = strdup(v); + char *json_str = sdbkv_dup_value(kv); if (!json_str) { return true; } @@ -55,7 +55,7 @@ static bool zone_load_cb(void *user, const char *k, const char *v) { if (!item) { goto beach; } - item->name = strdup(k); + item->name = strdup(sdbkv_key(kv)); if (!item->name) { free(item); goto beach; @@ -142,10 +142,10 @@ typedef struct { RzKeyParser *parser; } FlagLoadCtx; -static bool flag_load_cb(void *user, const char *k, const char *v) { +static bool flag_load_cb(void *user, const SdbKv *kv) { FlagLoadCtx *ctx = user; - char *json_str = strdup(v); + char *json_str = sdbkv_dup_value(kv); if (!json_str) { return true; } @@ -220,7 +220,7 @@ static bool flag_load_cb(void *user, const char *k, const char *v) { goto beach; } - RzFlagItem *item = rz_flag_set(ctx->flag, k, proto.offset, proto.size); + RzFlagItem *item = rz_flag_set(ctx->flag, sdbkv_key(kv), proto.offset, proto.size); if (proto.realname) { rz_flag_item_set_realname(item, proto.realname); } diff --git a/librz/flag/tags.c b/librz/flag/tags.c index effc17a9948..a2f2d0e67c2 100644 --- a/librz/flag/tags.c +++ b/librz/flag/tags.c @@ -12,17 +12,17 @@ RZ_API void rz_flag_tags_set(RzFlag *f, const char *name, const char *words) { RZ_API RZ_OWN RzList /**/ *rz_flag_tags_list(RzFlag *f) { rz_return_val_if_fail(f, NULL); RzList *res = rz_list_newf(free); - SdbList *o = sdb_foreach_list(f->tags, false); - SdbListIter *iter; - SdbKv *kv; - ls_foreach (o, iter, kv) { + RzPVector *items = sdb_get_items(f->tags, false); + void **iter; + rz_pvector_foreach (items, iter) { + SdbKv *kv = *iter; const char *tag = sdbkv_key(kv); if (strlen(tag) < 5) { continue; } rz_list_append(res, (void *)strdup(tag + 4)); } - ls_free(o); + rz_pvector_free(items); return res; } diff --git a/librz/include/rz_analysis.h b/librz/include/rz_analysis.h index 9ce050131c6..d8a47669d3a 100644 --- a/librz/include/rz_analysis.h +++ b/librz/include/rz_analysis.h @@ -2294,7 +2294,7 @@ RZ_API void rz_analysis_class_recover_all(RzAnalysis *analysis); RZ_API RzAnalysisClassErr rz_analysis_class_create(RzAnalysis *analysis, const char *name); RZ_API void rz_analysis_class_delete(RzAnalysis *analysis, const char *name); RZ_API bool rz_analysis_class_exists(RzAnalysis *analysis, const char *name); -RZ_API SdbList *rz_analysis_class_get_all(RzAnalysis *analysis, bool sorted); +RZ_API RZ_OWN RzPVector /**/ *rz_analysis_class_get_all(RzAnalysis *analysis, bool sorted); RZ_API void rz_analysis_class_foreach(RzAnalysis *analysis, SdbForeachCallback cb, void *user); RZ_API RzAnalysisClassErr rz_analysis_class_rename(RzAnalysis *analysis, const char *old_name, const char *new_name); diff --git a/librz/syscall/syscall.c b/librz/syscall/syscall.c index f5497d57f73..ff408c385c2 100644 --- a/librz/syscall/syscall.c +++ b/librz/syscall/syscall.c @@ -143,16 +143,15 @@ static inline bool sysregs_reload_needed(RzSyscall *s, const char *arch, int bit static bool sdb_load_sysregs(RzSysregsDB *sysregdb, Sdb *sdb) { rz_return_val_if_fail(sysregdb && sdb, false); - RzSysregItem *sysregitem; - SdbKv *kv; - SdbListIter *iter; - SdbList *l = sdb_foreach_list(sdb, false); - char *argument_key, *comment, *name; - ls_foreach (l, iter, kv) { + + void **iter; + RzPVector *items = sdb_get_items(sdb, false); + rz_pvector_foreach (items, iter) { + SdbKv *kv = *iter; if (!strcmp(sdbkv_value(kv), "mmio") || !strcmp(sdbkv_value(kv), "reg")) { - name = sdbkv_key(kv); - sysregitem = rz_sysreg_item_new(name); - argument_key = rz_str_newf("%s.address", name); + const char *name = sdbkv_key(kv); + RzSysregItem *sysregitem = rz_sysreg_item_new(name); + char *argument_key = rz_str_newf("%s.address", name); if (!argument_key) { rz_sysreg_item_free(sysregitem); return false; @@ -165,15 +164,15 @@ static bool sdb_load_sysregs(RzSysregsDB *sysregdb, Sdb *sdb) { } argument_key = rz_str_newf("%s.comment", name); - comment = sdb_get(sdb, argument_key, NULL); + char *comment = sdb_get(sdb, argument_key, NULL); free(argument_key); - sysregitem->type = strdup(sdbkv_value(kv)); + sysregitem->type = sdbkv_dup_value(kv); sysregitem->comment = comment; ht_up_insert(sysregdb->port, address, sysregitem); } } - ls_free(l); + rz_pvector_free(items); return true; } @@ -393,10 +392,10 @@ RZ_API const char *rz_syscall_get_i(RzSyscall *s, int num, int swi) { return sdb_const_get(s->db, foo, 0); } -static bool callback_list(void *u, const char *k, const char *v) { +static bool callback_list(void *u, const SdbKv *kv) { RzList *list = (RzList *)u; - if (!strchr(k, '.')) { - RzSyscallItem *si = rz_syscall_item_new_from_string(k, v); + if (!strchr(sdbkv_key(kv), '.')) { + RzSyscallItem *si = rz_syscall_item_new_from_string(sdbkv_key(kv), sdbkv_value(kv)); if (!si) { return true; } diff --git a/librz/type/serialize_functions.c b/librz/type/serialize_functions.c index 966f7c6d804..6b24fbd2a23 100644 --- a/librz/type/serialize_functions.c +++ b/librz/type/serialize_functions.c @@ -127,8 +127,8 @@ static RzCallable *get_callable_type(RzTypeDB *typedb, Sdb *sdb, const char *nam return NULL; } -static bool filter_func(void *user, const char *k, const char *v) { - return !strcmp(v, "func"); +static bool filter_func(void *user, const SdbKv *kv) { + return sdbkv_value_len(kv) == 4 && !strcmp(sdbkv_value(kv), "func"); } static bool sdb_load_callables(RzTypeDB *typedb, Sdb *sdb) { @@ -137,20 +137,19 @@ static bool sdb_load_callables(RzTypeDB *typedb, Sdb *sdb) { if (!type_str_cache) { return false; } - RzCallable *callable; - SdbKv *kv; - SdbListIter *iter; - SdbList *l = sdb_foreach_list_filter(sdb, filter_func, false); - ls_foreach (l, iter, kv) { + void **iter; + RzPVector *items = sdb_get_items_filter(sdb, filter_func, NULL, false); + rz_pvector_foreach (items, iter) { + SdbKv *kv = *iter; // eprintf("loading function: \"%s\"\n", sdbkv_key(kv)); - callable = get_callable_type(typedb, sdb, sdbkv_key(kv), type_str_cache); + RzCallable *callable = get_callable_type(typedb, sdb, sdbkv_key(kv), type_str_cache); if (callable) { ht_sp_update(typedb->callables, callable->name, callable); RZ_LOG_DEBUG("inserting the \"%s\" callable type\n", callable->name); } } ht_sp_free(type_str_cache); - ls_free(l); + rz_pvector_free(items); return true; } diff --git a/librz/type/serialize_types.c b/librz/type/serialize_types.c index 45dfb98ae13..e285cf3fc72 100644 --- a/librz/type/serialize_types.c +++ b/librz/type/serialize_types.c @@ -319,10 +319,10 @@ static TypeFormatPair *get_atomic_type(RzTypeDB *typedb, Sdb *sdb, const char *s bool sdb_load_base_types(RzTypeDB *typedb, Sdb *sdb) { rz_return_val_if_fail(typedb && sdb, false); - SdbKv *kv; - SdbListIter *iter; - SdbList *l = sdb_foreach_list(sdb, false); - ls_foreach (l, iter, kv) { + void **iter; + RzPVector *items = sdb_get_items(sdb, false); + rz_pvector_foreach (items, iter) { + SdbKv *kv = *iter; TypeFormatPair *tpair = NULL; if (!strcmp(sdbkv_value(kv), "struct")) { tpair = get_struct_type(typedb, sdb, sdbkv_key(kv)); @@ -351,7 +351,7 @@ bool sdb_load_base_types(RzTypeDB *typedb, Sdb *sdb) { } free(tpair); } - ls_free(l); + rz_pvector_free(items); return true; } diff --git a/librz/util/sdb/src/diff.c b/librz/util/sdb/src/diff.c index 3dd0fed2543..5ef8969e1a3 100644 --- a/librz/util/sdb/src/diff.c +++ b/librz/util/sdb/src/diff.c @@ -76,9 +76,9 @@ typedef struct sdb_diff_kv_cb_ctx { bool add; } SdbDiffKVCbCtx; -static bool sdb_diff_report_kv_cb(void *user, const char *k, const char *v) { +static bool sdb_diff_report_kv_cb(void *user, const SdbKv *kv) { const SdbDiffKVCbCtx *ctx = user; - sdb_diff_report_kv(ctx->ctx, k, v, ctx->add); + sdb_diff_report_kv(ctx->ctx, sdbkv_key(kv), sdbkv_value(kv), ctx->add); return true; } @@ -98,8 +98,10 @@ static void sdb_diff_report(SdbDiffCtx *ctx, Sdb *sdb, bool add) { sdb_foreach(sdb, sdb_diff_report_kv_cb, &cb_ctx); } -static bool sdb_diff_kv_cb(void *user, const char *k, const char *v) { +static bool sdb_diff_kv_cb(void *user, const SdbKv *kv) { const SdbDiffKVCbCtx *ctx = user; + const char *k = sdbkv_key(kv); + const char *v = sdbkv_value(kv); Sdb *other = ctx->add ? ctx->ctx->a : ctx->ctx->b; const char *other_val = sdb_const_get(other, k, NULL); if (!other_val || !*other_val) { diff --git a/librz/util/sdb/src/main.c b/librz/util/sdb/src/main.c index f486c873896..8c6d87d8607 100644 --- a/librz/util/sdb/src/main.c +++ b/librz/util/sdb/src/main.c @@ -140,7 +140,6 @@ static void synchronize(RZ_UNUSED int sig) { static int sdb_grep_dump(const char *dbname, int fmt, bool grep, const char *expgrep) { - char *v, k[SDB_CDB_MAX_KEY] = { 0 }; // local db beacuse is readonly and we dont need to finalize in case of ^C Sdb *db = sdb_new(NULL, dbname, 0); if (!db) { @@ -148,9 +147,11 @@ static int sdb_grep_dump(const char *dbname, int fmt, bool grep, } sdb_config(db, options); sdb_dump_begin(db); - while (sdb_dump_dupnext(db, k, &v, NULL)) { + SdbKv it = { 0 }; + while (sdb_dump_next(db, &it)) { + const char *k = sdbkv_key(&it); + const char *v = sdbkv_value(&it); if (grep && !strstr(k, expgrep) && !strstr(v, expgrep)) { - free(v); continue; } switch (fmt) { @@ -161,7 +162,6 @@ static int sdb_grep_dump(const char *dbname, int fmt, bool grep, printf("%s=%s\n", k, v); break; } - free(v); } switch (fmt) { case MODE_ZERO: diff --git a/librz/util/sdb/src/query.c b/librz/util/sdb/src/query.c index dad9ab0316e..35d121cd3f4 100644 --- a/librz/util/sdb/src/query.c +++ b/librz/util/sdb/src/query.c @@ -88,23 +88,25 @@ typedef struct { char *root; } ForeachListUser; -static bool foreach_list_cb(void *user, const char *k, const char *v) { +static bool foreach_list_cb(void *user, const SdbKv *kv) { ForeachListUser *rlu = user; - char *line, *root; - int rlen, klen, vlen; - ut8 *v2 = NULL; if (!rlu) { return false; } - root = rlu->root; - klen = strlen(k); + char *line; + int rlen; + ut8 *v2 = NULL; + char *root = rlu->root; + const char *k = sdbkv_key(kv); + ut32 klen = sdbkv_key_len(kv); + const char *v = sdbkv_value(kv); + ut32 vlen = sdbkv_value_len(kv); if (rlu->encode) { v2 = sdb_decode(v, NULL); if (v2) { v = (const char *)v2; } } - vlen = strlen(v); if (root) { rlen = strlen(root); line = malloc(klen + vlen + rlen + 3); @@ -318,13 +320,13 @@ RZ_API char *sdb_querys(Sdb *r, char *buf, size_t len, const char *_cmd) { goto fail; } else if (!strcmp(cmd, "*")) { ForeachListUser user = { out, encode, NULL }; - SdbList *list = sdb_foreach_list(s, true); - SdbListIter *iter; - SdbKv *kv; - ls_foreach (list, iter, kv) { - foreach_list_cb(&user, sdbkv_key(kv), sdbkv_value(kv)); + RzPVector *items = sdb_get_items(s, true); + void **iter; + rz_pvector_foreach (items, iter) { + SdbKv *kv = *iter; + foreach_list_cb(&user, kv); } - ls_free(list); + rz_pvector_free(items); goto fail; } } @@ -357,16 +359,16 @@ RZ_API char *sdb_querys(Sdb *r, char *buf, size_t len, const char *_cmd) { } } else if (*cmd == '~') { // delete if (cmd[1] == '~') { // grep - SdbKv *kv; - SdbListIter *li; - SdbList *l = sdb_foreach_match(s, cmd + 2, false); - ls_foreach (l, li, kv) { + void **it; + RzPVector *items = sdb_get_items_match(s, cmd + 2, false); + rz_pvector_foreach (items, it) { + SdbKv *kv = *it; strbuf_append(out, sdbkv_key(kv), 0); strbuf_append(out, "=", 0); strbuf_append(out, sdbkv_value(kv), 1); } fflush(stdout); - ls_free(l); + rz_pvector_free(items); } else { d = 1; sdb_unset_like(s, cmd + 1); diff --git a/librz/util/sdb/src/sdb.c b/librz/util/sdb/src/sdb.c index 6744adde48c..7c0c07b7599 100644 --- a/librz/util/sdb/src/sdb.c +++ b/librz/util/sdb/src/sdb.c @@ -7,6 +7,8 @@ #include #include #include +#include +#include #include "sdb.h" #include "sdb_private.h" @@ -124,8 +126,8 @@ RZ_API void sdb_file(Sdb *s, const char *dir) { } } -static bool sdb_merge_cb(void *user, const char *k, const char *v) { - sdb_set(user, k, v, 0); +static bool sdb_merge_cb(void *user, const SdbKv *kv) { + sdb_set(user, sdbkv_key(kv), sdbkv_value(kv), 0); return true; } @@ -136,8 +138,9 @@ RZ_API bool sdb_merge(Sdb *d, Sdb *s) { RZ_API bool sdb_isempty(Sdb *s) { if (s) { if (s->db.fd != -1) { + SdbKv it = { 0 }; sdb_dump_begin(s); - while (sdb_dump_hasnext(s)) { + while (sdb_dump_next(s, &it)) { return false; } } @@ -152,8 +155,9 @@ RZ_API int sdb_count(Sdb *s) { int count = 0; if (s) { if (s->db.fd != -1) { + SdbKv it = { 0 }; sdb_dump_begin(s); - while (sdb_dump_hasnext(s)) { + while (sdb_dump_next(s, &it)) { count++; } } @@ -352,7 +356,7 @@ RZ_API bool sdb_exists(Sdb *s, const char *key) { } SdbKv *kv = (SdbKv *)sdb_ht_find_kvp(s->ht, key, &found); if (found && kv) { - char *v = sdbkv_value(kv); + const char *v = sdbkv_value(kv); return v && *v; } if (s->fd == -1) { @@ -456,7 +460,7 @@ static bool match(const char *str, const char *expr) { return strstr(str, expr); } -RZ_API bool sdbkv_match(SdbKv *kv, const char *expr) { +RZ_API bool sdbkv_match(const SdbKv *kv, const char *expr) { // TODO: add syntax to negate condition // TODO: add syntax to OR k/v instead of AND // [^]str[$]=[^]str[$] @@ -508,12 +512,28 @@ RZ_API SdbKv *sdbkv_new2(const char *k, int kl, const char *v, int vl) { return kv; } -RZ_API void sdbkv_free(SdbKv *kv) { - if (kv) { - free(sdbkv_key(kv)); - free(sdbkv_value(kv)); - RZ_FREE(kv); +RZ_API void sdbkv_free(RZ_NULLABLE SdbKv *kv) { + if (!kv) { + return; } + free(kv->base.key); + free(kv->base.value); + free(kv); +} + +/** + * Create a duplicate of SdbKv + */ +static inline RZ_OWN SdbKv *sdbkv_dup(RZ_NONNULL const SdbKv *kv) { + return sdbkv_new2(sdbkv_key(kv), sdbkv_key_len(kv), sdbkv_value(kv), sdbkv_value_len(kv)); +} + +/** + * \brief Create a duplicate of SdbKv value string + */ +RZ_API RZ_OWN char *sdbkv_dup_value(RZ_NONNULL const SdbKv *kv) { + rz_return_val_if_fail(kv, NULL); + return rz_mem_dup(sdbkv_value(kv), sdbkv_value_len(kv) + 1); } static ut32 sdb_set_internal(Sdb *s, const char *key, char *val, int owned, ut32 cas) { @@ -596,114 +616,132 @@ RZ_API int sdb_set(Sdb *s, const char *key, const char *val, ut32 cas) { return sdb_set_internal(s, key, (char *)val, 0, cas); } -static bool sdb_foreach_list_cb(void *user, const char *k, const char *v) { - SdbList *list = (SdbList *)user; - SdbKv *kv = RZ_NEW0(SdbKv); - /* seems like some k/v are constructed in the stack and cant be used after returning */ - kv->base.key = strdup(k); - kv->base.value = strdup(v); - ls_append(list, kv); - return 1; +static bool get_items_cb(void *user, const SdbKv *kv) { + RzPVector *vec = (RzPVector *)user; + SdbKv *dup = sdbkv_dup(kv); + if (!dup) { + return false; + } + if (!rz_pvector_push(vec, dup)) { + sdbkv_free(dup); + return false; + } + return true; } -static int __cmp_asc(const void *a, const void *b) { +static int __cmp_asc(const void *a, const void *b, RZ_UNUSED void *user) { const SdbKv *ka = a, *kb = b; return strcmp(sdbkv_key(ka), sdbkv_key(kb)); } -RZ_API SdbList *sdb_foreach_list(Sdb *s, bool sorted) { - SdbList *list = ls_newf((SdbListFree)sdbkv_free); - sdb_foreach(s, sdb_foreach_list_cb, list); +/** + * \brief Get all key-value pairs in DB + * \param s DB + * \param sorted If set to true sort the resulting vector by key in lexicographic order + */ +RZ_API RZ_OWN RzPVector /**/ *sdb_get_items(RZ_NONNULL Sdb *s, bool sorted) { + rz_return_val_if_fail(s, NULL); + + RzPVector *vec = rz_pvector_new((RzPVectorFree)sdbkv_free); + if (!vec) { + return NULL; + } + sdb_foreach(s, get_items_cb, vec); if (sorted) { - ls_sort(list, __cmp_asc); + rz_pvector_sort(vec, __cmp_asc, NULL); } - return list; + return vec; } -struct foreach_list_filter_t { +struct get_items_filter_ctx { SdbForeachCallback filter; - SdbList *list; + RzPVector /**/ *vec; void *user; }; -static bool sdb_foreach_list_filter_cb(void *user, const char *k, const char *v) { - struct foreach_list_filter_t *u = (struct foreach_list_filter_t *)user; - SdbList *list = u->list; - SdbKv *kv = NULL; +static bool get_items_filter_cb(void *user, const SdbKv *kv) { + struct get_items_filter_ctx *ctx = (struct get_items_filter_ctx *)user; - if (!u->filter || u->filter(u->user, k, v)) { - kv = RZ_NEW0(SdbKv); - if (!kv) { - goto err; - } - kv->base.key = strdup(k); - kv->base.value = strdup(v); - if (!kv->base.key || !kv->base.value) { - goto err; - } - ls_append(list, kv); + if (!ctx->filter(ctx->user, kv)) { + return true; + } + SdbKv *dup = sdbkv_dup(kv); + if (!dup) { + return false; + } + if (!rz_pvector_push(ctx->vec, dup)) { + sdbkv_free(dup); + return false; } return true; -err: - sdbkv_free(kv); - return false; } -RZ_API SdbList *sdb_foreach_list_filter_user(Sdb *s, SdbForeachCallback filter, bool sorted, void *user) { - struct foreach_list_filter_t u; - SdbList *list = ls_newf((SdbListFree)sdbkv_free); +/** + * \brief Get key-value pairs in DB matching filter \p filter + * \param s DB + * \param filter Filter callback, a key-value pair is skipped if callback return false + * \param user User data which is passed to filter callback \p cb + * \param sorted If set to true sort the resulting vector by key in lexicographic order + */ +RZ_API RZ_OWN RzPVector /**/ *sdb_get_items_filter(RZ_NONNULL Sdb *s, RZ_NONNULL SdbForeachCallback filter, RZ_NULLABLE void *user, bool sorted) { + rz_return_val_if_fail(s && filter, NULL); - if (!list) { + RzPVector *vec = rz_pvector_new((RzPVectorFree)sdbkv_free); + if (!vec) { return NULL; } - u.filter = filter; - u.list = list; - u.user = user; - sdb_foreach(s, sdb_foreach_list_filter_cb, &u); + struct get_items_filter_ctx ctx = { + .filter = filter, + .vec = vec, + .user = user, + }; + sdb_foreach(s, get_items_filter_cb, &ctx); if (sorted) { - ls_sort(list, __cmp_asc); + rz_pvector_sort(vec, __cmp_asc, NULL); } - return list; + return vec; } -RZ_API SdbList *sdb_foreach_list_filter(Sdb *s, SdbForeachCallback filter, bool sorted) { - return sdb_foreach_list_filter_user(s, filter, sorted, NULL); -} - -typedef struct { +struct get_items_match_ctx { const char *expr; - SdbList *list; - bool single; -} _match_sdb_user; - -static bool sdb_foreach_match_cb(void *user, const char *k, const char *v) { - _match_sdb_user *o = (_match_sdb_user *)user; - SdbKv tkv = { .base.key = (char *)k, .base.value = (char *)v }; - if (sdbkv_match(&tkv, o->expr)) { - SdbKv *kv = RZ_NEW0(SdbKv); - kv->base.key = strdup(k); - kv->base.value = strdup(v); - ls_append(o->list, kv); - if (o->single) { - return false; - } + RzPVector /**/ *vec; +}; + +static bool get_items_match_cb(void *user, const SdbKv *kv) { + struct get_items_match_ctx *ctx = (struct get_items_match_ctx *)user; + if (sdbkv_match(kv, ctx->expr)) { + return true; + } + SdbKv *dup = sdbkv_dup(kv); + if (!dup) { + return false; + } + if (!rz_pvector_push(ctx->vec, dup)) { + sdbkv_free(dup); + return false; } return true; } -RZ_API SdbList *sdb_foreach_match(Sdb *s, const char *expr, bool single) { - SdbList *list = ls_newf((SdbListFree)sdbkv_free); - _match_sdb_user o = { expr, list, single }; - sdb_foreach(s, sdb_foreach_match_cb, &o); - return list; -} +/** + * \brief Get key-value pairs in DB with keys matching expression \p expr + * \param s DB + * \param expr Expression string + * \param sorted If set to true sort the resulting vector by key in lexicographic order + */ +RZ_API RZ_OWN RzPVector /**/ *sdb_get_items_match(RZ_NONNULL Sdb *s, RZ_NONNULL const char *expr, bool sorted) { + rz_return_val_if_fail(s && expr, NULL); -static int getbytes(Sdb *s, char *b, int len) { - if (!cdb_read(&s->db, b, len, s->pos)) { - return -1; + RzPVector *vec = rz_pvector_new((RzPVectorFree)sdbkv_free); + if (!vec) { + return NULL; } - s->pos += len; - return len; + struct get_items_match_ctx ctx = { expr, vec }; + sdb_foreach(s, get_items_match_cb, &ctx); + if (sorted) { + rz_pvector_sort(vec, __cmp_asc, NULL); + } + return vec; } static bool sdb_foreach_end(Sdb *s, bool result) { @@ -711,53 +749,47 @@ static bool sdb_foreach_end(Sdb *s, bool result) { return result; } -static bool sdb_foreach_cdb(Sdb *s, SdbForeachCallback cb, SdbForeachCallback cb2, void *user) { - char *v = NULL; - char k[SDB_CDB_MAX_KEY] = { 0 }; - bool found; +/** + * Apply callback \p cb to every key-value pair in cdb file. + * Keys which are presented in HT are skipped. + */ +static bool sdb_foreach_cdb(Sdb *s, SdbForeachCallback cb, void *user) { + SdbKv it = { 0 }; sdb_dump_begin(s); - while (sdb_dump_dupnext(s, k, &v, NULL)) { - SdbKv *kv = sdb_ht_find_kvp(s->ht, k, &found); - if (found) { - free(v); - if (kv && sdbkv_key(kv) && sdbkv_value(kv)) { - if (!cb(user, sdbkv_key(kv), sdbkv_value(kv))) { - return false; - } - if (cb2 && !cb2(user, k, sdbkv_value(kv))) { - return false; - } - } - } else { - if (!cb(user, k, v)) { - free(v); - return false; - } - free(v); + while (sdb_dump_next(s, &it)) { + if (sdb_ht_find_kvp(s->ht, sdbkv_key(&it), NULL)) { + continue; + } + if (!cb(user, &it)) { + return false; } } return true; } -RZ_API bool sdb_foreach(Sdb *s, SdbForeachCallback cb, void *user) { - if (!s) { - return false; - } +/** + * \brief Apply callback \p cb to every key-value pair in DB \p s + * \param s DB + * \param cb Callback, iteration is stopped if callback return false + * \param user User data which is passed to callback \p cb + */ +RZ_API bool sdb_foreach(RZ_NONNULL Sdb *s, RZ_NONNULL SdbForeachCallback cb, RZ_NULLABLE void *user) { + rz_return_val_if_fail(s && cb, false); + s->depth++; - bool result = sdb_foreach_cdb(s, cb, NULL, user); + bool result = sdb_foreach_cdb(s, cb, user); if (!result) { return sdb_foreach_end(s, false); } - ut32 i; - for (i = 0; i < s->ht->size; ++i) { + for (ut32 i = 0; i < s->ht->size; ++i) { HtSSBucket *bt = &s->ht->table[i]; SdbKv *kv; ut32 j, count; BUCKET_FOREACH_SAFE(s->ht, bt, j, count, kv) { if (kv && sdbkv_value(kv) && *sdbkv_value(kv)) { - if (!cb(user, sdbkv_key(kv), sdbkv_value(kv))) { + if (!cb(user, kv)) { return sdb_foreach_end(s, false); } } @@ -766,19 +798,10 @@ RZ_API bool sdb_foreach(Sdb *s, SdbForeachCallback cb, void *user) { return sdb_foreach_end(s, true); } -static bool _insert_into_disk(void *user, const char *key, const char *value) { +static bool _insert_into_disk(void *user, const SdbKv *kv) { Sdb *s = (Sdb *)user; if (s) { - sdb_disk_insert(s, key, value); - return true; - } - return false; -} - -static bool _remove_afer_insert(void *user, const char *k, const char *v) { - Sdb *s = (Sdb *)user; - if (s) { - sdb_ht_delete(s->ht, k); + sdb_disk_insert(s, sdbkv_key(kv), sdbkv_value(kv)); return true; } return false; @@ -791,7 +814,7 @@ RZ_API bool sdb_sync(Sdb *s) { if (!s || !sdb_disk_create(s)) { return false; } - result = sdb_foreach_cdb(s, _insert_into_disk, _remove_afer_insert, s); + result = sdb_foreach_cdb(s, _insert_into_disk, s); if (!result) { return false; } @@ -815,25 +838,21 @@ RZ_API bool sdb_sync(Sdb *s) { return true; } -RZ_API void sdb_dump_begin(Sdb *s) { - if (s->fd != -1) { - s->pos = sizeof(((struct cdb_make *)0)->final); - seek_set(s->fd, s->pos); - } else { - s->pos = 0; - } -} +RZ_API void sdb_dump_begin(RZ_NONNULL Sdb *s) { + rz_return_if_fail(s); -RZ_API bool sdb_dump_hasnext(Sdb *s) { - ut32 k, v; - if (!cdb_getkvlen(&s->db, &k, &v, s->pos)) { - return false; + s->pos = 0; + s->dump_end_pos = 0; + if (s->fd == -1) { + return; } - if (k < 1 || v < 1) { - return false; + ut8 buf[4]; + if (!cdb_read(&s->db, (char *)buf, 4, 0)) { + return; } - s->pos += k + v + 4; - return true; + s->dump_end_pos = rz_read_le32(buf); + s->pos = sizeof(((struct cdb_make *)0)->final); + seek_set(s->fd, s->pos); } RZ_API bool sdb_stats(Sdb *s, ut32 *disk, ut32 *mem) { @@ -843,8 +862,9 @@ RZ_API bool sdb_stats(Sdb *s, ut32 *disk, ut32 *mem) { if (disk) { ut32 count = 0; if (s->fd != -1) { + SdbKv it = { 0 }; sdb_dump_begin(s); - while (sdb_dump_hasnext(s)) { + while (sdb_dump_next(s, &it)) { count++; } } @@ -856,49 +876,43 @@ RZ_API bool sdb_stats(Sdb *s, ut32 *disk, ut32 *mem) { return disk || mem; } -// TODO: make it static? internal api? -RZ_API bool sdb_dump_dupnext(Sdb *s, char *key, char **value, int *_vlen) { - ut32 vlen = 0, klen = 0; - if (value) { - *value = NULL; - } - if (_vlen) { - *_vlen = 0; +/** + * \brief Get the next key-value pair + * + * Modifying of key/value strings is forbidden. + */ +RZ_API bool sdb_dump_next(RZ_NONNULL Sdb *s, RZ_OUT RZ_NONNULL SdbKv *kv) { + rz_return_val_if_fail(s && kv, false); + + if (!s->db.map || s->pos >= s->dump_end_pos) { + return false; } + // klen/vlen include trailing NUL + ut32 klen, vlen; if (!cdb_getkvlen(&s->db, &klen, &vlen, s->pos)) { return false; } - s->pos += 4; - if (klen < 1 || vlen < 1) { + if (klen < SDB_CDB_MIN_KEY || vlen < SDB_CDB_MIN_VALUE) { return false; } - if (_vlen) { - *_vlen = vlen; - } - if (key) { - key[0] = 0; - if (klen > SDB_CDB_MIN_KEY && klen < SDB_CDB_MAX_KEY) { - if (getbytes(s, key, klen) == -1) { - return 0; - } - key[klen] = 0; - } + s->pos += 4; + + char *key = s->db.map + s->pos; + s->pos += klen; + if (s->pos > s->dump_end_pos || key[klen - 1] != '\0') { + rz_return_val_if_reached(false); } - if (value) { - *value = 0; - if (vlen < SDB_CDB_MAX_VALUE) { - *value = malloc(vlen + 10); - if (!*value) { - return false; - } - if (getbytes(s, *value, vlen) == -1) { - free(*value); - *value = NULL; - return false; - } - (*value)[vlen] = 0; - } + + char *value = s->db.map + s->pos; + s->pos += vlen; + if (s->pos > s->dump_end_pos || value[vlen - 1] != '\0') { + rz_return_val_if_reached(false); } + + kv->base.key = key; + kv->base.key_len = klen - 1; + kv->base.value = value; + kv->base.value_len = vlen - 1; return true; } @@ -1049,9 +1063,9 @@ RZ_API void sdb_drain(Sdb *s, Sdb *f) { } } -static bool copy_foreach_cb(void *user, const char *k, const char *v) { +static bool copy_foreach_cb(void *user, const SdbKv *kv) { Sdb *dst = user; - sdb_set(dst, k, v, 0); + sdb_set(dst, sdbkv_key(kv), sdbkv_value(kv), 0); return true; } @@ -1069,10 +1083,10 @@ typedef struct { const char *key; } UnsetCallbackData; -static bool unset_cb(void *user, const char *k, const char *v) { +static bool unset_cb(void *user, const SdbKv *kv) { UnsetCallbackData *ucd = user; - if (sdb_match(k, ucd->key)) { - sdb_unset(ucd->sdb, k, 0); + if (sdb_match(sdbkv_key(kv), ucd->key)) { + sdb_unset(ucd->sdb, sdbkv_key(kv), 0); } return true; } @@ -1081,73 +1095,3 @@ RZ_API int sdb_unset_like(Sdb *s, const char *k) { UnsetCallbackData ucd = { s, k }; return sdb_foreach(s, unset_cb, &ucd); } - -typedef struct { - Sdb *sdb; - const char *key; - const char *val; - SdbForeachCallback cb; - const char **array; - int array_index; - int array_size; -} LikeCallbackData; - -static bool like_cb(void *user, const char *k, const char *v) { - LikeCallbackData *lcd = user; - if (!user) { - return false; - } - if (k && lcd->key && !sdb_match(k, lcd->key)) { - return true; - } - if (v && lcd->val && !sdb_match(v, lcd->val)) { - return true; - } - if (lcd->array) { - int idx = lcd->array_index; - int newsize = lcd->array_size + sizeof(char *) * 2; - const char **newarray = (const char **)realloc((void *)lcd->array, newsize); - if (!newarray) { - return false; - } - lcd->array = newarray; - lcd->array_size = newsize; - // concatenate in array - lcd->array[idx] = k; - lcd->array[idx + 1] = v; - lcd->array[idx + 2] = NULL; - lcd->array[idx + 3] = NULL; - lcd->array_index = idx + 2; - } else { - if (lcd->cb) { - lcd->cb(lcd->sdb, k, v); - } - } - return true; -} - -RZ_API char **sdb_like(Sdb *s, const char *k, const char *v, SdbForeachCallback cb) { - LikeCallbackData lcd = { s, k, v, cb, NULL, 0, 0 }; - if (cb) { - sdb_foreach(s, like_cb, &lcd); - return NULL; - } - if (k && !*k) { - lcd.key = NULL; - } - if (v && !*v) { - lcd.val = NULL; - } - lcd.array_size = sizeof(char *) * 2; - lcd.array = calloc(lcd.array_size, 1); - if (!lcd.array) { - return NULL; - } - lcd.array_index = 0; - sdb_foreach(s, like_cb, &lcd); - if (lcd.array_index == 0) { - free((void *)lcd.array); - return NULL; - } - return (char **)lcd.array; -} diff --git a/librz/util/sdb/src/sdb.h b/librz/util/sdb/src/sdb.h index ae60f3da235..5712e4897a9 100644 --- a/librz/util/sdb/src/sdb.h +++ b/librz/util/sdb/src/sdb.h @@ -9,6 +9,7 @@ extern "C" { #endif #include +#include #include "sdbht.h" #include "ls.h" #include "cdb.h" @@ -17,7 +18,7 @@ extern "C" { /* Key value sizes */ #define SDB_CDB_MIN_VALUE 1 #define SDB_CDB_MAX_VALUE CDB_MAX_VALUE -#define SDB_CDB_MIN_KEY 1 +#define SDB_CDB_MIN_KEY 2 #define SDB_CDB_MAX_KEY CDB_MAX_KEY #if __WINDOWS__ && !__CYGWIN__ @@ -73,6 +74,7 @@ typedef struct sdb_t { HtSS *ht; ut32 eod; ut32 pos; + ut32 dump_end_pos; ///< Used in sdb_dump_next() int fdump; char *ndump; ut64 expire; @@ -110,14 +112,12 @@ RZ_API void sdb_drain(Sdb *, Sdb *); RZ_API void sdb_copy(Sdb *src, Sdb *dst); RZ_API bool sdb_stats(Sdb *s, ut32 *disk, ut32 *mem); -RZ_API bool sdb_dump_hasnext(Sdb *s); -typedef bool (*SdbForeachCallback)(void *user, const char *k, const char *v); -RZ_API bool sdb_foreach(Sdb *s, SdbForeachCallback cb, void *user); -RZ_API SdbList *sdb_foreach_list(Sdb *s, bool sorted); -RZ_API SdbList *sdb_foreach_list_filter_user(Sdb *s, SdbForeachCallback filter, bool sorted, void *user); -RZ_API SdbList *sdb_foreach_list_filter(Sdb *s, SdbForeachCallback filter, bool sorted); -RZ_API SdbList *sdb_foreach_match(Sdb *s, const char *expr, bool sorted); +typedef bool (*SdbForeachCallback)(void *user, const SdbKv *kv); +RZ_API bool sdb_foreach(RZ_NONNULL Sdb *s, RZ_NONNULL SdbForeachCallback cb, RZ_NULLABLE void *user); +RZ_API RZ_OWN RzPVector /**/ *sdb_get_items(RZ_NONNULL Sdb *s, bool sorted); +RZ_API RZ_OWN RzPVector /**/ *sdb_get_items_filter(RZ_NONNULL Sdb *s, RZ_NONNULL SdbForeachCallback filter, RZ_NULLABLE void *user, bool sorted); +RZ_API RZ_OWN RzPVector /**/ *sdb_get_items_match(RZ_NONNULL Sdb *s, RZ_NONNULL const char *expr, bool sorted); RZ_API int sdb_query(Sdb *s, const char *cmd); RZ_API int sdb_queryf(Sdb *s, const char *fmt, ...); @@ -129,7 +129,6 @@ RZ_API bool sdb_exists(Sdb *, const char *key); RZ_API bool sdb_remove(Sdb *, const char *key, ut32 cas); RZ_API int sdb_unset(Sdb *, const char *key, ut32 cas); RZ_API int sdb_unset_like(Sdb *s, const char *k); -RZ_API char **sdb_like(Sdb *s, const char *k, const char *v, SdbForeachCallback cb); // diffing typedef struct sdb_diff_t { @@ -169,7 +168,7 @@ RZ_API int sdb_concat(Sdb *s, const char *key, const char *value, ut32 cas); RZ_API int sdb_uncat(Sdb *s, const char *key, const char *value, ut32 cas); RZ_API int sdb_add(Sdb *s, const char *key, const char *val, ut32 cas); RZ_API bool sdb_sync(Sdb *); -RZ_API void sdbkv_free(SdbKv *kv); +RZ_API void sdbkv_free(RZ_NULLABLE SdbKv *kv); /* num.c */ RZ_API bool sdb_num_exists(Sdb *, const char *key); @@ -199,9 +198,8 @@ RZ_API bool sdb_text_load_buf(Sdb *s, char *buf, size_t sz); RZ_API bool sdb_text_load(Sdb *s, const char *file); /* iterate */ -RZ_API void sdb_dump_begin(Sdb *s); -RZ_API SdbKv *sdb_dump_next(Sdb *s); -RZ_API bool sdb_dump_dupnext(Sdb *s, char *key, char **value, int *_vlen); +RZ_API void sdb_dump_begin(RZ_NONNULL Sdb *s); +RZ_API bool sdb_dump_next(RZ_NONNULL Sdb *s, RZ_OUT RZ_NONNULL SdbKv *kv); /* numeric */ RZ_API char *sdb_itoa(ut64 n, char *s, int base); diff --git a/librz/util/sdb/src/sdbht.h b/librz/util/sdb/src/sdbht.h index 47d8c8a8836..937e5b8093d 100644 --- a/librz/util/sdb/src/sdbht.h +++ b/librz/util/sdb/src/sdbht.h @@ -18,12 +18,12 @@ typedef struct sdb_kv { ut64 expire; } SdbKv; -static inline char *sdbkv_key(const SdbKv *kv) { - return (char *)kv->base.key; +static inline const char *sdbkv_key(const SdbKv *kv) { + return kv->base.key; } -static inline char *sdbkv_value(const SdbKv *kv) { - return (char *)kv->base.value; +static inline const char *sdbkv_value(const SdbKv *kv) { + return kv->base.value; } static inline ut32 sdbkv_key_len(const SdbKv *kv) { @@ -36,7 +36,8 @@ static inline ut32 sdbkv_value_len(const SdbKv *kv) { RZ_API SdbKv *sdbkv_new2(const char *k, int kl, const char *v, int vl); RZ_API SdbKv *sdbkv_new(const char *k, const char *v); -extern RZ_API void sdbkv_free(SdbKv *kv); +extern RZ_API void sdbkv_free(RZ_NULLABLE SdbKv *kv); +RZ_API RZ_OWN char *sdbkv_dup_value(RZ_NONNULL const SdbKv *kv); extern RZ_API ut32 sdb_hash(const char *key); diff --git a/librz/util/sdb/src/text.c b/librz/util/sdb/src/text.c index c1033a56888..dc10d564a43 100644 --- a/librz/util/sdb/src/text.c +++ b/librz/util/sdb/src/text.c @@ -136,11 +136,11 @@ static void write_value(int fd, const char *v) { #undef ESCAPE_LOOP #undef ESCAPE -static bool save_kv_cb(void *user, const char *k, const char *v) { +static bool save_kv_cb(void *user, const SdbKv *kv) { int fd = *(int *)user; - write_key(fd, k); + write_key(fd, sdbkv_key(kv)); write_(fd, "=", 1); - write_value(fd, v); + write_value(fd, sdbkv_value(kv)); write_(fd, "\n", 1); return true; } @@ -152,13 +152,13 @@ static bool text_save(Sdb *s, int fd, bool sort, SdbList *path) { // k=v entries if (sort) { - SdbList *l = sdb_foreach_list(s, true); - SdbKv *kv; - SdbListIter *it; - ls_foreach (l, it, kv) { - save_kv_cb(&fd, sdbkv_key(kv), sdbkv_value(kv)); + RzPVector *items = sdb_get_items(s, true); + void **it; + rz_pvector_foreach (items, it) { + SdbKv *kv = *it; + save_kv_cb(&fd, kv); } - ls_free(l); + rz_pvector_free(items); } else { // This is faster when sorting is not needed. sdb_foreach(s, save_kv_cb, &fd); diff --git a/librz/util/serialize_spaces.c b/librz/util/serialize_spaces.c index a0ac4d6b2a1..7bb1ffd410d 100644 --- a/librz/util/serialize_spaces.c +++ b/librz/util/serialize_spaces.c @@ -45,9 +45,9 @@ RZ_API void rz_serialize_spaces_save(RZ_NONNULL Sdb *db, RZ_NONNULL RzSpaces *sp } } -static bool foreach_space_cb(void *user, const char *k, const char *v) { +static bool foreach_space_cb(void *user, const SdbKv *kv) { RzSpaces *spaces = user; - rz_spaces_add(spaces, k); + rz_spaces_add(spaces, sdbkv_key(kv)); return true; } diff --git a/test/unit/test_analysis_function.c b/test/unit/test_analysis_function.c index f2745d22b9c..e73ebd6c980 100644 --- a/test/unit/test_analysis_function.c +++ b/test/unit/test_analysis_function.c @@ -432,6 +432,42 @@ bool test_rz_analysis_function_set_type() { mu_end; } +bool test_noreturn_functions_list() { + RzAnalysis *analysis = rz_analysis_new(); + + rz_analysis_noreturn_add(analysis, NULL, 0x800800); + + RzList *noret = rz_analysis_noreturn_functions(analysis); + mu_assert_eq(rz_list_length(noret), 1, "Num functions"); + mu_assert_streq(rz_list_first(noret), "0x800800", "Addr"); + rz_list_free(noret); + + rz_analysis_noreturn_drop(analysis, "0x800800"); + rz_analysis_noreturn_add(analysis, NULL, 0xdeadbeeff000bad1); + + noret = rz_analysis_noreturn_functions(analysis); + mu_assert_eq(rz_list_length(noret), 1, "Num functions"); + mu_assert_streq(rz_list_first(noret), "0xdeadbeeff000bad1", "Long addr"); + rz_list_free(noret); + + rz_analysis_noreturn_drop(analysis, "0xdeadbeeff000bad1"); + rz_analysis_noreturn_add(analysis, "foobar", UT64_MAX); + + noret = rz_analysis_noreturn_functions(analysis); + mu_assert_eq(rz_list_length(noret), 1, "Num functions"); + mu_assert_streq(rz_list_first(noret), "foobar", "Name"); + rz_list_free(noret); + + rz_analysis_noreturn_drop(analysis, "foobar"); + + noret = rz_analysis_noreturn_functions(analysis); + mu_assert_eq(rz_list_length(noret), 0, "Num functions"); + rz_list_free(noret); + + rz_analysis_free(analysis); + mu_end; +} + int all_tests() { mu_run_test(test_rz_analysis_function_relocate); mu_run_test(test_rz_analysis_function_labels); @@ -441,6 +477,7 @@ int all_tests() { mu_run_test(test_autonames); mu_run_test(test_initial_underscore); mu_run_test(test_rz_analysis_function_set_type); + mu_run_test(test_noreturn_functions_list); return tests_passed != tests_run; } diff --git a/test/unit/test_sdb_sdb.c b/test/unit/test_sdb_sdb.c index 155a5337334..e570dd0f828 100644 --- a/test/unit/test_sdb_sdb.c +++ b/test/unit/test_sdb_sdb.c @@ -7,11 +7,37 @@ #include #include -static bool foreach_delete_cb(void *user, const char *key, const char *val) { - if (strcmp(key, "bar")) { - sdb_unset(user, key, 0); +bool test_sdb_kv_list(void) { + Sdb *db = sdb_new(NULL, NULL, false); + sdb_set(db, "first__XX", " 2", 0); + sdb_set(db, "second_XXXX", " 4", 0); + sdb_set(db, "third__XXXXX", " 5", 0); + sdb_set(db, "fourth_XXX", " 3", 0); + sdb_set(db, "fifth__X", " 1", 0); + + RzPVector *items = sdb_get_items(db, true); + mu_assert_eq(rz_pvector_len(items), 5, "KV count"); + + size_t idx; + void **iter; + rz_pvector_enumerate (items, iter, idx) { + SdbKv *kv = *iter; + int pos = atoi(sdbkv_value(kv)); + mu_assert_eq(pos, idx + 1, "KV not sorted"); + mu_assert_eq(sdbkv_key_len(kv), idx + 8, "Key len"); + mu_assert_eq(sdbkv_value_len(kv), idx + 2, "Value len"); } - return 1; + + rz_pvector_free(items); + sdb_free(db); + mu_end; +} + +static bool foreach_delete_cb(void *user, const SdbKv *kv) { + if (strcmp(sdbkv_key(kv), "bar")) { + sdb_unset(user, sdbkv_key(kv), 0); + } + return true; } bool test_sdb_foreach_delete(void) { @@ -33,30 +59,30 @@ bool test_sdb_list_delete(void) { sdb_set(db, "foo", "bar", 0); sdb_set(db, "bar", "cow", 0); sdb_set(db, "low", "bar", 0); - SdbList *list = sdb_foreach_list(db, true); - SdbListIter *iter; - SdbKv *kv; - ls_foreach (list, iter, kv) { + RzPVector *items = sdb_get_items(db, true); + void **iter; + rz_pvector_foreach (items, iter) { + SdbKv *kv = *iter; // printf ("--> %s\n", kv->key); - sdb_unset(db, kv->base.key, 0); + sdb_unset(db, sdbkv_key(kv), 0); } - SdbList *list2 = sdb_foreach_list(db, true); - mu_assert("List is empty", !ls_length(list2)); - ls_free(list); - ls_free(list2); + RzPVector *items2 = sdb_get_items(db, true); + mu_assert("List is empty", !rz_pvector_len(items2)); + rz_pvector_free(items); + rz_pvector_free(items2); sdb_free(db); mu_end; } bool test_sdb_list_big(void) { Sdb *db = sdb_new0(); - int i; - for (i = 0; i < 5000; i++) { + for (int i = 0; i < 5000; i++) { sdb_num_set(db, sdb_fmt("%d", i), i + 1, 0); } - SdbList *list = sdb_foreach_list(db, true); + RzPVector *items = sdb_get_items(db, true); + mu_assert_eq(rz_pvector_len(items), 5000, "KV count"); // TODO: verify if its sorted - ls_free(list); + rz_pvector_free(items); sdb_free(db); mu_end; } @@ -70,9 +96,9 @@ bool test_sdb_delete_none(void) { sdb_unset(db, "barnas", 0); sdb_unset(db, "bar", 0); sdb_unset(db, "pinuts", 0); - SdbList *list = sdb_foreach_list(db, false); - mu_assert_eq(ls_length(list), 2, "Unmatched rows"); - ls_free(list); + RzPVector *items = sdb_get_items(db, false); + mu_assert_eq(rz_pvector_len(items), 2, "Unmatched rows"); + rz_pvector_free(items); sdb_free(db); mu_end; } @@ -88,9 +114,9 @@ bool test_sdb_delete_alot(void) { for (i = 0; i < count; i++) { sdb_unset(db, sdb_fmt("key.%d", i), 0); } - SdbList *list = sdb_foreach_list(db, false); - mu_assert_eq(ls_length(list), 0, "Unmatched rows"); - ls_free(list); + RzPVector *items = sdb_get_items(db, false); + mu_assert_eq(rz_pvector_len(items), 0, "Unmatched rows"); + rz_pvector_free(items); sdb_free(db); mu_end; @@ -159,8 +185,9 @@ bool test_sdb_namespace(void) { mu_end; } -static bool foreach_filter_user_cb(void *user, const char *key, const char *val) { +static bool foreach_filter_user_cb(void *user, const SdbKv *kv) { Sdb *db = (Sdb *)user; + const char *key = sdbkv_key(kv); const char *v = sdb_const_get(db, key, NULL); if (!v) { return false; @@ -168,7 +195,7 @@ static bool foreach_filter_user_cb(void *user, const char *key, const char *val) return key[0] == 'b' && v[0] == 'c'; } -bool test_sdb_foreach_filter_user(void) { +bool test_sdb_kv_list_filtered(void) { Sdb *db = sdb_new(NULL, NULL, false); sdb_set(db, "crow", NULL, 0); sdb_set(db, "foo", "bar", 0); @@ -179,44 +206,18 @@ bool test_sdb_foreach_filter_user(void) { sdb_set(db, "low", "bar", 0); sdb_set(db, "bip", "cow", 0); sdb_set(db, "big", "horse", 0); - SdbList *ls = sdb_foreach_list_filter_user(db, foreach_filter_user_cb, true, db); - SdbListIter *it = ls_iterator(ls); - SdbKv *kv = ls_iter_get(it); + RzPVector *items = sdb_get_items_filter(db, foreach_filter_user_cb, db, true); + mu_assert_eq(rz_pvector_len(items), 3, "list length"); + SdbKv *kv = rz_pvector_at(items, 0); mu_assert_streq(sdbkv_key(kv), "bar", "list should be sorted"); mu_assert_streq(sdbkv_value(kv), "cow", "list should be filtered"); - kv = ls_iter_get(it); + kv = rz_pvector_at(items, 1); mu_assert_streq(sdbkv_key(kv), "bip", "list should be sorted"); mu_assert_streq(sdbkv_value(kv), "cow", "list should be filtered"); - kv = ls_iter_get(it); + kv = rz_pvector_at(items, 2); mu_assert_streq(sdbkv_key(kv), "boo", "list should be sorted"); mu_assert_streq(sdbkv_value(kv), "cow", "list should be filtered"); - mu_assert_null(it, "list should be terminated"); - ls_free(ls); - sdb_free(db); - mu_end; -} - -static bool foreach_filter_cb(void *user, const char *key, const char *val) { - return key[0] == 'b'; -} - -bool test_sdb_foreach_filter(void) { - Sdb *db = sdb_new(NULL, NULL, false); - sdb_set(db, "foo", "bar", 0); - sdb_set(db, "bar", "cow", 0); - sdb_set(db, "boo", "cow", 0); - sdb_set(db, "low", "bar", 0); - sdb_set(db, "bip", "cow", 0); - SdbList *ls = sdb_foreach_list_filter(db, foreach_filter_cb, true); - SdbListIter *it = ls_iterator(ls); - SdbKv *kv = ls_iter_get(it); - mu_assert_streq(sdbkv_key(kv), "bar", "list should be sorted"); - kv = ls_iter_get(it); - mu_assert_streq(sdbkv_key(kv), "bip", "list should be sorted"); - kv = ls_iter_get(it); - mu_assert_streq(sdbkv_key(kv), "boo", "list should be sorted"); - mu_assert_null(it, "list should be terminated"); - ls_free(ls); + rz_pvector_free(items); sdb_free(db); mu_end; } @@ -549,8 +550,61 @@ bool test_sdb_text_load_file() { mu_end; } +bool test_sdb_sync_disk() { + Sdb *db = sdb_new(NULL, ".sync_disk_db", 0); + + sdb_set(db, "mykey", "foobar", 0); + sdb_set(db, "zoo", "beef", 0); + sdb_set(db, "spam", "egg", 0); + + sdb_sync(db); + sdb_free(db); + + db = sdb_new(NULL, ".sync_disk_db", 0); + mu_assert_false(sdb_isempty(db), "Non empty"); + + ut32 mem, disk; + sdb_stats(db, &disk, &mem); + mu_assert_eq(disk, 3, "Disk records"); + mu_assert_eq(mem, 0, "Mem records"); + + sdb_set(db, "mykey", "newfoobar", 0); + sdb_stats(db, &disk, &mem); + mu_assert_eq(disk, 3, "Disk records"); + mu_assert_eq(mem, 1, "Mem records"); + + char *val = sdb_get(db, "mykey", NULL); + mu_assert_streq(val, "newfoobar", "Overriden value"); + free(val); + + RzPVector *items = sdb_get_items(db, true); + mu_assert_eq(rz_pvector_len(items), 3, "KV count"); + + SdbKv *kv = rz_pvector_at(items, 0); + mu_assert_streq(sdbkv_key(kv), "mykey", "key"); + mu_assert_streq(sdbkv_value(kv), "newfoobar", "value"); + rz_pvector_free(items); + + sdb_sync(db); + sdb_free(db); + + db = sdb_new(NULL, ".sync_disk_db", 0); + + sdb_stats(db, &disk, &mem); + mu_assert_eq(disk, 3, "Disk records"); + mu_assert_eq(mem, 0, "Mem records"); + + val = sdb_get(db, "mykey", NULL); + mu_assert_streq(val, "newfoobar", "Overriden value"); + free(val); + + sdb_free(db); + mu_end; +} + int all_tests() { // XXX two bugs found with crash + mu_run_test(test_sdb_kv_list); mu_run_test(test_sdb_namespace); mu_run_test(test_sdb_foreach_delete); mu_run_test(test_sdb_list_delete); @@ -559,8 +613,7 @@ int all_tests() { mu_run_test(test_sdb_milset); mu_run_test(test_sdb_milset_random); mu_run_test(test_sdb_list_big); - mu_run_test(test_sdb_foreach_filter_user); - mu_run_test(test_sdb_foreach_filter); + mu_run_test(test_sdb_kv_list_filtered); mu_run_test(test_sdb_copy); mu_run_test(test_sdb_text_save_simple); mu_run_test(test_sdb_text_save_simple_unsorted); @@ -571,6 +624,7 @@ int all_tests() { mu_run_test(test_sdb_text_load_broken); mu_run_test(test_sdb_text_load_path_last_line); mu_run_test(test_sdb_text_load_file); + mu_run_test(test_sdb_sync_disk); return tests_passed != tests_run; } diff --git a/test/unit/test_serialize_analysis.c b/test/unit/test_serialize_analysis.c index 90b41b9db75..7115aba8105 100644 --- a/test/unit/test_serialize_analysis.c +++ b/test/unit/test_serialize_analysis.c @@ -1206,14 +1206,13 @@ bool test_analysis_classes_load() { sdb_free(db); mu_assert("load success", succ); - SdbList *classes = rz_analysis_class_get_all(analysis, true); - mu_assert_eq(classes->length, 2, "classes count"); - SdbListIter *iter = ls_head(classes); - SdbKv *kv = ls_iter_get(iter); + RzPVector *classes = rz_analysis_class_get_all(analysis, true); + mu_assert_eq(rz_pvector_len(classes), 2, "classes count"); + SdbKv *kv = rz_pvector_at(classes, 0); mu_assert_streq(sdbkv_key(kv), "Aeropause", "class"); - kv = ls_iter_get(iter); + kv = rz_pvector_at(classes, 1); mu_assert_streq(sdbkv_key(kv), "Bright", "class"); - ls_free(classes); + rz_pvector_free(classes); RzVector *vals = rz_analysis_class_method_get_all(analysis, "Aeropause"); mu_assert_eq(vals->len, 2, "method count"); @@ -1454,12 +1453,11 @@ bool test_analysis_load() { const char *hint = rz_analysis_hint_arch_at(analysis, 4321, NULL); mu_assert_streq(hint, "arm", "hint"); - SdbList *classes = rz_analysis_class_get_all(analysis, true); - mu_assert_eq(classes->length, 1, "classes count"); - SdbListIter *siter = ls_head(classes); - SdbKv *kv = ls_iter_get(siter); + RzPVector *classes = rz_analysis_class_get_all(analysis, true); + mu_assert_eq(rz_pvector_len(classes), 1, "classes count"); + SdbKv *kv = rz_pvector_at(classes, 0); mu_assert_streq(sdbkv_key(kv), "Aeropause", "class"); - ls_free(classes); + rz_pvector_free(classes); RzVector *vals = rz_analysis_class_method_get_all(analysis, "Aeropause"); mu_assert_eq(vals->len, 1, "method count"); RzAnalysisMethod *meth = rz_vector_index_ptr(vals, 0); From 4594027f8b5ad7828941e59dce9fb023220bbabe Mon Sep 17 00:00:00 2001 From: pelijah Date: Tue, 7 May 2024 13:05:09 +0300 Subject: [PATCH 3/6] Remove unused sdb hook feature (#4478) --- librz/util/sdb/src/sdb.c | 63 ---------------------------------------- librz/util/sdb/src/sdb.h | 7 ----- 2 files changed, 70 deletions(-) diff --git a/librz/util/sdb/src/sdb.c b/librz/util/sdb/src/sdb.c index 7c0c07b7599..8531e4f348e 100644 --- a/librz/util/sdb/src/sdb.c +++ b/librz/util/sdb/src/sdb.c @@ -172,7 +172,6 @@ static void sdb_fini(Sdb *s, int donull) { if (!s) { return; } - sdb_hook_free(s); cdb_free(&s->db); if (s->lock) { sdb_unlock(sdb_lock_file(s->dir)); @@ -564,7 +563,6 @@ static ut32 sdb_set_internal(Sdb *s, const char *key, char *val, int owned, ut32 return 0; } if (vlen == sdbkv_value_len(kv) && !strcmp(sdbkv_value(kv), val)) { - sdb_hook_call(s, key, val); return kv->cas; } kv->cas = cas = nextcas(); @@ -583,7 +581,6 @@ static ut32 sdb_set_internal(Sdb *s, const char *key, char *val, int owned, ut32 } else { sdb_ht_delete(s->ht, key); } - sdb_hook_call(s, key, val); return cas; } // empty values are also stored @@ -601,10 +598,8 @@ static ut32 sdb_set_internal(Sdb *s, const char *key, char *val, int owned, ut32 ut32 cas = kv->cas = nextcas(); sdb_ht_insert_kvp(s->ht, kv, true /*update*/); free(kv); - sdb_hook_call(s, key, val); return cas; } - // kv set failed, no need to callback sdb_hook_call (s, key, val); return 0; } @@ -977,64 +972,6 @@ RZ_API ut64 sdb_expire_get(Sdb *s, const char *key, ut32 *cas) { return 0LL; } -RZ_API bool sdb_hook(Sdb *s, SdbHook cb, void *user) { - int i = 0; - SdbHook hook; - SdbListIter *iter; - if (s->hooks) { - ls_foreach (s->hooks, iter, hook) { - if (!(i % 2) && (hook == cb)) { - return false; - } - i++; - } - } else { - s->hooks = ls_new(); - s->hooks->free = NULL; - } - ls_append(s->hooks, (void *)cb); - ls_append(s->hooks, user); - return true; -} - -RZ_API bool sdb_unhook(Sdb *s, SdbHook h) { - int i = 0; - SdbHook hook; - SdbListIter *iter, *iter2; - ls_foreach (s->hooks, iter, hook) { - if (!(i % 2) && (hook == h)) { - iter2 = iter->n; - ls_delete(s->hooks, iter); - ls_delete(s->hooks, iter2); - return true; - } - i++; - } - return false; -} - -RZ_API int sdb_hook_call(Sdb *s, const char *k, const char *v) { - SdbListIter *iter; - SdbHook hook; - int i = 0; - if (s->timestamped && s->last) { - s->last = sdb_now(); - } - ls_foreach (s->hooks, iter, hook) { - if (!(i % 2) && k && iter->n) { - void *u = iter->n->data; - hook(s, u, k, v); - } - i++; - } - return i >> 1; -} - -RZ_API void sdb_hook_free(Sdb *s) { - ls_free(s->hooks); - s->hooks = NULL; -} - RZ_API void sdb_config(Sdb *s, int options) { s->options = options; if (options & SDB_OPTION_SYNC) { diff --git a/librz/util/sdb/src/sdb.h b/librz/util/sdb/src/sdb.h index 5712e4897a9..eeced3254be 100644 --- a/librz/util/sdb/src/sdb.h +++ b/librz/util/sdb/src/sdb.h @@ -82,7 +82,6 @@ typedef struct sdb_t { int options; int ns_lock; // TODO: merge into options? SdbList *ns; - SdbList *hooks; ut32 depth; bool timestamped; } Sdb; @@ -297,12 +296,6 @@ RZ_API ut64 sdb_array_pop_num(Sdb *s, const char *key, ut32 *cas); RZ_API char *sdb_array_pop_head(Sdb *s, const char *key, ut32 *cas); RZ_API char *sdb_array_pop_tail(Sdb *s, const char *key, ut32 *cas); -typedef void (*SdbHook)(Sdb *s, void *user, const char *k, const char *v); - -RZ_API bool sdb_hook(Sdb *s, SdbHook cb, void *user); -RZ_API bool sdb_unhook(Sdb *s, SdbHook h); -RZ_API int sdb_hook_call(Sdb *s, const char *k, const char *v); -RZ_API void sdb_hook_free(Sdb *s); /* Util.c */ RZ_API int sdb_isnum(const char *s); RZ_API bool sdb_isempty(Sdb *s); From 02990d7291e8d98977eb42e815ebfec794bd9580 Mon Sep 17 00:00:00 2001 From: pelijah Date: Tue, 7 May 2024 15:50:37 +0300 Subject: [PATCH 4/6] Fix NULL dereference in rz_io_resize() (#4479) --- librz/include/rz_io.h | 2 +- librz/io/io.c | 36 +++++++++++++++++------------------- 2 files changed, 18 insertions(+), 20 deletions(-) diff --git a/librz/include/rz_io.h b/librz/include/rz_io.h index 934a3f03340..51c3de97295 100644 --- a/librz/include/rz_io.h +++ b/librz/include/rz_io.h @@ -333,7 +333,7 @@ RZ_API bool rz_io_write(RzIO *io, const ut8 *buf, size_t len); RZ_API ut64 rz_io_size(RzIO *io); RZ_API bool rz_io_is_listener(RzIO *io); RZ_API char *rz_io_system(RzIO *io, const char *cmd); -RZ_API bool rz_io_resize(RzIO *io, ut64 newsize); +RZ_API bool rz_io_resize(RZ_NONNULL RzIO *io, ut64 newsize); RZ_API bool rz_io_extend_at(RzIO *io, ut64 addr, ut64 size); RZ_API bool rz_io_set_write_mask(RzIO *io, const ut8 *mask, size_t len); RZ_API void rz_io_bind(RzIO *io, RzIOBind *bnd); diff --git a/librz/io/io.c b/librz/io/io.c index 24ef79ea7a2..f5edea44a7b 100644 --- a/librz/io/io.c +++ b/librz/io/io.c @@ -422,27 +422,25 @@ RZ_API char *rz_io_system(RzIO *io, const char *cmd) { return NULL; } -RZ_API bool rz_io_resize(RzIO *io, ut64 newsize) { - if (io) { - RzList *maps = rz_io_map_get_for_fd(io, io->desc->fd); - RzIOMap *current_map; - RzListIter *iter; - ut64 fd_size = rz_io_fd_size(io, io->desc->fd); - bool ret = rz_io_desc_resize(io->desc, newsize); - if (!ret) { - rz_list_free(maps); - return false; - } - rz_list_foreach (maps, iter, current_map) { - // we just resize map of the same size of its fd - if (current_map->itv.size == fd_size) { - rz_io_map_resize(io, current_map->id, newsize); - } - } +RZ_API bool rz_io_resize(RZ_NONNULL RzIO *io, ut64 newsize) { + rz_return_val_if_fail(io && io->desc, false); + + RzList *maps = rz_io_map_get_for_fd(io, io->desc->fd); + ut64 fd_size = rz_io_fd_size(io, io->desc->fd); + if (!rz_io_desc_resize(io->desc, newsize)) { rz_list_free(maps); - return true; + return false; } - return false; + RzListIter *iter; + RzIOMap *current_map; + rz_list_foreach (maps, iter, current_map) { + // we just resize map of the same size of its fd + if (current_map->itv.size == fd_size) { + rz_io_map_resize(io, current_map->id, newsize); + } + } + rz_list_free(maps); + return true; } RZ_API bool rz_io_close(RzIO *io) { From d78fee37f2da24854a193be17af84ec5efce09ae Mon Sep 17 00:00:00 2001 From: pelijah Date: Wed, 8 May 2024 02:31:31 +0300 Subject: [PATCH 5/6] Use HtUP instead of SdbHt in bin_xnu_kernelcache.c (#4480) --- librz/bin/p/bin_xnu_kernelcache.c | 65 ++++++++++++------------------- 1 file changed, 25 insertions(+), 40 deletions(-) diff --git a/librz/bin/p/bin_xnu_kernelcache.c b/librz/bin/p/bin_xnu_kernelcache.c index 11662f96edd..962d34b815b 100644 --- a/librz/bin/p/bin_xnu_kernelcache.c +++ b/librz/bin/p/bin_xnu_kernelcache.c @@ -104,7 +104,7 @@ static void handle_data_sections(RzBinSection *sect); static void symbols_from_mach0(RzPVector /**/ *ret, struct MACH0_(obj_t) * mach0, RzBinFile *bf, ut64 paddr, int ordinal); static RzList /**/ *resolve_syscalls(RzXNUKernelCacheObj *obj, ut64 enosys_addr); static RzList /**/ *resolve_mig_subsystem(RzXNUKernelCacheObj *obj); -static void symbols_from_stubs(RzPVector /**/ *ret, HtSS *kernel_syms_by_addr, RzXNUKernelCacheObj *obj, RzBinFile *bf, RKext *kext, int ordinal); +static void symbols_from_stubs(RzPVector /**/ *ret, HtUP /**/ *kernel_syms_by_addr, RzXNUKernelCacheObj *obj, RzBinFile *bf, RKext *kext, int ordinal); static RStubsInfo *get_stubs_info(struct MACH0_(obj_t) * mach0, ut64 paddr, RzXNUKernelCacheObj *obj); static int prot2perm(int x); @@ -1177,21 +1177,19 @@ static RzPVector /**/ *symbols(RzBinFile *bf) { symbols_from_mach0(ret, obj->mach0, bf, 0, 0); - HtSS *kernel_syms_by_addr = sdb_ht_new(); + HtUP *kernel_syms_by_addr = ht_up_new((HtUPDupValue)strdup, free); if (!kernel_syms_by_addr) { rz_pvector_free(ret); return NULL; } - char tmpbuf[32]; RzListIter *iter; void **it; RzBinSymbol *sym; ut64 enosys_addr = 0; rz_pvector_foreach (ret, it) { sym = *it; - const char *key = rz_strf(tmpbuf, "%" PFMT64x, sym->vaddr); - sdb_ht_insert(kernel_syms_by_addr, key, sym->dname ? sym->dname : sym->name); + ht_up_insert(kernel_syms_by_addr, sym->vaddr, sym->dname ? sym->dname : sym->name); if (!enosys_addr && strstr(sym->name, "enosys")) { enosys_addr = sym->vaddr; } @@ -1200,8 +1198,7 @@ static RzPVector /**/ *symbols(RzBinFile *bf) { RzList *syscalls = resolve_syscalls(obj, enosys_addr); if (syscalls) { rz_list_foreach (syscalls, iter, sym) { - const char *key = rz_strf(tmpbuf, "%" PFMT64x, sym->vaddr); - sdb_ht_insert(kernel_syms_by_addr, key, sym->name); + ht_up_insert(kernel_syms_by_addr, sym->vaddr, sym->name); rz_pvector_push(ret, sym); } syscalls->free = NULL; @@ -1211,8 +1208,7 @@ static RzPVector /**/ *symbols(RzBinFile *bf) { RzList *subsystem = resolve_mig_subsystem(obj); if (subsystem) { rz_list_foreach (subsystem, iter, sym) { - const char *key = rz_strf(tmpbuf, "%" PFMT64x, sym->vaddr); - sdb_ht_insert(kernel_syms_by_addr, key, sym->name); + ht_up_insert(kernel_syms_by_addr, sym->vaddr, sym->name); rz_pvector_push(ret, sym); } subsystem->free = NULL; @@ -1243,10 +1239,9 @@ static RzPVector /**/ *symbols(RzBinFile *bf) { } } - RZ_FREE(inits); - RZ_FREE(terms); - - sdb_ht_free(kernel_syms_by_addr); + free(inits); + free(terms); + ht_up_free(kernel_syms_by_addr); return ret; } @@ -1433,17 +1428,16 @@ static RzList /**/ *resolve_syscalls(RzXNUKernelCacheObj *obj, ut #define K_MIG_ROUTINE_SIZE (5 * 8) #define K_MIG_MAX_ROUTINES 100 -static HtSS *mig_hash_new(void) { - HtSS *hash = sdb_ht_new(); +static HtUP /**/ *mig_hash_new(void) { + HtUP *hash = ht_up_new(NULL, NULL); if (!hash) { return NULL; } - int i; - for (i = 0; i < RZ_MIG_INDEX_LEN; i += 2) { - const char *num = mig_index[i]; + for (size_t i = 0; i < RZ_MIG_INDEX_LEN; i += 2) { + ut64 num = strtoull(mig_index[i], NULL, 10); const char *name = mig_index[i + 1]; - sdb_ht_insert(hash, num, name); + ht_up_insert(hash, num, (void *)name); } return hash; @@ -1455,7 +1449,7 @@ static RzList /**/ *resolve_mig_subsystem(RzXNUKernelCacheObj *ob return NULL; } - HtSS *mig_hash = NULL; + HtUP *mig_hash = NULL; RzList *subsystem = NULL; ut8 *data_const = NULL; ut64 data_const_offset = 0, data_const_size = 0, data_const_vaddr = 0; @@ -1500,7 +1494,6 @@ static RzList /**/ *resolve_mig_subsystem(RzXNUKernelCacheObj *ob goto beach; } - char tmpbuf[32]; ut8 *cursor = data_const; ut8 *end = data_const + data_const_size; while (cursor + sizeof(ut64) * 2 <= end) { @@ -1560,10 +1553,8 @@ static RzList /**/ *resolve_mig_subsystem(RzXNUKernelCacheObj *ob } int num = idx + subs_min_idx; - bool found = false; - const char *key = rz_strf(tmpbuf, "%d", num); - const char *name = sdb_ht_find(mig_hash, key, &found); - if (found && name && *name) { + const char *name = ht_up_find(mig_hash, (ut64)num, NULL); + if (RZ_STR_ISNOTEMPTY(name)) { sym->name = rz_str_newf("mig.%d.%s", num, name); } else { sym->name = rz_str_newf("mig.%d", num); @@ -1586,20 +1577,16 @@ static RzList /**/ *resolve_mig_subsystem(RzXNUKernelCacheObj *ob RZ_FREE(routines); } - sdb_ht_free(mig_hash); - RZ_FREE(data_const); - RZ_FREE(sections); + ht_up_free(mig_hash); + free(data_const); + free(sections); return subsystem; beach: - if (subsystem) { - rz_list_free(subsystem); - } - if (mig_hash) { - sdb_ht_free(mig_hash); - } - RZ_FREE(data_const); - RZ_FREE(sections); + rz_list_free(subsystem); + ht_up_free(mig_hash); + free(data_const); + free(sections); return NULL; } @@ -1616,12 +1603,11 @@ static ut64 extract_addr_from_code(ut8 *arm64_code, ut64 vaddr) { return addr; } -static void symbols_from_stubs(RzPVector /**/ *ret, HtSS *kernel_syms_by_addr, RzXNUKernelCacheObj *obj, RzBinFile *bf, RKext *kext, int ordinal) { +static void symbols_from_stubs(RzPVector /**/ *ret, HtUP /**/ *kernel_syms_by_addr, RzXNUKernelCacheObj *obj, RzBinFile *bf, RKext *kext, int ordinal) { RStubsInfo *stubs_info = get_stubs_info(kext->mach0, kext->range.offset, obj); if (!stubs_info) { return; } - char tmpbuf[32]; ut64 stubs_cursor = stubs_info->stubs.offset; ut64 stubs_end = stubs_cursor + stubs_info->stubs.size; @@ -1654,8 +1640,7 @@ static void symbols_from_stubs(RzPVector /**/ *ret, HtSS *kernel_ target_addr = addr; } - const char *key = rz_strf(tmpbuf, "%" PFMT64x, addr); - const char *name = sdb_ht_find(kernel_syms_by_addr, key, &found); + const char *name = ht_up_find(kernel_syms_by_addr, addr, &found); if (found) { RzBinSymbol *sym = RZ_NEW0(RzBinSymbol); From 416fc1e13f0ad048ac22eda57ad427a5c29375f8 Mon Sep 17 00:00:00 2001 From: Peiwei Hu Date: Thu, 9 May 2024 12:27:50 +0800 Subject: [PATCH 6/6] core/canalysis.c: fix the ignored parameter in rz_core_analysis_function_signature_editor (#4481) --- librz/core/canalysis.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/librz/core/canalysis.c b/librz/core/canalysis.c index 023d300c867..dc6821832b9 100644 --- a/librz/core/canalysis.c +++ b/librz/core/canalysis.c @@ -4647,9 +4647,9 @@ RZ_IPI bool rz_core_analysis_function_set_signature(RzCore *core, RzAnalysisFunc } RZ_IPI void rz_core_analysis_function_signature_editor(RzCore *core, ut64 addr) { - RzAnalysisFunction *f = rz_analysis_get_fcn_in(core->analysis, core->offset, -1); + RzAnalysisFunction *f = rz_analysis_get_fcn_in(core->analysis, addr, -1); if (!f) { - RZ_LOG_ERROR("core: cannot find function in 0x%08" PFMT64x "\n", core->offset); + RZ_LOG_ERROR("core: cannot find function in 0x%08" PFMT64x "\n", addr); return; }