From ad2fecbab3bfda05387e9b5c21c362402cc44ea5 Mon Sep 17 00:00:00 2001 From: Anton Kochkov Date: Thu, 18 Mar 2021 14:38:57 +0800 Subject: [PATCH 01/25] RzType introduction --- librz/analysis/analysis.c | 66 ++- librz/analysis/base_types.h | 20 - librz/analysis/cc.c | 17 +- librz/analysis/dwarf_process.c | 61 +-- librz/analysis/fcn.c | 103 ++-- librz/analysis/meson.build | 7 +- librz/analysis/serialize_analysis.c | 7 +- librz/analysis/sign.c | 24 +- librz/analysis/type.c | 645 ------------------------- librz/analysis/type_pdb.c | 65 +-- librz/analysis/var.c | 75 ++- librz/core/analysis_tp.c | 16 +- librz/core/canalysis.c | 75 ++- librz/core/carg.c | 20 +- librz/core/cautocmpl.c | 10 +- librz/core/cbin.c | 106 +--- librz/core/cconfig.c | 4 +- librz/core/cmd.c | 4 +- librz/core/cmd_analysis.c | 27 +- librz/core/cmd_meta.c | 8 +- librz/core/cmd_print.c | 4 +- librz/core/cmd_type.c | 175 +++---- librz/core/cmd_zign.c | 2 +- librz/core/core.c | 44 -- librz/core/core_private.h | 39 +- librz/core/ctypes.c | 314 +++++------- librz/core/disasm.c | 26 +- librz/core/meson.build | 2 + librz/core/vmenus.c | 10 +- librz/include/rz_analysis.h | 67 +-- librz/include/rz_parse.h | 49 -- librz/include/rz_type.h | 169 +++++++ librz/include/rz_util.h | 1 - librz/include/rz_util/rz_ctypes.h | 51 -- librz/meson.build | 1 - librz/parse/ctype.c | 230 --------- librz/parse/meson.build | 4 - librz/type/base.c | 566 ++++++++++++++++++++++ librz/{parse => type}/code.c | 28 +- librz/{util => type}/format.c | 121 ++++- librz/type/function.c | 264 ++++++++++ librz/type/link.c | 121 +++++ librz/type/meson.build | 42 ++ librz/type/serialize_types.c | 19 + librz/type/type.c | 279 +++++++++++ librz/type/type_internal.h | 3 + librz/type/utype.c | 341 +++++++++++++ librz/util/meson.build | 2 - librz/util/utype.c | 718 ---------------------------- meson.build | 3 + test/unit/meson.build | 5 +- test/unit/test_analysis_types.c | 360 -------------- test/unit/test_dwarf_integration.c | 7 +- test/unit/test_parse_ctype.c | 96 ---- test/unit/test_pdb.c | 6 +- test/unit/test_serialize_analysis.c | 195 +------- test/unit/test_serialize_types.c | 199 ++++++++ test/unit/test_type.c | 536 +++++++++++++++++++++ test/unit/test_util.c | 169 +------ 59 files changed, 3229 insertions(+), 3399 deletions(-) delete mode 100644 librz/analysis/base_types.h delete mode 100644 librz/analysis/type.c create mode 100644 librz/include/rz_type.h delete mode 100644 librz/include/rz_util/rz_ctypes.h delete mode 100644 librz/parse/ctype.c create mode 100644 librz/type/base.c rename librz/{parse => type}/code.c (76%) rename librz/{util => type}/format.c (94%) create mode 100644 librz/type/function.c create mode 100644 librz/type/link.c create mode 100644 librz/type/meson.build create mode 100644 librz/type/serialize_types.c create mode 100644 librz/type/type.c create mode 100644 librz/type/type_internal.h create mode 100644 librz/type/utype.c delete mode 100644 librz/util/utype.c delete mode 100644 test/unit/test_analysis_types.c delete mode 100644 test/unit/test_parse_ctype.c create mode 100644 test/unit/test_serialize_types.c create mode 100644 test/unit/test_type.c diff --git a/librz/analysis/analysis.c b/librz/analysis/analysis.c index c530f56a1bb..2a95b63d7cd 100644 --- a/librz/analysis/analysis.c +++ b/librz/analysis/analysis.c @@ -110,7 +110,7 @@ RZ_API RzAnalysis *rz_analysis_new(void) { rz_event_hook(analysis->zign_spaces.event, RZ_SPACE_EVENT_RENAME, zign_rename_for, NULL); rz_analysis_hint_storage_init(analysis); rz_interval_tree_init(&analysis->meta, rz_meta_item_free); - analysis->sdb_types = sdb_ns(analysis->sdb, "types", 1); + analysis->type = rz_type_new(); analysis->sdb_fmts = sdb_ns(analysis->sdb, "spec", 1); analysis->sdb_cc = sdb_ns(analysis->sdb, "cc", 1); analysis->sdb_zigns = sdb_ns(analysis->sdb, "zigns", 1); @@ -239,39 +239,35 @@ RZ_API bool rz_analysis_set_reg_profile(RzAnalysis *analysis) { return ret; } -RZ_API bool rz_analysis_set_triplet(RzAnalysis *analysis, const char *os, const char *arch, int bits) { +static bool analysis_set_os(RzAnalysis *analysis, const char *os) { rz_return_val_if_fail(analysis, false); if (!os || !*os) { os = RZ_SYS_OS; } + free(analysis->os); + analysis->os = strdup(os); + rz_type_set_os(analysis->type, os); + return true; +} + +RZ_API bool rz_analysis_set_triplet(RzAnalysis *analysis, const char *os, const char *arch, int bits) { + rz_return_val_if_fail(analysis, false); if (!arch || !*arch) { arch = analysis->cur ? analysis->cur->arch : RZ_SYS_ARCH; } if (bits < 1) { bits = analysis->bits; } - free(analysis->os); - analysis->os = strdup(os); + analysis_set_os(analysis, os); rz_analysis_set_bits(analysis, bits); return rz_analysis_use(analysis, arch); } -// copypasta from core/cbin.c -static void sdb_concat_by_path(Sdb *s, const char *path) { - Sdb *db = sdb_new(0, path, 0); - sdb_merge(s, db); - sdb_close(db); - sdb_free(db); -} - RZ_API bool rz_analysis_set_os(RzAnalysis *analysis, const char *os) { - Sdb *types = analysis->sdb_types; const char *dir_prefix = rz_sys_prefix(NULL); const char *dbpath = sdb_fmt(RZ_JOIN_3_PATHS("%s", RZ_SDB_FCNSIGN, "types-%s.sdb"), dir_prefix, os); - if (rz_file_exists(dbpath)) { - sdb_concat_by_path(types, dbpath); - } + rz_type_load_sdb(analysis->type, dbpath); return rz_analysis_set_triplet(analysis, os, NULL, -1); } @@ -284,6 +280,7 @@ RZ_API bool rz_analysis_set_bits(RzAnalysis *analysis, int bits) { case 64: if (analysis->bits != bits) { analysis->bits = bits; + rz_type_set_bits(analysis->type, bits); rz_analysis_set_reg_profile(analysis); } return true; @@ -298,6 +295,7 @@ RZ_API void rz_analysis_set_cpu(RzAnalysis *analysis, const char *cpu) { if (v != -1) { analysis->pcalign = v; } + rz_type_set_cpu(analysis->type, cpu); } RZ_API int rz_analysis_set_big_endian(RzAnalysis *analysis, int bigend) { @@ -408,7 +406,7 @@ RZ_API void rz_analysis_purge(RzAnalysis *analysis) { rz_analysis_hint_clear(analysis); rz_interval_tree_fini(&analysis->meta); rz_interval_tree_init(&analysis->meta, rz_meta_item_free); - sdb_reset(analysis->sdb_types); + rz_type_purge(analysis->type); sdb_reset(analysis->sdb_zigns); sdb_reset(analysis->sdb_classes); sdb_reset(analysis->sdb_classes_attrs); @@ -439,10 +437,10 @@ RZ_API int rz_analysis_archinfo(RzAnalysis *analysis, int query) { RZ_API bool rz_analysis_noreturn_add(RzAnalysis *analysis, const char *name, ut64 addr) { const char *tmp_name = NULL; - Sdb *TDB = analysis->sdb_types; + Sdb *NDB = analysis->sdb_noret; char *fnl_name = NULL; if (addr != UT64_MAX) { - if (sdb_bool_set(TDB, K_NORET_ADDR(addr), true, 0)) { + if (sdb_bool_set(NDB, K_NORET_ADDR(addr), true, 0)) { RzAnalysisFunction *fcn = rz_analysis_get_function_at(analysis, addr); if (fcn) { fcn->is_noreturn = true; @@ -464,12 +462,12 @@ RZ_API bool rz_analysis_noreturn_add(RzAnalysis *analysis, const char *name, ut6 fcn->is_noreturn = true; } } - if (rz_type_func_exist(TDB, tmp_name)) { + if (rz_type_func_exist(analysis->type, tmp_name)) { fnl_name = strdup(tmp_name); - } else if (!(fnl_name = rz_type_func_guess(TDB, (char *)tmp_name))) { + } else if (!(fnl_name = rz_type_func_guess(analysis->type, (char *)tmp_name))) { if (addr == UT64_MAX) { if (name) { - sdb_bool_set(TDB, K_NORET_FUNC(name), true, 0); + sdb_bool_set(NDB, K_NORET_FUNC(name), true, 0); } else { eprintf("Can't find prototype for: %s\n", tmp_name); } @@ -479,19 +477,19 @@ RZ_API bool rz_analysis_noreturn_add(RzAnalysis *analysis, const char *name, ut6 //return false; } if (fnl_name) { - sdb_bool_set(TDB, K_NORET_FUNC(fnl_name), true, 0); + sdb_bool_set(NDB, K_NORET_FUNC(fnl_name), true, 0); free(fnl_name); } return true; } RZ_API bool rz_analysis_noreturn_drop(RzAnalysis *analysis, const char *expr) { - Sdb *TDB = analysis->sdb_types; + Sdb *NDB = analysis->sdb_noret; expr = rz_str_trim_head_ro(expr); const char *fcnname = NULL; if (!strncmp(expr, "0x", 2)) { ut64 n = rz_num_math(NULL, expr); - sdb_unset(TDB, K_NORET_ADDR(n), 0); + sdb_unset(NDB, K_NORET_ADDR(n), 0); RzAnalysisFunction *fcn = rz_analysis_get_fcn_in(analysis, n, -1); if (!fcn) { // eprintf ("can't find function at 0x%"PFMT64x"\n", n); @@ -501,15 +499,15 @@ RZ_API bool rz_analysis_noreturn_drop(RzAnalysis *analysis, const char *expr) { } else { fcnname = expr; } - sdb_unset(TDB, K_NORET_FUNC(fcnname), 0); + sdb_unset(NDB, K_NORET_FUNC(fcnname), 0); #if 0 char *tmp; // unnsecessary checks, imho the noreturn db should be pretty simple to allow forward and custom declarations without having to define the function prototype before - if (rz_type_func_exist (TDB, fcnname)) { - sdb_unset (TDB, K_NORET_FUNC (fcnname), 0); + if (rz_type_func_exist (NDB, fcnname)) { + sdb_unset (NDB, K_NORET_FUNC (fcnname), 0); return true; - } else if ((tmp = rz_type_func_guess (TDB, (char *)fcnname))) { - sdb_unset (TDB, K_NORET_FUNC (fcnname), 0); + } else if ((tmp = rz_type_func_guess (NDB, (char *)fcnname))) { + sdb_unset (NDB, K_NORET_FUNC (fcnname), 0); free (tmp); return true; } @@ -519,12 +517,12 @@ RZ_API bool rz_analysis_noreturn_drop(RzAnalysis *analysis, const char *expr) { } static bool rz_analysis_noreturn_at_name(RzAnalysis *analysis, const char *name) { - if (sdb_bool_get(analysis->sdb_types, K_NORET_FUNC(name), NULL)) { + if (sdb_bool_get(analysis->sdb_noret, K_NORET_FUNC(name), NULL)) { return true; } - char *tmp = rz_type_func_guess(analysis->sdb_types, (char *)name); + char *tmp = rz_type_func_guess(analysis->type, (char *)name); if (tmp) { - if (sdb_bool_get(analysis->sdb_types, K_NORET_FUNC(tmp), NULL)) { + if (sdb_bool_get(analysis->sdb_noret, K_NORET_FUNC(tmp), NULL)) { free(tmp); return true; } @@ -537,7 +535,7 @@ static bool rz_analysis_noreturn_at_name(RzAnalysis *analysis, const char *name) } RZ_API bool rz_analysis_noreturn_at_addr(RzAnalysis *analysis, ut64 addr) { - return sdb_bool_get(analysis->sdb_types, K_NORET_ADDR(addr), NULL); + return sdb_bool_get(analysis->sdb_noret, K_NORET_ADDR(addr), NULL); } static bool noreturn_recurse(RzAnalysis *analysis, ut64 addr) { diff --git a/librz/analysis/base_types.h b/librz/analysis/base_types.h deleted file mode 100644 index 269d041f6cc..00000000000 --- a/librz/analysis/base_types.h +++ /dev/null @@ -1,20 +0,0 @@ -// SPDX-FileCopyrightText: 2020 HoundThe -// SPDX-License-Identifier: LGPL-3.0-only - -#ifndef RZ_BASE_TYPES_H -#define RZ_BASE_TYPES_H - -#include "rz_util.h" - -#ifdef __cplusplus -extern "C" { -#endif - -RZ_IPI void enum_type_case_free(void *e, void *user); -RZ_IPI void struct_type_member_free(void *e, void *user); -RZ_IPI void union_type_member_free(void *e, void *user); - -#ifdef __cplusplus -} -#endif -#endif diff --git a/librz/analysis/cc.c b/librz/analysis/cc.c index f303f81e034..6d71e2031c0 100644 --- a/librz/analysis/cc.c +++ b/librz/analysis/cc.c @@ -219,7 +219,20 @@ RZ_API void rz_analysis_set_syscc_default(RzAnalysis *analysis, const char *cc) RZ_API const char *rz_analysis_cc_func(RzAnalysis *analysis, const char *func_name) { rz_return_val_if_fail(analysis && func_name, NULL); - const char *query = sdb_fmt("func.%s.cc", func_name); - const char *cc = sdb_const_get(analysis->sdb_types, query, 0); + const char *cc = rz_type_func_cc(analysis->type, func_name); return cc ? cc : rz_analysis_cc_default(analysis); } + +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))); + } + } + ls_free(l); + return ccl; +} diff --git a/librz/analysis/dwarf_process.c b/librz/analysis/dwarf_process.c index 50843243b2b..49be4bfeeca 100644 --- a/librz/analysis/dwarf_process.c +++ b/librz/analysis/dwarf_process.c @@ -1,8 +1,9 @@ // SPDX-FileCopyrightText: 2012-2020 houndthe // SPDX-License-Identifier: LGPL-3.0-only -#include "base_types.h" #include +#include +#include #include #include #include @@ -380,15 +381,15 @@ static st32 parse_type_outer(Context *ctx, const ut64 offset, RzStrBuf *strbuf, } /** - * @brief Parses structured entry into *result RzAnalysisStructMember + * @brief Parses structured entry into *result RzTypeStructMember * http://www.dwarfstd.org/doc/DWARF4.pdf#page=102&zoom=100,0,0 * * @param ctx * @param idx index of the current entry * @param result ptr to result member to fill up - * @return RzAnalysisStructMember* ptr to parsed Member + * @return RzTypeStructMember* ptr to parsed Member */ -static RzAnalysisStructMember *parse_struct_member(Context *ctx, ut64 idx, RzAnalysisStructMember *result) { +static RzTypeStructMember *parse_struct_member(Context *ctx, ut64 idx, RzTypeStructMember *result) { rz_return_val_if_fail(result, NULL); const RzBinDwarfDie *die = &ctx->all_dies[idx]; @@ -461,15 +462,15 @@ static RzAnalysisStructMember *parse_struct_member(Context *ctx, ut64 idx, RzAna } /** - * @brief Parses enum entry into *result RzAnalysisEnumCase + * @brief Parses enum entry into *result RzTypeEnumCase * http://www.dwarfstd.org/doc/DWARF4.pdf#page=110&zoom=100,0,0 * * @param ctx * @param idx index of the current entry * @param result ptr to result case to fill up - * @return RzAnalysisEnumCase* Ptr to parsed enum case + * @return RzTypeEnumCase* Ptr to parsed enum case */ -static RzAnalysisEnumCase *parse_enumerator(Context *ctx, ut64 idx, RzAnalysisEnumCase *result) { +static RzTypeEnumCase *parse_enumerator(Context *ctx, ut64 idx, RzTypeEnumCase *result) { const RzBinDwarfDie *die = &ctx->all_dies[idx]; char *name = NULL; @@ -506,7 +507,7 @@ static RzAnalysisEnumCase *parse_enumerator(Context *ctx, ut64 idx, RzAnalysisEn /** * @brief Parses a structured entry (structs, classes, unions) into - * RzAnalysisBaseType and saves it using rz_analysis_save_base_type () + * RzBaseType and saves it using rz_analysis_save_base_type () * * @param ctx * @param idx index of the current entry @@ -515,14 +516,14 @@ static RzAnalysisEnumCase *parse_enumerator(Context *ctx, ut64 idx, RzAnalysisEn static void parse_structure_type(Context *ctx, ut64 idx) { const RzBinDwarfDie *die = &ctx->all_dies[idx]; - RzAnalysisBaseTypeKind kind; + RzBaseTypeKind kind; if (die->tag == DW_TAG_union_type) { - kind = RZ_ANALYSIS_BASE_TYPE_KIND_UNION; + kind = RZ_BASE_TYPE_KIND_UNION; } else { - kind = RZ_ANALYSIS_BASE_TYPE_KIND_STRUCT; + kind = RZ_BASE_TYPE_KIND_STRUCT; } - RzAnalysisBaseType *base_type = rz_analysis_base_type_new(kind); + RzBaseType *base_type = rz_type_base_type_new(kind); if (!base_type) { return; } @@ -548,7 +549,7 @@ static void parse_structure_type(Context *ctx, ut64 idx) { base_type->size = get_die_size(die); - RzAnalysisStructMember member = { 0 }; + RzTypeStructMember member = { 0 }; // Parse out all members, can this in someway be extracted to a function? if (die->has_children) { int child_depth = 1; // Direct children of the node @@ -559,7 +560,7 @@ static void parse_structure_type(Context *ctx, ut64 idx) { // we take only direct descendats of the structure // can be also DW_TAG_suprogram for class methods or tag for templates if (child_depth == 1 && child_die->tag == DW_TAG_member) { - RzAnalysisStructMember *result = parse_struct_member(ctx, j, &member); + RzTypeStructMember *result = parse_struct_member(ctx, j, &member); if (!result) { goto cleanup; } else { @@ -577,13 +578,13 @@ static void parse_structure_type(Context *ctx, ut64 idx) { } } } - rz_analysis_save_base_type(ctx->analysis, base_type); + rz_type_save_base_type(ctx->analysis->type, base_type); cleanup: - rz_analysis_base_type_free(base_type); + rz_type_base_type_free(base_type); } /** - * @brief Parses a enum entry into RzAnalysisBaseType and saves it + * @brief Parses a enum entry into RzBaseType and saves it * int Sdb using rz_analysis_save_base_type () * * @param ctx @@ -592,7 +593,7 @@ static void parse_structure_type(Context *ctx, ut64 idx) { static void parse_enum_type(Context *ctx, ut64 idx) { const RzBinDwarfDie *die = &ctx->all_dies[idx]; - RzAnalysisBaseType *base_type = rz_analysis_base_type_new(RZ_ANALYSIS_BASE_TYPE_KIND_ENUM); + RzBaseType *base_type = rz_type_base_type_new(RZ_BASE_TYPE_KIND_ENUM); if (!base_type) { return; } @@ -611,7 +612,7 @@ static void parse_enum_type(Context *ctx, ut64 idx) { base_type->type = rz_strbuf_drain_nofree(&strbuf); } - RzAnalysisEnumCase cas; + RzTypeEnumCase cas; if (die->has_children) { int child_depth = 1; // Direct children of the node size_t j; @@ -620,13 +621,13 @@ static void parse_enum_type(Context *ctx, ut64 idx) { const RzBinDwarfDie *child_die = &ctx->all_dies[j]; // we take only direct descendats of the structure if (child_depth == 1 && child_die->tag == DW_TAG_enumerator) { - RzAnalysisEnumCase *result = parse_enumerator(ctx, j, &cas); + RzTypeEnumCase *result = parse_enumerator(ctx, j, &cas); if (!result) { goto cleanup; } else { void *element = rz_vector_push(&base_type->enum_data.cases, &cas); if (!element) { - enum_type_case_free(result, NULL); + rz_type_base_enum_case_free(result, NULL); goto cleanup; } } @@ -640,13 +641,13 @@ static void parse_enum_type(Context *ctx, ut64 idx) { } } } - rz_analysis_save_base_type(ctx->analysis, base_type); + rz_type_save_base_type(ctx->analysis->type, base_type); cleanup: - rz_analysis_base_type_free(base_type); + rz_type_base_type_free(base_type); } /** - * @brief Parses a typedef entry into RzAnalysisBaseType and saves it + * @brief Parses a typedef entry into RzBaseType and saves it * using rz_analysis_save_base_type () * * http://www.dwarfstd.org/doc/DWARF4.pdf#page=96&zoom=100,0,0 @@ -687,14 +688,14 @@ static void parse_typedef(Context *ctx, ut64 idx) { if (!name) { // type has to have a name for now goto cleanup; } - RzAnalysisBaseType *base_type = rz_analysis_base_type_new(RZ_ANALYSIS_BASE_TYPE_KIND_TYPEDEF); + RzBaseType *base_type = rz_type_base_type_new(RZ_BASE_TYPE_KIND_TYPEDEF); if (!base_type) { goto cleanup; } base_type->name = name; base_type->type = type; - rz_analysis_save_base_type(ctx->analysis, base_type); - rz_analysis_base_type_free(base_type); + rz_type_save_base_type(ctx->analysis->type, base_type); + rz_type_base_type_free(base_type); rz_strbuf_fini(&strbuf); return; cleanup: @@ -740,15 +741,15 @@ static void parse_atomic_type(Context *ctx, ut64 idx) { if (!name) { // type has to have a name for now return; } - RzAnalysisBaseType *base_type = rz_analysis_base_type_new(RZ_ANALYSIS_BASE_TYPE_KIND_ATOMIC); + RzBaseType *base_type = rz_type_base_type_new(RZ_BASE_TYPE_KIND_ATOMIC); if (!base_type) { free(name); return; } base_type->name = name; base_type->size = size; - rz_analysis_save_base_type(ctx->analysis, base_type); - rz_analysis_base_type_free(base_type); + rz_type_save_base_type(ctx->analysis->type, base_type); + rz_type_base_type_free(base_type); } static const char *get_specification_die_name(const RzBinDwarfDie *die) { diff --git a/librz/analysis/fcn.c b/librz/analysis/fcn.c index 33843d72642..d4409e73cde 100644 --- a/librz/analysis/fcn.c +++ b/librz/analysis/fcn.c @@ -1703,15 +1703,9 @@ RZ_API int rz_analysis_function_complexity(RzAnalysisFunction *fcn) { RZ_API char *rz_analysis_function_get_json(RzAnalysisFunction *function) { RzAnalysis *a = function->analysis; PJ *pj = a->coreb.pjWithEncoding(a->coreb.core); - char *args = strdup(""); - char *sdb_ret = rz_str_newf("func.%s.ret", function->name); - char *sdb_args = rz_str_newf("func.%s.args", function->name); - // RzList *args_list = rz_list_newf ((RzListFree) free); unsigned int i; - const char *ret_type = sdb_const_get(a->sdb_types, sdb_ret, 0); - const char *argc_str = sdb_const_get(a->sdb_types, sdb_args, 0); - - int argc = argc_str ? atoi(argc_str) : 0; + const char *ret_type = rz_type_func_ret(a->type, function->name); + int argc = rz_type_func_args_count(a->type, function->name); pj_o(pj); pj_ks(pj, "name", function->name); @@ -1725,26 +1719,19 @@ RZ_API char *rz_analysis_function_get_json(RzAnalysisFunction *function) { pj_a(pj); for (i = 0; i < argc; i++) { pj_o(pj); - char *sdb_arg_i = rz_str_newf("func.%s.arg.%d", function->name, i); - char *arg_i = sdb_get(a->sdb_types, sdb_arg_i, 0); - char *comma = strchr(arg_i, ','); - if (comma) { - *comma = 0; - pj_ks(pj, "name", comma + 1); - pj_ks(pj, "type", arg_i); - const char *cc_arg = rz_reg_get_name(a->reg, rz_reg_get_name_idx(sdb_fmt("A%d", i))); - if (cc_arg) { - pj_ks(pj, "cc", cc_arg); - } - } - free(arg_i); - free(sdb_arg_i); + char *arg_name = rz_type_func_args_name(a->type, function->name, i); + char *arg_type = rz_type_func_args_type(a->type, function->name, i); + pj_ks(pj, "name", arg_name); + pj_ks(pj, "type", arg_type); + const char *cc_arg = rz_reg_get_name(a->reg, rz_reg_get_name_idx(sdb_fmt("A%d", i))); + if (cc_arg) { + pj_ks(pj, "cc", cc_arg); + } + free(arg_type); + free(arg_name); pj_end(pj); } pj_end(pj); - free(sdb_args); - free(sdb_ret); - free(args); pj_end(pj); return pj_drain(pj); } @@ -1765,55 +1752,30 @@ RZ_API char *rz_analysis_function_get_signature(RzAnalysisFunction *function) { realname = function->name; } - char *ret = NULL, *args = strdup(""); - char *sdb_ret = rz_str_newf("func.%s.ret", realname); - char *sdb_args = rz_str_newf("func.%s.args", realname); - // RzList *args_list = rz_list_newf ((RzListFree) free); - unsigned int i, j; - const char *ret_type = sdb_const_get(a->sdb_types, sdb_ret, 0); - const char *argc_str = sdb_const_get(a->sdb_types, sdb_args, 0); - - int argc = argc_str ? atoi(argc_str) : 0; + unsigned int i; + const char *ret_type = rz_type_func_ret(a->type, function->name); + int argc = rz_type_func_args_count(a->type, function->name); + char *args = strdup(""); for (i = 0; i < argc; i++) { - char *sdb_arg_i = rz_str_newf("func.%s.arg.%d", realname, i); - char *arg_i = sdb_get(a->sdb_types, sdb_arg_i, 0); - // parse commas - int arg_i_len = strlen(arg_i); - for (j = 0; j < arg_i_len; j++) { - if (j > 0 && arg_i[j] == ',') { - if (arg_i[j - 1] == '*') { - // remove whitespace - memmove(arg_i + j, arg_i + j + 1, strlen(arg_i) - j); - } else { - arg_i[j] = ' '; - } - } - } + char *arg_name = rz_type_func_args_name(a->type, function->name, i); + char *arg_type = rz_type_func_args_type(a->type, function->name, i); char *new_args = (i + 1 == argc) - ? rz_str_newf("%s%s", args, arg_i) - : rz_str_newf("%s%s, ", args, arg_i); + ? rz_str_newf("%s%s %s", args, arg_type, arg_name) + : rz_str_newf("%s%s %s, ", args, arg_type, arg_name); free(args); args = new_args; - - free(arg_i); - free(sdb_arg_i); } - ret = rz_str_newf("%s %s (%s);", ret_type ? ret_type : "void", realname, args); - - free(sdb_args); - free(sdb_ret); - free(args); - return ret; + return rz_str_newf("%s %s (%s);", ret_type ? ret_type : "void", realname, args); } /* set function signature from string */ RZ_API int rz_analysis_str_to_fcn(RzAnalysis *a, RzAnalysisFunction *f, const char *sig) { rz_return_val_if_fail(a || f || sig, false); char *error_msg = NULL; - const char *out = rz_parse_c_string(a, sig, &error_msg); + const char *out = rz_type_parse_c_string(a->type, sig, &error_msg); if (out) { - rz_analysis_save_parsed_type(a, out); + rz_type_save_parsed_type(a->type, out); } if (error_msg) { eprintf("%s", error_msg); @@ -2256,3 +2218,22 @@ RZ_API void rz_analysis_function_update_analysis(RzAnalysisFunction *fcn) { ht_up_free(reachable); rz_list_free(fcns); } + +static int typecmp(const void *a, const void *b) { + return strcmp(a, b); +} + +RZ_API RzList *rz_analysis_types_from_fcn(RzAnalysis *analysis, RzAnalysisFunction *fcn) { + RzListIter *iter; + RzAnalysisVar *var; + RzList *list = rz_analysis_var_all_list(analysis, fcn); + RzList *type_used = rz_list_new(); + rz_list_foreach (list, iter, var) { + rz_list_append(type_used, var->type); + } + RzList *uniq = rz_list_uniq(type_used, typecmp); + rz_list_free(type_used); + return uniq; +} + + diff --git a/librz/analysis/meson.build b/librz/analysis/meson.build index c47abc5f7b7..1ea8a5742d7 100644 --- a/librz/analysis/meson.build +++ b/librz/analysis/meson.build @@ -29,14 +29,13 @@ rz_analysis_sources = [ 'rtti_itanium.c', 'sign.c', 'switch.c', - 'type.c', - 'type_pdb.c', 'dwarf_process.c', 'value.c', 'var.c', 'vtable.c', 'xrefs.c', 'serialize_analysis.c', + 'type_pdb.c', 'p/analysis_6502.c', 'p/analysis_6502_cs.c', 'p/analysis_8051.c', @@ -187,6 +186,7 @@ rz_analysis = library('rz_analysis', rz_analysis_sources, rz_parse_dep, rz_asm_dep, rz_bin_dep, + rz_type_dep, capstone_dep ], install: true, @@ -214,7 +214,8 @@ pkgconfig_mod.generate(rz_analysis, 'rz_search', 'rz_cons', 'rz_bin', - 'rz_flag' + 'rz_flag', + 'rz_type' ], description: 'rizin foundation libraries' ) diff --git a/librz/analysis/serialize_analysis.c b/librz/analysis/serialize_analysis.c index b4375fc075c..10216f475c5 100644 --- a/librz/analysis/serialize_analysis.c +++ b/librz/analysis/serialize_analysis.c @@ -2,6 +2,8 @@ // SPDX-License-Identifier: LGPL-3.0-only #include +#include +#include #include #include @@ -1928,12 +1930,11 @@ RZ_API bool rz_serialize_analysis_classes_load(RZ_NONNULL Sdb *db, RZ_NONNULL Rz } RZ_API void rz_serialize_analysis_types_save(RZ_NONNULL Sdb *db, RZ_NONNULL RzAnalysis *analysis) { - sdb_copy(analysis->sdb_types, db); + rz_serialize_types_save(db, analysis->type); } RZ_API bool rz_serialize_analysis_types_load(RZ_NONNULL Sdb *db, RZ_NONNULL RzAnalysis *analysis, RZ_NULLABLE RzSerializeResultInfo *res) { - sdb_reset(analysis->sdb_types); - sdb_copy(db, analysis->sdb_types); + return rz_serialize_types_load(db, analysis->type, res); return true; } diff --git a/librz/analysis/sign.c b/librz/analysis/sign.c index adfdd39e8cb..a49d233dbd9 100644 --- a/librz/analysis/sign.c +++ b/librz/analysis/sign.c @@ -83,29 +83,17 @@ RZ_API RzList *rz_sign_fcn_types(RzAnalysis *a, RzAnalysisFunction *fcn) { return NULL; } - char *scratch = rz_str_newf("func.%s.args", fcn->name); - if (!scratch) { - return NULL; - } - const char *fcntypes = sdb_const_get(a->sdb_types, scratch, 0); - free(scratch); - - scratch = rz_str_newf("func.%s.ret", fcn->name); - if (!scratch) { - return NULL; - } - const char *ret_type = sdb_const_get(a->sdb_types, scratch, 0); - free(scratch); + int fcnargs = rz_type_func_args_count(a->type, fcn->name); + const char *ret_type = rz_type_func_ret(a->type, fcn->name); - if (fcntypes) { + if (fcnargs) { if (ret_type) { rz_list_append(ret, rz_str_newf("func.%s.ret=%s", fcn->name, ret_type)); } - int argc = atoi(fcntypes); - rz_list_append(ret, rz_str_newf("func.%s.args=%d", fcn->name, argc)); + rz_list_append(ret, rz_str_newf("func.%s.args=%d", fcn->name, fcnargs)); int i; - for (i = 0; i < argc; i++) { - const char *arg = sdb_const_get(a->sdb_types, rz_str_newf("func.%s.arg.%d", fcn->name, i), 0); + for (i = 0; i < fcnargs; i++) { + const char *arg = rz_type_func_args_name(a->type, fcn->name, i); rz_list_append(ret, rz_str_newf("func.%s.arg.%d=\"%s\"", fcn->name, i, arg)); } } diff --git a/librz/analysis/type.c b/librz/analysis/type.c deleted file mode 100644 index 4d0d70809b3..00000000000 --- a/librz/analysis/type.c +++ /dev/null @@ -1,645 +0,0 @@ -// SPDX-FileCopyrightText: 2019 pancake -// SPDX-FileCopyrightText: 2019 oddcoder -// SPDX-FileCopyrightText: 2019 Anton Kochkov -// SPDX-License-Identifier: LGPL-3.0-only - -#include -#include -#include -#include "base_types.h" - -static char *is_type(char *type) { - char *name = NULL; - if ((name = strstr(type, "=type")) || - (name = strstr(type, "=struct")) || - (name = strstr(type, "=union")) || - (name = strstr(type, "=enum")) || - (name = strstr(type, "=typedef")) || - (name = strstr(type, "=func"))) { - return name; - } - return NULL; -} - -static char *get_type_data(Sdb *sdb_types, const char *type, const char *sname) { - char *key = rz_str_newf("%s.%s", type, sname); - if (!key) { - return NULL; - } - char *members = sdb_get(sdb_types, key, NULL); - free(key); - return members; -} - -RZ_API void rz_analysis_remove_parsed_type(RzAnalysis *analysis, const char *name) { - rz_return_if_fail(analysis && name); - Sdb *TDB = analysis->sdb_types; - SdbKv *kv; - SdbListIter *iter; - const char *type = sdb_const_get(TDB, name, 0); - if (!type) { - return; - } - int tmp_len = strlen(name) + strlen(type); - char *tmp = malloc(tmp_len + 1); - rz_type_del(TDB, name); - if (tmp) { - snprintf(tmp, tmp_len + 1, "%s.%s.", type, name); - SdbList *l = sdb_foreach_list(TDB, true); - ls_foreach (l, iter, kv) { - if (!strncmp(sdbkv_key(kv), tmp, tmp_len)) { - rz_type_del(TDB, sdbkv_key(kv)); - } - } - ls_free(l); - free(tmp); - } -} - -RZ_API void rz_analysis_save_parsed_type(RzAnalysis *analysis, const char *parsed) { - rz_return_if_fail(analysis && parsed); - - // First, if any parsed types exist, let's remove them. - char *type = strdup(parsed); - if (type) { - char *cur = type; - while (1) { - cur = is_type(cur); - if (!cur) { - break; - } - char *name = cur++; - *name = 0; - while (name > type && *(name - 1) != '\n') { - name--; - } - rz_analysis_remove_parsed_type(analysis, name); - } - free(type); - } - - // Now add the type to sdb. - sdb_query_lines(analysis->sdb_types, parsed); -} - -static int typecmp(const void *a, const void *b) { - return strcmp(a, b); -} - -RZ_API RzList *rz_analysis_types_from_fcn(RzAnalysis *analysis, RzAnalysisFunction *fcn) { - RzListIter *iter; - RzAnalysisVar *var; - RzList *list = rz_analysis_var_all_list(analysis, fcn); - RzList *type_used = rz_list_new(); - rz_list_foreach (list, iter, var) { - rz_list_append(type_used, var->type); - } - RzList *uniq = rz_list_uniq(type_used, typecmp); - rz_list_free(type_used); - return uniq; -} - -RZ_IPI void enum_type_case_free(void *e, void *user) { - (void)user; - RzAnalysisEnumCase *cas = e; - free((char *)cas->name); -} - -RZ_IPI void struct_type_member_free(void *e, void *user) { - (void)user; - RzAnalysisStructMember *member = e; - free((char *)member->name); - free((char *)member->type); -} - -RZ_IPI void union_type_member_free(void *e, void *user) { - (void)user; - RzAnalysisUnionMember *member = e; - free((char *)member->name); - free((char *)member->type); -} - -static RzAnalysisBaseType *get_enum_type(RzAnalysis *analysis, const char *sname) { - rz_return_val_if_fail(analysis && sname, NULL); - - RzAnalysisBaseType *base_type = rz_analysis_base_type_new(RZ_ANALYSIS_BASE_TYPE_KIND_ENUM); - if (!base_type) { - return NULL; - } - - char *members = get_type_data(analysis->sdb_types, "enum", sname); - if (!members) { - goto error; - } - - RzVector *cases = &base_type->enum_data.cases; - if (!rz_vector_reserve(cases, (size_t)sdb_alen(members))) { - goto error; - } - - char *cur; - sdb_aforeach(cur, members) { - char *val_key = rz_str_newf("enum.%s.%s", sname, cur); - if (!val_key) { - goto error; - } - const char *value = sdb_const_get(analysis->sdb_types, val_key, NULL); - free(val_key); - - if (!value) { // if nothing is found, ret NULL - goto error; - } - - RzAnalysisEnumCase cas = { .name = strdup(cur), .val = strtol(value, NULL, 16) }; - - void *element = rz_vector_push(cases, &cas); // returns null if no space available - if (!element) { - goto error; - } - - sdb_aforeach_next(cur); - } - free(members); - - return base_type; - -error: - free(members); - rz_analysis_base_type_free(base_type); - return NULL; -} - -static RzAnalysisBaseType *get_struct_type(RzAnalysis *analysis, const char *sname) { - rz_return_val_if_fail(analysis && sname, NULL); - - RzAnalysisBaseType *base_type = rz_analysis_base_type_new(RZ_ANALYSIS_BASE_TYPE_KIND_STRUCT); - if (!base_type) { - return NULL; - } - - char *sdb_members = get_type_data(analysis->sdb_types, "struct", sname); - if (!sdb_members) { - goto error; - } - - RzVector *members = &base_type->struct_data.members; - if (!rz_vector_reserve(members, (size_t)sdb_alen(sdb_members))) { - goto error; - } - - char *cur; - sdb_aforeach(cur, sdb_members) { - char *type_key = rz_str_newf("struct.%s.%s", sname, cur); - if (!type_key) { - goto error; - } - char *values = sdb_get(analysis->sdb_types, type_key, NULL); - free(type_key); - - if (!values) { - goto error; - } - char *offset = NULL; - char *type = sdb_anext(values, &offset); - if (!offset) { // offset is missing, malformed state - free(values); - goto error; - } - offset = sdb_anext(offset, NULL); - RzAnalysisStructMember cas = { - .name = strdup(cur), - .type = strdup(type), - .offset = strtol(offset, NULL, 10) - }; - - free(values); - - void *element = rz_vector_push(members, &cas); // returns null if no space available - if (!element) { - goto error; - } - - sdb_aforeach_next(cur); - } - free(sdb_members); - - return base_type; - -error: - rz_analysis_base_type_free(base_type); - free(sdb_members); - return NULL; -} - -static RzAnalysisBaseType *get_union_type(RzAnalysis *analysis, const char *sname) { - rz_return_val_if_fail(analysis && sname, NULL); - - RzAnalysisBaseType *base_type = rz_analysis_base_type_new(RZ_ANALYSIS_BASE_TYPE_KIND_UNION); - if (!base_type) { - return NULL; - } - - char *sdb_members = get_type_data(analysis->sdb_types, "union", sname); - if (!sdb_members) { - goto error; - } - - RzVector *members = &base_type->union_data.members; - if (!rz_vector_reserve(members, (size_t)sdb_alen(sdb_members))) { - goto error; - } - - char *cur; - sdb_aforeach(cur, sdb_members) { - char *type_key = rz_str_newf("union.%s.%s", sname, cur); - if (!type_key) { - goto error; - } - char *values = sdb_get(analysis->sdb_types, type_key, NULL); - free(type_key); - - if (!values) { - goto error; - } - char *value = sdb_anext(values, NULL); - RzAnalysisUnionMember cas = { .name = strdup(cur), .type = strdup(value) }; - free(values); - - void *element = rz_vector_push(members, &cas); // returns null if no space available - if (!element) { - goto error; - } - - sdb_aforeach_next(cur); - } - free(sdb_members); - - return base_type; - -error: - rz_analysis_base_type_free(base_type); - free(sdb_members); - return NULL; -} - -static RzAnalysisBaseType *get_typedef_type(RzAnalysis *analysis, const char *sname) { - rz_return_val_if_fail(analysis && RZ_STR_ISNOTEMPTY(sname), NULL); - - RzAnalysisBaseType *base_type = rz_analysis_base_type_new(RZ_ANALYSIS_BASE_TYPE_KIND_TYPEDEF); - if (!base_type) { - return NULL; - } - - base_type->type = get_type_data(analysis->sdb_types, "typedef", sname); - if (!base_type->type) { - goto error; - } - return base_type; - -error: - rz_analysis_base_type_free(base_type); - return NULL; -} - -static RzAnalysisBaseType *get_atomic_type(RzAnalysis *analysis, const char *sname) { - rz_return_val_if_fail(analysis && RZ_STR_ISNOTEMPTY(sname), NULL); - - RzAnalysisBaseType *base_type = rz_analysis_base_type_new(RZ_ANALYSIS_BASE_TYPE_KIND_ATOMIC); - if (!base_type) { - return NULL; - } - - base_type->type = get_type_data(analysis->sdb_types, "type", sname); - if (!base_type->type) { - goto error; - } - - RzStrBuf key; - base_type->size = sdb_num_get(analysis->sdb_types, rz_strbuf_initf(&key, "type.%s.size", sname), 0); - rz_strbuf_fini(&key); - - return base_type; - -error: - rz_analysis_base_type_free(base_type); - return NULL; -} - -// returns NULL if name is not found or any failure happened -RZ_API RzAnalysisBaseType *rz_analysis_get_base_type(RzAnalysis *analysis, const char *name) { - rz_return_val_if_fail(analysis && name, NULL); - - char *sname = rz_str_sanitize_sdb_key(name); - const char *type = sdb_const_get(analysis->sdb_types, sname, NULL); - if (!type) { - free(sname); - return NULL; - } - - RzAnalysisBaseType *base_type = NULL; - if (!strcmp(type, "struct")) { - base_type = get_struct_type(analysis, sname); - } else if (!strcmp(type, "enum")) { - base_type = get_enum_type(analysis, sname); - } else if (!strcmp(type, "union")) { - base_type = get_union_type(analysis, sname); - } else if (!strcmp(type, "typedef")) { - base_type = get_typedef_type(analysis, sname); - } else if (!strcmp(type, "type")) { - base_type = get_atomic_type(analysis, sname); - } - - if (base_type) { - base_type->name = sname; - } else { - free(sname); - } - - return base_type; -} - -static void save_struct(const RzAnalysis *analysis, const RzAnalysisBaseType *type) { - rz_return_if_fail(analysis && type && type->name && type->kind == RZ_ANALYSIS_BASE_TYPE_KIND_STRUCT); - char *kind = "struct"; - /* - C: - struct name {type param1; type param2; type paramN;}; - Sdb: - name=struct - struct.name=param1,param2,paramN - struct.name.param1=type,0,0 - struct.name.param2=type,4,0 - struct.name.paramN=type,8,0 - */ - char *sname = rz_str_sanitize_sdb_key(type->name); - // name=struct - sdb_set(analysis->sdb_types, sname, kind, 0); - - RzStrBuf arglist; - RzStrBuf param_key; - RzStrBuf param_val; - rz_strbuf_init(&arglist); - rz_strbuf_init(¶m_key); - rz_strbuf_init(¶m_val); - - int i = 0; - RzAnalysisStructMember *member; - rz_vector_foreach(&type->struct_data.members, member) { - // struct.name.param=type,offset,argsize - char *member_sname = rz_str_sanitize_sdb_key(member->name); - sdb_set(analysis->sdb_types, - rz_strbuf_setf(¶m_key, "%s.%s.%s", kind, sname, member_sname), - rz_strbuf_setf(¶m_val, "%s,%zu,%u", member->type, member->offset, 0), 0ULL); - free(member_sname); - - rz_strbuf_appendf(&arglist, (i++ == 0) ? "%s" : ",%s", member->name); - } - // struct.name=param1,param2,paramN - char *key = rz_str_newf("%s.%s", kind, sname); - sdb_set(analysis->sdb_types, key, rz_strbuf_get(&arglist), 0); - free(key); - - free(sname); - - rz_strbuf_fini(&arglist); - rz_strbuf_fini(¶m_key); - rz_strbuf_fini(¶m_val); -} - -static void save_union(const RzAnalysis *analysis, const RzAnalysisBaseType *type) { - rz_return_if_fail(analysis && type && type->name && type->kind == RZ_ANALYSIS_BASE_TYPE_KIND_UNION); - const char *kind = "union"; - /* - C: - union name {type param1; type param2; type paramN;}; - Sdb: - name=union - union.name=param1,param2,paramN - union.name.param1=type,0,0 - union.name.param2=type,0,0 - union.name.paramN=type,0,0 - */ - char *sname = rz_str_sanitize_sdb_key(type->name); - // name=union - sdb_set(analysis->sdb_types, sname, kind, 0); - - RzStrBuf arglist; - RzStrBuf param_key; - RzStrBuf param_val; - rz_strbuf_init(&arglist); - rz_strbuf_init(¶m_key); - rz_strbuf_init(¶m_val); - - int i = 0; - RzAnalysisUnionMember *member; - rz_vector_foreach(&type->union_data.members, member) { - // union.name.arg1=type,offset,argsize - char *member_sname = rz_str_sanitize_sdb_key(member->name); - sdb_set(analysis->sdb_types, - rz_strbuf_setf(¶m_key, "%s.%s.%s", kind, sname, member_sname), - rz_strbuf_setf(¶m_val, "%s,%zu,%u", member->type, member->offset, 0), 0ULL); - free(member_sname); - - rz_strbuf_appendf(&arglist, (i++ == 0) ? "%s" : ",%s", member->name); - } - // union.name=arg1,arg2,argN - char *key = rz_str_newf("%s.%s", kind, sname); - sdb_set(analysis->sdb_types, key, rz_strbuf_get(&arglist), 0); - free(key); - - free(sname); - - rz_strbuf_fini(&arglist); - rz_strbuf_fini(¶m_key); - rz_strbuf_fini(¶m_val); -} - -static void save_enum(const RzAnalysis *analysis, const RzAnalysisBaseType *type) { - rz_return_if_fail(analysis && type && type->name && type->kind == RZ_ANALYSIS_BASE_TYPE_KIND_ENUM); - /* - C: - enum name {case1 = 1, case2 = 2, caseN = 3}; - Sdb: - name=enum - enum.name=arg1,arg2,argN - enum.MyEnum.0x1=arg1 - enum.MyEnum.0x3=arg2 - enum.MyEnum.0x63=argN - enum.MyEnum.arg1=0x1 - enum.MyEnum.arg2=0x63 - enum.MyEnum.argN=0x3 - */ - char *sname = rz_str_sanitize_sdb_key(type->name); - sdb_set(analysis->sdb_types, sname, "enum", 0); - - RzStrBuf arglist; - RzStrBuf param_key; - RzStrBuf param_val; - rz_strbuf_init(&arglist); - rz_strbuf_init(¶m_key); - rz_strbuf_init(¶m_val); - - int i = 0; - RzAnalysisEnumCase *cas; - rz_vector_foreach(&type->enum_data.cases, cas) { - // enum.name.arg1=type,offset,??? - char *case_sname = rz_str_sanitize_sdb_key(cas->name); - sdb_set(analysis->sdb_types, - rz_strbuf_setf(¶m_key, "enum.%s.%s", sname, case_sname), - rz_strbuf_setf(¶m_val, "0x%" PFMT32x "", cas->val), 0); - - sdb_set(analysis->sdb_types, - rz_strbuf_setf(¶m_key, "enum.%s.0x%" PFMT32x "", sname, cas->val), - case_sname, 0); - free(case_sname); - - rz_strbuf_appendf(&arglist, (i++ == 0) ? "%s" : ",%s", cas->name); - } - // enum.name=arg1,arg2,argN - char *key = rz_str_newf("enum.%s", sname); - sdb_set(analysis->sdb_types, key, rz_strbuf_get(&arglist), 0); - free(key); - - free(sname); - - rz_strbuf_fini(&arglist); - rz_strbuf_fini(¶m_key); - rz_strbuf_fini(¶m_val); -} - -static void save_atomic_type(const RzAnalysis *analysis, const RzAnalysisBaseType *type) { - rz_return_if_fail(analysis && type && type->name && type->kind == RZ_ANALYSIS_BASE_TYPE_KIND_ATOMIC); - /* - C: (cannot define a custom atomic type) - Sdb: - char=type - type.char=c - type.char.size=8 - */ - char *sname = rz_str_sanitize_sdb_key(type->name); - sdb_set(analysis->sdb_types, sname, "type", 0); - - RzStrBuf key; - RzStrBuf val; - rz_strbuf_init(&key); - rz_strbuf_init(&val); - - sdb_set(analysis->sdb_types, - rz_strbuf_setf(&key, "type.%s.size", sname), - rz_strbuf_setf(&val, "%" PFMT64u "", type->size), 0); - - sdb_set(analysis->sdb_types, - rz_strbuf_setf(&key, "type.%s", sname), - type->type, 0); - - free(sname); - - rz_strbuf_fini(&key); - rz_strbuf_fini(&val); -} -static void save_typedef(const RzAnalysis *analysis, const RzAnalysisBaseType *type) { - rz_return_if_fail(analysis && type && type->name && type->kind == RZ_ANALYSIS_BASE_TYPE_KIND_TYPEDEF); - /* - C: - typedef char byte; - Sdb: - byte=typedef - typedef.byte=char - */ - char *sname = rz_str_sanitize_sdb_key(type->name); - sdb_set(analysis->sdb_types, sname, "typedef", 0); - - RzStrBuf key; - RzStrBuf val; - rz_strbuf_init(&key); - rz_strbuf_init(&val); - - sdb_set(analysis->sdb_types, - rz_strbuf_setf(&key, "typedef.%s", sname), - rz_strbuf_setf(&val, "%s", type->type), 0); - - free(sname); - - rz_strbuf_fini(&key); - rz_strbuf_fini(&val); -} - -RZ_API void rz_analysis_base_type_free(RzAnalysisBaseType *type) { - rz_return_if_fail(type); - RZ_FREE(type->name); - RZ_FREE(type->type); - - switch (type->kind) { - case RZ_ANALYSIS_BASE_TYPE_KIND_STRUCT: - rz_vector_fini(&type->struct_data.members); - break; - case RZ_ANALYSIS_BASE_TYPE_KIND_UNION: - rz_vector_fini(&type->union_data.members); - break; - case RZ_ANALYSIS_BASE_TYPE_KIND_ENUM: - rz_vector_fini(&type->enum_data.cases); - break; - case RZ_ANALYSIS_BASE_TYPE_KIND_TYPEDEF: - case RZ_ANALYSIS_BASE_TYPE_KIND_ATOMIC: - break; - default: - break; - } - RZ_FREE(type); -} - -RZ_API RzAnalysisBaseType *rz_analysis_base_type_new(RzAnalysisBaseTypeKind kind) { - RzAnalysisBaseType *type = RZ_NEW0(RzAnalysisBaseType); - if (!type) { - return NULL; - } - type->kind = kind; - switch (type->kind) { - case RZ_ANALYSIS_BASE_TYPE_KIND_STRUCT: - rz_vector_init(&type->struct_data.members, sizeof(RzAnalysisStructMember), struct_type_member_free, NULL); - break; - case RZ_ANALYSIS_BASE_TYPE_KIND_ENUM: - rz_vector_init(&type->enum_data.cases, sizeof(RzAnalysisEnumCase), enum_type_case_free, NULL); - break; - case RZ_ANALYSIS_BASE_TYPE_KIND_UNION: - rz_vector_init(&type->union_data.members, sizeof(RzAnalysisUnionMember), union_type_member_free, NULL); - break; - default: - break; - } - - return type; -} - -/** - * @brief Saves RzAnalysisBaseType into the SDB - * - * @param analysis - * @param type RzAnalysisBaseType to save - * @param name Name of the type - */ -RZ_API void rz_analysis_save_base_type(const RzAnalysis *analysis, const RzAnalysisBaseType *type) { - rz_return_if_fail(analysis && type && type->name); - - // TODO, solve collisions, if there are 2 types with the same name and kind - - switch (type->kind) { - case RZ_ANALYSIS_BASE_TYPE_KIND_STRUCT: - save_struct(analysis, type); - break; - case RZ_ANALYSIS_BASE_TYPE_KIND_ENUM: - save_enum(analysis, type); - break; - case RZ_ANALYSIS_BASE_TYPE_KIND_UNION: - save_union(analysis, type); - break; - case RZ_ANALYSIS_BASE_TYPE_KIND_TYPEDEF: - save_typedef(analysis, type); - break; - case RZ_ANALYSIS_BASE_TYPE_KIND_ATOMIC: - save_atomic_type(analysis, type); - break; - default: - break; - } -} diff --git a/librz/analysis/type_pdb.c b/librz/analysis/type_pdb.c index de57b85ff46..86bc07f6f11 100644 --- a/librz/analysis/type_pdb.c +++ b/librz/analysis/type_pdb.c @@ -3,9 +3,10 @@ #include #include +#include #include + #include "../bin/pdb/types.h" -#include "base_types.h" static bool is_parsable_type(const ELeafType type) { return (type == eLF_STRUCTURE || @@ -32,9 +33,9 @@ static char *create_type_name_from_offset(ut64 offset) { * * @param type_info Current type info (member) * @param types List of all types - * @return RzAnalysisStructMember* parsed member, NULL if fail + * @return RzTypeStructMember* parsed member, NULL if fail */ -static RzAnalysisStructMember *parse_member(STypeInfo *type_info, RzList *types) { +static RzTypeStructMember *parse_member(STypeInfo *type_info, RzList *types) { rz_return_val_if_fail(type_info && types, NULL); if (type_info->leaf_type != eLF_MEMBER) { return NULL; @@ -49,7 +50,7 @@ static RzAnalysisStructMember *parse_member(STypeInfo *type_info, RzList *types) type_info->get_val(type_info, &offset); // gets offset type_info->get_name(type_info, &name); type_info->get_print_type(type_info, &type); - RzAnalysisStructMember *member = RZ_NEW0(RzAnalysisStructMember); + RzTypeStructMember *member = RZ_NEW0(RzTypeStructMember); if (!member) { goto cleanup; } @@ -67,9 +68,9 @@ static RzAnalysisStructMember *parse_member(STypeInfo *type_info, RzList *types) * * @param type_info Current type info (enum case) * @param types List of all types - * @return RzAnalysisEnumCase* parsed enum case, NULL if fail + * @return RzTypeEnumCase* parsed enum case, NULL if fail */ -static RzAnalysisEnumCase *parse_enumerate(STypeInfo *type_info, RzList *types) { +static RzTypeEnumCase *parse_enumerate(STypeInfo *type_info, RzList *types) { rz_return_val_if_fail(type_info && types && type_info->leaf_type == eLF_ENUMERATE, NULL); rz_return_val_if_fail(type_info->get_val && type_info->get_name, NULL); @@ -78,7 +79,7 @@ static RzAnalysisEnumCase *parse_enumerate(STypeInfo *type_info, RzList *types) // sometimes, the type doesn't have get_val for some reason type_info->get_val(type_info, &value); type_info->get_name(type_info, &name); - RzAnalysisEnumCase *cas = RZ_NEW0(RzAnalysisEnumCase); + RzTypeEnumCase *cas = RZ_NEW0(RzTypeEnumCase); if (!cas) { goto cleanup; } @@ -93,19 +94,19 @@ static RzAnalysisEnumCase *parse_enumerate(STypeInfo *type_info, RzList *types) /** * @brief Parses enum into BaseType and saves it into SDB * - * @param analysis + * @param t RzType instance * @param type Current type * @param types List of all types */ -static void parse_enum(const RzAnalysis *analysis, SType *type, RzList *types) { - rz_return_if_fail(analysis && type && types); +static void parse_enum(const RzType *t, SType *type, RzList *types) { + rz_return_if_fail(t && type && types); STypeInfo *type_info = &type->type_data; // assert all member functions we need info from rz_return_if_fail(type_info->get_members && type_info->get_name && type_info->get_utype); - RzAnalysisBaseType *base_type = rz_analysis_base_type_new(RZ_ANALYSIS_BASE_TYPE_KIND_ENUM); + RzBaseType *base_type = rz_type_base_type_new(RZ_BASE_TYPE_KIND_ENUM); if (!base_type) { return; } @@ -131,7 +132,7 @@ static void parse_enum(const RzAnalysis *analysis, SType *type, RzList *types) { RzListIter *it = rz_list_iterator(members); while (rz_list_iter_next(it)) { STypeInfo *member_info = rz_list_iter_get(it); - RzAnalysisEnumCase *enum_case = parse_enumerate(member_info, types); + RzTypeEnumCase *enum_case = parse_enumerate(member_info, types); if (!enum_case) { continue; // skip it, move forward } @@ -145,24 +146,24 @@ static void parse_enum(const RzAnalysis *analysis, SType *type, RzList *types) { base_type->size = size; base_type->type = strdup(type_name); // we assume it's sanitized - rz_analysis_save_base_type(analysis, base_type); + rz_type_save_base_type(t, base_type); cleanup: if (to_free_name) { RZ_FREE(name); } - rz_analysis_base_type_free(base_type); + rz_type_base_type_free(base_type); return; } /** * @brief Parses classes, unions and structures into BaseType and saves them into SDB * - * @param analysis + * @param t RzType instance * @param type Current type * @param types List of all types */ -static void parse_structure(const RzAnalysis *analysis, SType *type, RzList *types) { - rz_return_if_fail(analysis && type && types); +static void parse_structure(const RzType *t, SType *type, RzList *types) { + rz_return_if_fail(t && type && types); STypeInfo *type_info = &type->type_data; // assert all member functions we need info from rz_return_if_fail(type_info->get_members && @@ -170,7 +171,7 @@ static void parse_structure(const RzAnalysis *analysis, SType *type, RzList *typ type_info->get_name && type_info->get_val); - RzAnalysisBaseType *base_type = rz_analysis_base_type_new(RZ_ANALYSIS_BASE_TYPE_KIND_STRUCT); + RzBaseType *base_type = rz_type_base_type_new(RZ_BASE_TYPE_KIND_STRUCT); if (!base_type) { return; } @@ -191,7 +192,7 @@ static void parse_structure(const RzAnalysis *analysis, SType *type, RzList *typ RzListIter *it = rz_list_iterator(members); while (rz_list_iter_next(it)) { STypeInfo *member_info = rz_list_iter_get(it); - RzAnalysisStructMember *struct_member = parse_member(member_info, types); + RzTypeStructMember *struct_member = parse_member(member_info, types); if (!struct_member) { continue; // skip the failure } @@ -201,31 +202,31 @@ static void parse_structure(const RzAnalysis *analysis, SType *type, RzList *typ } } if (type_info->leaf_type == eLF_STRUCTURE || type_info->leaf_type == eLF_CLASS) { - base_type->kind = RZ_ANALYSIS_BASE_TYPE_KIND_STRUCT; + base_type->kind = RZ_BASE_TYPE_KIND_STRUCT; } else { // union - base_type->kind = RZ_ANALYSIS_BASE_TYPE_KIND_UNION; + base_type->kind = RZ_BASE_TYPE_KIND_UNION; } char *sname = rz_str_sanitize_sdb_key(name); base_type->name = sname; base_type->size = size; - rz_analysis_save_base_type(analysis, base_type); + rz_type_save_base_type(t, base_type); cleanup: if (to_free_name) { RZ_FREE(name); } - rz_analysis_base_type_free(base_type); + rz_type_base_type_free(base_type); return; } /** * @brief Delegate the type parsing to appropriate function * - * @param analysis + * @param t RzType instance * @param type Current type * @param types List of all types */ -static void parse_type(const RzAnalysis *analysis, SType *type, RzList *types) { - rz_return_if_fail(analysis && type && types); +static void parse_type(const RzType *t, SType *type, RzList *types) { + rz_return_if_fail(t && type && types); int is_forward_decl; if (type->type_data.is_fwdref) { @@ -238,10 +239,10 @@ static void parse_type(const RzAnalysis *analysis, SType *type, RzList *types) { case eLF_CLASS: case eLF_STRUCTURE: case eLF_UNION: - parse_structure(analysis, type, types); + parse_structure(t, type, types); break; case eLF_ENUM: - parse_enum(analysis, type, types); + parse_enum(t, type, types); break; default: // shouldn't happen, happens when someone modifies leafs that get here @@ -254,11 +255,11 @@ static void parse_type(const RzAnalysis *analysis, SType *type, RzList *types) { /** * @brief Saves PDB types from TPI stream into the SDB * - * @param analysis + * @param t RzType instance * @param pdb PDB information */ -RZ_API void rz_parse_pdb_types(const RzAnalysis *analysis, const RzPdb *pdb) { - rz_return_if_fail(analysis && pdb); +RZ_API void rz_parse_pdb_types(const RzType *t, const RzPdb *pdb) { + rz_return_if_fail(t && pdb); RzList *plist = pdb->pdb_streams; // getting the TPI stream from the streams list STpiStream *tpi_stream = rz_list_get_n(plist, ePDB_STREAM_TPI); @@ -270,7 +271,7 @@ RZ_API void rz_parse_pdb_types(const RzAnalysis *analysis, const RzPdb *pdb) { while (rz_list_iter_next(iter)) { // iterate all types SType *type = rz_list_iter_get(iter); if (type && is_parsable_type(type->type_data.leaf_type)) { - parse_type(analysis, type, tpi_stream->types); + parse_type(t, type, tpi_stream->types); } } } diff --git a/librz/analysis/var.c b/librz/analysis/var.c index dd61f5511d3..a01db56ac6d 100644 --- a/librz/analysis/var.c +++ b/librz/analysis/var.c @@ -46,7 +46,7 @@ RZ_API bool rz_analysis_function_rebase_vars(RzAnalysis *a, RzAnalysisFunction * // If the type of var is a struct, // remove all other vars that are overlapped by var and are at the offset of one of its struct members static void shadow_var_struct_members(RzAnalysisVar *var) { - Sdb *TDB = var->fcn->analysis->sdb_types; + Sdb *TDB = var->fcn->analysis->type->sdb_types; const char *type_kind = sdb_const_get(TDB, var->type, 0); if (type_kind && rz_str_startswith(type_kind, "struct")) { char *field; @@ -557,7 +557,7 @@ RZ_API int rz_analysis_var_count(RzAnalysis *a, RzAnalysisFunction *fcn, int kin } static bool var_add_structure_fields_to_list(RzAnalysis *a, RzAnalysisVar *av, RzList *list) { - Sdb *TDB = a->sdb_types; + Sdb *TDB = a->type->sdb_types; const char *type_kind = sdb_const_get(TDB, av->type, 0); if (type_kind && !strcmp(type_kind, "struct")) { char *field_name, *new_name; @@ -726,30 +726,30 @@ static void extract_arg(RzAnalysis *analysis, RzAnalysisFunction *fcn, RzAnalysi if (isarg) { const char *place = fcn->cc ? rz_analysis_cc_arg(analysis, fcn->cc, ST32_MAX) : NULL; bool stack_rev = place ? !strcmp(place, "stack_rev") : false; - char *fname = rz_type_func_guess(analysis->sdb_types, fcn->name); + char *fname = rz_type_func_guess(analysis->type, fcn->name); if (fname) { ut64 sum_sz = 0; size_t from, to, i; if (stack_rev) { - const size_t cnt = rz_type_func_args_count(analysis->sdb_types, fname); + const size_t cnt = rz_type_func_args_count(analysis->type, fname); from = cnt ? cnt - 1 : cnt; to = fcn->cc ? rz_analysis_cc_max_arg(analysis, fcn->cc) : 0; } else { from = fcn->cc ? rz_analysis_cc_max_arg(analysis, fcn->cc) : 0; - to = rz_type_func_args_count(analysis->sdb_types, fname); + to = rz_type_func_args_count(analysis->type, fname); } const int bytes = (fcn->bits ? fcn->bits : analysis->bits) / 8; for (i = from; stack_rev ? i >= to : i < to; stack_rev ? i-- : i++) { - char *tp = rz_type_func_args_type(analysis->sdb_types, fname, i); + char *tp = rz_type_func_args_type(analysis->type, fname, i); if (!tp) { break; } if (sum_sz == frame_off) { vartype = tp; - varname = strdup(rz_type_func_args_name(analysis->sdb_types, fname, i)); + varname = strdup(rz_type_func_args_name(analysis->type, fname, i)); break; } - ut64 bit_sz = rz_type_get_bitsize(analysis->sdb_types, tp); + ut64 bit_sz = rz_type_get_bitsize(analysis->type, tp); sum_sz += bit_sz ? bit_sz / 8 : bytes; sum_sz = RZ_ROUND(sum_sz, bytes); free(tp); @@ -884,15 +884,14 @@ RZ_API void rz_analysis_extract_rarg(RzAnalysis *analysis, RzAnalysisOp *op, RzA RZ_LOG_DEBUG("No calling convention for function '%s' to extract register arguments\n", fcn->name); return; } - char *fname = rz_type_func_guess(analysis->sdb_types, fcn->name); - Sdb *TDB = analysis->sdb_types; + char *fname = rz_type_func_guess(analysis->type, fcn->name); int max_count = rz_analysis_cc_max_arg(analysis, fcn->cc); if (!max_count || (*count >= max_count)) { free(fname); return; } if (fname) { - argc = rz_type_func_args_count(TDB, fname); + argc = rz_type_func_args_count(analysis->type, fname); } bool is_call = (op->type & 0xf) == RZ_ANALYSIS_OP_TYPE_CALL || (op->type & 0xf) == RZ_ANALYSIS_OP_TYPE_UCALL; @@ -906,18 +905,18 @@ RZ_API void rz_analysis_extract_rarg(RzAnalysis *analysis, RzAnalysisOp *op, RzA RzCore *core = (RzCore *)analysis->coreb.core; RzFlagItem *flag = rz_flag_get_by_spaces(core->flags, offset, RZ_FLAGS_FS_IMPORTS, NULL); if (flag) { - callee = rz_type_func_guess(TDB, flag->name); + callee = rz_type_func_guess(analysis->type, flag->name); if (callee) { const char *cc = rz_analysis_cc_func(analysis, callee); if (cc && !strcmp(fcn->cc, cc)) { - callee_rargs = RZ_MIN(max_count, rz_type_func_args_count(TDB, callee)); + callee_rargs = RZ_MIN(max_count, rz_type_func_args_count(analysis->type, callee)); } } } } else if (!f->is_variadic && !strcmp(fcn->cc, f->cc)) { - callee = rz_type_func_guess(TDB, f->name); + callee = rz_type_func_guess(analysis->type, f->name); if (callee) { - callee_rargs = RZ_MIN(max_count, rz_type_func_args_count(TDB, callee)); + callee_rargs = RZ_MIN(max_count, rz_type_func_args_count(analysis->type, callee)); } callee_rargs = callee_rargs ? callee_rargs @@ -939,12 +938,12 @@ RZ_API void rz_analysis_extract_rarg(RzAnalysis *analysis, RzAnalysisOp *op, RzA delta = ri->index; } if (fname) { - type = rz_type_func_args_type(TDB, fname, i); - vname = rz_type_func_args_name(TDB, fname, i); + type = rz_type_func_args_type(analysis->type, fname, i); + vname = rz_type_func_args_name(analysis->type, fname, i); } if (!vname && callee) { - type = rz_type_func_args_type(TDB, callee, i); - vname = rz_type_func_args_name(TDB, callee, i); + type = rz_type_func_args_type(analysis->type, callee, i); + vname = rz_type_func_args_name(analysis->type, callee, i); } if (vname) { reg_set[i] = 1; @@ -997,8 +996,8 @@ RZ_API void rz_analysis_extract_rarg(RzAnalysis *analysis, RzAnalysisOp *op, RzA char *type = NULL; char *name = NULL; if ((i < argc) && fname) { - type = rz_type_func_args_type(TDB, fname, i); - vname = rz_type_func_args_name(TDB, fname, i); + type = rz_type_func_args_type(analysis->type, fname, i); + vname = rz_type_func_args_name(analysis->type, fname, i); } if (!vname) { name = rz_str_newf("arg%d", i + 1); @@ -1356,10 +1355,9 @@ RZ_API char *rz_analysis_fcn_format_sig(RZ_NONNULL RzAnalysis *analysis, RZ_NONN return NULL; } - Sdb *TDB = analysis->sdb_types; - char *type_fcn_name = rz_type_func_guess(TDB, fcn_name); - if (type_fcn_name && rz_type_func_exist(TDB, type_fcn_name)) { - const char *fcn_type = rz_type_func_ret(analysis->sdb_types, type_fcn_name); + char *type_fcn_name = rz_type_func_guess(analysis->type, fcn_name); + if (type_fcn_name && rz_type_func_exist(analysis->type, type_fcn_name)) { + const char *fcn_type = rz_type_func_ret(analysis->type, type_fcn_name); if (fcn_type) { const char *sp = " "; if (*fcn_type && (fcn_type[strlen(fcn_type) - 1] == '*')) { @@ -1378,14 +1376,14 @@ RZ_API char *rz_analysis_fcn_format_sig(RZ_NONNULL RzAnalysis *analysis, RZ_NONN } rz_strbuf_append(buf, " ("); - if (type_fcn_name && rz_type_func_exist(TDB, type_fcn_name)) { - int i, argc = rz_type_func_args_count(TDB, type_fcn_name); + if (type_fcn_name && rz_type_func_exist(analysis->type, type_fcn_name)) { + int i, argc = rz_type_func_args_count(analysis->type, type_fcn_name); bool comma = true; // This avoids false positives present in argument recovery // and straight away print arguments fetched from types db for (i = 0; i < argc; i++) { - char *type = rz_type_func_args_type(TDB, type_fcn_name, i); - const char *name = rz_type_func_args_name(TDB, type_fcn_name, i); + char *type = rz_type_func_args_type(analysis->type, type_fcn_name, i); + const char *name = rz_type_func_args_name(analysis->type, type_fcn_name, i); if (!type || !name) { eprintf("Missing type for %s\n", type_fcn_name); goto beach; @@ -1487,29 +1485,14 @@ RZ_API void rz_analysis_fcn_vars_add_types(RzAnalysis *analysis, RzAnalysisFunct rz_list_join(all_vars, cache.bvars); rz_list_join(all_vars, cache.svars); - RzStrBuf key, value; - rz_strbuf_init(&key); - rz_strbuf_init(&value); - rz_list_foreach (all_vars, iter, var) { if (var->isarg) { - if (!rz_strbuf_setf(&key, "func.%s.arg.%d", fcn->name, arg_count) || - !rz_strbuf_setf(&value, "%s,%s", var->type, var->name)) { - goto exit; - } - sdb_set(analysis->sdb_types, rz_strbuf_get(&key), rz_strbuf_get(&value), 0); + rz_type_func_arg_set(analysis->type, fcn->name, arg_count, var->name, var->type); arg_count++; } } if (arg_count > 0) { - if (!rz_strbuf_setf(&key, "func.%s.args", fcn->name) || - !rz_strbuf_setf(&value, "%d", arg_count)) { - goto exit; - } - sdb_set(analysis->sdb_types, rz_strbuf_get(&key), rz_strbuf_get(&value), 0); + rz_type_func_arg_count_set(analysis->type, fcn->name, arg_count); } -exit: - rz_strbuf_fini(&key); - rz_strbuf_fini(&value); rz_analysis_fcn_vars_cache_fini(&cache); } diff --git a/librz/core/analysis_tp.c b/librz/core/analysis_tp.c index 4f39129f4d9..d088cb532f7 100644 --- a/librz/core/analysis_tp.c +++ b/librz/core/analysis_tp.c @@ -297,7 +297,7 @@ RzAnalysisOp *op_cache_get(HtUP *cache, RzCore *core, ut64 addr) { static void type_match(RzCore *core, char *fcn_name, ut64 addr, ut64 baddr, const char *cc, int prev_idx, bool userfnc, ut64 caddr, HtUP *op_cache) { Sdb *trace = core->analysis->esil->trace->db; - Sdb *TDB = core->analysis->sdb_types; + RzType *T = core->analysis->type; RzAnalysis *analysis = core->analysis; RzList *types = NULL; int idx = sdb_num_get(trace, "idx", 0); @@ -307,7 +307,7 @@ static void type_match(RzCore *core, char *fcn_name, ut64 addr, ut64 baddr, cons if (!fcn_name || !cc) { return; } - int i, j, pos = 0, size = 0, max = rz_type_func_args_count(TDB, fcn_name); + int i, j, pos = 0, size = 0, max = rz_type_func_args_count(T, fcn_name); const char *place = rz_analysis_cc_arg(analysis, cc, ST32_MAX); rz_cons_break_push(NULL, NULL); @@ -338,8 +338,8 @@ static void type_match(RzCore *core, char *fcn_name, ut64 addr, ut64 baddr, cons } type = rz_str_new(rz_list_get_n(types, pos++)); } else { - type = rz_type_func_args_type(TDB, fcn_name, arg_num); - name = rz_type_func_args_name(TDB, fcn_name, arg_num); + type = rz_type_func_args_type(T, fcn_name, arg_num); + name = rz_type_func_args_name(T, fcn_name, arg_num); } if (!type && !userfnc) { continue; @@ -474,7 +474,7 @@ RZ_API void rz_core_analysis_type_match(RzCore *core, RzAnalysisFunction *fcn) { } RzAnalysis *analysis = core->analysis; - Sdb *TDB = analysis->sdb_types; + RzType *T = analysis->type; bool chk_constraint = rz_config_get_i(core->config, "analysis.types.constraint"); const int mininstrsz = rz_analysis_archinfo(analysis, RZ_ANALYSIS_ARCHINFO_MIN_OP_SIZE); const int minopcode = RZ_MAX(1, mininstrsz); @@ -579,10 +579,10 @@ RZ_API void rz_core_analysis_type_match(RzCore *core, RzAnalysisFunction *fcn) { } } if (full_name) { - if (rz_type_func_exist(TDB, full_name)) { + if (rz_type_func_exist(T, full_name)) { fcn_name = strdup(full_name); } else { - fcn_name = rz_type_func_guess(TDB, full_name); + fcn_name = rz_type_func_guess(T, full_name); } if (!fcn_name) { fcn_name = strdup(full_name); @@ -594,7 +594,7 @@ RZ_API void rz_core_analysis_type_match(RzCore *core, RzAnalysisFunction *fcn) { type_match(core, fcn_name, addr, bb->addr, cc, prev_idx, userfnc, callee_addr, op_cache); prev_idx = cur_idx; RZ_FREE(ret_type); - const char *rt = rz_type_func_ret(TDB, fcn_name); + const char *rt = rz_type_func_ret(T, fcn_name); if (rt) { ret_type = strdup(rt); } diff --git a/librz/core/canalysis.c b/librz/core/canalysis.c index be59b3cd2de..65daaf22f78 100644 --- a/librz/core/canalysis.c +++ b/librz/core/canalysis.c @@ -6622,8 +6622,8 @@ RZ_IPI char *rz_core_analysis_function_signature(RzCore *core, RzOutputMode mode } if (key) { - const char *fcn_type = rz_type_func_ret(core->analysis->sdb_types, key); - int nargs = rz_type_func_args_count(core->analysis->sdb_types, key); + const char *fcn_type = rz_type_func_ret(core->analysis->type, key); + int nargs = rz_type_func_args_count(core->analysis->type, key); if (fcn_type) { pj_o(j); pj_ks(j, "name", rz_str_get_null(key)); @@ -6813,7 +6813,7 @@ RZ_API void rz_core_analysis_propagate_noreturn_relocs(RzCore *core, ut64 addr) int bits1 = core->analysis->bits; int bits2 = core->rasm->bits; // find known noreturn functions to propagate - RzList *noretl = rz_types_function_noreturn(core->analysis->sdb_types); + RzList *noretl = rz_type_noreturn_functions(core->analysis->type); // List of the potentially noreturn functions SetU *todo = set_u_new(); struct core_noretl u = { core, noretl, todo }; @@ -7186,7 +7186,7 @@ RZ_IPI bool rz_core_analysis_function_delete_var(RzCore *core, RzAnalysisFunctio RZ_IPI char *rz_core_analysis_var_display(RzCore *core, RzAnalysisVar *var, bool add_name) { RzAnalysis *analysis = core->analysis; RzStrBuf *sb = rz_strbuf_new(NULL); - char *fmt = rz_type_format(analysis->sdb_types, var->type); + char *fmt = rz_type_format(analysis->type, var->type); RzRegItem *i; if (!fmt) { RZ_LOG_DEBUG("type:%s doesn't exist\n", var->type); @@ -7538,3 +7538,70 @@ RZ_API int rz_core_get_stacksz(RzCore *core, ut64 from, ut64 to) { } return maxstack; } + +RZ_API void rz_core_analysis_type_init(RzCore *core) { + rz_return_if_fail(core && core->analysis); + const char *dir_prefix = rz_config_get(core->config, "dir.prefix"); + int bits = core->rasm->bits; + const char *analysis_arch = rz_config_get(core->config, "analysis.arch"); + const char *os = rz_config_get(core->config, "asm.os"); + + rz_type_db_init(core->analysis->type, dir_prefix, analysis_arch, bits, os); +} + +static void sdb_concat_by_path(Sdb *s, const char *path) { + Sdb *db = sdb_new(0, path, 0); + sdb_merge(s, db); + sdb_close(db); + sdb_free(db); +} + +RZ_API void rz_core_analysis_cc_init(RzCore *core) { + const char *analysis_arch = rz_config_get(core->config, "analysis.arch"); + Sdb *cc = core->analysis->sdb_cc; + if (!strcmp(analysis_arch, "null")) { + sdb_reset(cc); + RZ_FREE(cc->path); + return; + } + + const char *dir_prefix = rz_config_get(core->config, "dir.prefix"); + int bits = core->analysis->bits; + char *dbpath = rz_str_newf(RZ_JOIN_3_PATHS("%s", RZ_SDB_FCNSIGN, "cc-%s-%d.sdb"), + dir_prefix, analysis_arch, bits); + char *dbhomepath = rz_str_newf(RZ_JOIN_3_PATHS("~", RZ_HOME_SDB_FCNSIGN, "cc-%s-%d.sdb"), + analysis_arch, bits); + // Avoid sdb reloading + if (cc->path && (!strcmp(cc->path, dbpath) || !strcmp(cc->path, dbhomepath))) { + free(dbpath); + free(dbhomepath); + return; + } + sdb_reset(cc); + RZ_FREE(cc->path); + if (rz_file_exists(dbpath)) { + sdb_concat_by_path(cc, dbpath); + cc->path = strdup(dbpath); + } + if (rz_file_exists(dbhomepath)) { + sdb_concat_by_path(cc, dbhomepath); + cc->path = strdup(dbhomepath); + } + // same as "tcc `arcc`" + char *s = rz_reg_profile_to_cc(core->analysis->reg); + if (s) { + if (!rz_analysis_cc_set(core->analysis, s)) { + eprintf("Warning: Invalid CC from reg profile.\n"); + } + free(s); + } else { + eprintf("Warning: Cannot derive CC from reg profile.\n"); + } + if (sdb_isempty(core->analysis->sdb_cc)) { + eprintf("Warning: Missing calling conventions for '%s'. Deriving it from the regprofile.\n", analysis_arch); + } + free(dbpath); + free(dbhomepath); +} + + diff --git a/librz/core/carg.c b/librz/core/carg.c index edc3dba7044..2f68d2b15bb 100644 --- a/librz/core/carg.c +++ b/librz/core/carg.c @@ -9,9 +9,8 @@ static void set_fcn_args_info(RzAnalysisFuncArg *arg, RzAnalysis *analysis, cons if (!fcn_name || !arg || !analysis) { return; } - Sdb *TDB = analysis->sdb_types; - arg->name = rz_type_func_args_name(TDB, fcn_name, arg_num); - arg->orig_c_type = rz_type_func_args_type(TDB, fcn_name, arg_num); + arg->name = rz_type_func_args_name(analysis->type, fcn_name, arg_num); + arg->orig_c_type = rz_type_func_args_type(analysis->type, fcn_name, arg_num); if (!arg->name || !arg->orig_c_type) { eprintf("Missing type for function argument (%s)\n", fcn_name); return; @@ -21,27 +20,25 @@ static void set_fcn_args_info(RzAnalysisFuncArg *arg, RzAnalysis *analysis, cons } else { arg->c_type = arg->orig_c_type; } - const char *query = sdb_fmt("type.%s", arg->c_type); - arg->fmt = sdb_const_get(TDB, query, 0); - const char *t_query = sdb_fmt("type.%s.size", arg->c_type); - arg->size = sdb_num_get(TDB, t_query, 0) / 8; + arg->fmt = rz_type_get(analysis->type, arg->c_type); + arg->size = rz_type_get_bitsize(analysis->type, arg->c_type) / 8; arg->cc_source = rz_analysis_cc_arg(analysis, cc, arg_num); } RZ_API char *resolve_fcn_name(RzAnalysis *analysis, const char *func_name) { const char *str = func_name; const char *name = func_name; - if (rz_type_func_exist(analysis->sdb_types, func_name)) { + if (rz_type_func_exist(analysis->type, func_name)) { return strdup(func_name); } while ((str = strchr(str, '.'))) { name = str + 1; str++; } - if (rz_type_func_exist(analysis->sdb_types, name)) { + if (rz_type_func_exist(analysis->type, name)) { return strdup(name); } - return rz_type_func_guess(analysis->sdb_types, (char *)func_name); + return rz_type_func_guess(analysis->type, (char *)func_name); } static ut64 get_buf_val(ut8 *buf, int endian, int width) { @@ -223,14 +220,13 @@ RZ_API RzList *rz_core_get_func_args(RzCore *core, const char *fcn_name) { if (!fcn_name || !core->analysis) { return NULL; } - Sdb *TDB = core->analysis->sdb_types; RzList *list = rz_list_newf((RzListFree)rz_analysis_fcn_arg_free); char *key = resolve_fcn_name(core->analysis, fcn_name); if (!key) { return NULL; } const char *sp = rz_reg_get_name(core->analysis->reg, RZ_REG_NAME_SP); - int nargs = rz_type_func_args_count(TDB, key); + int nargs = rz_type_func_args_count(core->analysis->type, key); if (!rz_analysis_cc_func(core->analysis, key)) { return NULL; } diff --git a/librz/core/cautocmpl.c b/librz/core/cautocmpl.c index efbf176c421..a56d175ca9c 100644 --- a/librz/core/cautocmpl.c +++ b/librz/core/cautocmpl.c @@ -219,7 +219,7 @@ static void autocmplt_cmd_arg_fcn(RzCore *core, RzLineNSCompletionResult *res, c static void autocmplt_cmd_arg_enum_type(RzCore *core, RzLineNSCompletionResult *res, const char *s, size_t len) { char *item; RzListIter *iter; - RzList *list = rz_types_enums(core->analysis->sdb_types); + RzList *list = rz_type_enums(core->analysis->type); rz_list_foreach (list, iter, item) { if (!strncmp(item, s, len)) { rz_line_ns_completion_result_add(res, item); @@ -231,7 +231,7 @@ static void autocmplt_cmd_arg_enum_type(RzCore *core, RzLineNSCompletionResult * static void autocmplt_cmd_arg_struct_type(RzCore *core, RzLineNSCompletionResult *res, const char *s, size_t len) { char *item; RzListIter *iter; - RzList *list = rz_types_structs(core->analysis->sdb_types); + RzList *list = rz_types_structs(core->analysis->type); rz_list_foreach (list, iter, item) { if (!strncmp(item, s, len)) { rz_line_ns_completion_result_add(res, item); @@ -243,7 +243,7 @@ static void autocmplt_cmd_arg_struct_type(RzCore *core, RzLineNSCompletionResult static void autocmplt_cmd_arg_union_type(RzCore *core, RzLineNSCompletionResult *res, const char *s, size_t len) { char *item; RzListIter *iter; - RzList *list = rz_types_unions(core->analysis->sdb_types); + RzList *list = rz_types_unions(core->analysis->type); rz_list_foreach (list, iter, item) { if (!strncmp(item, s, len)) { rz_line_ns_completion_result_add(res, item); @@ -255,7 +255,7 @@ static void autocmplt_cmd_arg_union_type(RzCore *core, RzLineNSCompletionResult static void autocmplt_cmd_arg_alias_type(RzCore *core, RzLineNSCompletionResult *res, const char *s, size_t len) { char *item; RzListIter *iter; - RzList *list = rz_types_typedefs(core->analysis->sdb_types); + RzList *list = rz_type_typedefs(core->analysis->type); rz_list_foreach (list, iter, item) { if (!strncmp(item, s, len)) { rz_line_ns_completion_result_add(res, item); @@ -267,7 +267,7 @@ static void autocmplt_cmd_arg_alias_type(RzCore *core, RzLineNSCompletionResult static void autocmplt_cmd_arg_any_type(RzCore *core, RzLineNSCompletionResult *res, const char *s, size_t len) { char *item; RzListIter *iter; - RzList *list = rz_types_all(core->analysis->sdb_types); + RzList *list = rz_types_all(core->analysis->type); rz_list_foreach (list, iter, item) { if (!strncmp(item, s, len)) { rz_line_ns_completion_result_add(res, item); diff --git a/librz/core/cbin.c b/librz/core/cbin.c index 0a8e32ad51a..c0369b51638 100644 --- a/librz/core/cbin.c +++ b/librz/core/cbin.c @@ -200,7 +200,7 @@ RZ_API void rz_core_bin_export_info(RzCore *core, int mode) { } else if (IS_MODE_SET(mode)) { char *code = rz_str_newf("%s;", v); char *error_msg = NULL; - char *out = rz_parse_c_string(core->analysis, code, &error_msg); + char *out = rz_type_parse_c_string(core->analysis->type, code, &error_msg); free(code); if (error_msg) { eprintf("%s", error_msg); @@ -1708,106 +1708,6 @@ static bool is_executable(RzBinObject *obj) { return false; } -RZ_API void rz_core_analysis_type_init(RzCore *core) { - rz_return_if_fail(core && core->analysis); - const char *dir_prefix = rz_config_get(core->config, "dir.prefix"); - int bits = core->rasm->bits; - Sdb *types = core->analysis->sdb_types; - // make sure they are empty this is initializing - sdb_reset(types); - const char *analysis_arch = rz_config_get(core->config, "analysis.arch"); - const char *os = rz_config_get(core->config, "asm.os"); - // spaguetti ahead - - const char *dbpath = sdb_fmt(RZ_JOIN_3_PATHS("%s", RZ_SDB_FCNSIGN, "types.sdb"), dir_prefix); - if (rz_file_exists(dbpath)) { - sdb_concat_by_path(types, dbpath); - } - dbpath = sdb_fmt(RZ_JOIN_3_PATHS("%s", RZ_SDB_FCNSIGN, "types-%s.sdb"), - dir_prefix, analysis_arch); - if (rz_file_exists(dbpath)) { - sdb_concat_by_path(types, dbpath); - } - dbpath = sdb_fmt(RZ_JOIN_3_PATHS("%s", RZ_SDB_FCNSIGN, "types-%s.sdb"), - dir_prefix, os); - if (rz_file_exists(dbpath)) { - sdb_concat_by_path(types, dbpath); - } - dbpath = sdb_fmt(RZ_JOIN_3_PATHS("%s", RZ_SDB_FCNSIGN, "types-%d.sdb"), - dir_prefix, bits); - if (rz_file_exists(dbpath)) { - sdb_concat_by_path(types, dbpath); - } - dbpath = sdb_fmt(RZ_JOIN_3_PATHS("%s", RZ_SDB_FCNSIGN, "types-%s-%d.sdb"), - dir_prefix, os, bits); - if (rz_file_exists(dbpath)) { - sdb_concat_by_path(types, dbpath); - } - dbpath = sdb_fmt(RZ_JOIN_3_PATHS("%s", RZ_SDB_FCNSIGN, "types-%s-%d.sdb"), - dir_prefix, analysis_arch, bits); - if (rz_file_exists(dbpath)) { - sdb_concat_by_path(types, dbpath); - } - dbpath = sdb_fmt(RZ_JOIN_3_PATHS("%s", RZ_SDB_FCNSIGN, "types-%s-%s.sdb"), - dir_prefix, analysis_arch, os); - if (rz_file_exists(dbpath)) { - sdb_concat_by_path(types, dbpath); - } - dbpath = sdb_fmt(RZ_JOIN_3_PATHS("%s", RZ_SDB_FCNSIGN, "types-%s-%s-%d.sdb"), - dir_prefix, analysis_arch, os, bits); - if (rz_file_exists(dbpath)) { - sdb_concat_by_path(types, dbpath); - } -} - -RZ_API void rz_core_analysis_cc_init(RzCore *core) { - const char *analysis_arch = rz_config_get(core->config, "analysis.arch"); - Sdb *cc = core->analysis->sdb_cc; - if (!strcmp(analysis_arch, "null")) { - sdb_reset(cc); - RZ_FREE(cc->path); - return; - } - - const char *dir_prefix = rz_config_get(core->config, "dir.prefix"); - int bits = core->analysis->bits; - char *dbpath = rz_str_newf(RZ_JOIN_3_PATHS("%s", RZ_SDB_FCNSIGN, "cc-%s-%d.sdb"), - dir_prefix, analysis_arch, bits); - char *dbhomepath = rz_str_newf(RZ_JOIN_3_PATHS("~", RZ_HOME_SDB_FCNSIGN, "cc-%s-%d.sdb"), - analysis_arch, bits); - // Avoid sdb reloading - if (cc->path && (!strcmp(cc->path, dbpath) || !strcmp(cc->path, dbhomepath))) { - free(dbpath); - free(dbhomepath); - return; - } - sdb_reset(cc); - RZ_FREE(cc->path); - if (rz_file_exists(dbpath)) { - sdb_concat_by_path(cc, dbpath); - cc->path = strdup(dbpath); - } - if (rz_file_exists(dbhomepath)) { - sdb_concat_by_path(cc, dbhomepath); - cc->path = strdup(dbhomepath); - } - // same as "tcc `arcc`" - char *s = rz_reg_profile_to_cc(core->analysis->reg); - if (s) { - if (!rz_analysis_cc_set(core->analysis, s)) { - eprintf("Warning: Invalid CC from reg profile.\n"); - } - free(s); - } else { - eprintf("Warning: Cannot derive CC from reg profile.\n"); - } - if (sdb_isempty(core->analysis->sdb_cc)) { - eprintf("Warning: Missing calling conventions for '%s'. Deriving it from the regprofile.\n", analysis_arch); - } - free(dbpath); - free(dbhomepath); -} - static int bin_info(RzCore *r, PJ *pj, int mode, ut64 laddr) { int i, j, v; RzBinInfo *info = rz_bin_get_info(r->bin); @@ -2165,8 +2065,8 @@ RZ_API bool rz_core_pdb_info(RzCore *core, const char *file, PJ *pj, int mode) { pdb.print_types(&pdb, pj, mode); pdb.print_gvars(&pdb, baddr, pj, mode); - // Save compound types into SDB - rz_parse_pdb_types(core->analysis, &pdb); + // Save compound types into types database + rz_parse_pdb_types(core->analysis->type, &pdb); pdb.finish_pdb_parse(&pdb); if (mode == 'j') { diff --git a/librz/core/cconfig.c b/librz/core/cconfig.c index fe2655eaee8..be6be407997 100644 --- a/librz/core/cconfig.c +++ b/librz/core/cconfig.c @@ -691,8 +691,8 @@ static bool cb_asmarch(void *user, void *data) { // changing asm.arch changes analysis.arch // changing analysis.arch sets types db // so ressetting is redundant and may lead to bugs - // 1 case this is usefull is when sdb_types is null - if (!core->analysis || !core->analysis->sdb_types) { + // 1 case this is usefull is when types is null + if (!core->analysis || !core->analysis->type) { rz_core_analysis_type_init(core); } rz_core_analysis_cc_init(core); diff --git a/librz/core/cmd.c b/librz/core/cmd.c index a9b0f5adc9b..d9cd77defb1 100644 --- a/librz/core/cmd.c +++ b/librz/core/cmd.c @@ -757,10 +757,10 @@ RZ_API bool rz_core_run_script(RzCore *core, const char *file) { ret = true; } else if (rz_file_is_c(file)) { const char *dir = rz_config_get(core->config, "dir.types"); - char *out = rz_parse_c_file(core->analysis, file, dir, NULL); + char *out = rz_type_parse_c_file(core->analysis->type, file, dir, NULL); if (out) { rz_cons_strcat(out); - sdb_query_lines(core->analysis->sdb_types, out); + rz_type_save_parsed_type(core->analysis->type, out); free(out); } ret = out != NULL; diff --git a/librz/core/cmd_analysis.c b/librz/core/cmd_analysis.c index 64ec4ee1da9..6d68f6a563b 100644 --- a/librz/core/cmd_analysis.c +++ b/librz/core/cmd_analysis.c @@ -2951,13 +2951,7 @@ RZ_IPI int rz_cmd_analysis_fcn(void *data, const char *input) { case 'r': { // "afsr" RzAnalysisFunction *fcn = rz_analysis_get_fcn_in(core->analysis, core->offset, -1); if (fcn) { - char *type = rz_str_newf("type.%s", input + 3); - if (sdb_exists(core->analysis->sdb_types, type)) { - char *query = rz_str_newf("analysis/types/func.%s.ret=%s", fcn->name, input + 3); - sdb_querys(core->sdb, NULL, 0, query); - free(query); - } - free(type); + rz_type_func_ret_set(core->analysis->type, fcn->name, input + 3); } else { eprintf("There's no function defined in here.\n"); } @@ -6908,7 +6902,7 @@ static void cmd_analysis_hint(RzCore *core, const char *input) { rz_str_trim(off); int toff = rz_num_math(NULL, off); if (toff) { - RzList *typeoffs = rz_type_get_by_offset(core->analysis->sdb_types, toff); + RzList *typeoffs = rz_type_get_by_offset(core->analysis->type, toff); RzListIter *iter; char *ty; rz_list_foreach (typeoffs, iter, ty) { @@ -6977,14 +6971,14 @@ static void cmd_analysis_hint(RzCore *core, const char *input) { offimm += rz_num_math(NULL, off); } // TODO: Allow to select from multiple choices - RzList *otypes = rz_type_get_by_offset(core->analysis->sdb_types, offimm); + RzList *otypes = rz_type_get_by_offset(core->analysis->type, offimm); RzListIter *iter; char *otype = NULL; rz_list_foreach (otypes, iter, otype) { // TODO: I don't think we should silently error, it is confusing if (!strcmp(type, otype)) { //eprintf ("Adding type offset %s\n", type); - rz_type_link_offset(core->analysis->sdb_types, type, addr); + rz_type_link_offset(core->analysis->type, type, addr); rz_analysis_hint_set_offset(core->analysis, addr, otype); break; } @@ -8758,8 +8752,8 @@ static void cmd_analysis_aC(RzCore *core, const char *input) { } char *key = (fcn_name) ? resolve_fcn_name(core->analysis, fcn_name) : NULL; if (key) { - const char *fcn_type = rz_type_func_ret(core->analysis->sdb_types, key); - int nargs = rz_type_func_args_count(core->analysis->sdb_types, key); + const char *fcn_type = rz_type_func_ret(core->analysis->type, key); + int nargs = rz_type_func_args_count(core->analysis->type, key); // remove other comments if (fcn_type) { rz_strbuf_appendf(sb, "%s%s%s(", rz_str_get_null(fcn_type), @@ -9257,13 +9251,10 @@ RZ_IPI RzCmdStatus rz_analysis_function_signature_type_handler(RzCore *core, int return RZ_CMD_STATUS_ERROR; } - char *type = rz_str_newf("type.%s", argv[1]); - if (sdb_exists(core->analysis->sdb_types, type)) { - char *query = rz_str_newf("analysis/types/func.%s.ret=%s", fcn->name, argv[1]); - sdb_querys(core->sdb, NULL, 0, query); - free(query); + if (!rz_type_func_ret_set(core->analysis->type, fcn->name, argv[1])) { + eprintf("Cannot find type %s\n", argv[1]); + return RZ_CMD_STATUS_ERROR; } - free(type); return RZ_CMD_STATUS_OK; } diff --git a/librz/core/cmd_meta.c b/librz/core/cmd_meta.c index 4bc073e3f20..ec657983e37 100644 --- a/librz/core/cmd_meta.c +++ b/librz/core/cmd_meta.c @@ -554,7 +554,7 @@ static int cmd_meta_others(RzCore *core, const char *input) { if (p) { p = (char *)rz_str_trim_head_ro(p); if (*p == '.') { - const char *realformat = rz_print_format_byname(core->print, p + 1); + const char *realformat = rz_type_format_byname(core->print, p + 1); if (realformat) { p = (char *)realformat; } else { @@ -563,17 +563,17 @@ static int cmd_meta_others(RzCore *core, const char *input) { } } if (n < 1) { - n = rz_print_format_struct_size(core->print, p, 0, 0); + n = rz_type_format_struct_size(core->print, p, 0, 0); if (n < 1) { eprintf("Warning: Cannot resolve struct size for '%s'\n", p); n = 32; // } } - //make sure we do not overflow on rz_print_format + //make sure we do not overflow on rz_type_format if (n > core->blocksize) { n = core->blocksize; } - int r = rz_print_format(core->print, addr, core->block, + int r = rz_type_format(core->print, addr, core->block, n, p, 0, NULL, NULL); if (r < 0) { n = -1; diff --git a/librz/core/cmd_print.c b/librz/core/cmd_print.c index c2b9ec0a842..49101cd99b0 100644 --- a/librz/core/cmd_print.c +++ b/librz/core/cmd_print.c @@ -1667,9 +1667,9 @@ static void cmd_print_format(RzCore *core, const char *_input, const ut8 *block, if (rz_str_endswith(_input, ".h")) { char *error_msg = NULL; const char *dir = rz_config_get(core->config, "dir.types"); - char *out = rz_parse_c_file(core->analysis, path, dir, &error_msg); + char *out = rz_type_parse_c_file(core->analysis->type, path, dir, &error_msg); if (out) { - rz_analysis_save_parsed_type(core->analysis, out); + rz_type_save_parsed_type(core->analysis->type, out); rz_core_cmd0(core, ".ts*"); free(out); } else { diff --git a/librz/core/cmd_type.c b/librz/core/cmd_type.c index 3f3bb0727db..f342ed77399 100644 --- a/librz/core/cmd_type.c +++ b/librz/core/cmd_type.c @@ -42,9 +42,8 @@ static void types_cc_print(RzCore *core, const char *cc, RzOutputMode mode) { static RzCmdStatus types_enum_member_find(RzCore *core, const char *enum_name, const char *enum_value) { rz_return_val_if_fail(enum_name || enum_value, RZ_CMD_STATUS_ERROR); - Sdb *TDB = core->analysis->sdb_types; ut64 value = rz_num_math(core->num, enum_value); - char *enum_member = rz_type_enum_member(TDB, enum_name, NULL, value); + char *enum_member = rz_type_enum_member(core->analysis->type, enum_name, NULL, value); if (!enum_member) { eprintf("Cannot find matching enum member"); return RZ_CMD_STATUS_ERROR; @@ -56,9 +55,8 @@ static RzCmdStatus types_enum_member_find(RzCore *core, const char *enum_name, c static RzCmdStatus types_enum_member_find_all(RzCore *core, const char *enum_value) { rz_return_val_if_fail(enum_value, RZ_CMD_STATUS_ERROR); - Sdb *TDB = core->analysis->sdb_types; ut64 value = rz_num_math(core->num, enum_value); - RzList *matches = rz_type_enum_find_member(TDB, value); + RzList *matches = rz_type_enum_find_member(core->analysis->type, value); if (!matches || rz_list_empty(matches)) { eprintf("Cannot find matching enum member"); return RZ_CMD_STATUS_ERROR; @@ -73,21 +71,20 @@ static RzCmdStatus types_enum_member_find_all(RzCore *core, const char *enum_val } static bool print_type_c(RzCore *core, const char *ctype) { - Sdb *TDB = core->analysis->sdb_types; const char *type = rz_str_trim_head_ro(ctype); const char *name = type ? strchr(type, '.') : NULL; if (name && type) { name++; // skip the '.' if (rz_str_startswith(type, "struct")) { - rz_types_struct_print_c(TDB, name, true); + rz_types_struct_print_c(core->analysis->type, name, true); } else if (rz_str_startswith(type, "union")) { - rz_types_union_print_c(TDB, name, true); + rz_types_union_print_c(core->analysis->type, name, true); } else if (rz_str_startswith(type, "enum")) { - rz_types_enum_print_c(TDB, name, true); + rz_types_enum_print_c(core->analysis->type, name, true); } else if (rz_str_startswith(type, "typedef")) { - rz_types_typedef_print_c(TDB, name); + rz_types_typedef_print_c(core->analysis->type, name); } else if (rz_str_startswith(type, "func")) { - rz_types_function_print(TDB, name, RZ_OUTPUT_MODE_STANDARD, NULL); + rz_types_function_print(core->analysis->type, name, RZ_OUTPUT_MODE_STANDARD, NULL); } return true; } @@ -95,32 +92,29 @@ static bool print_type_c(RzCore *core, const char *ctype) { } static void type_list_c_all(RzCore *core) { - Sdb *TDB = core->analysis->sdb_types; // List all unions in the C format with newlines - rz_types_union_print_c(TDB, NULL, true); + rz_types_union_print_c(core->analysis->type, NULL, true); // List all structures in the C format with newlines - rz_types_struct_print_c(TDB, NULL, true); + rz_types_struct_print_c(core->analysis->type, NULL, true); // List all typedefs in the C format with newlines - rz_types_typedef_print_c(TDB, NULL); + rz_types_typedef_print_c(core->analysis->type, NULL); // List all enums in the C format with newlines - rz_types_enum_print_c(TDB, NULL, true); + rz_types_enum_print_c(core->analysis->type, NULL, true); } static void type_list_c_all_nl(RzCore *core) { - Sdb *TDB = core->analysis->sdb_types; // List all unions in the C format without newlines - rz_types_union_print_c(TDB, NULL, false); + rz_types_union_print_c(core->analysis->type, NULL, false); // List all structures in the C format without newlines - rz_types_struct_print_c(TDB, NULL, false); + rz_types_struct_print_c(core->analysis->type, NULL, false); // List all typedefs in the C format without newlines - rz_types_typedef_print_c(TDB, NULL); + rz_types_typedef_print_c(core->analysis->type, NULL); // List all enums in the C format without newlines - rz_types_enum_print_c(TDB, NULL, false); + rz_types_enum_print_c(core->analysis->type, NULL, false); } static RzCmdStatus type_format_print(RzCore *core, const char *type, ut64 address) { - Sdb *TDB = core->analysis->sdb_types; - char *fmt = rz_type_format(TDB, type); + char *fmt = rz_type_format(core->analysis->type, type); if (RZ_STR_ISEMPTY(fmt)) { eprintf("Cannot find type %s\n", type); return RZ_CMD_STATUS_ERROR; @@ -130,8 +124,7 @@ static RzCmdStatus type_format_print(RzCore *core, const char *type, ut64 addres } static RzCmdStatus type_format_print_variable(RzCore *core, const char *type, const char *varname) { - Sdb *TDB = core->analysis->sdb_types; - char *fmt = rz_type_format(TDB, type); + char *fmt = rz_type_format(core->analysis->type, type); if (RZ_STR_ISEMPTY(fmt)) { eprintf("Cannot find type \"%s\"\n", type); return RZ_CMD_STATUS_ERROR; @@ -152,8 +145,7 @@ static RzCmdStatus type_format_print_variable(RzCore *core, const char *type, co } static RzCmdStatus type_format_print_value(RzCore *core, const char *type, ut64 val) { - Sdb *TDB = core->analysis->sdb_types; - char *fmt = rz_type_format(TDB, type); + char *fmt = rz_type_format(core->analysis->type, type); if (RZ_STR_ISEMPTY(fmt)) { eprintf("Cannot find type %s\n", type); return RZ_CMD_STATUS_ERROR; @@ -163,8 +155,7 @@ static RzCmdStatus type_format_print_value(RzCore *core, const char *type, ut64 } static RzCmdStatus type_format_print_hexstring(RzCore *core, const char *type, const char *hexpairs) { - Sdb *TDB = core->analysis->sdb_types; - char *fmt = rz_type_format(TDB, type); + char *fmt = rz_type_format(core->analysis->type, type); if (RZ_STR_ISEMPTY(fmt)) { eprintf("Cannot find type %s\n", type); return RZ_CMD_STATUS_ERROR; @@ -476,7 +467,7 @@ static void cmd_type_noreturn(RzCore *core, const char *input) { switch (input[0]) { case '-': // "tn-" if (input[1] == '*') { - RzList *noretl = rz_types_function_noreturn(core->analysis->sdb_types); + RzList *noretl = rz_type_noreturn_functions(core->analysis->type); RzListIter *iter; char *name; rz_list_foreach (noretl, iter, name) { @@ -548,7 +539,7 @@ static void types_list(RzCore *core, int mode) { RZ_IPI int rz_cmd_type(void *data, const char *input) { RzCore *core = (RzCore *)data; - Sdb *TDB = core->analysis->sdb_types; + RzType *T = core->analysis->type; char *res; switch (input[0]) { @@ -565,7 +556,7 @@ RZ_IPI int rz_cmd_type(void *data, const char *input) { if (input[2] == ' ') { rz_core_types_show_format(core, rz_str_trim_head_ro(input + 2), RZ_OUTPUT_MODE_RIZIN); } else { - rz_core_types_union_print_format_all(core, TDB); + rz_core_types_union_print_format_all(core); } break; case 'j': // "tuj" @@ -573,27 +564,27 @@ RZ_IPI int rz_cmd_type(void *data, const char *input) { rz_core_types_show_format(core, rz_str_trim_head_ro(input + 2), RZ_OUTPUT_MODE_JSON); rz_cons_newline(); } else { - rz_types_union_print_json(TDB); + rz_types_union_print_json(T); } break; case 'c': // "tuc" - rz_types_union_print_c(TDB, rz_str_trim_head_ro(input + 2), true); + rz_types_union_print_c(T, rz_str_trim_head_ro(input + 2), true); break; case 'd': // "tud" - rz_types_union_print_c(TDB, rz_str_trim_head_ro(input + 2), false); + rz_types_union_print_c(T, rz_str_trim_head_ro(input + 2), false); break; case ' ': // "tu " rz_core_types_show_format(core, rz_str_trim_head_ro(input + 1), RZ_OUTPUT_MODE_STANDARD); break; case 0: - rz_types_union_print_sdb(TDB); + rz_types_union_print_sdb(T); break; } } break; case 'k': // "tk" res = (input[1] == ' ') - ? sdb_querys(TDB, NULL, -1, input + 2) - : sdb_querys(TDB, NULL, -1, "*"); + ? rz_type_kuery(T, input + 2) + : rz_type_kuery(T, "*"); if (res) { rz_cons_print(res); free(res); @@ -633,7 +624,7 @@ RZ_IPI int rz_cmd_type(void *data, const char *input) { if (input[2] == ' ') { rz_core_types_show_format(core, rz_str_trim_head_ro(input + 1), RZ_OUTPUT_MODE_RIZIN); } else { - rz_core_types_struct_print_format_all(core, TDB); + rz_core_types_struct_print_format_all(core); } break; case ' ': @@ -641,19 +632,19 @@ RZ_IPI int rz_cmd_type(void *data, const char *input) { break; case 's': if (input[2] == ' ') { - rz_cons_printf("%" PFMT64u "\n", (rz_type_get_bitsize(TDB, input + 3) / 8)); + rz_cons_printf("%" PFMT64u "\n", (rz_type_get_bitsize(T, input + 3) / 8)); } else { rz_core_cmd_help(core, help_msg_ts); } break; case 0: - rz_types_struct_print_sdb(TDB); + rz_types_struct_print_sdb(T); break; case 'c': // "tsc" - rz_types_struct_print_c(TDB, rz_str_trim_head_ro(input + 2), true); + rz_types_struct_print_c(T, rz_str_trim_head_ro(input + 2), true); break; case 'd': // "tsd" - rz_types_struct_print_c(TDB, rz_str_trim_head_ro(input + 2), false); + rz_types_struct_print_c(T, rz_str_trim_head_ro(input + 2), false); break; case 'j': // "tsj" // TODO: current output is a bit poor, will be good to improve @@ -661,21 +652,21 @@ RZ_IPI int rz_cmd_type(void *data, const char *input) { rz_core_types_show_format(core, rz_str_trim_head_ro(input + 2), RZ_OUTPUT_MODE_JSON); rz_cons_newline(); } else { - rz_types_struct_print_json(TDB); + rz_types_struct_print_json(T); } break; } } break; case 'e': { // "te" char *res = NULL, *temp = strchr(input, ' '); - Sdb *TDB = core->analysis->sdb_types; + RzType *T = core->analysis->type; char *name = temp ? strdup(temp + 1) : NULL; char *member_value = name ? strchr(name, ' ') : NULL; if (member_value) { *member_value++ = 0; } - if (name && (rz_type_kind(TDB, name) != RZ_TYPE_ENUM)) { + if (name && (rz_type_kind(T, name) != RZ_BASE_TYPE_KIND_ENUM)) { eprintf("%s is not an enum\n", name); free(name); break; @@ -707,13 +698,13 @@ RZ_IPI int rz_cmd_type(void *data, const char *input) { } break; case 'b': // "teb" - res = rz_type_enum_member(TDB, name, member_value, 0); + res = rz_type_enum_member(T, name, member_value, 0); break; case 'c': // "tec" - rz_types_enum_print_c(TDB, rz_str_trim_head_ro(input + 2), true); + rz_types_enum_print_c(T, rz_str_trim_head_ro(input + 2), true); break; case 'd': // "ted" - rz_types_enum_print_c(TDB, rz_str_trim_head_ro(input + 2), false); + rz_types_enum_print_c(T, rz_str_trim_head_ro(input + 2), false); break; case 'f': // "tef" if (member_value) { @@ -755,7 +746,7 @@ RZ_IPI int rz_cmd_type(void *data, const char *input) { if (input[1] == ' ') { rz_types_open_file(core, input + 2); } else if (input[1] == 's') { // "tos" - rz_types_open_sdb(core, input + 3); + rz_type_load_sdb(core->analysis->type, input + 3); } else if (input[1] == 'e') { // "toe" rz_types_open_editor(core, input + 2); } @@ -849,12 +840,12 @@ RZ_IPI int rz_cmd_type(void *data, const char *input) { case '-': switch (input[2]) { case '*': - rz_type_unlink_all(TDB); + rz_type_unlink_all(T); break; case ' ': { const char *ptr = input + 3; ut64 addr = rz_num_math(core->num, ptr); - rz_type_unlink(TDB, addr); + rz_type_unlink(T, addr); break; } } @@ -919,12 +910,12 @@ RZ_IPI int rz_cmd_type(void *data, const char *input) { if (input[1] == '?') { rz_core_cmd_help(core, help_msg_t_minus); } else if (input[1] == '*') { - sdb_reset(TDB); - rz_parse_c_reset(core->parser); + rz_type_purge(core->analysis->type); + rz_type_parse_c_reset(core->analysis->type); } else { const char *name = rz_str_trim_head_ro(input + 1); if (*name) { - rz_analysis_remove_parsed_type(core->analysis, name); + rz_type_remove_parsed_type(core->analysis->type, name); } else { eprintf("Invalid use of t- . See t-? for help.\n"); } @@ -939,7 +930,7 @@ RZ_IPI int rz_cmd_type(void *data, const char *input) { case 'k': // "tfk" if (input[2] == ' ') { const char *name = rz_str_trim_head_ro(input + 3); - rz_types_function_print(TDB, name, RZ_OUTPUT_MODE_SDB, NULL); + rz_types_function_print(T, name, RZ_OUTPUT_MODE_SDB, NULL); } else { rz_core_types_function_print_all(core, RZ_OUTPUT_MODE_SDB); } @@ -948,7 +939,7 @@ RZ_IPI int rz_cmd_type(void *data, const char *input) { if (input[2] == ' ') { const char *name = rz_str_trim_head_ro(input + 2); PJ *pj = rz_core_pj_new(core); - rz_types_function_print(TDB, name, RZ_OUTPUT_MODE_JSON, pj); + rz_types_function_print(T, name, RZ_OUTPUT_MODE_JSON, pj); pj_end(pj); rz_cons_println(pj_string(pj)); pj_free(pj); @@ -958,7 +949,7 @@ RZ_IPI int rz_cmd_type(void *data, const char *input) { break; case ' ': { const char *name = rz_str_trim_head_ro(input + 2); - rz_types_function_print(TDB, name, RZ_OUTPUT_MODE_SDB, NULL); + rz_types_function_print(T, name, RZ_OUTPUT_MODE_SDB, NULL); break; } default: @@ -974,7 +965,7 @@ RZ_IPI int rz_cmd_type(void *data, const char *input) { break; } if (input[1] == 'c') { // "ttc" - rz_types_typedef_print_c(TDB, input + 2); + rz_types_typedef_print_c(T, input + 2); break; } if (input[1] == '?') { // "tt?" @@ -1010,13 +1001,13 @@ RZ_IPI RzCmdStatus rz_type_handler(RzCore *core, int argc, const char **argv, Rz } RZ_IPI RzCmdStatus rz_type_del_handler(RzCore *core, int argc, const char **argv) { - rz_analysis_remove_parsed_type(core->analysis, argv[1]); + rz_type_remove_parsed_type(core->analysis->type, argv[1]); return RZ_CMD_STATUS_OK; } RZ_IPI RzCmdStatus rz_type_del_all_handler(RzCore *core, int argc, const char **argv) { - sdb_reset(core->analysis->sdb_types); - rz_parse_c_reset(core->parser); + rz_type_purge(core->analysis->type); + rz_type_parse_c_reset(core->analysis->type); return RZ_CMD_STATUS_OK; } @@ -1093,8 +1084,7 @@ RZ_IPI RzCmdStatus rz_type_list_enum_handler(RzCore *core, int argc, const char RZ_IPI RzCmdStatus rz_type_enum_bitfield_handler(RzCore *core, int argc, const char **argv) { const char *enum_name = argc > 1 ? argv[1] : NULL; const char *enum_member = argc > 2 ? argv[2] : NULL; - Sdb *TDB = core->analysis->sdb_types; - char *output = rz_type_enum_member(TDB, enum_name, enum_member, 0); + char *output = rz_type_enum_member(core->analysis->type, enum_name, enum_member, 0); if (!output) { eprintf("Cannot find anything matching the specified bitfield"); return RZ_CMD_STATUS_ERROR; @@ -1106,15 +1096,13 @@ RZ_IPI RzCmdStatus rz_type_enum_bitfield_handler(RzCore *core, int argc, const c RZ_IPI RzCmdStatus rz_type_enum_c_handler(RzCore *core, int argc, const char **argv) { const char *enum_name = argc > 1 ? argv[1] : NULL; - Sdb *TDB = core->analysis->sdb_types; - rz_types_enum_print_c(TDB, enum_name, true); + rz_types_enum_print_c(core->analysis->type, enum_name, true); return RZ_CMD_STATUS_OK; } RZ_IPI RzCmdStatus rz_type_enum_c_nl_handler(RzCore *core, int argc, const char **argv) { const char *enum_name = argc > 1 ? argv[1] : NULL; - Sdb *TDB = core->analysis->sdb_types; - rz_types_enum_print_c(TDB, enum_name, false); + rz_types_enum_print_c(core->analysis->type, enum_name, false); return RZ_CMD_STATUS_OK; } @@ -1127,7 +1115,7 @@ RZ_IPI RzCmdStatus rz_type_list_function_handler(RzCore *core, int argc, const c const char *function = argc > 1 ? argv[1] : NULL; if (function) { PJ *pj = (mode == RZ_OUTPUT_MODE_JSON) ? rz_core_pj_new(core) : NULL; - rz_types_function_print(core->analysis->sdb_types, function, mode, pj); + rz_types_function_print(core->analysis->type, function, mode, pj); if (mode == RZ_OUTPUT_MODE_JSON) { rz_cons_println(pj_string(pj)); pj_free(pj); @@ -1140,13 +1128,7 @@ RZ_IPI RzCmdStatus rz_type_list_function_handler(RzCore *core, int argc, const c RZ_IPI RzCmdStatus rz_type_kuery_handler(RzCore *core, int argc, const char **argv) { const char *query = argc > 1 ? argv[1] : NULL; - Sdb *TDB = core->analysis->sdb_types; - char *output = NULL; - if (query) { - output = sdb_querys(TDB, NULL, -1, query); - } else { - output = sdb_querys(TDB, NULL, -1, "*"); - } + char *output = rz_type_kuery(core->analysis->type, query); if (!output) { eprintf("Cannot find anything matching your query"); return RZ_CMD_STATUS_ERROR; @@ -1174,15 +1156,13 @@ RZ_IPI RzCmdStatus rz_type_link_show_handler(RzCore *core, int argc, const char } RZ_IPI RzCmdStatus rz_type_link_del_handler(RzCore *core, int argc, const char **argv) { - Sdb *TDB = core->analysis->sdb_types; ut64 addr = rz_num_math(core->num, argv[1]); - rz_type_unlink(TDB, addr); + rz_type_unlink(core->analysis->type, addr); return RZ_CMD_STATUS_OK; } RZ_IPI RzCmdStatus rz_type_link_del_all_handler(RzCore *core, int argc, const char **argv) { - Sdb *TDB = core->analysis->sdb_types; - rz_type_unlink_all(TDB); + rz_type_unlink_all(core->analysis->type); return RZ_CMD_STATUS_OK; } @@ -1209,7 +1189,7 @@ RZ_IPI RzCmdStatus rz_type_noreturn_del_handler(RzCore *core, int argc, const ch } RZ_IPI RzCmdStatus rz_type_noreturn_del_all_handler(RzCore *core, int argc, const char **argv) { - RzList *noretl = rz_types_function_noreturn(core->analysis->sdb_types); + RzList *noretl = rz_type_noreturn_functions(core->analysis->type); RzListIter *iter; char *name; rz_list_foreach (noretl, iter, name) { @@ -1230,7 +1210,7 @@ RZ_IPI RzCmdStatus rz_type_open_editor_handler(RzCore *core, int argc, const cha } RZ_IPI RzCmdStatus rz_type_open_sdb_handler(RzCore *core, int argc, const char **argv) { - rz_types_open_sdb(core, argv[1]); + rz_type_load_sdb(core->analysis->type, argv[1]); return RZ_CMD_STATUS_OK; } @@ -1260,16 +1240,15 @@ RZ_IPI RzCmdStatus rz_type_print_hexstring_handler(RzCore *core, int argc, const RZ_IPI RzCmdStatus rz_type_list_structure_handler(RzCore *core, int argc, const char **argv, RzOutputMode mode) { const char *typename = argc > 1 ? argv[1] : NULL; - Sdb *TDB = core->analysis->sdb_types; if (typename) { rz_core_types_show_format(core, typename, mode); } else { if (mode == RZ_OUTPUT_MODE_RIZIN) { - rz_core_types_struct_print_format_all(core, TDB); + rz_core_types_struct_print_format_all(core); } else if (mode == RZ_OUTPUT_MODE_JSON) { - rz_types_struct_print_json(TDB); + rz_types_struct_print_json(core->analysis->type); } else { - rz_types_struct_print_sdb(TDB); + rz_types_struct_print_sdb(core->analysis->type); } } return RZ_CMD_STATUS_OK; @@ -1277,15 +1256,13 @@ RZ_IPI RzCmdStatus rz_type_list_structure_handler(RzCore *core, int argc, const RZ_IPI RzCmdStatus rz_type_structure_c_handler(RzCore *core, int argc, const char **argv) { const char *typename = argc > 1 ? argv[1] : NULL; - Sdb *TDB = core->analysis->sdb_types; - rz_types_struct_print_c(TDB, typename, true); + rz_types_struct_print_c(core->analysis->type, typename, true); return RZ_CMD_STATUS_OK; } RZ_IPI RzCmdStatus rz_type_structure_c_nl_handler(RzCore *core, int argc, const char **argv) { const char *typename = argc > 1 ? argv[1] : NULL; - Sdb *TDB = core->analysis->sdb_types; - rz_types_struct_print_c(TDB, typename, false); + rz_types_struct_print_c(core->analysis->type, typename, false); return RZ_CMD_STATUS_OK; } @@ -1304,27 +1281,27 @@ RZ_IPI RzCmdStatus rz_type_list_typedef_handler(RzCore *core, int argc, const ch RZ_IPI RzCmdStatus rz_type_typedef_c_handler(RzCore *core, int argc, const char **argv) { const char *typename = argc > 1 ? argv[1] : NULL; - Sdb *TDB = core->analysis->sdb_types; + RzType *T = core->analysis->type; if (!typename) { - rz_types_typedef_print_c(TDB, NULL); + rz_types_typedef_print_c(T, NULL); return RZ_CMD_STATUS_OK; } - rz_types_typedef_print_c(TDB, typename); + rz_types_typedef_print_c(T, typename); return RZ_CMD_STATUS_OK; } RZ_IPI RzCmdStatus rz_type_list_union_handler(RzCore *core, int argc, const char **argv, RzOutputMode mode) { const char *typename = argc > 1 ? argv[1] : NULL; - Sdb *TDB = core->analysis->sdb_types; + RzType *T = core->analysis->type; if (typename) { rz_core_types_show_format(core, typename, mode); } else { if (mode == RZ_OUTPUT_MODE_RIZIN) { - rz_core_types_union_print_format_all(core, TDB); + rz_core_types_union_print_format_all(core); } else if (mode == RZ_OUTPUT_MODE_JSON) { - rz_types_union_print_json(TDB); + rz_types_union_print_json(T); } else { - rz_types_union_print_sdb(TDB); + rz_types_union_print_sdb(T); } } return RZ_CMD_STATUS_OK; @@ -1332,15 +1309,13 @@ RZ_IPI RzCmdStatus rz_type_list_union_handler(RzCore *core, int argc, const char RZ_IPI RzCmdStatus rz_type_union_c_handler(RzCore *core, int argc, const char **argv) { const char *typename = argc > 1 ? argv[1] : NULL; - Sdb *TDB = core->analysis->sdb_types; - rz_types_union_print_c(TDB, typename, true); + rz_types_union_print_c(core->analysis->type, typename, true); return RZ_CMD_STATUS_OK; } RZ_IPI RzCmdStatus rz_type_union_c_nl_handler(RzCore *core, int argc, const char **argv) { const char *typename = argc > 1 ? argv[1] : NULL; - Sdb *TDB = core->analysis->sdb_types; - rz_types_union_print_c(TDB, typename, false); + rz_types_union_print_c(core->analysis->type, typename, false); return RZ_CMD_STATUS_OK; } diff --git a/librz/core/cmd_zign.c b/librz/core/cmd_zign.c index 2e1aba15db8..b25fc27c939 100644 --- a/librz/core/cmd_zign.c +++ b/librz/core/cmd_zign.c @@ -627,7 +627,7 @@ static void apply_types(RzCore *core, RzAnalysisFunction *fcn, RzSignItem *it) { } } rz_str_remove_char(alltypes, '"'); - rz_analysis_save_parsed_type(core->analysis, alltypes); + rz_type_save_parsed_type(core->analysis->type, alltypes); free(start); free(alltypes); } diff --git a/librz/core/core.c b/librz/core/core.c index da03b24ed92..fe96243453d 100644 --- a/librz/core/core.c +++ b/librz/core/core.c @@ -1718,34 +1718,6 @@ RZ_API void rz_core_autocomplete(RZ_NULLABLE RzCore *core, RzLineCompletion *com } } rz_list_free(vars); - } else if (!strncmp(buf->data, "t ", 2) || !strncmp(buf->data, "t- ", 3)) { - SdbList *l = sdb_foreach_list(core->analysis->sdb_types, true); - SdbListIter *iter; - SdbKv *kv; - int chr = (buf->data[1] == ' ') ? 2 : 3; - ls_foreach (l, iter, kv) { - int len = strlen(buf->data + chr); - if (!len || !strncmp(buf->data + chr, sdbkv_key(kv), len)) { - if (!strcmp(sdbkv_value(kv), "type") || !strcmp(sdbkv_value(kv), "enum") || !strcmp(sdbkv_value(kv), "struct")) { - rz_line_completion_push(completion, sdbkv_key(kv)); - } - } - } - ls_free(l); - } else if ((!strncmp(buf->data, "te ", 3))) { - SdbList *l = sdb_foreach_list(core->analysis->sdb_types, true); - SdbListIter *iter; - SdbKv *kv; - int chr = 3; - ls_foreach (l, iter, kv) { - int len = strlen(buf->data + chr); - if (!len || !strncmp(buf->data + chr, sdbkv_key(kv), len)) { - if (!strcmp(sdbkv_value(kv), "enum")) { - rz_line_completion_push(completion, sdbkv_key(kv)); - } - } - } - ls_free(l); } else if (!strncmp(buf->data, "$", 1)) { int i; for (i = 0; i < core->rcmd->aliases.count; i++) { @@ -1755,21 +1727,6 @@ RZ_API void rz_core_autocomplete(RZ_NULLABLE RzCore *core, RzLineCompletion *com rz_line_completion_push(completion, key); } } - } else if (!strncmp(buf->data, "ts ", 3) || !strncmp(buf->data, "ta ", 3) || !strncmp(buf->data, "tp ", 3) || !strncmp(buf->data, "tl ", 3) || !strncmp(buf->data, "tpx ", 4) || !strncmp(buf->data, "tss ", 4) || !strncmp(buf->data, "ts* ", 4)) { - SdbList *l = sdb_foreach_list(core->analysis->sdb_types, true); - SdbListIter *iter; - SdbKv *kv; - int chr = (buf->data[2] == ' ') ? 3 : 4; - ls_foreach (l, iter, kv) { - int len = strlen(buf->data + chr); - const char *key = sdbkv_key(kv); - if (!len || !strncmp(buf->data + chr, key, len)) { - if (!strncmp(sdbkv_value(kv), "struct", strlen("struct") + 1)) { - rz_line_completion_push(completion, key); - } - } - } - ls_free(l); } else if (!strncmp(buf->data, "zo ", 3) || !strncmp(buf->data, "zoz ", 4)) { if (core->analysis->zign_path && core->analysis->zign_path[0]) { char *zignpath = rz_file_abspath(core->analysis->zign_path); @@ -2552,7 +2509,6 @@ RZ_API bool rz_core_init(RzCore *core) { core->analysis->cb.on_fcn_new = on_fcn_new; core->analysis->cb.on_fcn_delete = on_fcn_delete; core->analysis->cb.on_fcn_rename = on_fcn_rename; - core->print->sdb_types = core->analysis->sdb_types; core->rasm->syscall = rz_syscall_ref(core->analysis->syscall); // BIND syscall analysis/asm core->analysis->core = core; core->analysis->cb_printf = (void *)rz_cons_printf; diff --git a/librz/core/core_private.h b/librz/core/core_private.h index faa75b2a7fb..2b1b0f3e794 100644 --- a/librz/core/core_private.h +++ b/librz/core/core_private.h @@ -45,48 +45,43 @@ RZ_IPI void rz_core_analysis_function_until(RzCore *core, ut64 addr_end); RZ_IPI void rz_core_analysis_value_pointers(RzCore *core, RzOutputMode mode); /* ctypes.c */ -RZ_IPI RzList *rz_types_calling_conventions(Sdb *db); RZ_IPI void rz_core_types_calling_conventions_print(RzCore *core, RzOutputMode mode); -RZ_IPI RzList *rz_types_enums(Sdb *db); RZ_IPI void rz_core_types_enum_print(RzCore *core, const char *enum_name, RzOutputMode mode, PJ *pj); RZ_IPI void rz_core_types_enum_print_all(RzCore *core, RzOutputMode mode); -RZ_IPI void rz_types_enum_print_c(Sdb *TDB, const char *arg, bool multiline); +RZ_IPI void rz_types_enum_print_c(RzType *type, const char *arg, bool multiline); RZ_IPI bool rz_core_types_typedef_info(RzCore *core, const char *name); -RZ_IPI void rz_types_typedef_print_c(Sdb *TDB, const char *typedef_name); +RZ_IPI void rz_types_typedef_print_c(RzType *type, const char *typedef_name); RZ_IPI void rz_core_list_loaded_typedefs(RzCore *core, RzOutputMode mode); -RZ_IPI RzList *rz_types_typedefs(Sdb *TDB); -RZ_IPI RzList *rz_types_unions(Sdb *TDB); -RZ_IPI RzList *rz_types_structs(Sdb *TDB); +RZ_IPI RzList *rz_types_unions(RzType *type); +RZ_IPI RzList *rz_types_structs(RzType *type); +RZ_IPI RzList *rz_types_all(RzType *type); // Structured types JSON -RZ_IPI void rz_types_structured_print_json(Sdb *TDB, SdbList *l); -RZ_IPI void rz_types_union_print_json(Sdb *TDB); -RZ_IPI void rz_types_struct_print_json(Sdb *TDB); +RZ_IPI void rz_types_structured_print_json(SdbList *l); +RZ_IPI void rz_types_union_print_json(RzType *type); +RZ_IPI void rz_types_struct_print_json(RzType *type); // Structured types SDB -RZ_IPI void rz_types_structured_print_sdb(Sdb *TDB, SdbList *l); -RZ_IPI void rz_types_union_print_sdb(Sdb *TDB); -RZ_IPI void rz_types_struct_print_sdb(Sdb *TDB); +RZ_IPI void rz_types_structured_print_sdb(SdbList *l); +RZ_IPI void rz_types_union_print_sdb(RzType *type); +RZ_IPI void rz_types_struct_print_sdb(RzType *type); // Structured types C format -RZ_IPI void rz_types_union_print_c(Sdb *TDB, const char *name, bool multiline); -RZ_IPI void rz_types_struct_print_c(Sdb *TDB, const char *name, bool multiline); -RZ_IPI void rz_types_function_print(Sdb *TDB, const char *function, RzOutputMode mode, PJ *pj); +RZ_IPI void rz_types_union_print_c(RzType *type, const char *name, bool multiline); +RZ_IPI void rz_types_struct_print_c(RzType *type, const char *name, bool multiline); +RZ_IPI void rz_types_function_print(RzType *type, const char *function, RzOutputMode mode, PJ *pj); RZ_IPI void rz_core_types_function_print_all(RzCore *core, RzOutputMode mode); -RZ_IPI RzList *rz_types_function_noreturn(Sdb *db); RZ_IPI void rz_core_types_function_noreturn_print(RzCore *core, RzOutputMode mode); RZ_IPI void rz_core_types_show_format(RzCore *core, const char *name, RzOutputMode mode); -RZ_IPI void rz_core_types_struct_print_format_all(RzCore *core, Sdb *TDB); -RZ_IPI void rz_core_types_union_print_format_all(RzCore *core, Sdb *TDB); -RZ_IPI RzList *rz_types_links(Sdb *db); +RZ_IPI void rz_core_types_struct_print_format_all(RzCore *core); +RZ_IPI void rz_core_types_union_print_format_all(RzCore *core); RZ_IPI void rz_core_types_link_print(RzCore *core, const char *type, ut64 addr, RzOutputMode mode, PJ *pj); RZ_IPI void rz_core_types_link_print_all(RzCore *core, RzOutputMode mode); RZ_IPI void rz_core_types_link(RzCore *core, const char *type, ut64 addr); RZ_IPI void rz_core_types_link_show(RzCore *core, ut64 addr); RZ_IPI void rz_core_types_print_all(RzCore *core, RzOutputMode mode); -RZ_IPI RzList *rz_types_all(Sdb *TDB); RZ_IPI void rz_types_define(RzCore *core, const char *type); RZ_IPI void rz_types_open_file(RzCore *core, const char *path); RZ_IPI void rz_types_open_editor(RzCore *core, const char *typename); -RZ_IPI void rz_types_open_sdb(RzCore *core, const char *path); +RZ_IPI void rz_types_open_sdb(RzType *type, const char *path); /* agraph.c */ RZ_IPI void rz_core_agraph_add_node(RzCore *core, const char *title, const char *body, int color); diff --git a/librz/core/ctypes.c b/librz/core/ctypes.c index 13956393de2..4c589c35684 100644 --- a/librz/core/ctypes.c +++ b/librz/core/ctypes.c @@ -9,6 +9,7 @@ #include #include #include +#include #include "core_private.h" @@ -27,22 +28,9 @@ static void kv_lines_print_sorted(char *kv_lines) { // Calling conventions -RZ_IPI RzList *rz_types_calling_conventions(Sdb *db) { - RzList *ccl = rz_list_new(); - SdbKv *kv; - SdbListIter *iter; - SdbList *l = sdb_foreach_list(db, true); - ls_foreach (l, iter, kv) { - if (!strcmp(sdbkv_value(kv), "cc")) { - rz_list_append(ccl, strdup(sdbkv_key(kv))); - } - } - ls_free(l); - return ccl; -} - +// TODO: Technically it doesn't belong in types and `t` commands RZ_IPI void rz_core_types_calling_conventions_print(RzCore *core, RzOutputMode mode) { - RzList *list = rz_types_calling_conventions(core->analysis->sdb_cc); + RzList *list = rz_analysis_calling_conventions(core->analysis); RzListIter *iter; const char *cc; switch (mode) { @@ -90,29 +78,15 @@ RZ_IPI void rz_core_types_calling_conventions_print(RzCore *core, RzOutputMode m // Enums -RZ_IPI RzList *rz_types_enums(Sdb *db) { - RzList *ccl = rz_list_new(); - SdbKv *kv; - SdbListIter *iter; - SdbList *l = sdb_foreach_list(db, true); - ls_foreach (l, iter, kv) { - if (!strcmp(sdbkv_value(kv), "enum")) { - rz_list_append(ccl, strdup(sdbkv_key(kv))); - } - } - ls_free(l); - return ccl; -} - RZ_IPI void rz_core_types_enum_print(RzCore *core, const char *enum_name, RzOutputMode mode, PJ *pj) { rz_return_if_fail(enum_name); - Sdb *TDB = core->analysis->sdb_types; + RzType *T = core->analysis->type; switch (mode) { case RZ_OUTPUT_MODE_JSON: { rz_return_if_fail(pj); - RTypeEnum *member; + RzTypeEnum *member; RzListIter *iter; - RzList *list = rz_type_get_enum(TDB, enum_name); + RzList *list = rz_type_get_enum(T, enum_name); pj_o(pj); if (list && !rz_list_empty(list)) { pj_ks(pj, "name", enum_name); @@ -128,9 +102,9 @@ RZ_IPI void rz_core_types_enum_print(RzCore *core, const char *enum_name, RzOutp break; } case RZ_OUTPUT_MODE_STANDARD: { - RzList *list = rz_type_get_enum(TDB, enum_name); + RzList *list = rz_type_get_enum(T, enum_name); RzListIter *iter; - RTypeEnum *member; + RzTypeEnum *member; rz_list_foreach (list, iter, member) { rz_cons_printf("%s = %s\n", member->name, member->val); } @@ -141,6 +115,7 @@ RZ_IPI void rz_core_types_enum_print(RzCore *core, const char *enum_name, RzOutp rz_cons_println(enum_name); break; case RZ_OUTPUT_MODE_SDB: { + Sdb *TDB = T->sdb_types; char *keys = sdb_querys(TDB, NULL, -1, sdb_fmt("~~enum.%s", enum_name)); if (keys) { kv_lines_print_sorted(keys); @@ -154,8 +129,7 @@ RZ_IPI void rz_core_types_enum_print(RzCore *core, const char *enum_name, RzOutp } RZ_IPI void rz_core_types_enum_print_all(RzCore *core, RzOutputMode mode) { - Sdb *TDB = core->analysis->sdb_types; - RzList *enumlist = rz_types_enums(TDB); + RzList *enumlist = rz_type_enums(core->analysis->type); RzListIter *it; char *e; PJ *pj = (mode == RZ_OUTPUT_MODE_JSON) ? rz_core_pj_new(core) : NULL; @@ -173,11 +147,11 @@ RZ_IPI void rz_core_types_enum_print_all(RzCore *core, RzOutputMode mode) { } } -RZ_IPI void rz_types_enum_print_c(Sdb *TDB, const char *arg, bool multiline) { +RZ_IPI void rz_types_enum_print_c(RzType *type, const char *arg, bool multiline) { char *name = NULL; SdbKv *kv; SdbListIter *iter; - SdbList *l = sdb_foreach_list(TDB, true); + SdbList *l = sdb_foreach_list(type->sdb_types, true); const char *separator = ""; bool match = false; ls_foreach (l, iter, kv) { @@ -194,10 +168,10 @@ RZ_IPI void rz_types_enum_print_c(Sdb *TDB, const char *arg, bool multiline) { } rz_cons_printf("%s %s {%s", sdbkv_value(kv), name, multiline ? "\n" : ""); { - RzList *list = rz_type_get_enum(TDB, name); + RzList *list = rz_type_get_enum(type, name); if (list && !rz_list_empty(list)) { RzListIter *iter; - RTypeEnum *member; + RzTypeEnum *member; separator = multiline ? "\t" : ""; rz_list_foreach (list, iter, member) { rz_cons_printf("%s%s = %" PFMT64u, separator, member->name, rz_num_math(NULL, member->val)); @@ -239,7 +213,7 @@ static bool sdb_if_struct_cb(void *user, const char *k, const char *v) { return false; } -RZ_IPI void rz_types_structured_print_json(Sdb *TDB, SdbList *l) { +RZ_IPI void rz_types_structured_print_json(SdbList *l) { SdbKv *kv; SdbListIter *it; PJ *pj = pj_new(); @@ -263,19 +237,21 @@ RZ_IPI void rz_types_structured_print_json(Sdb *TDB, SdbList *l) { pj_free(pj); } -RZ_IPI void rz_types_union_print_json(Sdb *TDB) { +RZ_IPI void rz_types_union_print_json(RzType *type) { + Sdb *TDB = type->sdb_types; SdbList *l = sdb_foreach_list_filter(TDB, sdb_if_union_cb, true); - rz_types_structured_print_json(TDB, l); + rz_types_structured_print_json(l); ls_free(l); } -RZ_IPI void rz_types_struct_print_json(Sdb *TDB) { +RZ_IPI void rz_types_struct_print_json(RzType *type) { + Sdb *TDB = type->sdb_types; SdbList *l = sdb_foreach_list_filter_user(TDB, sdb_if_struct_cb, true, TDB); - rz_types_structured_print_json(TDB, l); + rz_types_structured_print_json(l); ls_free(l); } -RZ_IPI void rz_types_structured_print_sdb(Sdb *TDB, SdbList *l) { +RZ_IPI void rz_types_structured_print_sdb(SdbList *l) { SdbKv *kv; SdbListIter *it; ls_foreach (l, it, kv) { @@ -283,15 +259,17 @@ RZ_IPI void rz_types_structured_print_sdb(Sdb *TDB, SdbList *l) { } } -RZ_IPI void rz_types_union_print_sdb(Sdb *TDB) { +RZ_IPI void rz_types_union_print_sdb(RzType *type) { + Sdb *TDB = type->sdb_types; SdbList *l = sdb_foreach_list_filter(TDB, sdb_if_union_cb, true); - rz_types_structured_print_sdb(TDB, l); + rz_types_structured_print_sdb(l); ls_free(l); } -RZ_IPI void rz_types_struct_print_sdb(Sdb *TDB) { +RZ_IPI void rz_types_struct_print_sdb(RzType *type) { + Sdb *TDB = type->sdb_types; SdbList *l = sdb_foreach_list_filter_user(TDB, sdb_if_struct_cb, true, TDB); - rz_types_structured_print_sdb(TDB, l); + rz_types_structured_print_sdb(l); ls_free(l); } @@ -359,26 +337,30 @@ RZ_IPI void rz_types_structured_print_c(Sdb *TDB, SdbList *l, const char *arg, b free(name); } -RZ_IPI void rz_types_union_print_c(Sdb *TDB, const char *name, bool multiline) { +RZ_IPI void rz_types_union_print_c(RzType *type, const char *name, bool multiline) { + Sdb *TDB = type->sdb_types; SdbList *l = sdb_foreach_list_filter(TDB, sdb_if_union_cb, true); rz_types_structured_print_c(TDB, l, name, multiline); ls_free(l); } -RZ_IPI void rz_types_struct_print_c(Sdb *TDB, const char *name, bool multiline) { +RZ_IPI void rz_types_struct_print_c(RzType *type, const char *name, bool multiline) { + Sdb *TDB = type->sdb_types; SdbList *l = sdb_foreach_list_filter_user(TDB, sdb_if_struct_cb, true, TDB); rz_types_structured_print_c(TDB, l, name, multiline); ls_free(l); } -RZ_IPI RzList *rz_types_unions(Sdb *TDB) { +RZ_IPI RzList *rz_types_unions(RzType *type) { + Sdb *TDB = type->sdb_types; SdbList *sl = sdb_foreach_list_filter_user(TDB, sdb_if_union_cb, true, TDB); RzList *l = rz_list_of_sdblist(sl); ls_free(sl); return l; } -RZ_IPI RzList *rz_types_structs(Sdb *TDB) { +RZ_IPI RzList *rz_types_structs(RzType *type) { + Sdb *TDB = type->sdb_types; SdbList *sl = sdb_foreach_list_filter_user(TDB, sdb_if_struct_cb, true, TDB); RzList *l = rz_list_of_sdblist(sl); ls_free(sl); @@ -387,13 +369,9 @@ RZ_IPI RzList *rz_types_structs(Sdb *TDB) { // Typedefs -static bool sdb_if_typedef_cb(void *p, const char *k, const char *v) { - return !strncmp(v, "typedef", strlen("typedef") + 1); -} - RZ_IPI bool rz_core_types_typedef_info(RzCore *core, const char *name) { const char *istypedef; - Sdb *TDB = core->analysis->sdb_types; + Sdb *TDB = core->analysis->type->sdb_types; istypedef = sdb_const_get(TDB, name, 0); if (istypedef && !strncmp(istypedef, "typedef", 7)) { const char *q = sdb_fmt("typedef.%s", name); @@ -412,7 +390,7 @@ RZ_IPI bool rz_core_types_typedef_info(RzCore *core, const char *name) { RZ_IPI void rz_core_list_loaded_typedefs(RzCore *core, RzOutputMode mode) { PJ *pj = NULL; - Sdb *TDB = core->analysis->sdb_types; + Sdb *TDB = core->analysis->type->sdb_types; if (mode == RZ_OUTPUT_MODE_JSON) { pj = rz_core_pj_new(core); if (!pj) { @@ -448,11 +426,11 @@ RZ_IPI void rz_core_list_loaded_typedefs(RzCore *core, RzOutputMode mode) { ls_free(l); } -RZ_IPI void rz_types_typedef_print_c(Sdb *TDB, const char *typedef_name) { +RZ_IPI void rz_types_typedef_print_c(RzType *types, const char *typedef_name) { char *name = NULL; SdbKv *kv; SdbListIter *iter; - SdbList *l = sdb_foreach_list(TDB, true); + SdbList *l = sdb_foreach_list(types->sdb_types, true); bool match = false; ls_foreach (l, iter, kv) { if (!strcmp(sdbkv_value(kv), "typedef")) { @@ -467,7 +445,7 @@ RZ_IPI void rz_types_typedef_print_c(Sdb *TDB, const char *typedef_name) { } } const char *q = sdb_fmt("typedef.%s", name); - const char *res = sdb_const_get(TDB, q, 0); + const char *res = sdb_const_get(types->sdb_types, q, 0); if (res) { rz_cons_printf("%s %s %s;\n", sdbkv_value(kv), res, name); } @@ -481,17 +459,11 @@ RZ_IPI void rz_types_typedef_print_c(Sdb *TDB, const char *typedef_name) { ls_free(l); } -RZ_IPI RzList *rz_types_typedefs(Sdb *TDB) { - SdbList *sl = sdb_foreach_list_filter_user(TDB, sdb_if_typedef_cb, true, TDB); - RzList *l = rz_list_of_sdblist(sl); - ls_free(sl); - return l; -} - // Function types -RZ_IPI void rz_types_function_print(Sdb *TDB, const char *function, RzOutputMode mode, PJ *pj) { +RZ_IPI void rz_types_function_print(RzType *type, const char *function, RzOutputMode mode, PJ *pj) { rz_return_if_fail(function); + Sdb *TDB = type->sdb_types; char *res = sdb_querys(TDB, NULL, -1, sdb_fmt("func.%s.args", function)); int i, args = sdb_num_get(TDB, sdb_fmt("func.%s.args", function), 0); const char *ret = sdb_const_get(TDB, sdb_fmt("func.%s.ret", function), 0); @@ -551,7 +523,7 @@ RZ_IPI void rz_types_function_print(Sdb *TDB, const char *function, RzOutputMode } RZ_IPI void rz_core_types_function_print_all(RzCore *core, RzOutputMode mode) { - Sdb *TDB = core->analysis->sdb_types; + Sdb *TDB = core->analysis->type->sdb_types; SdbKv *kv; SdbListIter *iter; PJ *pj = (mode == RZ_OUTPUT_MODE_JSON) ? rz_core_pj_new(core) : NULL; @@ -562,7 +534,7 @@ RZ_IPI void rz_core_types_function_print_all(RzCore *core, RzOutputMode mode) { ls_foreach (l, iter, kv) { if (!strcmp(sdbkv_value(kv), "func")) { const char *name = sdbkv_key(kv); - rz_types_function_print(TDB, name, mode, pj); + rz_types_function_print(core->analysis->type, name, mode, pj); } } ls_free(l); @@ -577,9 +549,10 @@ RZ_IPI void rz_core_types_function_print_all(RzCore *core, RzOutputMode mode) { static bool nonreturn_print_rizin(void *p, const char *k, const char *v) { RzCore *core = (RzCore *)p; + Sdb *TDB = core->analysis->type->sdb_types; if (!strncmp(v, "func", strlen("func") + 1)) { char *query = sdb_fmt("func.%s.noreturn", k); - if (sdb_bool_get(core->analysis->sdb_types, query, NULL)) { + if (sdb_bool_get(TDB, query, NULL)) { rz_cons_printf("tnn %s\n", k); } } @@ -612,47 +585,14 @@ static bool nonreturn_print_json(RzCore *core, RzList *noretl) { return true; } -RZ_IPI RzList *rz_types_function_noreturn(Sdb *db) { - RzList *noretl = rz_list_newf(free); - SdbKv *kv; - SdbListIter *iter; - SdbList *l = sdb_foreach_list(db, true); - ls_foreach (l, iter, kv) { - 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); - } - 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); - } - } - ls_free(l); - return noretl; -} - RZ_IPI void rz_core_types_function_noreturn_print(RzCore *core, RzOutputMode mode) { - Sdb *TDB = core->analysis->sdb_types; - RzList *noretl = rz_types_function_noreturn(TDB); + RzList *noretl = rz_type_noreturn_functions(core->analysis->type); switch (mode) { - case RZ_OUTPUT_MODE_RIZIN: + case RZ_OUTPUT_MODE_RIZIN: { + Sdb *TDB = core->analysis->type->sdb_types; sdb_foreach(TDB, nonreturn_print_rizin, core); break; + } case RZ_OUTPUT_MODE_JSON: nonreturn_print_json(core, noretl); break; @@ -665,45 +605,41 @@ RZ_IPI void rz_core_types_function_noreturn_print(RzCore *core, RzOutputMode mod // Type formatting RZ_IPI void rz_core_types_show_format(RzCore *core, const char *name, RzOutputMode mode) { - const char *isenum = sdb_const_get(core->analysis->sdb_types, name, 0); - if (isenum && !strcmp(isenum, "enum")) { - eprintf("IS ENUM\n"); - } else { - char *fmt = rz_type_format(core->analysis->sdb_types, name); - if (fmt) { - rz_str_trim(fmt); - switch (mode) { - case RZ_OUTPUT_MODE_JSON: { - PJ *pj = rz_core_pj_new(core); - if (!pj) { - return; - } - pj_o(pj); - pj_ks(pj, "name", name); - pj_ks(pj, "format", fmt); - pj_end(pj); - rz_cons_printf("%s", pj_string(pj)); - pj_free(pj); - } break; - case RZ_OUTPUT_MODE_RIZIN: { - rz_cons_printf("pf.%s %s\n", name, fmt); - } break; - case RZ_OUTPUT_MODE_STANDARD: { - // FIXME: Not really a standard format - // We should think about better representation by default here - rz_cons_printf("pf %s\n", fmt); - } break; - default: - break; + char *fmt = rz_type_format(core->analysis->type, name); + if (fmt) { + rz_str_trim(fmt); + switch (mode) { + case RZ_OUTPUT_MODE_JSON: { + PJ *pj = rz_core_pj_new(core); + if (!pj) { + return; } - free(fmt); - } else { - eprintf("Cannot find '%s' type\n", name); + pj_o(pj); + pj_ks(pj, "name", name); + pj_ks(pj, "format", fmt); + pj_end(pj); + rz_cons_printf("%s", pj_string(pj)); + pj_free(pj); + } break; + case RZ_OUTPUT_MODE_RIZIN: { + rz_cons_printf("pf.%s %s\n", name, fmt); + } break; + case RZ_OUTPUT_MODE_STANDARD: { + // FIXME: Not really a standard format + // We should think about better representation by default here + rz_cons_printf("pf %s\n", fmt); + } break; + default: + break; } + free(fmt); + } else { + eprintf("Cannot find '%s' type\n", name); } } -static void print_all_format(RzCore *core, Sdb *TDB, SdbForeachCallback sdbcb) { +static void print_all_format(RzCore *core, SdbForeachCallback sdbcb) { + Sdb *TDB = core->analysis->type->sdb_types; SdbList *l = sdb_foreach_list(TDB, true); SdbListIter *it; SdbKv *kv; @@ -715,30 +651,16 @@ static void print_all_format(RzCore *core, Sdb *TDB, SdbForeachCallback sdbcb) { ls_free(l); } -RZ_IPI void rz_core_types_struct_print_format_all(RzCore *core, Sdb *TDB) { - print_all_format(core, TDB, sdb_if_struct_cb); +RZ_IPI void rz_core_types_struct_print_format_all(RzCore *core) { + print_all_format(core, sdb_if_struct_cb); } -RZ_IPI void rz_core_types_union_print_format_all(RzCore *core, Sdb *TDB) { - print_all_format(core, TDB, sdb_if_union_cb); +RZ_IPI void rz_core_types_union_print_format_all(RzCore *core) { + print_all_format(core, sdb_if_union_cb); } // Type links -RZ_IPI RzList *rz_types_links(Sdb *db) { - RzList *ccl = rz_list_new(); - SdbKv *kv; - SdbListIter *iter; - SdbList *l = sdb_foreach_list(db, true); - ls_foreach (l, iter, kv) { - if (!strcmp(sdbkv_value(kv), "link")) { - rz_list_append(ccl, strdup(sdbkv_key(kv))); - } - } - ls_free(l); - return ccl; -} - static void set_retval(RzCore *core, ut64 at) { RzAnalysis *analysis = core->analysis; RzAnalysisHint *hint = rz_analysis_hint_get(analysis, at); @@ -764,12 +686,13 @@ static void set_retval(RzCore *core, ut64 at) { } static void set_offset_hint(RzCore *core, RzAnalysisOp *op, const char *type, ut64 laddr, ut64 at, int offimm) { - char *res = rz_type_get_struct_memb(core->analysis->sdb_types, type, offimm); + Sdb *TDB = core->analysis->type->sdb_types; + char *res = rz_type_get_struct_memb(core->analysis->type, type, offimm); const char *cmt = ((offimm == 0) && res) ? res : type; if (offimm > 0) { // set hint only if link is present char *query = sdb_fmt("link.%08" PFMT64x, laddr); - if (res && sdb_const_get(core->analysis->sdb_types, query, 0)) { + if (res && sdb_const_get(TDB, query, 0)) { rz_analysis_hint_set_offset(core->analysis, at, res); } } else if (cmt && rz_analysis_op_ismemref(op->type)) { @@ -778,6 +701,7 @@ static void set_offset_hint(RzCore *core, RzAnalysisOp *op, const char *type, ut } RZ_API void rz_core_link_stroff(RzCore *core, RzAnalysisFunction *fcn) { + rz_return_if_fail(core && core->analysis && fcn); RzAnalysisBlock *bb; RzListIter *it; RzAnalysisOp aop = { 0 }; @@ -786,7 +710,7 @@ RZ_API void rz_core_link_stroff(RzCore *core, RzAnalysisFunction *fcn) { bool resolved = false; const char *varpfx; int dbg_follow = rz_config_get_i(core->config, "dbg.follow"); - Sdb *TDB = core->analysis->sdb_types; + RzType *T = core->analysis->type; RzAnalysisEsil *esil; int iotrap = rz_config_get_i(core->config, "esil.iotrap"); int stacksize = rz_config_get_i(core->config, "esil.stack.depth"); @@ -795,9 +719,6 @@ RZ_API void rz_core_link_stroff(RzCore *core, RzAnalysisFunction *fcn) { const char *sp_name = rz_reg_get_name(core->analysis->reg, RZ_REG_NAME_SP); RzRegItem *pc = rz_reg_get(core->analysis->reg, pc_name, -1); - if (!fcn) { - return; - } if (!(esil = rz_analysis_esil_new(stacksize, iotrap, addrsize))) { return; } @@ -884,12 +805,12 @@ RZ_API void rz_core_link_stroff(RzCore *core, RzAnalysisFunction *fcn) { rz_analysis_op_fini(&aop); continue; } - char *slink = rz_type_link_at(TDB, src_addr); - char *vlink = rz_type_link_at(TDB, src_addr + src_imm); - char *dlink = rz_type_link_at(TDB, dst_addr); + char *slink = rz_type_link_at(T, src_addr); + char *vlink = rz_type_link_at(T, src_addr + src_imm); + char *dlink = rz_type_link_at(T, dst_addr); //TODO: Handle register based arg for struct offset propgation if (vlink && var && var->kind != 'r') { - if (rz_type_kind(TDB, vlink) == RZ_TYPE_UNION) { + if (rz_type_kind(T, vlink) == RZ_BASE_TYPE_KIND_UNION) { varpfx = "union"; } else { varpfx = "struct"; @@ -952,7 +873,7 @@ RZ_IPI void rz_core_types_link_print(RzCore *core, const char *type, ut64 addr, rz_cons_printf("tl %s 0x%" PFMT64x "\n", type, addr); break; case RZ_OUTPUT_MODE_LONG: { - char *fmt = rz_type_format(core->analysis->sdb_types, type); + char *fmt = rz_type_format(core->analysis->type, type); if (!fmt) { eprintf("Can't fint type %s", type); } @@ -967,7 +888,7 @@ RZ_IPI void rz_core_types_link_print(RzCore *core, const char *type, ut64 addr, } RZ_IPI void rz_core_types_link_print_all(RzCore *core, RzOutputMode mode) { - Sdb *TDB = core->analysis->sdb_types; + Sdb *TDB = core->analysis->type->sdb_types; SdbKv *kv; SdbListIter *iter; PJ *pj = (mode == RZ_OUTPUT_MODE_JSON) ? rz_core_pj_new(core) : NULL; @@ -993,14 +914,14 @@ RZ_IPI void rz_core_types_link_print_all(RzCore *core, RzOutputMode mode) { } RZ_IPI void rz_core_types_link(RzCore *core, const char *type, ut64 addr) { - Sdb *TDB = core->analysis->sdb_types; + Sdb *TDB = core->analysis->type->sdb_types; char *tmp = sdb_get(TDB, type, 0); if (RZ_STR_ISEMPTY(tmp)) { eprintf("unknown type %s\n", type); free(tmp); return; } - rz_type_set_link(TDB, type, addr); + rz_type_set_link(core->analysis->type, type, addr); RzList *fcns = rz_analysis_get_functions_in(core->analysis, core->offset); if (rz_list_length(fcns) > 1) { eprintf("Multiple functions found in here.\n"); @@ -1013,7 +934,7 @@ RZ_IPI void rz_core_types_link(RzCore *core, const char *type, ut64 addr) { } RZ_IPI void rz_core_types_link_show(RzCore *core, ut64 addr) { - Sdb *TDB = core->analysis->sdb_types; + Sdb *TDB = core->analysis->type->sdb_types; const char *query = sdb_fmt("link.%08" PFMT64x, addr); const char *link = sdb_const_get(TDB, query, 0); if (link) { @@ -1030,7 +951,7 @@ static bool sdb_if_type_cb(void *p, const char *k, const char *v) { RZ_IPI void rz_core_types_print_all(RzCore *core, RzOutputMode mode) { SdbListIter *it; SdbKv *kv; - Sdb *TDB = core->analysis->sdb_types; + Sdb *TDB = core->analysis->type->sdb_types; SdbList *l = sdb_foreach_list_filter(TDB, sdb_if_type_cb, true); switch (mode) { case RZ_OUTPUT_MODE_JSON: { @@ -1086,7 +1007,8 @@ static bool sdb_if_c_type_cb(void *p, const char *k, const char *v) { return sdb_if_union_cb(p, k, v) || sdb_if_struct_cb(p, k, v) || sdb_if_type_cb(p, k, v); } -RZ_IPI RzList *rz_types_all(Sdb *TDB) { +RZ_IPI RzList *rz_types_all(RzType *type) { + Sdb *TDB = type->sdb_types; SdbList *sl = sdb_foreach_list_filter_user(TDB, sdb_if_c_type_cb, true, TDB); RzList *l = rz_list_of_sdblist(sl); ls_free(sl); @@ -1102,10 +1024,10 @@ RZ_IPI void rz_types_define(RzCore *core, const char *type) { return; } char *error_msg = NULL; - char *out = rz_parse_c_string(core->analysis, tmp, &error_msg); + char *out = rz_type_parse_c_string(core->analysis->type, tmp, &error_msg); free(tmp); if (out) { - rz_analysis_save_parsed_type(core->analysis, out); + rz_type_save_parsed_type(core->analysis->type, out); free(out); } if (error_msg) { @@ -1117,6 +1039,7 @@ RZ_IPI void rz_types_define(RzCore *core, const char *type) { RZ_IPI void rz_types_open_file(RzCore *core, const char *path) { const char *dir = rz_config_get(core->config, "dir.types"); char *homefile = NULL; + RzType *type = core->analysis->type; if (*path == '~') { if (path[1] && path[2]) { homefile = rz_str_home(path + 2); @@ -1127,9 +1050,9 @@ RZ_IPI void rz_types_open_file(RzCore *core, const char *path) { char *tmp = rz_core_editor(core, "*.h", ""); if (tmp) { char *error_msg = NULL; - char *out = rz_parse_c_string(core->analysis, tmp, &error_msg); + char *out = rz_type_parse_c_string(type, tmp, &error_msg); if (out) { - rz_analysis_save_parsed_type(core->analysis, out); + rz_type_save_parsed_type(type, out); free(out); } if (error_msg) { @@ -1140,9 +1063,9 @@ RZ_IPI void rz_types_open_file(RzCore *core, const char *path) { } } else { char *error_msg = NULL; - char *out = rz_parse_c_file(core->analysis, path, dir, &error_msg); + char *out = rz_type_parse_c_file(type, path, dir, &error_msg); if (out) { - rz_analysis_save_parsed_type(core->analysis, out); + rz_type_save_parsed_type(type, out); free(out); } if (error_msg) { @@ -1154,17 +1077,17 @@ RZ_IPI void rz_types_open_file(RzCore *core, const char *path) { } RZ_IPI void rz_types_open_editor(RzCore *core, const char *typename) { - Sdb *TDB = core->analysis->sdb_types; + RzType *type = core->analysis->type; char *str = rz_core_cmd_strf(core, "tc %s", typename ? typename : ""); char *tmp = rz_core_editor(core, "*.h", str); if (tmp) { char *error_msg = NULL; - char *out = rz_parse_c_string(core->analysis, tmp, &error_msg); + char *out = rz_type_parse_c_string(type, tmp, &error_msg); if (out) { // remove previous types and save new edited types - sdb_reset(TDB); - rz_parse_c_reset(core->parser); - rz_analysis_save_parsed_type(core->analysis, out); + rz_type_purge(type); + rz_type_parse_c_reset(type); + rz_type_save_parsed_type(type, out); free(out); } if (error_msg) { @@ -1176,12 +1099,3 @@ RZ_IPI void rz_types_open_editor(RzCore *core, const char *typename) { free(str); } -RZ_IPI void rz_types_open_sdb(RzCore *core, const char *path) { - Sdb *TDB = core->analysis->sdb_types; - if (rz_file_exists(path)) { - Sdb *db_tmp = sdb_new(0, path, 0); - sdb_merge(TDB, db_tmp); - sdb_close(db_tmp); - sdb_free(db_tmp); - } -} diff --git a/librz/core/disasm.c b/librz/core/disasm.c index a88b73d24e9..2ac8ae6d443 100644 --- a/librz/core/disasm.c +++ b/librz/core/disasm.c @@ -4724,8 +4724,8 @@ static void ds_print_esil_analysis(RDisasmState *ds) { if (ds->asm_types < 1) { break; } - const char *fcn_type = rz_type_func_ret(core->analysis->sdb_types, key); - int nargs = rz_type_func_args_count(core->analysis->sdb_types, key); + const char *fcn_type = rz_type_func_ret(core->analysis->type, key); + int nargs = rz_type_func_args_count(core->analysis->type, key); // remove other comments delete_last_comment(ds); // ds_comment_start (ds, ""); @@ -4825,7 +4825,6 @@ static void ds_print_calls_hints(RDisasmState *ds) { return; } RzAnalysis *analysis = ds->core->analysis; - Sdb *TDB = analysis->sdb_types; char *name; char *full_name = NULL; if (ds->analop.type == RZ_ANALYSIS_OP_TYPE_CALL) { @@ -4843,13 +4842,13 @@ static void ds_print_calls_hints(RDisasmState *ds) { if (!full_name) { return; } - if (rz_type_func_exist(TDB, full_name)) { + if (rz_type_func_exist(analysis->type, full_name)) { name = strdup(full_name); - } else if (!(name = rz_type_func_guess(TDB, full_name))) { + } else if (!(name = rz_type_func_guess(analysis->type, full_name))) { return; } ds_begin_comment(ds); - const char *fcn_type = rz_type_func_ret(TDB, name); + const char *fcn_type = rz_type_func_ret(analysis->type, name); if (!fcn_type || !*fcn_type) { free(name); return; @@ -4857,13 +4856,13 @@ static void ds_print_calls_hints(RDisasmState *ds) { char *cmt = rz_str_newf("; %s%s%s(", fcn_type, fcn_type[strlen(fcn_type) - 1] == '*' ? "" : " ", name); - int i, arg_max = rz_type_func_args_count(TDB, name); + int i, arg_max = rz_type_func_args_count(analysis->type, name); if (!arg_max) { cmt = rz_str_append(cmt, "void)"); } else { for (i = 0; i < arg_max; i++) { - char *type = rz_type_func_args_type(TDB, name, i); - const char *tname = rz_type_func_args_name(TDB, name, i); + char *type = rz_type_func_args_type(analysis->type, name, i); + const char *tname = rz_type_func_args_name(analysis->type, name, i); if (type && *type) { cmt = rz_str_appendf(cmt, "%s%s%s%s%s", i == 0 ? "" : " ", type, type[strlen(type) - 1] == '*' ? "" : " ", @@ -5286,21 +5285,22 @@ RZ_API int rz_core_print_disasm(RzPrint *p, RzCore *core, ut64 addr, ut8 *buf, i f = ds->fcn = fcnIn(ds, ds->at, RZ_ANALYSIS_FCN_TYPE_NULL); ds_show_comments_right(ds); // TRY adding here - char *link_key = sdb_fmt("link.%08" PFMT64x, ds->addr + idx); - const char *link_type = sdb_const_get(core->analysis->sdb_types, link_key, 0); + char *link_type = rz_type_link_at(core->analysis->type, ds->addr + idx); if (link_type) { - char *fmt = rz_type_format(core->analysis->sdb_types, link_type); + char *fmt = rz_type_format(core->analysis->type, link_type); if (fmt) { rz_cons_printf("(%s)\n", link_type); rz_core_cmdf(core, "pf %s @ 0x%08" PFMT64x "\n", fmt, ds->addr + idx); - const ut32 type_bitsize = rz_type_get_bitsize(core->analysis->sdb_types, link_type); + const ut32 type_bitsize = rz_type_get_bitsize(core->analysis->type, link_type); // always round up when calculating byte_size from bit_size of types // could be struct with a bitfield entry inc = (type_bitsize >> 3) + (!!(type_bitsize & 0x7)); free(fmt); + free(link_type); rz_analysis_op_fini(&ds->analop); continue; } + free(link_type); } else { if (idx >= 0) { ret = ds_disassemble(ds, buf + addrbytes * idx, len - addrbytes * idx); diff --git a/librz/core/meson.build b/librz/core/meson.build index 95ffd1d0ea7..74a332142c1 100644 --- a/librz/core/meson.build +++ b/librz/core/meson.build @@ -97,6 +97,7 @@ rz_core_deps = [ rz_egg_dep, rz_search_dep, rz_analysis_dep, + rz_type_dep, rz_debug_dep, rz_config_dep, rz_bin_dep, @@ -138,6 +139,7 @@ pkgconfig_mod.generate( 'rz_cons', 'rz_analysis', 'rz_socket', + 'rz_type', 'rz_io', 'rz_lang', 'rz_hash', diff --git a/librz/core/vmenus.c b/librz/core/vmenus.c index 14f5fbf235a..531db44dc21 100644 --- a/librz/core/vmenus.c +++ b/librz/core/vmenus.c @@ -60,11 +60,6 @@ static char *prompt(const char *str, const char *txt) { return res; } -static inline char *getformat(RzCoreVisualTypes *vt, const char *k) { - return sdb_get(vt->core->analysis->sdb_types, - sdb_fmt("type.%s", k), 0); -} - static char *colorize_asm_string(RzCore *core, const char *buf_asm, int optype, ut64 addr) { char *tmp, *spacer = NULL; char *source = (char *)buf_asm; @@ -589,7 +584,7 @@ static bool sdbforcb(void *p, const char *k, const char *v) { } } else if (!strcmp(v, vt->type)) { if (!strcmp(vt->type, "type")) { - char *fmt = getformat(vt, k); + const char *fmt = rz_type_get(vt->core->analysis->type, k); if (vt->t_idx == vt->t_ctr) { free(vt->curname); vt->curname = strdup(k); @@ -604,7 +599,6 @@ static bool sdbforcb(void *p, const char *k, const char *v) { rz_cons_printf(" %s pf %3s %s\n", pre, fmt, k); } - free(fmt); } else { if (vt->t_idx == vt->t_ctr) { free(vt->curname); @@ -676,7 +670,7 @@ RZ_API int rz_core_visual_types(RzCore *core) { vt.t_ctr = 0; vt.type = opts[h_opt]; vt.optword = optword; - sdb_foreach(core->analysis->sdb_types, sdbforcb, &vt); + sdb_foreach(core->analysis->type->sdb_types, sdbforcb, &vt); } rz_cons_visual_flush(); diff --git a/librz/include/rz_analysis.h b/librz/include/rz_analysis.h index bddf04abe16..6dd1a566aba 100644 --- a/librz/include/rz_analysis.h +++ b/librz/include/rz_analysis.h @@ -21,6 +21,7 @@ #include #include #include +#include #define esilprintf(op, fmt, ...) rz_strbuf_setf(&op->esil, fmt, ##__VA_ARGS__) @@ -205,57 +206,6 @@ enum { RZ_ANALYSIS_DIFF_TYPE_UNMATCH = 'u' }; -typedef struct rz_analysis_enum_case_t { - char *name; - int val; -} RzAnalysisEnumCase; - -typedef struct rz_analysis_struct_member_t { - char *name; - char *type; - size_t offset; // in bytes - size_t size; // in bits? -} RzAnalysisStructMember; - -typedef struct rz_analysis_union_member_t { - char *name; - char *type; - size_t offset; // in bytes - size_t size; // in bits? -} RzAnalysisUnionMember; - -typedef enum { - RZ_ANALYSIS_BASE_TYPE_KIND_STRUCT, - RZ_ANALYSIS_BASE_TYPE_KIND_UNION, - RZ_ANALYSIS_BASE_TYPE_KIND_ENUM, - RZ_ANALYSIS_BASE_TYPE_KIND_TYPEDEF, // probably temporary addition, dev purposes - RZ_ANALYSIS_BASE_TYPE_KIND_ATOMIC, // For real atomic base types -} RzAnalysisBaseTypeKind; - -typedef struct rz_analysis_base_type_struct_t { - RzVector /**/ members; -} RzAnalysisBaseTypeStruct; - -typedef struct rz_analysis_base_type_union_t { - RzVector /**/ members; -} RzAnalysisBaseTypeUnion; - -typedef struct rz_analysis_base_type_enum_t { - RzVector /* +// SPDX-License-Identifier: LGPL-3.0-only + +#ifndef RZ_TYPE_H +#define RZ_TYPE_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +RZ_LIB_VERSION_HEADER(rz_type); + +typedef struct rz_type_target_t { + const char *cpu; + int bits; + const char *os; +} RzTypeTarget; + +typedef struct rz_type_t { + void *user; + Sdb *sdb_types; + RzTypeTarget *target; +} RzType; + +typedef struct rz_type_enum_case_t { + char *name; + int val; +} RzTypeEnumCase; + +typedef struct rz_type_struct_member_t { + char *name; + char *type; + size_t offset; // in bytes + size_t size; // in bits? +} RzTypeStructMember; + +typedef struct rz_type_union_member_t { + char *name; + char *type; + size_t offset; // in bytes + size_t size; // in bits? +} RzTypeUnionMember; + +typedef enum { + RZ_BASE_TYPE_KIND_STRUCT, + RZ_BASE_TYPE_KIND_UNION, + RZ_BASE_TYPE_KIND_ENUM, + RZ_BASE_TYPE_KIND_TYPEDEF, // probably temporary addition, dev purposes + RZ_BASE_TYPE_KIND_ATOMIC, // For real atomic base types +} RzBaseTypeKind; + +typedef struct rz_base_type_struct_t { + RzVector /**/ members; +} RzBaseTypeStruct; + +typedef struct rz_base_type_union_t { + RzVector /**/ members; +} RzBaseTypeUnion; + +typedef struct rz_base_type_enum_t { + RzVector /* -// SPDX-License-Identifier: LGPL-3.0-only - -#include - -#include - -struct rz_parse_ctype_t { - mpc_parser_t *integerlit; - mpc_parser_t *identifier; - mpc_parser_t *qualifier; - mpc_parser_t *pointer; - mpc_parser_t *array; - mpc_parser_t *type; -}; - -#define ALL_PARSERS(ctype) ctype->integerlit, ctype->identifier, ctype->qualifier, ctype->pointer, ctype->array, ctype->type -#define ALL_PARSERS_COUNT 6 - -static const char *lang = - "integerlit : /0x[0-9A-Fa-f]+/ | /[0-9]+/;" - "identifier : (\"struct\" | \"union\" | \"enum\")? /[a-zA-Z_][0-9a-zA-Z_]+/;" - "qualifier : \"const\";" - "pointer : ? '*';" - "array : '[' ']';" - "type : ? ( | )*;"; - -RZ_API RzParseCType *rz_parse_ctype_new(void) { - RzParseCType *ctype = RZ_NEW(RzParseCType); - if (!ctype) { - return NULL; - } - - ctype->integerlit = mpc_new("integerlit"); - ctype->identifier = mpc_new("identifier"); - ctype->qualifier = mpc_new("qualifier"); - ctype->pointer = mpc_new("pointer"); - ctype->array = mpc_new("array"); - ctype->type = mpc_new("type"); - - mpc_err_t *err = mpca_lang(MPCA_LANG_DEFAULT, lang, ALL_PARSERS(ctype), NULL); - if (err) { - mpc_err_print(err); - mpc_err_delete(err); - rz_parse_ctype_free(ctype); - return NULL; - } - - return ctype; -} - -RZ_API void rz_parse_ctype_free(RzParseCType *ctype) { - if (!ctype) { - return; - } - mpc_cleanup(ALL_PARSERS_COUNT, ALL_PARSERS(ctype)); - free(ctype); -} - -static bool is_qualifier_const(mpc_ast_t *a) { - return strcmp(a->tag, "qualifier|string") == 0 && a->contents && strcmp(a->contents, "const") == 0; -} - -static bool is_identifier_string(mpc_ast_t *a) { - return strcmp(a->tag, "identifier|regex") == 0 && a->contents; -} - -static bool is_identifier_kind(mpc_ast_t *a) { - return strcmp(a->tag, "identifier|>") == 0 && a->children_num == 2 && strcmp(a->children[0]->tag, "string") == 0 && a->children[0]->contents && strcmp(a->children[1]->tag, "regex") == 0 && a->children[1]->contents; -} - -static bool is_non_const_pointer(mpc_ast_t *a) { - return strcmp(a->tag, "pointer|char") == 0 && a->contents && strcmp(a->contents, "*") == 0; -} - -static bool is_const_pointer(mpc_ast_t *a) { - return strcmp(a->tag, "pointer|>") == 0 && a->children_num == 2 && is_qualifier_const(a->children[0]) && strcmp(a->children[1]->tag, "char") == 0 && a->children[1]->contents && strcmp(a->children[1]->contents, "*") == 0; -} - -static bool is_array(mpc_ast_t *a) { - return strcmp(a->tag, "array|>") == 0 && a->children_num == 3 && strcmp(a->children[0]->tag, "char") == 0 && a->children[0]->contents && strcmp(a->children[0]->contents, "[") == 0 && strcmp(a->children[1]->tag, "integerlit|regex") == 0 && a->children[1]->contents && strcmp(a->children[2]->tag, "char") == 0 && a->children[2]->contents && strcmp(a->children[2]->contents, "]") == 0; -} - -static RzParseCTypeType *ctype_convert_ast(mpc_ast_t *a) { - bool is_const = false; - RzParseCTypeType *cur = NULL; - int i; - for (i = 0; i < a->children_num; i++) { - mpc_ast_t *child = a->children[i]; - - // const - if (is_qualifier_const(child)) { - is_const = true; - } - - // (struct|union|enum)? - else if (rz_str_startswith(child->tag, "identifier|")) { - if (cur) { - // identifier should always be the innermost type - goto beach; - } - cur = RZ_NEW0(RzParseCTypeType); - if (!cur) { - goto beach; - } - cur->kind = RZ_PARSE_CTYPE_TYPE_KIND_IDENTIFIER; - cur->identifier.is_const = is_const; - cur->identifier.kind = RZ_PARSE_CTYPE_IDENTIFIER_KIND_UNSPECIFIED; - if (is_identifier_string(child)) { - cur->identifier.name = strdup(child->contents); - } else if (is_identifier_kind(child)) { - if (strcmp(child->children[0]->contents, "struct") == 0) { - cur->identifier.kind = RZ_PARSE_CTYPE_IDENTIFIER_KIND_STRUCT; - } else if (strcmp(child->children[0]->contents, "union") == 0) { - cur->identifier.kind = RZ_PARSE_CTYPE_IDENTIFIER_KIND_UNION; - } else if (strcmp(child->children[0]->contents, "enum") == 0) { - cur->identifier.kind = RZ_PARSE_CTYPE_IDENTIFIER_KIND_ENUM; - } - cur->identifier.name = strdup(child->children[1]->contents); - } else { - goto beach; - } - if (!cur->identifier.name) { - goto beach; - } - is_const = false; - } - - // - else if (is_identifier_string(child)) { - if (cur) { - // identifier should always be the innermost type - goto beach; - } - cur = RZ_NEW0(RzParseCTypeType); - if (!cur) { - goto beach; - } - cur->kind = RZ_PARSE_CTYPE_TYPE_KIND_IDENTIFIER; - cur->identifier.kind = RZ_PARSE_CTYPE_IDENTIFIER_KIND_UNSPECIFIED; - cur->identifier.is_const = is_const; - cur->identifier.name = strdup(child->contents); - if (!cur->identifier.name) { - goto beach; - } - is_const = false; - } - - // * - else if (is_non_const_pointer(child)) { - RzParseCTypeType *pointer = RZ_NEW0(RzParseCTypeType); - if (!pointer) { - goto beach; - } - pointer->kind = RZ_PARSE_CTYPE_TYPE_KIND_POINTER; - pointer->pointer.is_const = false; - pointer->pointer.type = cur; - cur = pointer; - } - - // const * - else if (is_const_pointer(child)) { - RzParseCTypeType *pointer = RZ_NEW0(RzParseCTypeType); - if (!pointer) { - goto beach; - } - pointer->kind = RZ_PARSE_CTYPE_TYPE_KIND_POINTER; - pointer->pointer.is_const = true; - pointer->pointer.type = cur; - cur = pointer; - } - - // - else if (is_array(child)) { - RzParseCTypeType *array = RZ_NEW0(RzParseCTypeType); - if (!array) { - goto beach; - } - array->kind = RZ_PARSE_CTYPE_TYPE_KIND_ARRAY; - array->array.count = strtoull(child->children[1]->contents, NULL, 0); - array->array.type = cur; - cur = array; - } - - else { - goto beach; - } - } - - return cur; -beach: - rz_parse_ctype_type_free(cur); - return NULL; -} - -RZ_API RzParseCTypeType *rz_parse_ctype_parse(RzParseCType *ctype, const char *str, char **error) { - mpc_result_t r; - if (mpc_parse("", str, ctype->type, &r)) { - RzParseCTypeType *ret = ctype_convert_ast(r.output); - if (error) { - *error = !ret ? strdup("internal error") : NULL; - } - mpc_ast_delete(r.output); - return ret; - } else { - if (error) { - *error = mpc_err_string(r.error); - } - mpc_err_delete(r.error); - return NULL; - } -} - -RZ_API void rz_parse_ctype_type_free(RzParseCTypeType *type) { - if (!type) { - return; - } - switch (type->kind) { - case RZ_PARSE_CTYPE_TYPE_KIND_IDENTIFIER: - free(type->identifier.name); - break; - case RZ_PARSE_CTYPE_TYPE_KIND_POINTER: - rz_parse_ctype_type_free(type->pointer.type); - break; - case RZ_PARSE_CTYPE_TYPE_KIND_ARRAY: - rz_parse_ctype_type_free(type->array.type); - break; - } - free(type); -} diff --git a/librz/parse/meson.build b/librz/parse/meson.build index af7b3f09e6f..462507af48b 100644 --- a/librz/parse/meson.build +++ b/librz/parse/meson.build @@ -1,8 +1,6 @@ rz_parse_sources = [ - 'code.c', 'filter.c', 'parse.c', - 'ctype.c', 'p/parse_6502_pseudo.c', 'p/parse_arm_pseudo.c', 'p/parse_att2intel.c', @@ -30,8 +28,6 @@ rz_parse = library('rz_parse', rz_parse_sources, rz_syscall_dep, rz_reg_dep, rz_cons_dep, - tcc_dep, - mpc_dep ], install: true, implicit_include_directories: false, diff --git a/librz/type/base.c b/librz/type/base.c new file mode 100644 index 00000000000..dde2a02523b --- /dev/null +++ b/librz/type/base.c @@ -0,0 +1,566 @@ +// SPDX-FileCopyrightText: 2021 Anton Kochkov +// SPDX-License-Identifier: LGPL-3.0-only + +#include +#include +#include +#include + +#include "type_internal.h" + +RZ_API void rz_type_base_enum_case_free(void *e, void *user) { + (void)user; + RzTypeEnumCase *cas = e; + free((char *)cas->name); +} + +RZ_API void rz_type_base_struct_member_free(void *e, void *user) { + (void)user; + RzTypeStructMember *member = e; + free((char *)member->name); + free((char *)member->type); +} + +RZ_API void rz_type_base_union_member_free(void *e, void *user) { + (void)user; + RzTypeUnionMember *member = e; + free((char *)member->name); + free((char *)member->type); +} + +static char *get_type_data(Sdb *sdb_types, const char *type, const char *sname) { + char *key = rz_str_newf("%s.%s", type, sname); + if (!key) { + return NULL; + } + char *members = sdb_get(sdb_types, key, NULL); + free(key); + return members; +} + +static RzBaseType *get_enum_type(RzType *type, const char *sname) { + rz_return_val_if_fail(type && sname, NULL); + + RzBaseType *base_type = rz_type_base_type_new(RZ_BASE_TYPE_KIND_ENUM); + if (!base_type) { + return NULL; + } + + char *members = get_type_data(type->sdb_types, "enum", sname); + if (!members) { + goto error; + } + + RzVector *cases = &base_type->enum_data.cases; + if (!rz_vector_reserve(cases, (size_t)sdb_alen(members))) { + goto error; + } + + char *cur; + sdb_aforeach(cur, members) { + char *val_key = rz_str_newf("enum.%s.%s", sname, cur); + if (!val_key) { + goto error; + } + const char *value = sdb_const_get(type->sdb_types, val_key, NULL); + free(val_key); + + if (!value) { // if nothing is found, ret NULL + goto error; + } + + RzTypeEnumCase cas = { .name = strdup(cur), .val = strtol(value, NULL, 16) }; + + void *element = rz_vector_push(cases, &cas); // returns null if no space available + if (!element) { + goto error; + } + + sdb_aforeach_next(cur); + } + free(members); + + return base_type; + +error: + free(members); + rz_type_base_type_free(base_type); + return NULL; +} + +static RzBaseType *get_struct_type(RzType *type, const char *sname) { + rz_return_val_if_fail(type && sname, NULL); + + RzBaseType *base_type = rz_type_base_type_new(RZ_BASE_TYPE_KIND_STRUCT); + if (!base_type) { + return NULL; + } + + char *sdb_members = get_type_data(type->sdb_types, "struct", sname); + if (!sdb_members) { + goto error; + } + + RzVector *members = &base_type->struct_data.members; + if (!rz_vector_reserve(members, (size_t)sdb_alen(sdb_members))) { + goto error; + } + + char *cur; + sdb_aforeach(cur, sdb_members) { + char *type_key = rz_str_newf("struct.%s.%s", sname, cur); + if (!type_key) { + goto error; + } + char *values = sdb_get(type->sdb_types, type_key, NULL); + free(type_key); + + if (!values) { + goto error; + } + char *offset = NULL; + char *type = sdb_anext(values, &offset); + if (!offset) { // offset is missing, malformed state + free(values); + goto error; + } + offset = sdb_anext(offset, NULL); + RzTypeStructMember cas = { + .name = strdup(cur), + .type = strdup(type), + .offset = strtol(offset, NULL, 10) + }; + + free(values); + + void *element = rz_vector_push(members, &cas); // returns null if no space available + if (!element) { + goto error; + } + + sdb_aforeach_next(cur); + } + free(sdb_members); + + return base_type; + +error: + rz_type_base_type_free(base_type); + free(sdb_members); + return NULL; +} + +static RzBaseType *get_union_type(RzType *type, const char *sname) { + rz_return_val_if_fail(type && sname, NULL); + + RzBaseType *base_type = rz_type_base_type_new(RZ_BASE_TYPE_KIND_UNION); + if (!base_type) { + return NULL; + } + + char *sdb_members = get_type_data(type->sdb_types, "union", sname); + if (!sdb_members) { + goto error; + } + + RzVector *members = &base_type->union_data.members; + if (!rz_vector_reserve(members, (size_t)sdb_alen(sdb_members))) { + goto error; + } + + char *cur; + sdb_aforeach(cur, sdb_members) { + char *type_key = rz_str_newf("union.%s.%s", sname, cur); + if (!type_key) { + goto error; + } + char *values = sdb_get(type->sdb_types, type_key, NULL); + free(type_key); + + if (!values) { + goto error; + } + char *value = sdb_anext(values, NULL); + RzTypeUnionMember cas = { .name = strdup(cur), .type = strdup(value) }; + free(values); + + void *element = rz_vector_push(members, &cas); // returns null if no space available + if (!element) { + goto error; + } + + sdb_aforeach_next(cur); + } + free(sdb_members); + + return base_type; + +error: + rz_type_base_type_free(base_type); + free(sdb_members); + return NULL; +} + +static RzBaseType *get_typedef_type(RzType *type, const char *sname) { + rz_return_val_if_fail(type && RZ_STR_ISNOTEMPTY(sname), NULL); + + RzBaseType *base_type = rz_type_base_type_new(RZ_BASE_TYPE_KIND_TYPEDEF); + if (!base_type) { + return NULL; + } + + base_type->type = get_type_data(type->sdb_types, "typedef", sname); + if (!base_type->type) { + goto error; + } + return base_type; + +error: + rz_type_base_type_free(base_type); + return NULL; +} + +static RzBaseType *get_atomic_type(RzType *type, const char *sname) { + rz_return_val_if_fail(type && RZ_STR_ISNOTEMPTY(sname), NULL); + + RzBaseType *base_type = rz_type_base_type_new(RZ_BASE_TYPE_KIND_ATOMIC); + if (!base_type) { + return NULL; + } + + base_type->type = get_type_data(type->sdb_types, "type", sname); + if (!base_type->type) { + goto error; + } + + RzStrBuf key; + base_type->size = sdb_num_get(type->sdb_types, rz_strbuf_initf(&key, "type.%s.size", sname), 0); + rz_strbuf_fini(&key); + + return base_type; + +error: + rz_type_base_type_free(base_type); + return NULL; +} + +// returns NULL if name is not found or any failure happened +RZ_API RzBaseType *rz_type_get_base_type(RzType *t, const char *name) { + rz_return_val_if_fail(t && name, NULL); + + char *sname = rz_str_sanitize_sdb_key(name); + const char *type = sdb_const_get(t->sdb_types, sname, NULL); + if (!type) { + free(sname); + return NULL; + } + + RzBaseType *base_type = NULL; + if (!strcmp(type, "struct")) { + base_type = get_struct_type(t, sname); + } else if (!strcmp(type, "enum")) { + base_type = get_enum_type(t, sname); + } else if (!strcmp(type, "union")) { + base_type = get_union_type(t, sname); + } else if (!strcmp(type, "typedef")) { + base_type = get_typedef_type(t, sname); + } else if (!strcmp(type, "type")) { + base_type = get_atomic_type(t, sname); + } + + if (base_type) { + base_type->name = sname; + } else { + free(sname); + } + + return base_type; +} + +static void save_struct(const RzType *t, const RzBaseType *type) { + rz_return_if_fail(t && type && type->name && type->kind == RZ_BASE_TYPE_KIND_STRUCT); + char *kind = "struct"; + /* + C: + struct name {type param1; type param2; type paramN;}; + Sdb: + name=struct + struct.name=param1,param2,paramN + struct.name.param1=type,0,0 + struct.name.param2=type,4,0 + struct.name.paramN=type,8,0 + */ + char *sname = rz_str_sanitize_sdb_key(type->name); + // name=struct + sdb_set(t->sdb_types, sname, kind, 0); + + RzStrBuf arglist; + RzStrBuf param_key; + RzStrBuf param_val; + rz_strbuf_init(&arglist); + rz_strbuf_init(¶m_key); + rz_strbuf_init(¶m_val); + + int i = 0; + RzTypeStructMember *member; + rz_vector_foreach(&type->struct_data.members, member) { + // struct.name.param=type,offset,argsize + char *member_sname = rz_str_sanitize_sdb_key(member->name); + sdb_set(t->sdb_types, + rz_strbuf_setf(¶m_key, "%s.%s.%s", kind, sname, member_sname), + rz_strbuf_setf(¶m_val, "%s,%zu,%u", member->type, member->offset, 0), 0ULL); + free(member_sname); + + rz_strbuf_appendf(&arglist, (i++ == 0) ? "%s" : ",%s", member->name); + } + // struct.name=param1,param2,paramN + char *key = rz_str_newf("%s.%s", kind, sname); + sdb_set(t->sdb_types, key, rz_strbuf_get(&arglist), 0); + free(key); + + free(sname); + + rz_strbuf_fini(&arglist); + rz_strbuf_fini(¶m_key); + rz_strbuf_fini(¶m_val); +} + +static void save_union(const RzType *t, const RzBaseType *type) { + rz_return_if_fail(t && type && type->name && type->kind == RZ_BASE_TYPE_KIND_UNION); + const char *kind = "union"; + /* + C: + union name {type param1; type param2; type paramN;}; + Sdb: + name=union + union.name=param1,param2,paramN + union.name.param1=type,0,0 + union.name.param2=type,0,0 + union.name.paramN=type,0,0 + */ + char *sname = rz_str_sanitize_sdb_key(type->name); + // name=union + sdb_set(t->sdb_types, sname, kind, 0); + + RzStrBuf arglist; + RzStrBuf param_key; + RzStrBuf param_val; + rz_strbuf_init(&arglist); + rz_strbuf_init(¶m_key); + rz_strbuf_init(¶m_val); + + int i = 0; + RzTypeUnionMember *member; + rz_vector_foreach(&type->union_data.members, member) { + // union.name.arg1=type,offset,argsize + char *member_sname = rz_str_sanitize_sdb_key(member->name); + sdb_set(t->sdb_types, + rz_strbuf_setf(¶m_key, "%s.%s.%s", kind, sname, member_sname), + rz_strbuf_setf(¶m_val, "%s,%zu,%u", member->type, member->offset, 0), 0ULL); + free(member_sname); + + rz_strbuf_appendf(&arglist, (i++ == 0) ? "%s" : ",%s", member->name); + } + // union.name=arg1,arg2,argN + char *key = rz_str_newf("%s.%s", kind, sname); + sdb_set(t->sdb_types, key, rz_strbuf_get(&arglist), 0); + free(key); + + free(sname); + + rz_strbuf_fini(&arglist); + rz_strbuf_fini(¶m_key); + rz_strbuf_fini(¶m_val); +} + +static void save_enum(const RzType *t, const RzBaseType *type) { + rz_return_if_fail(t && type && type->name && type->kind == RZ_BASE_TYPE_KIND_ENUM); + /* + C: + enum name {case1 = 1, case2 = 2, caseN = 3}; + Sdb: + name=enum + enum.name=arg1,arg2,argN + enum.MyEnum.0x1=arg1 + enum.MyEnum.0x3=arg2 + enum.MyEnum.0x63=argN + enum.MyEnum.arg1=0x1 + enum.MyEnum.arg2=0x63 + enum.MyEnum.argN=0x3 + */ + char *sname = rz_str_sanitize_sdb_key(type->name); + sdb_set(t->sdb_types, sname, "enum", 0); + + RzStrBuf arglist; + RzStrBuf param_key; + RzStrBuf param_val; + rz_strbuf_init(&arglist); + rz_strbuf_init(¶m_key); + rz_strbuf_init(¶m_val); + + int i = 0; + RzTypeEnumCase *cas; + rz_vector_foreach(&type->enum_data.cases, cas) { + // enum.name.arg1=type,offset,??? + char *case_sname = rz_str_sanitize_sdb_key(cas->name); + sdb_set(t->sdb_types, + rz_strbuf_setf(¶m_key, "enum.%s.%s", sname, case_sname), + rz_strbuf_setf(¶m_val, "0x%" PFMT32x "", cas->val), 0); + + sdb_set(t->sdb_types, + rz_strbuf_setf(¶m_key, "enum.%s.0x%" PFMT32x "", sname, cas->val), + case_sname, 0); + free(case_sname); + + rz_strbuf_appendf(&arglist, (i++ == 0) ? "%s" : ",%s", cas->name); + } + // enum.name=arg1,arg2,argN + char *key = rz_str_newf("enum.%s", sname); + sdb_set(t->sdb_types, key, rz_strbuf_get(&arglist), 0); + free(key); + + free(sname); + + rz_strbuf_fini(&arglist); + rz_strbuf_fini(¶m_key); + rz_strbuf_fini(¶m_val); +} + +static void save_atomic_type(const RzType *t, const RzBaseType *type) { + rz_return_if_fail(t && type && type->name && type->kind == RZ_BASE_TYPE_KIND_ATOMIC); + /* + C: (cannot define a custom atomic type) + Sdb: + char=type + type.char=c + type.char.size=8 + */ + char *sname = rz_str_sanitize_sdb_key(type->name); + sdb_set(t->sdb_types, sname, "type", 0); + + RzStrBuf key; + RzStrBuf val; + rz_strbuf_init(&key); + rz_strbuf_init(&val); + + sdb_set(t->sdb_types, + rz_strbuf_setf(&key, "type.%s.size", sname), + rz_strbuf_setf(&val, "%" PFMT64u "", type->size), 0); + + sdb_set(t->sdb_types, + rz_strbuf_setf(&key, "type.%s", sname), + type->type, 0); + + free(sname); + + rz_strbuf_fini(&key); + rz_strbuf_fini(&val); +} + +static void save_typedef(const RzType *t, const RzBaseType *type) { + rz_return_if_fail(t && type && type->name && type->kind == RZ_BASE_TYPE_KIND_TYPEDEF); + /* + C: + typedef char byte; + Sdb: + byte=typedef + typedef.byte=char + */ + char *sname = rz_str_sanitize_sdb_key(type->name); + sdb_set(t->sdb_types, sname, "typedef", 0); + + RzStrBuf key; + RzStrBuf val; + rz_strbuf_init(&key); + rz_strbuf_init(&val); + + sdb_set(t->sdb_types, + rz_strbuf_setf(&key, "typedef.%s", sname), + rz_strbuf_setf(&val, "%s", type->type), 0); + + free(sname); + + rz_strbuf_fini(&key); + rz_strbuf_fini(&val); +} + +RZ_API void rz_type_base_type_free(RzBaseType *type) { + rz_return_if_fail(type); + RZ_FREE(type->name); + RZ_FREE(type->type); + + switch (type->kind) { + case RZ_BASE_TYPE_KIND_STRUCT: + rz_vector_fini(&type->struct_data.members); + break; + case RZ_BASE_TYPE_KIND_UNION: + rz_vector_fini(&type->union_data.members); + break; + case RZ_BASE_TYPE_KIND_ENUM: + rz_vector_fini(&type->enum_data.cases); + break; + case RZ_BASE_TYPE_KIND_TYPEDEF: + case RZ_BASE_TYPE_KIND_ATOMIC: + break; + default: + break; + } + RZ_FREE(type); +} + +RZ_API RzBaseType *rz_type_base_type_new(RzBaseTypeKind kind) { + RzBaseType *type = RZ_NEW0(RzBaseType); + if (!type) { + return NULL; + } + type->kind = kind; + switch (type->kind) { + case RZ_BASE_TYPE_KIND_STRUCT: + rz_vector_init(&type->struct_data.members, sizeof(RzTypeStructMember), rz_type_base_struct_member_free, NULL); + break; + case RZ_BASE_TYPE_KIND_ENUM: + rz_vector_init(&type->enum_data.cases, sizeof(RzTypeEnumCase), rz_type_base_enum_case_free, NULL); + break; + case RZ_BASE_TYPE_KIND_UNION: + rz_vector_init(&type->union_data.members, sizeof(RzTypeUnionMember), rz_type_base_union_member_free, NULL); + break; + default: + break; + } + + return type; +} + +/** + * @brief Saves RzBaseType into the SDB + * + * @param t + * @param type RzBaseType to save + * @param name Name of the type + */ +RZ_API void rz_type_save_base_type(const RzType *t, const RzBaseType *type) { + rz_return_if_fail(t && type && type->name); + + // TODO, solve collisions, if there are 2 types with the same name and kind + + switch (type->kind) { + case RZ_BASE_TYPE_KIND_STRUCT: + save_struct(t, type); + break; + case RZ_BASE_TYPE_KIND_ENUM: + save_enum(t, type); + break; + case RZ_BASE_TYPE_KIND_UNION: + save_union(t, type); + break; + case RZ_BASE_TYPE_KIND_TYPEDEF: + save_typedef(t, type); + break; + case RZ_BASE_TYPE_KIND_ATOMIC: + save_atomic_type(t, type); + break; + default: + break; + } +} + diff --git a/librz/parse/code.c b/librz/type/code.c similarity index 76% rename from librz/parse/code.c rename to librz/type/code.c index 5618bc68a9d..f87cca082ae 100644 --- a/librz/parse/code.c +++ b/librz/type/code.c @@ -1,9 +1,9 @@ // SPDX-FileCopyrightText: 2013-2019 pancake // SPDX-License-Identifier: LGPL-3.0-only -#include "rz_util.h" -#include "rz_types.h" -#include "rz_parse.h" +#include +#include + #include "tcc.h" extern int tcc_sym_push(char *typename, int typesize, int meta); @@ -31,7 +31,7 @@ static bool __typeLoad(void *p, const char *k, const char *v) { return false; } int btype = 0; - RzAnalysis *analysis = (RzAnalysis *)p; + RzType *t = (RzType *)p; //rz_cons_printf ("tk %s=%s\n", k, v); // TODO: Add unions support if (!strncmp(v, "struct", 6) && strncmp(k, "struct.", 7)) { @@ -41,7 +41,7 @@ static bool __typeLoad(void *p, const char *k, const char *v) { int typesize = 0; // TODO: Add typesize here char *query = sdb_fmt("struct.%s", k); - char *members = sdb_get(analysis->sdb_types, query, 0); + char *members = sdb_get(t->sdb_types, query, 0); char *next, *ptr = members; if (members) { do { @@ -50,7 +50,7 @@ static bool __typeLoad(void *p, const char *k, const char *v) { break; } query = sdb_fmt("struct.%s.%s", k, name); - char *subtype = sdb_get(analysis->sdb_types, query, 0); + char *subtype = sdb_get(t->sdb_types, query, 0); if (!subtype) { break; } @@ -64,7 +64,7 @@ static bool __typeLoad(void *p, const char *k, const char *v) { char *subname = tmp; // TODO: Go recurse here query = sdb_fmt("struct.%s.%s.meta", subtype, subname); - btype = sdb_num_get(analysis->sdb_types, query, 0); + btype = sdb_num_get(t->sdb_types, query, 0); tcc_sym_push(subtype, 0, btype); } free(subtype); @@ -94,15 +94,15 @@ static void __errorFunc(void *opaque, const char *msg) { } } -RZ_API char *rz_parse_c_file(RzAnalysis *analysis, const char *path, const char *dir, char **error_msg) { +RZ_API char *rz_type_parse_c_file(RzType *t, const char *path, const char *dir, char **error_msg) { char *str = NULL; - TCCState *T = tcc_new(analysis->cpu, analysis->bits, analysis->os); + TCCState *T = tcc_new(t->target->cpu, t->target->bits, t->target->os); if (!T) { return NULL; } tcc_set_callback(T, &__appendString, &str); tcc_set_error_func(T, (void *)error_msg, __errorFunc); - sdb_foreach(analysis->sdb_types, __typeLoad, analysis); + sdb_foreach(t->sdb_types, __typeLoad, t); if (tcc_add_file(T, path, dir) == -1) { free(str); str = NULL; @@ -111,15 +111,15 @@ RZ_API char *rz_parse_c_file(RzAnalysis *analysis, const char *path, const char return str; } -RZ_API char *rz_parse_c_string(RzAnalysis *analysis, const char *code, char **error_msg) { +RZ_API char *rz_type_parse_c_string(RzType *t, const char *code, char **error_msg) { char *str = NULL; - TCCState *T = tcc_new(analysis->cpu, analysis->bits, analysis->os); + TCCState *T = tcc_new(t->target->cpu, t->target->bits, t->target->os); if (!T) { return NULL; } tcc_set_callback(T, &__appendString, &str); tcc_set_error_func(T, (void *)error_msg, __errorFunc); - sdb_foreach(analysis->sdb_types, __typeLoad, NULL); + sdb_foreach(t->sdb_types, __typeLoad, NULL); if (tcc_compile_string(T, code) != 0) { free(str); str = NULL; @@ -129,6 +129,6 @@ RZ_API char *rz_parse_c_string(RzAnalysis *analysis, const char *code, char **er } // XXX do not use globals -RZ_API void rz_parse_c_reset(RzParse *p) { +RZ_API void rz_type_parse_c_reset(RzType *p) { anon_sym = SYM_FIRST_ANOM; } diff --git a/librz/util/format.c b/librz/type/format.c similarity index 94% rename from librz/util/format.c rename to librz/type/format.c index 882e04bd85f..c2e0d580ee4 100644 --- a/librz/util/format.c +++ b/librz/type/format.c @@ -2,10 +2,10 @@ // SPDX-FileCopyrightText: 2007-2020 Skia // SPDX-License-Identifier: LGPL-3.0-only -#include "rz_cons.h" -#include "rz_util.h" -#include "rz_util/rz_print.h" -#include "rz_reg.h" +#include +#include +#include +#include #define NOPTR 0 #define PTRSEEK 1 @@ -1526,12 +1526,121 @@ static void rz_print_format_num(const RzPrint *p, int endian, int mode, const ch } } -RZ_API const char *rz_print_format_byname(RzPrint *p, const char *name) { +RZ_API const char *rz_type_format_byname(RzPrint *p, const char *name) { return sdb_const_get(p->formats, name, NULL); } +static char *fmt_struct_union(Sdb *TDB, char *var, bool is_typedef) { + // assumes var list is sorted by offset.. should do more checks here + char *p = NULL, *vars = NULL, var2[132], *fmt = NULL; + size_t n; + char *fields = rz_str_newf("%s.fields", var); + char *nfields = (is_typedef) ? fields : var; + for (n = 0; (p = sdb_array_get(TDB, nfields, n, NULL)); n++) { + char *struct_name; + const char *tfmt = NULL; + bool isStruct = false; + bool isEnum = false; + bool isfp = false; + snprintf(var2, sizeof(var2), "%s.%s", var, p); + size_t alen = sdb_array_size(TDB, var2); + int elements = sdb_array_get_num(TDB, var2, alen - 1, NULL); + char *type = sdb_array_get(TDB, var2, 0, NULL); + if (type) { + char var3[128] = { 0 }; + // Handle general pointers except for char * + if ((strstr(type, "*(") || strstr(type, " *")) && strncmp(type, "char *", 7)) { + isfp = true; + } else if (rz_str_startswith(type, "struct ")) { + struct_name = type + 7; + // TODO: iterate over all the struct fields, and format the format and vars + snprintf(var3, sizeof(var3), "struct.%s", struct_name); + tfmt = sdb_const_get(TDB, var3, NULL); + isStruct = true; + } else { + // special case for char[]. Use char* format type without * + if (!strcmp(type, "char") && elements > 0) { + tfmt = sdb_const_get(TDB, "type.char *", NULL); + if (tfmt && *tfmt == '*') { + tfmt++; + } + } else { + if (rz_str_startswith(type, "enum ")) { + snprintf(var3, sizeof(var3), "%s", type + 5); + isEnum = true; + } else { + snprintf(var3, sizeof(var3), "type.%s", type); + } + tfmt = sdb_const_get(TDB, var3, NULL); + } + } + if (isfp) { + // consider function pointer as void * for printing + fmt = rz_str_append(fmt, "p"); + vars = rz_str_append(vars, p); + vars = rz_str_append(vars, " "); + } else if (tfmt) { + (void)rz_str_replace_ch(type, ' ', '_', true); + if (elements > 0) { + fmt = rz_str_appendf(fmt, "[%d]", elements); + } + if (isStruct) { + fmt = rz_str_append(fmt, "?"); + vars = rz_str_appendf(vars, "(%s)%s", struct_name, p); + vars = rz_str_append(vars, " "); + } else if (isEnum) { + fmt = rz_str_append(fmt, "E"); + vars = rz_str_appendf(vars, "(%s)%s", type + 5, p); + vars = rz_str_append(vars, " "); + } else { + fmt = rz_str_append(fmt, tfmt); + vars = rz_str_append(vars, p); + vars = rz_str_append(vars, " "); + } + } else { + eprintf("Cannot resolve type '%s'\n", var3); + } + free(type); + } + free(p); + } + free(fields); + fmt = rz_str_append(fmt, " "); + fmt = rz_str_append(fmt, vars); + free(vars); + return fmt; +} + +RZ_API char *rz_type_format(RzType *type, const char *t) { + char var[130], var2[132]; + Sdb *TDB = type->sdb_types + const char *kind = sdb_const_get(TDB, t, NULL); + if (!kind) { + return NULL; + } + // only supports struct atm + snprintf(var, sizeof(var), "%s.%s", kind, t); + if (!strcmp(kind, "type")) { + const char *fmt = sdb_const_get(TDB, var, NULL); + if (fmt) { + return strdup(fmt); + } + } else if (!strcmp(kind, "struct") || !strcmp(kind, "union")) { + return fmt_struct_union(TDB, var, false); + } + if (!strcmp(kind, "typedef")) { + snprintf(var2, sizeof(var2), "typedef.%s", t); + const char *type = sdb_const_get(TDB, var2, NULL); + // only supports struct atm + if (type && !strcmp(type, "struct")) { + return fmt_struct_union(TDB, var, true); + } + } + return NULL; +} + // XXX: this is somewhat incomplete. must be updated to handle all format chars -RZ_API int rz_print_format_struct_size(RzPrint *p, const char *f, int mode, int n) { +RZ_API int rz_type_format_struct_size(RzPrint *p, const char *f, int mode, int n) { char *end, *args, *fmt; int size = 0, tabsize = 0, i, idx = 0, biggest = 0, fmt_len = 0, times = 1; bool tabsize_set = false; diff --git a/librz/type/function.c b/librz/type/function.c new file mode 100644 index 00000000000..ddf35941757 --- /dev/null +++ b/librz/type/function.c @@ -0,0 +1,264 @@ +// SPDX-FileCopyrightText: 2013-2020 pancake +// SPDX-FileCopyrightText: 2013-2020 oddcoder +// SPDX-FileCopyrightText: 2013-2020 sivaramaaa +// SPDX-FileCopyrightText: 2021 Anton Kochkov +// SPDX-License-Identifier: LGPL-3.0-only + +#include +#include +#include +#include + +// Function prototypes api +RZ_API bool rz_type_func_exist(RzType *t, const char *func_name) { + rz_return_val_if_fail(t, false); + Sdb *TDB = t->sdb_types; + const char *fcn = sdb_const_get(TDB, func_name, 0); + return fcn && !strcmp(fcn, "func"); +} + +RZ_API bool rz_type_func_has_args(RzType *t, const char *func_name) { + rz_return_val_if_fail(t, false); + Sdb *TDB = t->sdb_types; + const char *query = sdb_fmt("func.%s.args", func_name); + const char *fcn = sdb_const_get(TDB, query, 0); + return (fcn != NULL); +} + +RZ_API const char *rz_type_func_ret(RzType *t, const char *func_name) { + rz_return_val_if_fail(t, NULL); + Sdb *TDB = t->sdb_types; + const char *query = sdb_fmt("func.%s.ret", func_name); + return sdb_const_get(TDB, query, 0); +} + +RZ_API const char *rz_type_func_cc(RzType *t, const char *func_name) { + rz_return_val_if_fail(t, NULL); + Sdb *TDB = t->sdb_types; + const char *query = sdb_fmt("func.%s.cc", func_name); + return sdb_const_get(TDB, query, 0); +} + +RZ_API int rz_type_func_args_count(RzType *t, const char *func_name) { + rz_return_val_if_fail(t, 0); + Sdb *TDB = t->sdb_types; + const char *query = sdb_fmt("func.%s.args", func_name); + return sdb_num_get(TDB, query, 0); +} + +RZ_API RZ_OWN char *rz_type_func_args_type(RzType *t, RZ_NONNULL const char *func_name, int i) { + rz_return_val_if_fail(t, NULL); + Sdb *TDB = t->sdb_types; + const char *query = sdb_fmt("func.%s.arg.%d", func_name, i); + char *ret = sdb_get(TDB, query, 0); + if (ret) { + char *comma = strchr(ret, ','); + if (comma) { + *comma = 0; + return ret; + } + free(ret); + } + return NULL; +} + +RZ_API const char *rz_type_func_args_name(RzType *t, RZ_NONNULL const char *func_name, int i) { + rz_return_val_if_fail(t, NULL); + Sdb *TDB = t->sdb_types; + const char *query = sdb_fmt("func.%s.arg.%d", func_name, i); + const char *get = sdb_const_get(TDB, query, 0); + if (get) { + char *ret = strchr(get, ','); + return ret == 0 ? ret : ret + 1; + } + return NULL; +} + +RZ_API bool rz_type_func_arg_count_set(RzType *t, RZ_NONNULL const char *func_name, int arg_count) { + rz_return_val_if_fail(t, NULL); + Sdb *TDB = t->sdb_types; + bool result = false; + RzStrBuf key, value; + rz_strbuf_init(&key); + rz_strbuf_init(&value); + if (!rz_strbuf_setf(&key, "func.%s.args", func_name) || + !rz_strbuf_setf(&value, "%d", arg_count)) { + goto exit; + } + sdb_set(TDB, rz_strbuf_get(&key), rz_strbuf_get(&value), 0); +exit: + rz_strbuf_fini(&key); + rz_strbuf_fini(&value); + return result; +} + +RZ_API bool rz_type_func_arg_set(RzType *t, RZ_NONNULL const char *func_name, int i, RZ_NONNULL const char *arg_name, RZ_NONNULL const char *arg_type) { + rz_return_val_if_fail(t, NULL); + Sdb *TDB = t->sdb_types; + bool result = false; + RzStrBuf key, value; + rz_strbuf_init(&key); + rz_strbuf_init(&value); + if (!rz_strbuf_setf(&key, "func.%s.arg.%d", func_name, i) || + !rz_strbuf_setf(&value, "%s,%s", arg_type, arg_name)) { + goto exit; + } + sdb_set(TDB, rz_strbuf_get(&key), rz_strbuf_get(&value), 0); +exit: + rz_strbuf_fini(&key); + rz_strbuf_fini(&value); + return result; +} + +RZ_API bool rz_type_func_ret_set(RzType *t, const char *func_name, const char *type) { + rz_return_val_if_fail(t && func_name && type, NULL); + Sdb *TDB = t->sdb_types; + char *sdb_type = rz_str_newf("type.%s", type); + if (!sdb_exists(TDB, sdb_type)) { + free(sdb_type); + return false; + } + free(sdb_type); + const char *query = sdb_fmt("func.%s.ret=%s", func_name, type); + return sdb_querys(TDB, NULL, 0, query); +} + +#define MIN_MATCH_LEN 4 + +static inline bool is_function(const char *name) { + return name && !strcmp("func", name); +} + +static RZ_OWN char *type_func_try_guess(Sdb *TDB, RZ_NONNULL char *name) { + if (strlen(name) < MIN_MATCH_LEN) { + return NULL; + } + + const char *res = sdb_const_get(TDB, name, NULL); + if (is_function(res)) { + return strdup(name); + } + + return NULL; +} + +static inline bool is_auto_named(char *func_name, size_t slen) { + return slen > 4 && (rz_str_startswith(func_name, "fcn.") || rz_str_startswith(func_name, "loc.")); +} + +static inline bool has_rz_prefixes(char *func_name, int offset, size_t slen) { + return slen > 4 && (offset + 3 < slen) && func_name[offset + 3] == '.'; +} + +static char *strip_rz_prefixes(char *func_name, size_t slen) { + // strip r2 prefixes (sym, sym.imp, etc') + int offset = 0; + + while (has_rz_prefixes(func_name, offset, slen)) { + offset += 4; + } + + return func_name + offset; +} + +static char *strip_common_prefixes_stdlib(char *func_name) { + // strip common prefixes from standard lib functions + if (rz_str_startswith(func_name, "__isoc99_")) { + func_name += 9; + } else if (rz_str_startswith(func_name, "__libc_") && !strstr(func_name, "_main")) { + func_name += 7; + } else if (rz_str_startswith(func_name, "__GI_")) { + func_name += 5; + } + + return func_name; +} + +static char *strip_dll_prefix(char *func_name) { + char *tmp = strstr(func_name, "dll_"); + if (tmp) { + return tmp + 3; + } + + return func_name; +} + +static void clean_function_name(char *func_name) { + char *last = (char *)rz_str_lchr(func_name, '_'); + if (!last || !rz_str_isnumber(last + 1)) { + return; + } + + *last = '\0'; +} + +// TODO: +// - symbol names are long and noisy, some of them might not be matched due +// to additional information added around name +RZ_API RZ_OWN char *rz_type_func_guess(RzType *t, RZ_NONNULL char *func_name) { + rz_return_val_if_fail(t, NULL); + Sdb *TDB = t->sdb_types; + char *str = func_name; + char *result = NULL; + rz_return_val_if_fail(TDB, false); + rz_return_val_if_fail(func_name, false); + + size_t slen = strlen(str); + if (slen < MIN_MATCH_LEN || is_auto_named(str, slen)) { + return NULL; + } + + str = strip_rz_prefixes(str, slen); + str = strip_common_prefixes_stdlib(str); + str = strip_dll_prefix(str); + + if ((result = type_func_try_guess(TDB, str))) { + return result; + } + + str = strdup(str); + clean_function_name(str); + + if (*str == '_' && (result = type_func_try_guess(TDB, str + 1))) { + free(str); + return result; + } + + free(str); + return result; +} + +RZ_API RzList *rz_type_noreturn_functions(RzType *type) { + RzList *noretl = rz_list_newf(free); + SdbKv *kv; + SdbListIter *iter; + SdbList *l = sdb_foreach_list(type->sdb_types, true); + ls_foreach (l, iter, kv) { + 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); + } + 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); + } + } + ls_free(l); + return noretl; +} + diff --git a/librz/type/link.c b/librz/type/link.c new file mode 100644 index 00000000000..34592af48da --- /dev/null +++ b/librz/type/link.c @@ -0,0 +1,121 @@ +// SPDX-FileCopyrightText: 2021 Anton Kochkov +// SPDX-License-Identifier: LGPL-3.0-only + +#include +#include +#include +#include + +#include "type_internal.h" + +// XXX 12 is the maxstructsizedelta +#define TYPE_RANGE_BASE(x) ((x) >> 16) + +static RzList *types_range_list(Sdb *db, ut64 addr) { + RzList *list = NULL; + ut64 base = TYPE_RANGE_BASE(addr); + char *s = rz_str_newf("range.%" PFMT64x, base); + if (s) { + char *r = sdb_get(db, s, 0); + if (r) { + list = rz_str_split_list(r, " ", -1); + } + free(s); + } + return list; +} + +static void types_range_del(Sdb *db, ut64 addr) { + ut64 base = TYPE_RANGE_BASE(addr); + const char *k = sdb_fmt("range.%" PFMT64x, base); + char valstr[SDB_NUM_BUFSZ]; + const char *v = sdb_itoa(addr, valstr, SDB_NUM_BASE); + sdb_array_remove(db, k, v, 0); +} + +static void types_range_add(Sdb *db, ut64 addr) { + ut64 base = TYPE_RANGE_BASE(addr); + const char *k = sdb_fmt("range.%" PFMT64x, base); + (void)sdb_array_add_num(db, k, addr, 0); +} + +RZ_API char *rz_type_link_at(RzType *t, ut64 addr) { + rz_return_val_if_fail(t, NULL); + Sdb *TDB = t->sdb_types; + if (addr == UT64_MAX) { + return NULL; + } + const char *query = sdb_fmt("link.%08" PFMT64x, addr); + char *res = sdb_get(TDB, query, 0); + if (!res) { // resolve struct memb if possible for given addr + RzList *list = types_range_list(TDB, addr); + RzListIter *iter; + const char *s; + rz_list_foreach (list, iter, s) { + ut64 laddr = rz_num_get(NULL, s); + if (addr > laddr) { + int delta = addr - laddr; + const char *lk = sdb_fmt("link.%08" PFMT64x, laddr); + char *k = sdb_get(TDB, lk, 0); + res = rz_type_get_struct_memb(t, k, delta); + if (res) { + break; + } + free(k); + } + } + } + return res; +} + +RZ_API bool rz_type_set_link(RzType *t, const char *type, ut64 addr) { + rz_return_val_if_fail(t, false); + Sdb *TDB = t->sdb_types; + if (sdb_const_get(TDB, type, 0)) { + char *laddr = rz_str_newf("link.%08" PFMT64x, addr); + sdb_set(TDB, laddr, type, 0); + types_range_add(TDB, addr); + free(laddr); + return true; + } + return false; +} + +RZ_API bool rz_type_link_offset(RzType *t, const char *type, ut64 addr) { + rz_return_val_if_fail(t, false); + Sdb *TDB = t->sdb_types; + if (sdb_const_get(TDB, type, 0)) { + char *laddr = rz_str_newf("offset.%08" PFMT64x, addr); + sdb_set(TDB, laddr, type, 0); + free(laddr); + return true; + } + return false; +} + +RZ_API bool rz_type_unlink(RzType *t, ut64 addr) { + rz_return_val_if_fail(t, false); + Sdb *TDB = t->sdb_types; + char *laddr = sdb_fmt("link.%08" PFMT64x, addr); + sdb_unset(TDB, laddr, 0); + types_range_del(TDB, addr); + return true; +} + +static bool sdbdeletelink(void *p, const char *k, const char *v) { + //Sdb *TDB = (Sdb *)p; + if (!strncmp(k, "link.", strlen("link."))) { + //rz_type_del(TDB, k); + //FIXME + } + return true; +} + +RZ_API bool rz_type_unlink_all(RzType *t) { + rz_return_val_if_fail(t, false); + Sdb *TDB = t->sdb_types; + sdb_foreach(TDB, sdbdeletelink, TDB); + return true; +} + + diff --git a/librz/type/meson.build b/librz/type/meson.build new file mode 100644 index 00000000000..bbdf1566c75 --- /dev/null +++ b/librz/type/meson.build @@ -0,0 +1,42 @@ +rz_type_sources = [ + 'base.c', + 'code.c', + 'function.c', + 'link.c', + 'serialize_types.c', + 'type.c', + 'utype.c' +] + +rz_type_inc = [ + platform_inc, +] + +rz_type = library('rz_type', rz_type_sources, + include_directories: rz_type_inc, + c_args: library_cflags, + dependencies: [ + rz_util_dep, + tcc_dep, + mpc_dep + ], + install: true, + implicit_include_directories: false, + install_rpath: rpath_lib, + soversion: rizin_libversion +) + +rz_type_dep = declare_dependency(link_with: rz_type, + include_directories: rz_type_inc) + +pkgconfig_mod.generate(rz_type, + subdirs: 'librz', + version: rizin_version, + name: 'rz_type', + filebase: 'rz_type', + libraries: pkgcfg_sanitize_libs, + requires: [ + 'rz_util', + ], + description: 'rizin foundation libraries' +) diff --git a/librz/type/serialize_types.c b/librz/type/serialize_types.c new file mode 100644 index 00000000000..7c3b51fd834 --- /dev/null +++ b/librz/type/serialize_types.c @@ -0,0 +1,19 @@ +// SPDX-FileCopyrightText: 2021 Anton Kochkov +// SPDX-License-Identifier: LGPL-3.0-only + +#include +#include +#include +#include + +RZ_API void rz_serialize_types_save(RZ_NONNULL Sdb *db, RZ_NONNULL RzType *types) { + sdb_copy(types->sdb_types, db); +} + +RZ_API bool rz_serialize_types_load(RZ_NONNULL Sdb *db, RZ_NONNULL RzType *types, RZ_NULLABLE RzSerializeResultInfo *res) { + sdb_reset(types->sdb_types); + sdb_copy(db, types->sdb_types); + return true; +} + + diff --git a/librz/type/type.c b/librz/type/type.c new file mode 100644 index 00000000000..661d490e2b5 --- /dev/null +++ b/librz/type/type.c @@ -0,0 +1,279 @@ +// SPDX-FileCopyrightText: 2019 pancake +// SPDX-FileCopyrightText: 2019 oddcoder +// SPDX-FileCopyrightText: 2019-2021 Anton Kochkov +// SPDX-License-Identifier: LGPL-3.0-only + +#include +#include +#include +#include + +#include "type_internal.h" + +RZ_API RzType *rz_type_new() { + RzType *type = RZ_NEW0(RzType); + if (!type) { + return NULL; + } + Sdb *sdb = sdb_new0(); + type->sdb_types = sdb_ns(sdb, "types", 1); + return type; +} + +RZ_API void rz_type_free(RzType *t) { + sdb_free(t->sdb_types); + free(t); +} + +// copypasta from core/cbin.c +static void sdb_concat_by_path(Sdb *s, const char *path) { + Sdb *db = sdb_new(0, path, 0); + sdb_merge(s, db); + sdb_close(db); + sdb_free(db); +} + +RZ_API void rz_type_load_sdb(RzType *t, const char *path) { + if (rz_file_exists(path)) { + sdb_concat_by_path(t->sdb_types, path); + } +} + +RZ_API void rz_type_purge(RzType *t) { + sdb_reset(t->sdb_types); +} + +RZ_API void rz_type_set_bits(RzType *t, int bits) { + t->target->bits = bits; +} + +RZ_API void rz_type_set_os(RzType *t, const char *os) { + t->target->os = os; +} + +RZ_API void rz_type_set_cpu(RzType *t, const char *cpu) { + t->target->cpu = cpu; +} + +RZ_API char *rz_type_kuery(RzType *t, const char *query) { + char *output = NULL; + if (query) { + output = sdb_querys(t->sdb_types, NULL, -1, query); + } else { + output = sdb_querys(t->sdb_types, NULL, -1, "*"); + } + return output; +} + +static char *is_ctype(char *type) { + char *name = NULL; + if ((name = strstr(type, "=type")) || + (name = strstr(type, "=struct")) || + (name = strstr(type, "=union")) || + (name = strstr(type, "=enum")) || + (name = strstr(type, "=typedef")) || + (name = strstr(type, "=func"))) { + return name; + } + return NULL; +} + +RZ_API bool rz_type_del(RzType *t, RZ_NONNULL const char *name) { + rz_return_val_if_fail(t && name, false); + Sdb *TDB = t->sdb_types; + const char *kind = sdb_const_get(TDB, name, 0); + if (!kind) { + return false; + } + if (!strcmp(kind, "type")) { + sdb_unset(TDB, sdb_fmt("type.%s", name), 0); + sdb_unset(TDB, sdb_fmt("type.%s.size", name), 0); + sdb_unset(TDB, sdb_fmt("type.%s.meta", name), 0); + sdb_unset(TDB, name, 0); + } else if (!strcmp(kind, "struct") || !strcmp(kind, "union")) { + int i, n = sdb_array_length(TDB, sdb_fmt("%s.%s", kind, name)); + char *elements_key = rz_str_newf("%s.%s", kind, name); + for (i = 0; i < n; i++) { + char *p = sdb_array_get(TDB, elements_key, i, NULL); + sdb_unset(TDB, sdb_fmt("%s.%s", elements_key, p), 0); + free(p); + } + sdb_unset(TDB, elements_key, 0); + sdb_unset(TDB, name, 0); + free(elements_key); + } else if (!strcmp(kind, "func")) { + int i, n = sdb_num_get(TDB, sdb_fmt("func.%s.args", name), 0); + for (i = 0; i < n; i++) { + sdb_unset(TDB, sdb_fmt("func.%s.arg.%d", name, i), 0); + } + sdb_unset(TDB, sdb_fmt("func.%s.ret", name), 0); + sdb_unset(TDB, sdb_fmt("func.%s.cc", name), 0); + sdb_unset(TDB, sdb_fmt("func.%s.noreturn", name), 0); + sdb_unset(TDB, sdb_fmt("func.%s.args", name), 0); + sdb_unset(TDB, name, 0); + } else if (!strcmp(kind, "enum")) { + RzList *list = rz_type_get_enum(t, name); + RzTypeEnum *member; + RzListIter *iter; + rz_list_foreach (list, iter, member) { + sdb_unset(TDB, sdb_fmt("enum.%s.%s", name, member->name), 0); + sdb_unset(TDB, sdb_fmt("enum.%s.%s", name, member->val), 0); + } + sdb_unset(TDB, name, 0); + rz_list_free(list); + } else if (!strcmp(kind, "typedef")) { + RzStrBuf buf; + rz_strbuf_init(&buf); + rz_strbuf_setf(&buf, "typedef.%s", name); + sdb_unset(TDB, rz_strbuf_get(&buf), 0); + rz_strbuf_fini(&buf); + sdb_unset(TDB, name, 0); + } else { + eprintf("Unrecognized type kind \"%s\"\n", kind); + return false; + } + return true; +} + +RZ_API void rz_type_remove_parsed_type(RzType *t, const char *name) { + rz_return_if_fail(t && name); + Sdb *TDB = t->sdb_types; + SdbKv *kv; + SdbListIter *iter; + const char *type = sdb_const_get(TDB, name, 0); + if (!type) { + return; + } + int tmp_len = strlen(name) + strlen(type); + char *tmp = malloc(tmp_len + 1); + rz_type_del(t, name); + if (tmp) { + snprintf(tmp, tmp_len + 1, "%s.%s.", type, name); + SdbList *l = sdb_foreach_list(TDB, true); + ls_foreach (l, iter, kv) { + if (!strncmp(sdbkv_key(kv), tmp, tmp_len)) { + rz_type_del(t, sdbkv_key(kv)); + } + } + ls_free(l); + free(tmp); + } +} + +RZ_API void rz_type_save_parsed_type(RzType *t, const char *parsed) { + rz_return_if_fail(t && parsed); + + // First, if any parsed types exist, let's remove them. + char *type = strdup(parsed); + if (type) { + char *cur = type; + while (1) { + cur = is_ctype(cur); + if (!cur) { + break; + } + char *name = cur++; + *name = 0; + while (name > type && *(name - 1) != '\n') { + name--; + } + rz_type_remove_parsed_type(t, name); + } + free(type); + } + + // Now add the type to sdb. + sdb_query_lines(t->sdb_types, parsed); +} + +RZ_API void rz_type_db_init(RzType *types, const char *dir_prefix, const char *arch, int bits, const char *os) { + rz_return_if_fail(types); + Sdb *TDB = types->sdb_types; + + // make sure they are empty this is initializing + sdb_reset(TDB); + + const char *dbpath = sdb_fmt(RZ_JOIN_3_PATHS("%s", RZ_SDB_FCNSIGN, "types.sdb"), dir_prefix); + if (rz_file_exists(dbpath)) { + sdb_concat_by_path(TDB, dbpath); + } + dbpath = sdb_fmt(RZ_JOIN_3_PATHS("%s", RZ_SDB_FCNSIGN, "types-%s.sdb"), + dir_prefix, arch); + if (rz_file_exists(dbpath)) { + sdb_concat_by_path(TDB, dbpath); + } + dbpath = sdb_fmt(RZ_JOIN_3_PATHS("%s", RZ_SDB_FCNSIGN, "types-%s.sdb"), + dir_prefix, os); + if (rz_file_exists(dbpath)) { + sdb_concat_by_path(TDB, dbpath); + } + dbpath = sdb_fmt(RZ_JOIN_3_PATHS("%s", RZ_SDB_FCNSIGN, "types-%d.sdb"), + dir_prefix, bits); + if (rz_file_exists(dbpath)) { + sdb_concat_by_path(TDB, dbpath); + } + dbpath = sdb_fmt(RZ_JOIN_3_PATHS("%s", RZ_SDB_FCNSIGN, "types-%s-%d.sdb"), + dir_prefix, os, bits); + if (rz_file_exists(dbpath)) { + sdb_concat_by_path(TDB, dbpath); + } + dbpath = sdb_fmt(RZ_JOIN_3_PATHS("%s", RZ_SDB_FCNSIGN, "types-%s-%d.sdb"), + dir_prefix, arch, bits); + if (rz_file_exists(dbpath)) { + sdb_concat_by_path(TDB, dbpath); + } + dbpath = sdb_fmt(RZ_JOIN_3_PATHS("%s", RZ_SDB_FCNSIGN, "types-%s-%s.sdb"), + dir_prefix, arch, os); + if (rz_file_exists(dbpath)) { + sdb_concat_by_path(TDB, dbpath); + } + dbpath = sdb_fmt(RZ_JOIN_3_PATHS("%s", RZ_SDB_FCNSIGN, "types-%s-%s-%d.sdb"), + dir_prefix, arch, os, bits); + if (rz_file_exists(dbpath)) { + sdb_concat_by_path(TDB, dbpath); + } +} + +// Listing all available types by category + +RZ_API RzList *rz_type_enums(RzType *type) { + RzList *ccl = rz_list_new(); + SdbKv *kv; + SdbListIter *iter; + SdbList *l = sdb_foreach_list(type->sdb_types, true); + ls_foreach (l, iter, kv) { + if (!strcmp(sdbkv_value(kv), "enum")) { + rz_list_append(ccl, strdup(sdbkv_key(kv))); + } + } + ls_free(l); + return ccl; +} + +static bool sdb_if_typedef_cb(void *p, const char *k, const char *v) { + return !strncmp(v, "typedef", strlen("typedef") + 1); +} + +RZ_API RzList *rz_type_typedefs(RzType *type) { + Sdb *TDB = type->sdb_types; + SdbList *sl = sdb_foreach_list_filter_user(TDB, sdb_if_typedef_cb, true, TDB); + RzList *l = rz_list_of_sdblist(sl); + ls_free(sl); + return l; +} + +RZ_API RzList *rz_type_links(RzType *type) { + RzList *ccl = rz_list_new(); + SdbKv *kv; + SdbListIter *iter; + SdbList *l = sdb_foreach_list(type->sdb_types, true); + ls_foreach (l, iter, kv) { + if (!strcmp(sdbkv_value(kv), "link")) { + rz_list_append(ccl, strdup(sdbkv_key(kv))); + } + } + ls_free(l); + return ccl; +} + + diff --git a/librz/type/type_internal.h b/librz/type/type_internal.h new file mode 100644 index 00000000000..19369471053 --- /dev/null +++ b/librz/type/type_internal.h @@ -0,0 +1,3 @@ +// SPDX-FileCopyrightText: 2021 Anton Kochkov +// SPDX-License-Identifier: LGPL-3.0-only +// diff --git a/librz/type/utype.c b/librz/type/utype.c new file mode 100644 index 00000000000..4e9eb433d29 --- /dev/null +++ b/librz/type/utype.c @@ -0,0 +1,341 @@ +// SPDX-FileCopyrightText: 2013-2020 pancake +// SPDX-FileCopyrightText: 2013-2020 oddcoder +// SPDX-FileCopyrightText: 2013-2020 sivaramaaa +// SPDX-License-Identifier: LGPL-3.0-only + +#include +#include +#include + +RZ_API const char *rz_type_get(RzType *t, const char *name) { + rz_return_val_if_fail(t, NULL); + Sdb *TDB = t->sdb_types; + const char *query = sdb_fmt("type.%s", name); + return sdb_const_get(TDB, query, 0); +} + +RZ_API bool rz_type_set(RzType *t, ut64 at, RZ_NONNULL const char *field, ut64 val) { + rz_return_val_if_fail(t && field, false); + Sdb *TDB = t->sdb_types; + const char *kind; + char var[128]; + sprintf(var, "link.%08" PFMT64x, at); + kind = sdb_const_get(TDB, var, NULL); + if (kind) { + const char *p = sdb_const_get(TDB, kind, NULL); + if (p) { + snprintf(var, sizeof(var), "%s.%s.%s", p, kind, field); + int off = sdb_array_get_num(TDB, var, 1, NULL); + //int siz = sdb_array_get_num (DB, var, 2, NULL); + eprintf("wv 0x%08" PFMT64x " @ 0x%08" PFMT64x, val, at + off); + return true; + } + eprintf("Invalid kind of type\n"); + } + return false; +} + +RZ_API int rz_type_kind(RzType *t, RZ_NONNULL const char *name) { + rz_return_val_if_fail(t && name, -1); + Sdb *TDB = t->sdb_types; + const char *type = sdb_const_get(TDB, name, 0); + if (!type) { + return -1; + } + if (!strcmp(type, "enum")) { + return RZ_BASE_TYPE_KIND_ENUM; + } + if (!strcmp(type, "struct")) { + return RZ_BASE_TYPE_KIND_STRUCT; + } + if (!strcmp(type, "union")) { + return RZ_BASE_TYPE_KIND_UNION; + } + if (!strcmp(type, "type")) { + return RZ_BASE_TYPE_KIND_ATOMIC; + } + if (!strcmp(type, "typedef")) { + return RZ_BASE_TYPE_KIND_TYPEDEF; + } + return -1; +} + +RZ_API RzList *rz_type_get_enum(RzType *t, RZ_NONNULL const char *name) { + rz_return_val_if_fail(t && name, NULL); + Sdb *TDB = t->sdb_types; + char *p, var[130]; + int n; + + if (rz_type_kind(t, name) != RZ_BASE_TYPE_KIND_ENUM) { + return NULL; + } + RzList *res = rz_list_new(); + snprintf(var, sizeof(var), "enum.%s", name); + for (n = 0; (p = sdb_array_get(TDB, var, n, NULL)); n++) { + RzTypeEnum *member = RZ_NEW0(RzTypeEnum); + if (member) { + char *var2 = rz_str_newf("%s.%s", var, p); + if (var2) { + char *val = sdb_array_get(TDB, var2, 0, NULL); + if (val) { + member->name = p; + member->val = val; + rz_list_append(res, member); + } else { + free(member); + free(var2); + } + } else { + free(member); + } + } + } + return res; +} + +RZ_API char *rz_type_enum_member(RzType *t, RZ_NONNULL const char *name, const char *member, ut64 val) { + rz_return_val_if_fail(t && name, NULL); + Sdb *TDB = t->sdb_types; + if (rz_type_kind(t, name) != RZ_BASE_TYPE_KIND_ENUM) { + return NULL; + } + const char *q = member + ? sdb_fmt("enum.%s.%s", name, member) + : sdb_fmt("enum.%s.0x%" PFMT64x, name, val); + return sdb_get(TDB, q, 0); +} + +RZ_API RzList *rz_type_enum_find_member(RzType *t, ut64 val) { + rz_return_val_if_fail(t, NULL); + Sdb *TDB = t->sdb_types; + SdbKv *kv; + SdbListIter *iter; + SdbList *l = sdb_foreach_list(TDB, true); + RzList *res = rz_list_new(); + ls_foreach (l, iter, kv) { + if (!strcmp(sdbkv_value(kv), "enum")) { + const char *name = sdbkv_key(kv); + if (name) { + const char *q = sdb_fmt("enum.%s.0x%" PFMT64x, name, val); + char *member = sdb_get(TDB, q, 0); + if (member) { + char *pair = rz_str_newf("%s.%s", name, member); + rz_list_append(res, pair); + free(member); + } + } + } + } + ls_free(l); + return res; +} + +RZ_API char *rz_type_enum_getbitfield(RzType *t, RZ_NONNULL const char *name, ut64 val) { + rz_return_val_if_fail(t && name, NULL); + Sdb *TDB = t->sdb_types; + char *q, *ret = NULL; + const char *res; + int i; + + if (rz_type_kind(t, name) != RZ_BASE_TYPE_KIND_ENUM) { + return NULL; + } + bool isFirst = true; + ret = rz_str_appendf(ret, "0x%08" PFMT64x " : ", val); + for (i = 0; i < 32; i++) { + ut32 n = 1ULL << i; + if (!(val & n)) { + continue; + } + q = sdb_fmt("enum.%s.0x%x", name, n); + res = sdb_const_get(TDB, q, 0); + if (isFirst) { + isFirst = false; + } else { + ret = rz_str_append(ret, " | "); + } + if (res) { + ret = rz_str_append(ret, res); + } else { + ret = rz_str_appendf(ret, "0x%x", n); + } + } + return ret; +} + +RZ_API ut64 rz_type_get_bitsize(RzType *types, RZ_NONNULL const char *type) { + rz_return_val_if_fail(types && type, 0); + Sdb *TDB = types->sdb_types; + char *query; + /* Filter out the structure keyword if type looks like "struct mystruc" */ + const char *tmptype; + if (!strncmp(type, "struct ", 7)) { + tmptype = type + 7; + } else if (!strncmp(type, "union ", 6)) { + tmptype = type + 6; + } else { + tmptype = type; + } + if ((strstr(type, "*(") || strstr(type, " *")) && strncmp(type, "char *", 7)) { + return 32; + } + const char *t = sdb_const_get(TDB, tmptype, 0); + if (!t) { + if (!strncmp(tmptype, "enum ", 5)) { + //XXX: Need a proper way to determine size of enum + return 32; + } + return 0; + } + if (!strcmp(t, "type")) { + query = rz_str_newf("type.%s.size", tmptype); + ut64 r = sdb_num_get(TDB, query, 0); // returns size in bits + free(query); + return r; + } + if (!strcmp(t, "struct") || !strcmp(t, "union")) { + query = rz_str_newf("%s.%s", t, tmptype); + char *members = sdb_get(TDB, query, 0); + char *next, *ptr = members; + ut64 ret = 0; + if (members) { + do { + char *name = sdb_anext(ptr, &next); + if (!name) { + break; + } + free(query); + query = rz_str_newf("%s.%s.%s", t, tmptype, name); + char *subtype = sdb_get(TDB, query, 0); + RZ_FREE(query); + if (!subtype) { + break; + } + char *tmp = strchr(subtype, ','); + if (tmp) { + *tmp++ = 0; + tmp = strchr(tmp, ','); + if (tmp) { + *tmp++ = 0; + } + int elements = rz_num_math(NULL, tmp); + if (elements == 0) { + elements = 1; + } + if (!strcmp(t, "struct")) { + ret += rz_type_get_bitsize(types, subtype) * elements; + } else { + ut64 sz = rz_type_get_bitsize(types, subtype) * elements; + ret = sz > ret ? sz : ret; + } + } + free(subtype); + ptr = next; + } while (next); + free(members); + } + free(query); + return ret; + } + return 0; +} + +RZ_API char *rz_type_get_struct_memb(RzType *t, RZ_NONNULL const char *type, int offset) { + rz_return_val_if_fail(t && type, NULL); + Sdb *TDB = t->sdb_types; + int i, cur_offset, next_offset = 0; + char *res = NULL; + + if (offset < 0) { + return NULL; + } + char *query = sdb_fmt("struct.%s", type); + char *members = sdb_get(TDB, query, 0); + if (!members) { + //eprintf ("%s is not a struct\n", type); + return NULL; + } + int nargs = rz_str_split(members, ','); + for (i = 0; i < nargs; i++) { + const char *name = rz_str_word_get0(members, i); + if (!name) { + break; + } + query = sdb_fmt("struct.%s.%s", type, name); + char *subtype = sdb_get(TDB, query, 0); + if (!subtype) { + break; + } + int len = rz_str_split(subtype, ','); + if (len < 3) { + free(subtype); + break; + } + cur_offset = rz_num_math(NULL, rz_str_word_get0(subtype, len - 2)); + if (cur_offset > 0 && cur_offset < next_offset) { + free(subtype); + break; + } + if (!cur_offset) { + cur_offset = next_offset; + } + if (cur_offset == offset) { + res = rz_str_newf("%s.%s", type, name); + free(subtype); + break; + } + int arrsz = rz_num_math(NULL, rz_str_word_get0(subtype, len - 1)); + int fsize = (rz_type_get_bitsize(t, subtype) * (arrsz ? arrsz : 1)) / 8; + if (!fsize) { + free(subtype); + break; + } + next_offset = cur_offset + fsize; + // Handle nested structs + if (offset > cur_offset && offset < next_offset) { + char *nested_type = (char *)rz_str_word_get0(subtype, 0); + if (rz_str_startswith(nested_type, "struct ") && !rz_str_endswith(nested_type, " *")) { + len = rz_str_split(nested_type, ' '); + if (len < 2) { + free(subtype); + break; + } + nested_type = (char *)rz_str_word_get0(nested_type, 1); + char *nested_res = rz_type_get_struct_memb(t, nested_type, offset - cur_offset); + if (nested_res) { + len = rz_str_split(nested_res, '.'); + res = rz_str_newf("%s.%s.%s", type, name, rz_str_word_get0(nested_res, len - 1)); + free(nested_res); + free(subtype); + break; + } + } + } + free(subtype); + } + free(members); + return res; +} + +// XXX this function is slow! +RZ_API RzList *rz_type_get_by_offset(RzType *t, ut64 offset) { + rz_return_val_if_fail(t, NULL); + Sdb *TDB = t->sdb_types; + RzList *offtypes = rz_list_new(); + SdbList *ls = sdb_foreach_list(TDB, true); + SdbListIter *lsi; + SdbKv *kv; + ls_foreach (ls, lsi, kv) { + // TODO: Add unions support + if (!strncmp(sdbkv_value(kv), "struct", 6) && strncmp(sdbkv_key(kv), "struct.", 7)) { + char *res = rz_type_get_struct_memb(t, sdbkv_key(kv), offset); + if (res) { + rz_list_append(offtypes, res); + } + } + } + ls_free(ls); + return offtypes; +} + + diff --git a/librz/util/meson.build b/librz/util/meson.build index 98e3c589f6d..7774e7c7a66 100644 --- a/librz/util/meson.build +++ b/librz/util/meson.build @@ -31,7 +31,6 @@ rz_util_sources = [ 'log.c', 'mem.c', 'name.c', - 'format.c', 'pie.c', 'seven.c', 'print.c', @@ -43,7 +42,6 @@ rz_util_sources = [ 'astr.c', 'pkcs7.c', 'x509.c', - 'utype.c', 'randomart.c', 'range.c', 'rbtree.c', diff --git a/librz/util/utype.c b/librz/util/utype.c deleted file mode 100644 index 25a95816aab..00000000000 --- a/librz/util/utype.c +++ /dev/null @@ -1,718 +0,0 @@ -// SPDX-FileCopyrightText: 2013-2020 pancake -// SPDX-FileCopyrightText: 2013-2020 oddcoder -// SPDX-FileCopyrightText: 2013-2020 sivaramaaa -// SPDX-License-Identifier: LGPL-3.0-only - -#include - -RZ_API int rz_type_set(Sdb *TDB, ut64 at, const char *field, ut64 val) { - const char *kind; - char var[128]; - sprintf(var, "link.%08" PFMT64x, at); - kind = sdb_const_get(TDB, var, NULL); - if (kind) { - const char *p = sdb_const_get(TDB, kind, NULL); - if (p) { - snprintf(var, sizeof(var), "%s.%s.%s", p, kind, field); - int off = sdb_array_get_num(TDB, var, 1, NULL); - //int siz = sdb_array_get_num (DB, var, 2, NULL); - eprintf("wv 0x%08" PFMT64x " @ 0x%08" PFMT64x, val, at + off); - return true; - } - eprintf("Invalid kind of type\n"); - } - return false; -} - -RZ_API int rz_type_kind(Sdb *TDB, const char *name) { - if (!name) { - return -1; - } - const char *type = sdb_const_get(TDB, name, 0); - if (!type) { - return -1; - } - if (!strcmp(type, "enum")) { - return RZ_TYPE_ENUM; - } - if (!strcmp(type, "struct")) { - return RZ_TYPE_STRUCT; - } - if (!strcmp(type, "union")) { - return RZ_TYPE_UNION; - } - if (!strcmp(type, "type")) { - return RZ_TYPE_BASIC; - } - if (!strcmp(type, "typedef")) { - return RZ_TYPE_TYPEDEF; - } - return -1; -} - -RZ_API RzList *rz_type_get_enum(Sdb *TDB, const char *name) { - char *p, var[130]; - int n; - - if (rz_type_kind(TDB, name) != RZ_TYPE_ENUM) { - return NULL; - } - RzList *res = rz_list_new(); - snprintf(var, sizeof(var), "enum.%s", name); - for (n = 0; (p = sdb_array_get(TDB, var, n, NULL)); n++) { - RTypeEnum *member = RZ_NEW0(RTypeEnum); - if (member) { - char *var2 = rz_str_newf("%s.%s", var, p); - if (var2) { - char *val = sdb_array_get(TDB, var2, 0, NULL); - if (val) { - member->name = p; - member->val = val; - rz_list_append(res, member); - } else { - free(member); - free(var2); - } - } else { - free(member); - } - } - } - return res; -} - -RZ_API char *rz_type_enum_member(Sdb *TDB, const char *name, const char *member, ut64 val) { - if (rz_type_kind(TDB, name) != RZ_TYPE_ENUM) { - return NULL; - } - const char *q = member - ? sdb_fmt("enum.%s.%s", name, member) - : sdb_fmt("enum.%s.0x%" PFMT64x, name, val); - return sdb_get(TDB, q, 0); -} - -RZ_API RzList *rz_type_enum_find_member(Sdb *TDB, ut64 val) { - SdbKv *kv; - SdbListIter *iter; - SdbList *l = sdb_foreach_list(TDB, true); - RzList *res = rz_list_new(); - ls_foreach (l, iter, kv) { - if (!strcmp(sdbkv_value(kv), "enum")) { - const char *name = sdbkv_key(kv); - if (name) { - const char *q = sdb_fmt("enum.%s.0x%" PFMT64x, name, val); - char *member = sdb_get(TDB, q, 0); - if (member) { - char *pair = rz_str_newf("%s.%s", name, member); - rz_list_append(res, pair); - free(member); - } - } - } - } - ls_free(l); - return res; -} - -RZ_API char *rz_type_enum_getbitfield(Sdb *TDB, const char *name, ut64 val) { - char *q, *ret = NULL; - const char *res; - int i; - - if (rz_type_kind(TDB, name) != RZ_TYPE_ENUM) { - return NULL; - } - bool isFirst = true; - ret = rz_str_appendf(ret, "0x%08" PFMT64x " : ", val); - for (i = 0; i < 32; i++) { - ut32 n = 1ULL << i; - if (!(val & n)) { - continue; - } - q = sdb_fmt("enum.%s.0x%x", name, n); - res = sdb_const_get(TDB, q, 0); - if (isFirst) { - isFirst = false; - } else { - ret = rz_str_append(ret, " | "); - } - if (res) { - ret = rz_str_append(ret, res); - } else { - ret = rz_str_appendf(ret, "0x%x", n); - } - } - return ret; -} - -RZ_API ut64 rz_type_get_bitsize(Sdb *TDB, const char *type) { - char *query; - /* Filter out the structure keyword if type looks like "struct mystruc" */ - const char *tmptype; - if (!strncmp(type, "struct ", 7)) { - tmptype = type + 7; - } else if (!strncmp(type, "union ", 6)) { - tmptype = type + 6; - } else { - tmptype = type; - } - if ((strstr(type, "*(") || strstr(type, " *")) && strncmp(type, "char *", 7)) { - return 32; - } - const char *t = sdb_const_get(TDB, tmptype, 0); - if (!t) { - if (!strncmp(tmptype, "enum ", 5)) { - //XXX: Need a proper way to determine size of enum - return 32; - } - return 0; - } - if (!strcmp(t, "type")) { - query = rz_str_newf("type.%s.size", tmptype); - ut64 r = sdb_num_get(TDB, query, 0); // returns size in bits - free(query); - return r; - } - if (!strcmp(t, "struct") || !strcmp(t, "union")) { - query = rz_str_newf("%s.%s", t, tmptype); - char *members = sdb_get(TDB, query, 0); - char *next, *ptr = members; - ut64 ret = 0; - if (members) { - do { - char *name = sdb_anext(ptr, &next); - if (!name) { - break; - } - free(query); - query = rz_str_newf("%s.%s.%s", t, tmptype, name); - char *subtype = sdb_get(TDB, query, 0); - RZ_FREE(query); - if (!subtype) { - break; - } - char *tmp = strchr(subtype, ','); - if (tmp) { - *tmp++ = 0; - tmp = strchr(tmp, ','); - if (tmp) { - *tmp++ = 0; - } - int elements = rz_num_math(NULL, tmp); - if (elements == 0) { - elements = 1; - } - if (!strcmp(t, "struct")) { - ret += rz_type_get_bitsize(TDB, subtype) * elements; - } else { - ut64 sz = rz_type_get_bitsize(TDB, subtype) * elements; - ret = sz > ret ? sz : ret; - } - } - free(subtype); - ptr = next; - } while (next); - free(members); - } - free(query); - return ret; - } - return 0; -} - -RZ_API char *rz_type_get_struct_memb(Sdb *TDB, const char *type, int offset) { - int i, cur_offset, next_offset = 0; - char *res = NULL; - - if (offset < 0) { - return NULL; - } - char *query = sdb_fmt("struct.%s", type); - char *members = sdb_get(TDB, query, 0); - if (!members) { - //eprintf ("%s is not a struct\n", type); - return NULL; - } - int nargs = rz_str_split(members, ','); - for (i = 0; i < nargs; i++) { - const char *name = rz_str_word_get0(members, i); - if (!name) { - break; - } - query = sdb_fmt("struct.%s.%s", type, name); - char *subtype = sdb_get(TDB, query, 0); - if (!subtype) { - break; - } - int len = rz_str_split(subtype, ','); - if (len < 3) { - free(subtype); - break; - } - cur_offset = rz_num_math(NULL, rz_str_word_get0(subtype, len - 2)); - if (cur_offset > 0 && cur_offset < next_offset) { - free(subtype); - break; - } - if (!cur_offset) { - cur_offset = next_offset; - } - if (cur_offset == offset) { - res = rz_str_newf("%s.%s", type, name); - free(subtype); - break; - } - int arrsz = rz_num_math(NULL, rz_str_word_get0(subtype, len - 1)); - int fsize = (rz_type_get_bitsize(TDB, subtype) * (arrsz ? arrsz : 1)) / 8; - if (!fsize) { - free(subtype); - break; - } - next_offset = cur_offset + fsize; - // Handle nested structs - if (offset > cur_offset && offset < next_offset) { - char *nested_type = (char *)rz_str_word_get0(subtype, 0); - if (rz_str_startswith(nested_type, "struct ") && !rz_str_endswith(nested_type, " *")) { - len = rz_str_split(nested_type, ' '); - if (len < 2) { - free(subtype); - break; - } - nested_type = (char *)rz_str_word_get0(nested_type, 1); - char *nested_res = rz_type_get_struct_memb(TDB, nested_type, offset - cur_offset); - if (nested_res) { - len = rz_str_split(nested_res, '.'); - res = rz_str_newf("%s.%s.%s", type, name, rz_str_word_get0(nested_res, len - 1)); - free(nested_res); - free(subtype); - break; - } - } - } - free(subtype); - } - free(members); - return res; -} - -// XXX this function is slow! -RZ_API RzList *rz_type_get_by_offset(Sdb *TDB, ut64 offset) { - RzList *offtypes = rz_list_new(); - SdbList *ls = sdb_foreach_list(TDB, true); - SdbListIter *lsi; - SdbKv *kv; - ls_foreach (ls, lsi, kv) { - // TODO: Add unions support - if (!strncmp(sdbkv_value(kv), "struct", 6) && strncmp(sdbkv_key(kv), "struct.", 7)) { - char *res = rz_type_get_struct_memb(TDB, sdbkv_key(kv), offset); - if (res) { - rz_list_append(offtypes, res); - } - } - } - ls_free(ls); - return offtypes; -} - -// XXX 12 is the maxstructsizedelta -#define TYPE_RANGE_BASE(x) ((x) >> 16) - -static RzList *types_range_list(Sdb *db, ut64 addr) { - RzList *list = NULL; - ut64 base = TYPE_RANGE_BASE(addr); - char *s = rz_str_newf("range.%" PFMT64x, base); - if (s) { - char *r = sdb_get(db, s, 0); - if (r) { - list = rz_str_split_list(r, " ", -1); - } - free(s); - } - return list; -} - -static void types_range_del(Sdb *db, ut64 addr) { - ut64 base = TYPE_RANGE_BASE(addr); - const char *k = sdb_fmt("range.%" PFMT64x, base); - char valstr[SDB_NUM_BUFSZ]; - const char *v = sdb_itoa(addr, valstr, SDB_NUM_BASE); - sdb_array_remove(db, k, v, 0); -} - -static void types_range_add(Sdb *db, ut64 addr) { - ut64 base = TYPE_RANGE_BASE(addr); - const char *k = sdb_fmt("range.%" PFMT64x, base); - (void)sdb_array_add_num(db, k, addr, 0); -} - -RZ_API char *rz_type_link_at(Sdb *TDB, ut64 addr) { - if (addr == UT64_MAX) { - return NULL; - } - const char *query = sdb_fmt("link.%08" PFMT64x, addr); - char *res = sdb_get(TDB, query, 0); - if (!res) { // resolve struct memb if possible for given addr - RzList *list = types_range_list(TDB, addr); - RzListIter *iter; - const char *s; - rz_list_foreach (list, iter, s) { - ut64 laddr = rz_num_get(NULL, s); - if (addr > laddr) { - int delta = addr - laddr; - const char *lk = sdb_fmt("link.%08" PFMT64x, laddr); - char *k = sdb_get(TDB, lk, 0); - res = rz_type_get_struct_memb(TDB, k, delta); - if (res) { - break; - } - free(k); - } - } - } - return res; -} - -RZ_API int rz_type_set_link(Sdb *TDB, const char *type, ut64 addr) { - if (sdb_const_get(TDB, type, 0)) { - char *laddr = rz_str_newf("link.%08" PFMT64x, addr); - sdb_set(TDB, laddr, type, 0); - types_range_add(TDB, addr); - free(laddr); - return true; - } - return false; -} - -RZ_API int rz_type_link_offset(Sdb *TDB, const char *type, ut64 addr) { - if (sdb_const_get(TDB, type, 0)) { - char *laddr = rz_str_newf("offset.%08" PFMT64x, addr); - sdb_set(TDB, laddr, type, 0); - free(laddr); - return true; - } - return false; -} - -RZ_API int rz_type_unlink(Sdb *TDB, ut64 addr) { - char *laddr = sdb_fmt("link.%08" PFMT64x, addr); - sdb_unset(TDB, laddr, 0); - types_range_del(TDB, addr); - return true; -} - -static bool sdbdeletelink(void *p, const char *k, const char *v) { - Sdb *TDB = (Sdb *)p; - if (!strncmp(k, "link.", strlen("link."))) { - rz_type_del(TDB, k); - } - return true; -} - -RZ_API int rz_type_unlink_all(Sdb *TDB) { - sdb_foreach(TDB, sdbdeletelink, TDB); - return true; -} - -static char *fmt_struct_union(Sdb *TDB, char *var, bool is_typedef) { - // assumes var list is sorted by offset.. should do more checks here - char *p = NULL, *vars = NULL, var2[132], *fmt = NULL; - size_t n; - char *fields = rz_str_newf("%s.fields", var); - char *nfields = (is_typedef) ? fields : var; - for (n = 0; (p = sdb_array_get(TDB, nfields, n, NULL)); n++) { - char *struct_name; - const char *tfmt = NULL; - bool isStruct = false; - bool isEnum = false; - bool isfp = false; - snprintf(var2, sizeof(var2), "%s.%s", var, p); - size_t alen = sdb_array_size(TDB, var2); - int elements = sdb_array_get_num(TDB, var2, alen - 1, NULL); - char *type = sdb_array_get(TDB, var2, 0, NULL); - if (type) { - char var3[128] = { 0 }; - // Handle general pointers except for char * - if ((strstr(type, "*(") || strstr(type, " *")) && strncmp(type, "char *", 7)) { - isfp = true; - } else if (rz_str_startswith(type, "struct ")) { - struct_name = type + 7; - // TODO: iterate over all the struct fields, and format the format and vars - snprintf(var3, sizeof(var3), "struct.%s", struct_name); - tfmt = sdb_const_get(TDB, var3, NULL); - isStruct = true; - } else { - // special case for char[]. Use char* format type without * - if (!strcmp(type, "char") && elements > 0) { - tfmt = sdb_const_get(TDB, "type.char *", NULL); - if (tfmt && *tfmt == '*') { - tfmt++; - } - } else { - if (rz_str_startswith(type, "enum ")) { - snprintf(var3, sizeof(var3), "%s", type + 5); - isEnum = true; - } else { - snprintf(var3, sizeof(var3), "type.%s", type); - } - tfmt = sdb_const_get(TDB, var3, NULL); - } - } - if (isfp) { - // consider function pointer as void * for printing - fmt = rz_str_append(fmt, "p"); - vars = rz_str_append(vars, p); - vars = rz_str_append(vars, " "); - } else if (tfmt) { - (void)rz_str_replace_ch(type, ' ', '_', true); - if (elements > 0) { - fmt = rz_str_appendf(fmt, "[%d]", elements); - } - if (isStruct) { - fmt = rz_str_append(fmt, "?"); - vars = rz_str_appendf(vars, "(%s)%s", struct_name, p); - vars = rz_str_append(vars, " "); - } else if (isEnum) { - fmt = rz_str_append(fmt, "E"); - vars = rz_str_appendf(vars, "(%s)%s", type + 5, p); - vars = rz_str_append(vars, " "); - } else { - fmt = rz_str_append(fmt, tfmt); - vars = rz_str_append(vars, p); - vars = rz_str_append(vars, " "); - } - } else { - eprintf("Cannot resolve type '%s'\n", var3); - } - free(type); - } - free(p); - } - free(fields); - fmt = rz_str_append(fmt, " "); - fmt = rz_str_append(fmt, vars); - free(vars); - return fmt; -} - -RZ_API char *rz_type_format(Sdb *TDB, const char *t) { - char var[130], var2[132]; - const char *kind = sdb_const_get(TDB, t, NULL); - if (!kind) { - return NULL; - } - // only supports struct atm - snprintf(var, sizeof(var), "%s.%s", kind, t); - if (!strcmp(kind, "type")) { - const char *fmt = sdb_const_get(TDB, var, NULL); - if (fmt) { - return strdup(fmt); - } - } else if (!strcmp(kind, "struct") || !strcmp(kind, "union")) { - return fmt_struct_union(TDB, var, false); - } - if (!strcmp(kind, "typedef")) { - snprintf(var2, sizeof(var2), "typedef.%s", t); - const char *type = sdb_const_get(TDB, var2, NULL); - // only supports struct atm - if (type && !strcmp(type, "struct")) { - return fmt_struct_union(TDB, var, true); - } - } - return NULL; -} - -RZ_API void rz_type_del(Sdb *TDB, const char *name) { - const char *kind = sdb_const_get(TDB, name, 0); - if (!kind) { - return; - } - if (!strcmp(kind, "type")) { - sdb_unset(TDB, sdb_fmt("type.%s", name), 0); - sdb_unset(TDB, sdb_fmt("type.%s.size", name), 0); - sdb_unset(TDB, sdb_fmt("type.%s.meta", name), 0); - sdb_unset(TDB, name, 0); - } else if (!strcmp(kind, "struct") || !strcmp(kind, "union")) { - int i, n = sdb_array_length(TDB, sdb_fmt("%s.%s", kind, name)); - char *elements_key = rz_str_newf("%s.%s", kind, name); - for (i = 0; i < n; i++) { - char *p = sdb_array_get(TDB, elements_key, i, NULL); - sdb_unset(TDB, sdb_fmt("%s.%s", elements_key, p), 0); - free(p); - } - sdb_unset(TDB, elements_key, 0); - sdb_unset(TDB, name, 0); - free(elements_key); - } else if (!strcmp(kind, "func")) { - int i, n = sdb_num_get(TDB, sdb_fmt("func.%s.args", name), 0); - for (i = 0; i < n; i++) { - sdb_unset(TDB, sdb_fmt("func.%s.arg.%d", name, i), 0); - } - sdb_unset(TDB, sdb_fmt("func.%s.ret", name), 0); - sdb_unset(TDB, sdb_fmt("func.%s.cc", name), 0); - sdb_unset(TDB, sdb_fmt("func.%s.noreturn", name), 0); - sdb_unset(TDB, sdb_fmt("func.%s.args", name), 0); - sdb_unset(TDB, name, 0); - } else if (!strcmp(kind, "enum")) { - RzList *list = rz_type_get_enum(TDB, name); - RTypeEnum *member; - RzListIter *iter; - rz_list_foreach (list, iter, member) { - sdb_unset(TDB, sdb_fmt("enum.%s.%s", name, member->name), 0); - sdb_unset(TDB, sdb_fmt("enum.%s.%s", name, member->val), 0); - } - sdb_unset(TDB, name, 0); - rz_list_free(list); - } else if (!strcmp(kind, "typedef")) { - RzStrBuf buf; - rz_strbuf_init(&buf); - rz_strbuf_setf(&buf, "typedef.%s", name); - sdb_unset(TDB, rz_strbuf_get(&buf), 0); - rz_strbuf_fini(&buf); - sdb_unset(TDB, name, 0); - } else { - eprintf("Unrecognized type kind \"%s\"\n", kind); - } -} - -// Function prototypes api -RZ_API int rz_type_func_exist(Sdb *TDB, const char *func_name) { - const char *fcn = sdb_const_get(TDB, func_name, 0); - return fcn && !strcmp(fcn, "func"); -} - -RZ_API const char *rz_type_func_ret(Sdb *TDB, const char *func_name) { - const char *query = sdb_fmt("func.%s.ret", func_name); - return sdb_const_get(TDB, query, 0); -} - -RZ_API int rz_type_func_args_count(Sdb *TDB, const char *func_name) { - const char *query = sdb_fmt("func.%s.args", func_name); - return sdb_num_get(TDB, query, 0); -} - -RZ_API RZ_OWN char *rz_type_func_args_type(Sdb *TDB, RZ_NONNULL const char *func_name, int i) { - const char *query = sdb_fmt("func.%s.arg.%d", func_name, i); - char *ret = sdb_get(TDB, query, 0); - if (ret) { - char *comma = strchr(ret, ','); - if (comma) { - *comma = 0; - return ret; - } - free(ret); - } - return NULL; -} - -RZ_API const char *rz_type_func_args_name(Sdb *TDB, RZ_NONNULL const char *func_name, int i) { - const char *query = sdb_fmt("func.%s.arg.%d", func_name, i); - const char *get = sdb_const_get(TDB, query, 0); - if (get) { - char *ret = strchr(get, ','); - return ret == 0 ? ret : ret + 1; - } - return NULL; -} - -#define MIN_MATCH_LEN 4 - -static inline bool is_function(const char *name) { - return name && !strcmp("func", name); -} - -static RZ_OWN char *type_func_try_guess(Sdb *TDB, RZ_NONNULL char *name) { - if (strlen(name) < MIN_MATCH_LEN) { - return NULL; - } - - const char *res = sdb_const_get(TDB, name, NULL); - if (is_function(res)) { - return strdup(name); - } - - return NULL; -} - -static inline bool is_auto_named(char *func_name, size_t slen) { - return slen > 4 && (rz_str_startswith(func_name, "fcn.") || rz_str_startswith(func_name, "loc.")); -} - -static inline bool has_rz_prefixes(char *func_name, int offset, size_t slen) { - return slen > 4 && (offset + 3 < slen) && func_name[offset + 3] == '.'; -} - -static char *strip_rz_prefixes(char *func_name, size_t slen) { - // strip r2 prefixes (sym, sym.imp, etc') - int offset = 0; - - while (has_rz_prefixes(func_name, offset, slen)) { - offset += 4; - } - - return func_name + offset; -} - -static char *strip_common_prefixes_stdlib(char *func_name) { - // strip common prefixes from standard lib functions - if (rz_str_startswith(func_name, "__isoc99_")) { - func_name += 9; - } else if (rz_str_startswith(func_name, "__libc_") && !strstr(func_name, "_main")) { - func_name += 7; - } else if (rz_str_startswith(func_name, "__GI_")) { - func_name += 5; - } - - return func_name; -} - -static char *strip_dll_prefix(char *func_name) { - char *tmp = strstr(func_name, "dll_"); - if (tmp) { - return tmp + 3; - } - - return func_name; -} - -static void clean_function_name(char *func_name) { - char *last = (char *)rz_str_lchr(func_name, '_'); - if (!last || !rz_str_isnumber(last + 1)) { - return; - } - - *last = '\0'; -} - -// TODO: -// - symbol names are long and noisy, some of them might not be matched due -// to additional information added around name -RZ_API RZ_OWN char *rz_type_func_guess(Sdb *TDB, RZ_NONNULL char *func_name) { - char *str = func_name; - char *result = NULL; - rz_return_val_if_fail(TDB, false); - rz_return_val_if_fail(func_name, false); - - size_t slen = strlen(str); - if (slen < MIN_MATCH_LEN || is_auto_named(str, slen)) { - return NULL; - } - - str = strip_rz_prefixes(str, slen); - str = strip_common_prefixes_stdlib(str); - str = strip_dll_prefix(str); - - if ((result = type_func_try_guess(TDB, str))) { - return result; - } - - str = strdup(str); - clean_function_name(str); - - if (*str == '_' && (result = type_func_try_guess(TDB, str + 1))) { - free(str); - return result; - } - - free(str); - return result; -} diff --git a/meson.build b/meson.build index 46e7fc6871d..e15c1b8d16e 100644 --- a/meson.build +++ b/meson.build @@ -499,6 +499,7 @@ if host_machine.system() == 'windows' build_root / 'librz' / 'search', build_root / 'librz' / 'socket', build_root / 'librz' / 'syscall', + build_root / 'librz' / 'type', build_root / 'librz' / 'util', ] endif @@ -523,6 +524,7 @@ subdir('librz/config') subdir('librz/parse') subdir('librz/lang') subdir('librz/asm') +subdir('librz/type') subdir('librz/analysis') subdir('librz/egg') subdir('librz/debug') @@ -587,6 +589,7 @@ if meson.is_subproject() rz_search_dep, rz_socket_dep, rz_syscall_dep, + rz_type_dep, rz_util_dep ], include_directories: include_directories('.', 'librz/include'), diff --git a/test/unit/meson.build b/test/unit/meson.build index d8ad489d7d0..6343fd222b1 100644 --- a/test/unit/meson.build +++ b/test/unit/meson.build @@ -11,7 +11,6 @@ if get_option('enable_tests') 'analysis_function', 'analysis_hints', 'analysis_meta', - 'analysis_types', 'analysis_var', 'analysis_xrefs', 'annotated_code', @@ -53,7 +52,6 @@ if get_option('enable_tests') 'json', 'list', 'ovf', - 'parse_ctype', 'pdb', 'pj', 'queue', @@ -65,6 +63,7 @@ if get_option('enable_tests') 'serialize_config', 'serialize_flag', 'serialize_spaces', + 'serialize_types', 'sign', 'skiplist', 'skyline', @@ -77,6 +76,7 @@ if get_option('enable_tests') 'table', 'task', 'tree', + 'type', 'uleb128', 'unum', 'util', @@ -106,6 +106,7 @@ if get_option('enable_tests') rz_bp_dep, rz_reg_dep, rz_syscall_dep, + rz_type_dep, rz_analysis_dep, rz_parse_dep, rz_egg_dep, diff --git a/test/unit/test_analysis_types.c b/test/unit/test_analysis_types.c deleted file mode 100644 index e52f66d662f..00000000000 --- a/test/unit/test_analysis_types.c +++ /dev/null @@ -1,360 +0,0 @@ -// SPDX-FileCopyrightText: 2020 HoundThe -// SPDX-License-Identifier: LGPL-3.0-only - -#include -#include - -#include "minunit.h" -#include "test_sdb.h" - -static void setup_sdb_for_struct(Sdb *res) { - // td "struct kappa {int bar;int cow;};" - sdb_set(res, "kappa", "struct", 0); - sdb_set(res, "struct.kappa", "bar,cow", 0); - sdb_set(res, "struct.kappa.bar", "int32_t,0,0", 0); - sdb_set(res, "struct.kappa.cow", "int32_t,4,0", 0); -} - -static void setup_sdb_for_union(Sdb *res) { - // td "union kappa {int bar;int cow;};" - sdb_set(res, "kappa", "union", 0); - sdb_set(res, "union.kappa", "bar,cow", 0); - sdb_set(res, "union.kappa.bar", "int32_t,0,0", 0); - sdb_set(res, "union.kappa.cow", "int32_t,0,0", 0); -} - -static void setup_sdb_for_enum(Sdb *res) { - // td "enum foo { firstCase=1, secondCase=2,};" - sdb_set(res, "foo", "enum", 0); - sdb_set(res, "enum.foo", "firstCase,secondCase", 0); - sdb_set(res, "enum.foo.firstCase", "0x1", 0); - sdb_set(res, "enum.foo.secondCase", "0x2", 0); - sdb_set(res, "enum.foo.0x1", "firstCase", 0); - sdb_set(res, "enum.foo.0x2", "secondCase", 0); -} - -static void setup_sdb_for_typedef(Sdb *res) { - // td typedef char *string; - sdb_set(res, "string", "typedef", 0); - sdb_set(res, "typedef.string", "char *", 0); -} - -static void setup_sdb_for_atomic(Sdb *res) { - sdb_set(res, "char", "type", 0); - sdb_set(res, "type.char.size", "8", 0); - sdb_set(res, "type.char", "c", 0); -} - -static void setup_sdb_for_not_found(Sdb *res) { - // malformed type states - sdb_set(res, "foo", "enum", 0); - sdb_set(res, "bar", "struct", 0); - sdb_set(res, "quax", "union", 0); - sdb_set(res, "enum.foo", "aa,bb", 0); - sdb_set(res, "struct.bar", "cc,dd", 0); - sdb_set(res, "union.quax", "ee,ff", 0); - - sdb_set(res, "omega", "struct", 0); - sdb_set(res, "struct.omega", "ee,ff,gg", 0); - sdb_set(res, "struct.omega.ee", "0,1", 0); - sdb_set(res, "struct.omega.ff", "", 0); -} - -static bool test_analysis_get_base_type_struct(void) { - RzAnalysis *analysis = rz_analysis_new(); - mu_assert_notnull(analysis, "Couldn't create new RzAnalysis"); - mu_assert_notnull(analysis->sdb_types, "Couldn't create new RzAnalysis.sdb_types"); - - setup_sdb_for_struct(analysis->sdb_types); - - RzAnalysisBaseType *base = rz_analysis_get_base_type(analysis, "kappa"); - mu_assert_notnull(base, "Couldn't create get base type of struct \"kappa\""); - - mu_assert_eq(RZ_ANALYSIS_BASE_TYPE_KIND_STRUCT, base->kind, "Wrong base type"); - mu_assert_streq(base->name, "kappa", "type name"); - - RzAnalysisStructMember *member; - - member = rz_vector_index_ptr(&base->struct_data.members, 0); - mu_assert_eq(member->offset, 0, "Incorrect offset for struct member"); - mu_assert_streq(member->type, "int32_t", "Incorrect type for struct member"); - mu_assert_streq(member->name, "bar", "Incorrect name for struct member"); - - member = rz_vector_index_ptr(&base->struct_data.members, 1); - mu_assert_eq(member->offset, 4, "Incorrect offset for struct member"); - mu_assert_streq(member->type, "int32_t", "Incorrect type for struct member"); - mu_assert_streq(member->name, "cow", "Incorrect name for struct member"); - - rz_analysis_base_type_free(base); - rz_analysis_free(analysis); - mu_end; -} - -static bool test_analysis_save_base_type_struct(void) { - RzAnalysis *analysis = rz_analysis_new(); - mu_assert_notnull(analysis, "Couldn't create new RzAnalysis"); - mu_assert_notnull(analysis->sdb_types, "Couldn't create new RzAnalysis.sdb_types"); - - RzAnalysisBaseType *base = rz_analysis_base_type_new(RZ_ANALYSIS_BASE_TYPE_KIND_STRUCT); - base->name = strdup("kappa"); - - RzAnalysisStructMember member = { - .offset = 0, - .type = strdup("int32_t"), - .name = strdup("bar") - }; - rz_vector_push(&base->struct_data.members, &member); - - member.offset = 4; - member.type = strdup("int32_t"); - member.name = strdup("cow"); - rz_vector_push(&base->struct_data.members, &member); - - rz_analysis_save_base_type(analysis, base); - rz_analysis_base_type_free(base); - - Sdb *reg = sdb_new0(); - setup_sdb_for_struct(reg); - assert_sdb_eq(analysis->sdb_types, reg, "save struct type"); - sdb_free(reg); - - rz_analysis_free(analysis); - mu_end; -} - -static bool test_analysis_get_base_type_union(void) { - RzAnalysis *analysis = rz_analysis_new(); - mu_assert_notnull(analysis, "Couldn't create new RzAnalysis"); - mu_assert_notnull(analysis->sdb_types, "Couldn't create new RzAnalysis.sdb_types"); - - setup_sdb_for_union(analysis->sdb_types); - - RzAnalysisBaseType *base = rz_analysis_get_base_type(analysis, "kappa"); - mu_assert_notnull(base, "Couldn't create get base type of union \"kappa\""); - - mu_assert_eq(RZ_ANALYSIS_BASE_TYPE_KIND_UNION, base->kind, "Wrong base type"); - mu_assert_streq(base->name, "kappa", "type name"); - - RzAnalysisUnionMember *member; - - member = rz_vector_index_ptr(&base->union_data.members, 0); - mu_assert_streq(member->type, "int32_t", "Incorrect type for union member"); - mu_assert_streq(member->name, "bar", "Incorrect name for union member"); - - member = rz_vector_index_ptr(&base->union_data.members, 1); - mu_assert_streq(member->type, "int32_t", "Incorrect type for union member"); - mu_assert_streq(member->name, "cow", "Incorrect name for union member"); - - rz_analysis_base_type_free(base); - rz_analysis_free(analysis); - mu_end; -} - -static bool test_analysis_save_base_type_union(void) { - RzAnalysis *analysis = rz_analysis_new(); - mu_assert_notnull(analysis, "Couldn't create new RzAnalysis"); - mu_assert_notnull(analysis->sdb_types, "Couldn't create new RzAnalysis.sdb_types"); - - RzAnalysisBaseType *base = rz_analysis_base_type_new(RZ_ANALYSIS_BASE_TYPE_KIND_UNION); - base->name = strdup("kappa"); - - RzAnalysisUnionMember member = { - .offset = 0, - .type = strdup("int32_t"), - .name = strdup("bar") - }; - rz_vector_push(&base->union_data.members, &member); - - member.offset = 0; - member.type = strdup("int32_t"); - member.name = strdup("cow"); - rz_vector_push(&base->union_data.members, &member); - - rz_analysis_save_base_type(analysis, base); - rz_analysis_base_type_free(base); - - Sdb *reg = sdb_new0(); - setup_sdb_for_union(reg); - assert_sdb_eq(analysis->sdb_types, reg, "save union type"); - sdb_free(reg); - - rz_analysis_free(analysis); - mu_end; -} - -static bool test_analysis_get_base_type_enum(void) { - RzAnalysis *analysis = rz_analysis_new(); - mu_assert_notnull(analysis, "Couldn't create new RzAnalysis"); - mu_assert_notnull(analysis->sdb_types, "Couldn't create new RzAnalysis.sdb_types"); - - setup_sdb_for_enum(analysis->sdb_types); - - RzAnalysisBaseType *base = rz_analysis_get_base_type(analysis, "foo"); - mu_assert_notnull(base, "Couldn't create get base type of enum \"foo\""); - - mu_assert_eq(RZ_ANALYSIS_BASE_TYPE_KIND_ENUM, base->kind, "Wrong base type"); - mu_assert_streq(base->name, "foo", "type name"); - - RzAnalysisEnumCase *cas = rz_vector_index_ptr(&base->enum_data.cases, 0); - mu_assert_eq(cas->val, 1, "Incorrect value for enum case"); - mu_assert_streq(cas->name, "firstCase", "Incorrect name for enum case"); - - cas = rz_vector_index_ptr(&base->enum_data.cases, 1); - mu_assert_eq(cas->val, 2, "Incorrect value for enum case"); - mu_assert_streq(cas->name, "secondCase", "Incorrect name for enum case"); - - rz_analysis_base_type_free(base); - rz_analysis_free(analysis); - mu_end; -} - -static bool test_analysis_save_base_type_enum(void) { - RzAnalysis *analysis = rz_analysis_new(); - mu_assert_notnull(analysis, "Couldn't create new RzAnalysis"); - mu_assert_notnull(analysis->sdb_types, "Couldn't create new RzAnalysis.sdb_types"); - - RzAnalysisBaseType *base = rz_analysis_base_type_new(RZ_ANALYSIS_BASE_TYPE_KIND_ENUM); - base->name = strdup("foo"); - - RzAnalysisEnumCase cas = { - .name = strdup("firstCase"), - .val = 1 - }; - rz_vector_push(&base->enum_data.cases, &cas); - - cas.name = strdup("secondCase"); - cas.val = 2; - rz_vector_push(&base->enum_data.cases, &cas); - - rz_analysis_save_base_type(analysis, base); - rz_analysis_base_type_free(base); - - Sdb *reg = sdb_new0(); - setup_sdb_for_enum(reg); - assert_sdb_eq(analysis->sdb_types, reg, "save enum type"); - sdb_free(reg); - - rz_analysis_free(analysis); - mu_end; -} - -static bool test_analysis_get_base_type_typedef(void) { - RzAnalysis *analysis = rz_analysis_new(); - mu_assert_notnull(analysis, "Couldn't create new RzAnalysis"); - mu_assert_notnull(analysis->sdb_types, "Couldn't create new RzAnalysis.sdb_types"); - - setup_sdb_for_typedef(analysis->sdb_types); - - RzAnalysisBaseType *base = rz_analysis_get_base_type(analysis, "string"); - mu_assert_notnull(base, "Couldn't create get base type of typedef \"string\""); - - mu_assert_eq(RZ_ANALYSIS_BASE_TYPE_KIND_TYPEDEF, base->kind, "Wrong base type"); - mu_assert_streq(base->name, "string", "type name"); - mu_assert_streq(base->type, "char *", "typedefd type"); - - rz_analysis_base_type_free(base); - rz_analysis_free(analysis); - mu_end; -} - -static bool test_analysis_save_base_type_typedef(void) { - RzAnalysis *analysis = rz_analysis_new(); - mu_assert_notnull(analysis, "Couldn't create new RzAnalysis"); - mu_assert_notnull(analysis->sdb_types, "Couldn't create new RzAnalysis.sdb_types"); - - RzAnalysisBaseType *base = rz_analysis_base_type_new(RZ_ANALYSIS_BASE_TYPE_KIND_TYPEDEF); - base->name = strdup("string"); - base->type = strdup("char *"); - - rz_analysis_save_base_type(analysis, base); - rz_analysis_base_type_free(base); - - Sdb *reg = sdb_new0(); - setup_sdb_for_typedef(reg); - assert_sdb_eq(analysis->sdb_types, reg, "save typedef type"); - sdb_free(reg); - - rz_analysis_free(analysis); - mu_end; -} - -static bool test_analysis_get_base_type_atomic(void) { - RzAnalysis *analysis = rz_analysis_new(); - mu_assert_notnull(analysis, "Couldn't create new RzAnalysis"); - mu_assert_notnull(analysis->sdb_types, "Couldn't create new RzAnalysis.sdb_types"); - - setup_sdb_for_atomic(analysis->sdb_types); - - RzAnalysisBaseType *base = rz_analysis_get_base_type(analysis, "char"); - mu_assert_notnull(base, "Couldn't create get base type of atomic type \"char\""); - - mu_assert_eq(RZ_ANALYSIS_BASE_TYPE_KIND_ATOMIC, base->kind, "Wrong base type"); - mu_assert_streq(base->name, "char", "type name"); - mu_assert_streq(base->type, "c", "atomic type type"); - mu_assert_eq(base->size, 8, "atomic type size"); - - rz_analysis_base_type_free(base); - rz_analysis_free(analysis); - mu_end; -} - -static bool test_analysis_save_base_type_atomic(void) { - RzAnalysis *analysis = rz_analysis_new(); - mu_assert_notnull(analysis, "Couldn't create new RzAnalysis"); - mu_assert_notnull(analysis->sdb_types, "Couldn't create new RzAnalysis.sdb_types"); - - RzAnalysisBaseType *base = rz_analysis_base_type_new(RZ_ANALYSIS_BASE_TYPE_KIND_ATOMIC); - base->name = strdup("char"); - base->type = strdup("c"); - base->size = 8; - - rz_analysis_save_base_type(analysis, base); - rz_analysis_base_type_free(base); - - Sdb *reg = sdb_new0(); - setup_sdb_for_atomic(reg); - assert_sdb_eq(analysis->sdb_types, reg, "save atomic type"); - sdb_free(reg); - - rz_analysis_free(analysis); - mu_end; -} - -static bool test_analysis_get_base_type_not_found(void) { - RzAnalysis *analysis = rz_analysis_new(); - setup_sdb_for_not_found(analysis->sdb_types); - - mu_assert_notnull(analysis, "Couldn't create new RzAnalysis"); - mu_assert_notnull(analysis->sdb_types, "Couldn't create new RzAnalysis.sdb_types"); - - RzAnalysisBaseType *base = rz_analysis_get_base_type(analysis, "non_existant23321312___"); - mu_assert_null(base, "Should find nothing"); - base = rz_analysis_get_base_type(analysis, "foo"); - mu_assert_null(base, "Should find nothing"); - base = rz_analysis_get_base_type(analysis, "bar"); - mu_assert_null(base, "Should find nothing"); - base = rz_analysis_get_base_type(analysis, "quax"); - mu_assert_null(base, "Should find nothing"); - base = rz_analysis_get_base_type(analysis, "omega"); - mu_assert_null(base, "Should find nothing"); - - rz_analysis_free(analysis); - mu_end; -} - -int all_tests(void) { - mu_run_test(test_analysis_get_base_type_struct); - mu_run_test(test_analysis_save_base_type_struct); - mu_run_test(test_analysis_get_base_type_union); - mu_run_test(test_analysis_save_base_type_union); - mu_run_test(test_analysis_get_base_type_enum); - mu_run_test(test_analysis_save_base_type_enum); - mu_run_test(test_analysis_get_base_type_typedef); - mu_run_test(test_analysis_save_base_type_typedef); - mu_run_test(test_analysis_get_base_type_atomic); - mu_run_test(test_analysis_save_base_type_atomic); - mu_run_test(test_analysis_get_base_type_not_found); - return tests_passed != tests_run; -} - -mu_main(all_tests) \ No newline at end of file diff --git a/test/unit/test_dwarf_integration.c b/test/unit/test_dwarf_integration.c index 30e2c505c35..23ac89448aa 100644 --- a/test/unit/test_dwarf_integration.c +++ b/test/unit/test_dwarf_integration.c @@ -26,7 +26,6 @@ static bool test_parse_dwarf_types(void) { analysis->cpu = strdup("x86"); analysis->bits = 32; mu_assert("pe/vista-glass.exe binary could not be opened", res); - mu_assert_notnull(analysis->sdb_types, "Couldn't create new RzAnalysis.sdb_types"); RzBinDwarfDebugAbbrev *abbrevs = rz_bin_dwarf_parse_abbrev(bin->cur); mu_assert_notnull(abbrevs, "Couldn't parse Abbreviations"); RzBinDwarfDebugInfo *info = rz_bin_dwarf_parse_info(bin->cur, abbrevs); @@ -40,7 +39,7 @@ static bool test_parse_dwarf_types(void) { rz_analysis_dwarf_process_info(analysis, &ctx); char *value = NULL; - Sdb *sdb = analysis->sdb_types; + Sdb *sdb = analysis->type->sdb_types; check_kv("_cairo_status", "enum"); check_kv("enum._cairo_status.0x0", "CAIRO_STATUS_SUCCESS"); check_kv("enum._cairo_status.CAIRO_STATUS_SUCCESS", "0x0"); @@ -61,7 +60,6 @@ static bool test_parse_dwarf_types(void) { "CAIRO_STATUS_FONT_TYPE_MISMATCH,CAIRO_STATUS_USER_FONT_IMMUTABLE,CAIRO_STATUS_USER_FONT_ERROR," "CAIRO_STATUS_NEGATIVE_COUNT,CAIRO_STATUS_INVALID_CLUSTERS," "CAIRO_STATUS_INVALID_SLANT,CAIRO_STATUS_INVALID_WEIGHT"); - check_kv("_MARGINS", "struct"); // TODO evaluate member_location operations in DWARF to get offset and test it check_kv("struct._MARGINS", "cxLeftWidth,cxRightWidth,cyTopHeight,cyBottomHeight"); @@ -94,7 +92,6 @@ static bool test_dwarf_function_parsing_cpp(void) { analysis->cpu = strdup("x86"); analysis->bits = 64; mu_assert("elf/dwarf4_many_comp_units.elf binary could not be opened", res); - mu_assert_notnull(analysis->sdb_types, "Couldn't create new RzAnalysis.sdb_types"); RzBinDwarfDebugAbbrev *abbrevs = rz_bin_dwarf_parse_abbrev(bin->cur); mu_assert_notnull(abbrevs, "Couldn't parse Abbreviations"); RzBinDwarfDebugInfo *info = rz_bin_dwarf_parse_info(bin->cur, abbrevs); @@ -150,7 +147,6 @@ static bool test_dwarf_function_parsing_go(void) { analysis->cpu = strdup("x86"); analysis->bits = 64; mu_assert("bins/elf/dwarf_go_tree", res); - mu_assert_notnull(analysis->sdb_types, "Couldn't create new RzAnalysis.sdb_types"); RzBinDwarfDebugAbbrev *abbrevs = rz_bin_dwarf_parse_abbrev(bin->cur); mu_assert_notnull(abbrevs, "Couldn't parse Abbreviations"); RzBinDwarfDebugInfo *info = rz_bin_dwarf_parse_info(bin->cur, abbrevs); @@ -204,7 +200,6 @@ static bool test_dwarf_function_parsing_rust(void) { analysis->cpu = strdup("x86"); analysis->bits = 64; mu_assert("bins/elf/dwarf_rust_bubble", res); - mu_assert_notnull(analysis->sdb_types, "Couldn't create new RzAnalysis.sdb_types"); RzBinDwarfDebugAbbrev *abbrevs = rz_bin_dwarf_parse_abbrev(bin->cur); mu_assert_notnull(abbrevs, "Couldn't parse Abbreviations"); RzBinDwarfDebugInfo *info = rz_bin_dwarf_parse_info(bin->cur, abbrevs); diff --git a/test/unit/test_parse_ctype.c b/test/unit/test_parse_ctype.c deleted file mode 100644 index 948eecc116c..00000000000 --- a/test/unit/test_parse_ctype.c +++ /dev/null @@ -1,96 +0,0 @@ -// SPDX-FileCopyrightText: 2019 Florian Märkl -// SPDX-License-Identifier: LGPL-3.0-only - -#include -#include "minunit.h" - -bool test_rz_parse_ctype(void) { - RzParseCType *ctype = rz_parse_ctype_new(); - mu_assert_notnull(ctype, "rz_parse_ctype_new"); - char *error; - RzParseCTypeType *type = rz_parse_ctype_parse(ctype, "const char * [0x42] const * [23]", &error); - if (error) { - eprintf("%s\n", error); - free(error); - } - mu_assert_notnull(type, "rz_parse_ctype_parse"); - - RzParseCTypeType *cur = type; - - mu_assert_eq(cur->kind, RZ_PARSE_CTYPE_TYPE_KIND_ARRAY, "array"); - mu_assert_eq(cur->array.count, 23, "array count (dec)"); - cur = cur->array.type; - - mu_assert_eq(cur->kind, RZ_PARSE_CTYPE_TYPE_KIND_POINTER, "pointer"); - mu_assert_eq(cur->pointer.is_const, true, "pointer const"); - cur = cur->pointer.type; - - mu_assert_eq(cur->kind, RZ_PARSE_CTYPE_TYPE_KIND_ARRAY, "array"); - mu_assert_eq(cur->array.count, 0x42, "array count (hex)"); - cur = cur->array.type; - - mu_assert_eq(cur->kind, RZ_PARSE_CTYPE_TYPE_KIND_POINTER, "pointer"); - mu_assert_eq(cur->pointer.is_const, false, "pointer non-const"); - cur = cur->pointer.type; - - mu_assert_eq(cur->kind, RZ_PARSE_CTYPE_TYPE_KIND_IDENTIFIER, "identifier"); - mu_assert_eq(cur->identifier.kind, RZ_PARSE_CTYPE_IDENTIFIER_KIND_UNSPECIFIED, "identifier kind"); - mu_assert_eq(cur->identifier.is_const, true, "identifier const"); - mu_assert_streq(cur->identifier.name, "char", "identifier name"); - - rz_parse_ctype_type_free(type); - rz_parse_ctype_free(ctype); - mu_end; -} - -bool test_rz_parse_ctype_identifier_kind(void) { - RzParseCType *ctype = rz_parse_ctype_new(); - mu_assert_notnull(ctype, "rz_parse_ctype_new"); - char *error; - RzParseCTypeType *type = rz_parse_ctype_parse(ctype, "struct ulu", &error); - if (error) { - eprintf("%s\n", error); - free(error); - } - mu_assert_notnull(type, "rz_parse_ctype_parse(\"struct ulu\")"); - mu_assert_eq(type->kind, RZ_PARSE_CTYPE_TYPE_KIND_IDENTIFIER, "identifier"); - mu_assert_eq(type->identifier.kind, RZ_PARSE_CTYPE_IDENTIFIER_KIND_STRUCT, "identifier kind"); - mu_assert_eq(type->identifier.is_const, false, "identifier const"); - mu_assert_streq(type->identifier.name, "ulu", "identifier name"); - rz_parse_ctype_type_free(type); - - type = rz_parse_ctype_parse(ctype, "union mulu", &error); - if (error) { - eprintf("%s\n", error); - free(error); - } - mu_assert_notnull(type, "rz_parse_ctype_parse(\"union mulu\")"); - mu_assert_eq(type->kind, RZ_PARSE_CTYPE_TYPE_KIND_IDENTIFIER, "identifier"); - mu_assert_eq(type->identifier.kind, RZ_PARSE_CTYPE_IDENTIFIER_KIND_UNION, "identifier kind"); - mu_assert_eq(type->identifier.is_const, false, "identifier const"); - mu_assert_streq(type->identifier.name, "mulu", "identifier name"); - rz_parse_ctype_type_free(type); - - type = rz_parse_ctype_parse(ctype, "enum urshak", &error); - if (error) { - eprintf("%s\n", error); - free(error); - } - mu_assert_notnull(type, "rz_parse_ctype_parse(\"enum urshak\")"); - mu_assert_eq(type->kind, RZ_PARSE_CTYPE_TYPE_KIND_IDENTIFIER, "identifier"); - mu_assert_eq(type->identifier.kind, RZ_PARSE_CTYPE_IDENTIFIER_KIND_ENUM, "identifier kind"); - mu_assert_eq(type->identifier.is_const, false, "identifier const"); - mu_assert_streq(type->identifier.name, "urshak", "identifier name"); - rz_parse_ctype_type_free(type); - - rz_parse_ctype_free(ctype); - mu_end; -} - -int all_tests() { - mu_run_test(test_rz_parse_ctype); - mu_run_test(test_rz_parse_ctype_identifier_kind); - return tests_passed != tests_run; -} - -mu_main(all_tests) \ No newline at end of file diff --git a/test/unit/test_pdb.c b/test/unit/test_pdb.c index 97af8b40fe3..6372fc42bba 100644 --- a/test/unit/test_pdb.c +++ b/test/unit/test_pdb.c @@ -12,7 +12,7 @@ #define check_kv(k, v) \ do { \ - char *value = sdb_get(analysis->sdb_types, k, NULL); \ + char *value = sdb_get(analysis->type->sdb_types, k, NULL); \ mu_assert_nullable_streq(value, v, "Wrong key - value pair"); \ } while (0) @@ -40,7 +40,7 @@ int pdb_info_save_types(RzAnalysis *analysis, const char *file, RzPdb *pdb) { pdb->finish_pdb_parse(pdb); return false; } - rz_parse_pdb_types(analysis, pdb); + rz_parse_pdb_types(analysis->type, pdb); pdb->finish_pdb_parse(pdb); return true; } @@ -509,4 +509,4 @@ bool all_tests() { return tests_passed != tests_run; } -mu_main(all_tests) \ No newline at end of file +mu_main(all_tests) diff --git a/test/unit/test_serialize_analysis.c b/test/unit/test_serialize_analysis.c index 1a19cbe6691..3b253c13fab 100644 --- a/test/unit/test_serialize_analysis.c +++ b/test/unit/test_serialize_analysis.c @@ -1250,187 +1250,6 @@ bool test_analysis_classes_load() { mu_end; } -Sdb *types_ref_db() { - Sdb *db = sdb_new0(); - sdb_set(db, "snatcher", "union", 0); - sdb_set(db, "struct.junker.gillian", "char *,0,0", 0); - sdb_set(db, "junker", "struct", 0); - sdb_set(db, "typedef.human", "union snatcher", 0); - sdb_set(db, "union.snatcher.random", "int,0,0", 0); - sdb_set(db, "human", "typedef", 0); - sdb_set(db, "struct.junker.seed", "uint64_t,8,0", 0); - sdb_set(db, "union.snatcher", "random,hajile", 0); - sdb_set(db, "struct.junker", "gillian,seed", 0); - sdb_set(db, "union.snatcher.hajile", "uint32_t,0,0", 0); - sdb_set(db, "badchar", "type", 0); - sdb_set(db, "type.badchar.size", "16", 0); - sdb_set(db, "type.badchar", "c", 0); - sdb_set(db, "enum.mika", "ELIJAH,MODNAR", 0); - sdb_set(db, "enum.mika.MODNAR", "0x539", 0); - sdb_set(db, "enum.mika.ELIJAH", "0x2a", 0); - sdb_set(db, "enum.mika.0x2a", "ELIJAH", 0); - sdb_set(db, "mika", "enum", 0); - sdb_set(db, "enum.mika.0x539", "MODNAR", 0); - return db; -} - -bool test_analysis_types_save() { - RzAnalysis *analysis = rz_analysis_new(); - - // struct - RzAnalysisBaseType *type = rz_analysis_base_type_new(RZ_ANALYSIS_BASE_TYPE_KIND_STRUCT); - type->name = strdup("junker"); - - RzAnalysisStructMember member; - member.name = strdup("gillian"); - member.offset = 0; - member.type = strdup("char *"); - rz_vector_push(&type->struct_data.members, &member); - - member.name = strdup("seed"); - member.offset = 8; - member.type = strdup("uint64_t"); - rz_vector_push(&type->struct_data.members, &member); - - rz_analysis_save_base_type(analysis, type); - rz_analysis_base_type_free(type); - - // union - type = rz_analysis_base_type_new(RZ_ANALYSIS_BASE_TYPE_KIND_UNION); - type->name = strdup("snatcher"); - - RzAnalysisUnionMember mumber; - mumber.name = strdup("random"); - mumber.offset = 0; - mumber.type = strdup("int"); - rz_vector_push(&type->union_data.members, &mumber); - - mumber.name = strdup("hajile"); - mumber.offset = 0; - mumber.type = strdup("uint32_t"); - rz_vector_push(&type->union_data.members, &mumber); - - rz_analysis_save_base_type(analysis, type); - rz_analysis_base_type_free(type); - - // enum - type = rz_analysis_base_type_new(RZ_ANALYSIS_BASE_TYPE_KIND_ENUM); - type->name = strdup("mika"); - - RzAnalysisEnumCase cas; - cas.name = strdup("ELIJAH"); - cas.val = 42; - rz_vector_push(&type->enum_data.cases, &cas); - - cas.name = strdup("MODNAR"); - cas.val = 1337; - rz_vector_push(&type->enum_data.cases, &cas); - - rz_analysis_save_base_type(analysis, type); - rz_analysis_base_type_free(type); - - // typedef - type = rz_analysis_base_type_new(RZ_ANALYSIS_BASE_TYPE_KIND_TYPEDEF); - type->name = strdup("human"); - type->type = strdup("union snatcher"); - rz_analysis_save_base_type(analysis, type); - rz_analysis_base_type_free(type); - - // atomic - type = rz_analysis_base_type_new(RZ_ANALYSIS_BASE_TYPE_KIND_ATOMIC); - type->name = strdup("badchar"); - type->size = 16; - type->type = strdup("c"); - rz_analysis_save_base_type(analysis, type); - rz_analysis_base_type_free(type); - - Sdb *db = sdb_new0(); - rz_serialize_analysis_types_save(db, analysis); - - Sdb *expected = types_ref_db(); - assert_sdb_eq(db, expected, "types save"); - sdb_free(db); - sdb_free(expected); - rz_analysis_free(analysis); - mu_end; -} - -bool test_analysis_types_load() { - RzAnalysis *analysis = rz_analysis_new(); - Sdb *db = types_ref_db(); - bool succ = rz_serialize_analysis_types_load(db, analysis, NULL); - sdb_free(db); - mu_assert("load success", succ); - - // struct - RzAnalysisBaseType *type = rz_analysis_get_base_type(analysis, "junker"); - mu_assert_notnull(type, "get type"); - mu_assert_eq(type->kind, RZ_ANALYSIS_BASE_TYPE_KIND_STRUCT, "type kind"); - mu_assert_eq(type->struct_data.members.len, 2, "members count"); - - RzAnalysisStructMember *member = rz_vector_index_ptr(&type->struct_data.members, 0); - mu_assert_streq(member->name, "gillian", "member name"); - mu_assert_eq(member->offset, 0, "member offset"); - mu_assert_streq(member->type, "char *", "member type"); - - member = rz_vector_index_ptr(&type->struct_data.members, 1); - mu_assert_streq(member->name, "seed", "member name"); - mu_assert_eq(member->offset, 8, "member offset"); - mu_assert_streq(member->type, "uint64_t", "member type"); - - rz_analysis_base_type_free(type); - - // union - type = rz_analysis_get_base_type(analysis, "snatcher"); - mu_assert_notnull(type, "get type"); - mu_assert_eq(type->kind, RZ_ANALYSIS_BASE_TYPE_KIND_UNION, "type kind"); - mu_assert_eq(type->union_data.members.len, 2, "members count"); - - RzAnalysisUnionMember *mumber = rz_vector_index_ptr(&type->union_data.members, 0); - mu_assert_streq(mumber->name, "random", "member name"); - mu_assert_streq(mumber->type, "int", "member type"); - - mumber = rz_vector_index_ptr(&type->union_data.members, 1); - mu_assert_streq(mumber->name, "hajile", "member name"); - mu_assert_streq(mumber->type, "uint32_t", "member type"); - - rz_analysis_base_type_free(type); - - // enum - type = rz_analysis_get_base_type(analysis, "mika"); - mu_assert_notnull(type, "get type"); - mu_assert_eq(type->kind, RZ_ANALYSIS_BASE_TYPE_KIND_ENUM, "type kind"); - mu_assert_eq(type->enum_data.cases.len, 2, "cases count"); - - RzAnalysisEnumCase *cas = rz_vector_index_ptr(&type->enum_data.cases, 0); - mu_assert_streq(cas->name, "ELIJAH", "case name"); - mu_assert_eq(cas->val, 42, "case value"); - - cas = rz_vector_index_ptr(&type->enum_data.cases, 1); - mu_assert_streq(cas->name, "MODNAR", "case name"); - mu_assert_eq(cas->val, 1337, "case value"); - - rz_analysis_base_type_free(type); - - // typedef - type = rz_analysis_get_base_type(analysis, "human"); - mu_assert_notnull(type, "get type"); - mu_assert_eq(type->kind, RZ_ANALYSIS_BASE_TYPE_KIND_TYPEDEF, "type kind"); - mu_assert_streq(type->type, "union snatcher", "typedefd type"); - rz_analysis_base_type_free(type); - - // atomic - type = rz_analysis_get_base_type(analysis, "badchar"); - mu_assert_notnull(type, "get type"); - mu_assert_eq(type->kind, RZ_ANALYSIS_BASE_TYPE_KIND_ATOMIC, "type kind"); - mu_assert_eq(type->size, 16, "atomic type size"); - mu_assert_streq(type->type, "c", "atomic type"); - rz_analysis_base_type_free(type); - - rz_analysis_free(analysis); - mu_end; -} - Sdb *sign_ref_db() { Sdb *db = sdb_new0(); Sdb *spaces = sdb_ns(db, "spaces", true); @@ -1709,12 +1528,12 @@ bool test_analysis_save() { rz_analysis_class_method_set(analysis, "Aeropause", &crystal); rz_analysis_class_method_fini(&crystal); - RzAnalysisBaseType *type = rz_analysis_base_type_new(RZ_ANALYSIS_BASE_TYPE_KIND_ATOMIC); + RzBaseType *type = rz_type_base_type_new(RZ_BASE_TYPE_KIND_ATOMIC); type->name = strdup("badchar"); type->size = 16; type->type = strdup("c"); - rz_analysis_save_base_type(analysis, type); - rz_analysis_base_type_free(type); + rz_type_save_base_type(analysis->type, type); + rz_type_base_type_free(type); rz_spaces_set(&analysis->zign_spaces, "koridai"); rz_sign_add_comment(analysis, "sym.boring", "gee it sure is boring around here"); @@ -1779,12 +1598,12 @@ bool test_analysis_load() { mu_assert_streq(meth->name, "some_meth", "method name"); rz_vector_free(vals); - RzAnalysisBaseType *type = rz_analysis_get_base_type(analysis, "badchar"); + RzBaseType *type = rz_type_get_base_type(analysis->type, "badchar"); mu_assert_notnull(type, "get type"); - mu_assert_eq(type->kind, RZ_ANALYSIS_BASE_TYPE_KIND_ATOMIC, "type kind"); + mu_assert_eq(type->kind, RZ_BASE_TYPE_KIND_ATOMIC, "type kind"); mu_assert_eq(type->size, 16, "atomic type size"); mu_assert_streq(type->type, "c", "atomic type"); - rz_analysis_base_type_free(type); + rz_type_base_type_free(type); rz_spaces_set(&analysis->zign_spaces, "koridai"); RzSignItem *item = rz_sign_get_item(analysis, "sym.boring"); @@ -1831,8 +1650,6 @@ int all_tests() { mu_run_test(test_analysis_hints_load); mu_run_test(test_analysis_classes_save); mu_run_test(test_analysis_classes_load); - mu_run_test(test_analysis_types_save); - mu_run_test(test_analysis_types_load); mu_run_test(test_analysis_sign_save); mu_run_test(test_analysis_sign_load); mu_run_test(test_analysis_cc_save); diff --git a/test/unit/test_serialize_types.c b/test/unit/test_serialize_types.c new file mode 100644 index 00000000000..213aa78ade2 --- /dev/null +++ b/test/unit/test_serialize_types.c @@ -0,0 +1,199 @@ +// SPDX-FileCopyrightText: 2020 Florian Märkl +// SPDX-License-Identifier: LGPL-3.0-only + +#include +#include +#include +#include +#include +#include "minunit.h" +#include "test_sdb.h" + +Sdb *types_ref_db() { + Sdb *db = sdb_new0(); + sdb_set(db, "snatcher", "union", 0); + sdb_set(db, "struct.junker.gillian", "char *,0,0", 0); + sdb_set(db, "junker", "struct", 0); + sdb_set(db, "typedef.human", "union snatcher", 0); + sdb_set(db, "union.snatcher.random", "int,0,0", 0); + sdb_set(db, "human", "typedef", 0); + sdb_set(db, "struct.junker.seed", "uint64_t,8,0", 0); + sdb_set(db, "union.snatcher", "random,hajile", 0); + sdb_set(db, "struct.junker", "gillian,seed", 0); + sdb_set(db, "union.snatcher.hajile", "uint32_t,0,0", 0); + sdb_set(db, "badchar", "type", 0); + sdb_set(db, "type.badchar.size", "16", 0); + sdb_set(db, "type.badchar", "c", 0); + sdb_set(db, "enum.mika", "ELIJAH,MODNAR", 0); + sdb_set(db, "enum.mika.MODNAR", "0x539", 0); + sdb_set(db, "enum.mika.ELIJAH", "0x2a", 0); + sdb_set(db, "enum.mika.0x2a", "ELIJAH", 0); + sdb_set(db, "mika", "enum", 0); + sdb_set(db, "enum.mika.0x539", "MODNAR", 0); + return db; +} + +bool test_types_save() { + RzType *types = rz_type_new(); + + // struct + RzBaseType *type = rz_type_base_type_new(RZ_BASE_TYPE_KIND_STRUCT); + type->name = strdup("junker"); + + RzTypeStructMember member; + member.name = strdup("gillian"); + member.offset = 0; + member.type = strdup("char *"); + rz_vector_push(&type->struct_data.members, &member); + + member.name = strdup("seed"); + member.offset = 8; + member.type = strdup("uint64_t"); + rz_vector_push(&type->struct_data.members, &member); + + rz_type_save_base_type(types, type); + rz_type_base_type_free(type); + + // union + type = rz_type_base_type_new(RZ_BASE_TYPE_KIND_UNION); + type->name = strdup("snatcher"); + + RzTypeUnionMember mumber; + mumber.name = strdup("random"); + mumber.offset = 0; + mumber.type = strdup("int"); + rz_vector_push(&type->union_data.members, &mumber); + + mumber.name = strdup("hajile"); + mumber.offset = 0; + mumber.type = strdup("uint32_t"); + rz_vector_push(&type->union_data.members, &mumber); + + rz_type_save_base_type(types, type); + rz_type_base_type_free(type); + + // enum + type = rz_type_base_type_new(RZ_BASE_TYPE_KIND_ENUM); + type->name = strdup("mika"); + + RzTypeEnumCase cas; + cas.name = strdup("ELIJAH"); + cas.val = 42; + rz_vector_push(&type->enum_data.cases, &cas); + + cas.name = strdup("MODNAR"); + cas.val = 1337; + rz_vector_push(&type->enum_data.cases, &cas); + + rz_type_save_base_type(types, type); + rz_type_base_type_free(type); + + // typedef + type = rz_type_base_type_new(RZ_BASE_TYPE_KIND_TYPEDEF); + type->name = strdup("human"); + type->type = strdup("union snatcher"); + rz_type_save_base_type(types, type); + rz_type_base_type_free(type); + + // atomic + type = rz_type_base_type_new(RZ_BASE_TYPE_KIND_ATOMIC); + type->name = strdup("badchar"); + type->size = 16; + type->type = strdup("c"); + rz_type_save_base_type(types, type); + rz_type_base_type_free(type); + + Sdb *db = sdb_new0(); + rz_serialize_types_save(db, types); + + Sdb *expected = types_ref_db(); + assert_sdb_eq(db, expected, "types save"); + sdb_free(db); + sdb_free(expected); + rz_type_free(types); + mu_end; +} + +bool test_types_load() { + RzType *types = rz_type_new(); + Sdb *db = types_ref_db(); + bool succ = rz_serialize_types_load(db, types, NULL); + sdb_free(db); + mu_assert("load success", succ); + + // struct + RzBaseType *type = rz_type_get_base_type(types, "junker"); + mu_assert_notnull(type, "get type"); + mu_assert_eq(type->kind, RZ_BASE_TYPE_KIND_STRUCT, "type kind"); + mu_assert_eq(type->struct_data.members.len, 2, "members count"); + + RzTypeStructMember *member = rz_vector_index_ptr(&type->struct_data.members, 0); + mu_assert_streq(member->name, "gillian", "member name"); + mu_assert_eq(member->offset, 0, "member offset"); + mu_assert_streq(member->type, "char *", "member type"); + + member = rz_vector_index_ptr(&type->struct_data.members, 1); + mu_assert_streq(member->name, "seed", "member name"); + mu_assert_eq(member->offset, 8, "member offset"); + mu_assert_streq(member->type, "uint64_t", "member type"); + + rz_type_base_type_free(type); + + // union + type = rz_type_get_base_type(types, "snatcher"); + mu_assert_notnull(type, "get type"); + mu_assert_eq(type->kind, RZ_BASE_TYPE_KIND_UNION, "type kind"); + mu_assert_eq(type->union_data.members.len, 2, "members count"); + + RzTypeUnionMember *mumber = rz_vector_index_ptr(&type->union_data.members, 0); + mu_assert_streq(mumber->name, "random", "member name"); + mu_assert_streq(mumber->type, "int", "member type"); + + mumber = rz_vector_index_ptr(&type->union_data.members, 1); + mu_assert_streq(mumber->name, "hajile", "member name"); + mu_assert_streq(mumber->type, "uint32_t", "member type"); + + rz_type_base_type_free(type); + + // enum + type = rz_type_get_base_type(types, "mika"); + mu_assert_notnull(type, "get type"); + mu_assert_eq(type->kind, RZ_BASE_TYPE_KIND_ENUM, "type kind"); + mu_assert_eq(type->enum_data.cases.len, 2, "cases count"); + + RzTypeEnumCase *cas = rz_vector_index_ptr(&type->enum_data.cases, 0); + mu_assert_streq(cas->name, "ELIJAH", "case name"); + mu_assert_eq(cas->val, 42, "case value"); + + cas = rz_vector_index_ptr(&type->enum_data.cases, 1); + mu_assert_streq(cas->name, "MODNAR", "case name"); + mu_assert_eq(cas->val, 1337, "case value"); + + rz_type_base_type_free(type); + + // typedef + type = rz_type_get_base_type(types, "human"); + mu_assert_notnull(type, "get type"); + mu_assert_eq(type->kind, RZ_BASE_TYPE_KIND_TYPEDEF, "type kind"); + mu_assert_streq(type->type, "union snatcher", "typedefd type"); + rz_type_base_type_free(type); + + // atomic + type = rz_type_get_base_type(types, "badchar"); + mu_assert_notnull(type, "get type"); + mu_assert_eq(type->kind, RZ_BASE_TYPE_KIND_ATOMIC, "type kind"); + mu_assert_eq(type->size, 16, "atomic type size"); + mu_assert_streq(type->type, "c", "atomic type"); + rz_type_base_type_free(type); + + rz_type_free(types); + mu_end; +} + +int all_tests() { + mu_run_test(test_types_save); + mu_run_test(test_types_load); + return tests_passed != tests_run; +} + +mu_main(all_tests) diff --git a/test/unit/test_type.c b/test/unit/test_type.c new file mode 100644 index 00000000000..cf3f2c8a8ad --- /dev/null +++ b/test/unit/test_type.c @@ -0,0 +1,536 @@ +// SPDX-FileCopyrightText: 2018 ret2libc +// SPDX-FileCopyrightText: 2020 HoundThe +// SPDX-License-Identifier: LGPL-3.0-only + +#include +#include + +#include "minunit.h" +#include "test_sdb.h" + +static Sdb *setup_sdb_for_function(void) { + Sdb *res = sdb_new0(); + sdb_set(res, "ExitProcess", "func", 0); + sdb_set(res, "ReadFile", "func", 0); + sdb_set(res, "memcpy", "func", 0); + sdb_set(res, "strchr", "func", 0); + sdb_set(res, "__stack_chk_fail", "func", 0); + sdb_set(res, "WSAStartup", "func", 0); + return res; +} + +static void setup_sdb_for_struct(Sdb *res) { + // td "struct kappa {int bar;int cow;};" + sdb_set(res, "kappa", "struct", 0); + sdb_set(res, "struct.kappa", "bar,cow", 0); + sdb_set(res, "struct.kappa.bar", "int32_t,0,0", 0); + sdb_set(res, "struct.kappa.cow", "int32_t,4,0", 0); +} + +static void setup_sdb_for_union(Sdb *res) { + // td "union kappa {int bar;int cow;};" + sdb_set(res, "kappa", "union", 0); + sdb_set(res, "union.kappa", "bar,cow", 0); + sdb_set(res, "union.kappa.bar", "int32_t,0,0", 0); + sdb_set(res, "union.kappa.cow", "int32_t,0,0", 0); +} + +static void setup_sdb_for_enum(Sdb *res) { + // td "enum foo { firstCase=1, secondCase=2,};" + sdb_set(res, "foo", "enum", 0); + sdb_set(res, "enum.foo", "firstCase,secondCase", 0); + sdb_set(res, "enum.foo.firstCase", "0x1", 0); + sdb_set(res, "enum.foo.secondCase", "0x2", 0); + sdb_set(res, "enum.foo.0x1", "firstCase", 0); + sdb_set(res, "enum.foo.0x2", "secondCase", 0); +} + +static void setup_sdb_for_typedef(Sdb *res) { + // td typedef char *string; + sdb_set(res, "string", "typedef", 0); + sdb_set(res, "typedef.string", "char *", 0); +} + +static void setup_sdb_for_atomic(Sdb *res) { + sdb_set(res, "char", "type", 0); + sdb_set(res, "type.char.size", "8", 0); + sdb_set(res, "type.char", "c", 0); +} + +static void setup_sdb_for_not_found(Sdb *res) { + // malformed type states + sdb_set(res, "foo", "enum", 0); + sdb_set(res, "bar", "struct", 0); + sdb_set(res, "quax", "union", 0); + sdb_set(res, "enum.foo", "aa,bb", 0); + sdb_set(res, "struct.bar", "cc,dd", 0); + sdb_set(res, "union.quax", "ee,ff", 0); + + sdb_set(res, "omega", "struct", 0); + sdb_set(res, "struct.omega", "ee,ff,gg", 0); + sdb_set(res, "struct.omega.ee", "0,1", 0); + sdb_set(res, "struct.omega.ff", "", 0); +} + +static bool test_types_get_base_type_struct(void) { + RzType *types = rz_type_new(); + mu_assert_notnull(types, "Couldn't create new RzType"); + mu_assert_notnull(types->sdb_types, "Couldn't create new RzType.sdb_types"); + + setup_sdb_for_struct(types->sdb_types); + + RzBaseType *base = rz_type_get_base_type(types, "kappa"); + mu_assert_notnull(base, "Couldn't create get base type of struct \"kappa\""); + + mu_assert_eq(RZ_BASE_TYPE_KIND_STRUCT, base->kind, "Wrong base type"); + mu_assert_streq(base->name, "kappa", "type name"); + + RzTypeStructMember *member; + + member = rz_vector_index_ptr(&base->struct_data.members, 0); + mu_assert_eq(member->offset, 0, "Incorrect offset for struct member"); + mu_assert_streq(member->type, "int32_t", "Incorrect type for struct member"); + mu_assert_streq(member->name, "bar", "Incorrect name for struct member"); + + member = rz_vector_index_ptr(&base->struct_data.members, 1); + mu_assert_eq(member->offset, 4, "Incorrect offset for struct member"); + mu_assert_streq(member->type, "int32_t", "Incorrect type for struct member"); + mu_assert_streq(member->name, "cow", "Incorrect name for struct member"); + + rz_type_base_type_free(base); + rz_type_free(types); + mu_end; +} + +static bool test_types_save_base_type_struct(void) { + RzType *types = rz_type_new(); + mu_assert_notnull(types, "Couldn't create new RzType"); + mu_assert_notnull(types->sdb_types, "Couldn't create new RzType.sdb_types"); + + RzBaseType *base = rz_type_base_type_new(RZ_BASE_TYPE_KIND_STRUCT); + base->name = strdup("kappa"); + + RzTypeStructMember member = { + .offset = 0, + .type = strdup("int32_t"), + .name = strdup("bar") + }; + rz_vector_push(&base->struct_data.members, &member); + + member.offset = 4; + member.type = strdup("int32_t"); + member.name = strdup("cow"); + rz_vector_push(&base->struct_data.members, &member); + + rz_type_save_base_type(types, base); + rz_type_base_type_free(base); + + Sdb *reg = sdb_new0(); + setup_sdb_for_struct(reg); + assert_sdb_eq(types->sdb_types, reg, "save struct type"); + sdb_free(reg); + + rz_type_free(types); + mu_end; +} + +static bool test_types_get_base_type_union(void) { + RzType *types = rz_type_new(); + mu_assert_notnull(types, "Couldn't create new RzType"); + mu_assert_notnull(types->sdb_types, "Couldn't create new RzType.sdb_types"); + + setup_sdb_for_union(types->sdb_types); + + RzBaseType *base = rz_type_get_base_type(types, "kappa"); + mu_assert_notnull(base, "Couldn't create get base type of union \"kappa\""); + + mu_assert_eq(RZ_BASE_TYPE_KIND_UNION, base->kind, "Wrong base type"); + mu_assert_streq(base->name, "kappa", "type name"); + + RzTypeUnionMember *member; + + member = rz_vector_index_ptr(&base->union_data.members, 0); + mu_assert_streq(member->type, "int32_t", "Incorrect type for union member"); + mu_assert_streq(member->name, "bar", "Incorrect name for union member"); + + member = rz_vector_index_ptr(&base->union_data.members, 1); + mu_assert_streq(member->type, "int32_t", "Incorrect type for union member"); + mu_assert_streq(member->name, "cow", "Incorrect name for union member"); + + rz_type_base_type_free(base); + rz_type_free(types); + mu_end; +} + +static bool test_types_save_base_type_union(void) { + RzType *types = rz_type_new(); + mu_assert_notnull(types, "Couldn't create new RzType"); + mu_assert_notnull(types->sdb_types, "Couldn't create new RzType.sdb_types"); + + RzBaseType *base = rz_type_base_type_new(RZ_BASE_TYPE_KIND_UNION); + base->name = strdup("kappa"); + + RzTypeUnionMember member = { + .offset = 0, + .type = strdup("int32_t"), + .name = strdup("bar") + }; + rz_vector_push(&base->union_data.members, &member); + + member.offset = 0; + member.type = strdup("int32_t"); + member.name = strdup("cow"); + rz_vector_push(&base->union_data.members, &member); + + rz_type_save_base_type(types, base); + rz_type_base_type_free(base); + + Sdb *reg = sdb_new0(); + setup_sdb_for_union(reg); + assert_sdb_eq(types->sdb_types, reg, "save union type"); + sdb_free(reg); + + rz_type_free(types); + mu_end; +} + +static bool test_types_get_base_type_enum(void) { + RzType *types = rz_type_new(); + mu_assert_notnull(types, "Couldn't create new RzType"); + + setup_sdb_for_enum(types->sdb_types); + + RzBaseType *base = rz_type_get_base_type(types, "foo"); + mu_assert_notnull(base, "Couldn't create get base type of enum \"foo\""); + + mu_assert_eq(RZ_BASE_TYPE_KIND_ENUM, base->kind, "Wrong base type"); + mu_assert_streq(base->name, "foo", "type name"); + + RzTypeEnumCase *cas = rz_vector_index_ptr(&base->enum_data.cases, 0); + mu_assert_eq(cas->val, 1, "Incorrect value for enum case"); + mu_assert_streq(cas->name, "firstCase", "Incorrect name for enum case"); + + cas = rz_vector_index_ptr(&base->enum_data.cases, 1); + mu_assert_eq(cas->val, 2, "Incorrect value for enum case"); + mu_assert_streq(cas->name, "secondCase", "Incorrect name for enum case"); + + rz_type_base_type_free(base); + rz_type_free(types); + mu_end; +} + +static bool test_types_save_base_type_enum(void) { + RzType *types = rz_type_new(); + mu_assert_notnull(types, "Couldn't create new RzType"); + + RzBaseType *base = rz_type_base_type_new(RZ_BASE_TYPE_KIND_ENUM); + base->name = strdup("foo"); + + RzTypeEnumCase cas = { + .name = strdup("firstCase"), + .val = 1 + }; + rz_vector_push(&base->enum_data.cases, &cas); + + cas.name = strdup("secondCase"); + cas.val = 2; + rz_vector_push(&base->enum_data.cases, &cas); + + rz_type_save_base_type(types, base); + rz_type_base_type_free(base); + + Sdb *reg = sdb_new0(); + setup_sdb_for_enum(reg); + assert_sdb_eq(types->sdb_types, reg, "save enum type"); + sdb_free(reg); + + rz_type_free(types); + mu_end; +} + +static bool test_types_get_base_type_typedef(void) { + RzType *types = rz_type_new(); + mu_assert_notnull(types, "Couldn't create new RzType"); + + setup_sdb_for_typedef(types->sdb_types); + + RzBaseType *base = rz_type_get_base_type(types, "string"); + mu_assert_notnull(base, "Couldn't create get base type of typedef \"string\""); + + mu_assert_eq(RZ_BASE_TYPE_KIND_TYPEDEF, base->kind, "Wrong base type"); + mu_assert_streq(base->name, "string", "type name"); + mu_assert_streq(base->type, "char *", "typedefd type"); + + rz_type_base_type_free(base); + rz_type_free(types); + mu_end; +} + +static bool test_types_save_base_type_typedef(void) { + RzType *types = rz_type_new(); + mu_assert_notnull(types, "Couldn't create new RzType"); + mu_assert_notnull(types->sdb_types, "Couldn't create new RzType.sdb_types"); + + RzBaseType *base = rz_type_base_type_new(RZ_BASE_TYPE_KIND_TYPEDEF); + base->name = strdup("string"); + base->type = strdup("char *"); + + rz_type_save_base_type(types, base); + rz_type_base_type_free(base); + + Sdb *reg = sdb_new0(); + setup_sdb_for_typedef(reg); + assert_sdb_eq(types->sdb_types, reg, "save typedef type"); + sdb_free(reg); + + rz_type_free(types); + mu_end; +} + +static bool test_types_get_base_type_atomic(void) { + RzType *types = rz_type_new(); + mu_assert_notnull(types, "Couldn't create new RzType"); + mu_assert_notnull(types->sdb_types, "Couldn't create new RzType.sdb_types"); + + setup_sdb_for_atomic(types->sdb_types); + + RzBaseType *base = rz_type_get_base_type(types, "char"); + mu_assert_notnull(base, "Couldn't create get base type of atomic type \"char\""); + + mu_assert_eq(RZ_BASE_TYPE_KIND_ATOMIC, base->kind, "Wrong base type"); + mu_assert_streq(base->name, "char", "type name"); + mu_assert_streq(base->type, "c", "atomic type type"); + mu_assert_eq(base->size, 8, "atomic type size"); + + rz_type_base_type_free(base); + rz_type_free(types); + mu_end; +} + +static bool test_types_save_base_type_atomic(void) { + RzType *types = rz_type_new(); + mu_assert_notnull(types, "Couldn't create new RzTypes"); + mu_assert_notnull(types->sdb_types, "Couldn't create new RzTypes.sdb_types"); + + RzBaseType *base = rz_type_base_type_new(RZ_BASE_TYPE_KIND_ATOMIC); + base->name = strdup("char"); + base->type = strdup("c"); + base->size = 8; + + rz_type_save_base_type(types, base); + rz_type_base_type_free(base); + + Sdb *reg = sdb_new0(); + setup_sdb_for_atomic(reg); + assert_sdb_eq(types->sdb_types, reg, "save atomic type"); + sdb_free(reg); + + rz_type_free(types); + mu_end; +} + +static bool test_types_get_base_type_not_found(void) { + RzType *types = rz_type_new(); + setup_sdb_for_not_found(types->sdb_types); + + mu_assert_notnull(types, "Couldn't create new RzType"); + mu_assert_notnull(types->sdb_types, "Couldn't create new RzType.sdb_types"); + + RzBaseType *base = rz_type_get_base_type(types, "non_existant23321312___"); + mu_assert_null(base, "Should find nothing"); + base = rz_type_get_base_type(types, "foo"); + mu_assert_null(base, "Should find nothing"); + base = rz_type_get_base_type(types, "bar"); + mu_assert_null(base, "Should find nothing"); + base = rz_type_get_base_type(types, "quax"); + mu_assert_null(base, "Should find nothing"); + base = rz_type_get_base_type(types, "omega"); + mu_assert_null(base, "Should find nothing"); + + rz_type_free(types); + mu_end; +} + + +bool test_dll_names(void) { + RzType *T = rz_type_new(); + T->sdb_types = setup_sdb_for_function(); + char *s; + + s = rz_type_func_guess(T, "sub.KERNEL32.dll_ExitProcess"); + mu_assert_notnull(s, "dll_ should be ignored"); + mu_assert_streq(s, "ExitProcess", "dll_ should be ignored"); + free(s); + + s = rz_type_func_guess(T, "sub.dll_ExitProcess_32"); + mu_assert_notnull(s, "number should be ignored"); + mu_assert_streq(s, "ExitProcess", "number should be ignored"); + free(s); + + s = rz_type_func_guess(T, "sym.imp.KERNEL32.dll_ReadFile"); + mu_assert_notnull(s, "dll_ and number should be ignored case 1"); + mu_assert_streq(s, "ReadFile", "dll_ and number should be ignored case 1"); + free(s); + + s = rz_type_func_guess(T, "sub.VCRUNTIME14.dll_memcpy"); + mu_assert_notnull(s, "dll_ and number should be ignored case 2"); + mu_assert_streq(s, "memcpy", "dll_ and number should be ignored case 2"); + free(s); + + s = rz_type_func_guess(T, "sub.KERNEL32.dll_ExitProcess_32"); + mu_assert_notnull(s, "dll_ and number should be ignored case 3"); + mu_assert_streq(s, "ExitProcess", "dll_ and number should be ignored case 3"); + free(s); + + s = rz_type_func_guess(T, "WS2_32.dll_WSAStartup"); + mu_assert_notnull(s, "dll_ and number should be ignored case 4"); + mu_assert_streq(s, "WSAStartup", "dll_ and number should be ignored case 4"); + free(s); + + sdb_free(T->sdb_types); + rz_type_free(T); + mu_end; +} + +bool test_ignore_prefixes(void) { + RzType *T = rz_type_new(); + T->sdb_types = setup_sdb_for_function(); + char *s; + + s = rz_type_func_guess(T, "fcn.KERNEL32.dll_ExitProcess_32"); + mu_assert_null(s, "fcn. names should be ignored"); + free(s); + + s = rz_type_func_guess(T, "loc.KERNEL32.dll_ExitProcess_32"); + mu_assert_null(s, "loc. names should be ignored"); + free(s); + + sdb_free(T->sdb_types); + rz_type_free(T); + mu_end; +} + +bool test_remove_rz_prefixes(void) { + RzType *T = rz_type_new(); + T->sdb_types = setup_sdb_for_function(); + char *s; + + s = rz_type_func_guess(T, "sym.imp.ExitProcess"); + mu_assert_notnull(s, "sym.imp should be ignored"); + mu_assert_streq(s, "ExitProcess", "sym.imp should be ignored"); + free(s); + + s = rz_type_func_guess(T, "sym.imp.fcn.ExitProcess"); + mu_assert_notnull(s, "sym.imp.fcn should be ignored"); + mu_assert_streq(s, "ExitProcess", "sym.imp.fcn should be ignored"); + free(s); + + s = rz_type_func_guess(T, "longprefix.ExitProcess"); + mu_assert_null(s, "prefixes longer than 3 should not be ignored"); + free(s); + + sdb_free(T->sdb_types); + rz_type_free(T); + mu_end; +} + +bool test_autonames(void) { + RzType *T = rz_type_new(); + T->sdb_types = setup_sdb_for_function(); + char *s; + + s = rz_type_func_guess(T, "sub.strchr_123"); + mu_assert_null(s, "function that calls common fcns shouldn't be identified as such"); + free(s); + + s = rz_type_func_guess(T, "sub.__strchr_123"); + mu_assert_null(s, "initial _ should not confuse the api"); + free(s); + + s = rz_type_func_guess(T, "sub.__stack_chk_fail_740"); + mu_assert_null(s, "initial _ should not confuse the api"); + free(s); + + s = rz_type_func_guess(T, "sym.imp.strchr"); + mu_assert_notnull(s, "sym.imp. should be ignored"); + mu_assert_streq(s, "strchr", "strchr should be identified"); + free(s); + + sdb_free(T->sdb_types); + rz_type_free(T); + mu_end; +} + +bool test_initial_underscore(void) { + RzType *T = rz_type_new(); + T->sdb_types = setup_sdb_for_function(); + char *s; + + s = rz_type_func_guess(T, "sym._strchr"); + mu_assert_notnull(s, "sym._ should be ignored"); + mu_assert_streq(s, "strchr", "strchr should be identified"); + free(s); + + sdb_free(T->sdb_types); + rz_type_free(T); + mu_end; +} + +/* references */ +typedef struct { + const char *name; + RZ_REF_TYPE; +} TypeTest; + +static TypeTest *rz_type_test_new(const char *name) { + TypeTest *tt = RZ_NEW0(TypeTest); + if (tt) { + rz_ref_init(tt); + tt->name = name; + } + return tt; +} + +static void rz_type_test_free(TypeTest *tt) { + tt->name = ""; +} + +RZ_REF_FUNCTIONS(TypeTest, rz_type_test); + +bool test_references(void) { + TypeTest *tt = rz_type_test_new("foo"); + mu_assert_eq(tt->refcount, 1, "reference count issue"); + rz_type_test_ref(tt); + mu_assert_eq(tt->refcount, 2, "reference count issue"); + rz_type_test_unref(tt); + mu_assert_streq(tt->name, "foo", "typetest name should be foo"); + mu_assert_eq(tt->refcount, 1, "reference count issue"); + rz_type_test_unref(tt); // tt becomes invalid + mu_assert_eq(tt->refcount, 0, "reference count issue"); + mu_assert_streq(tt->name, "", "typetest name should be foo"); + free(tt); + mu_end; +} + +int all_tests() { + mu_run_test(test_types_get_base_type_struct); + mu_run_test(test_types_save_base_type_struct); + mu_run_test(test_types_get_base_type_union); + mu_run_test(test_types_save_base_type_union); + mu_run_test(test_types_get_base_type_enum); + mu_run_test(test_types_save_base_type_enum); + mu_run_test(test_types_get_base_type_typedef); + mu_run_test(test_types_save_base_type_typedef); + mu_run_test(test_types_get_base_type_atomic); + mu_run_test(test_types_save_base_type_atomic); + mu_run_test(test_types_get_base_type_not_found); + mu_run_test(test_ignore_prefixes); + mu_run_test(test_remove_rz_prefixes); + mu_run_test(test_dll_names); + mu_run_test(test_references); + mu_run_test(test_autonames); + mu_run_test(test_initial_underscore); + return tests_passed != tests_run; +} + +mu_main(all_tests) diff --git a/test/unit/test_util.c b/test/unit/test_util.c index 7415428bde8..2162d1dd762 100644 --- a/test/unit/test_util.c +++ b/test/unit/test_util.c @@ -4,118 +4,6 @@ #include #include "minunit.h" -static Sdb *setup_sdb(void) { - Sdb *res = sdb_new0(); - sdb_set(res, "ExitProcess", "func", 0); - sdb_set(res, "ReadFile", "func", 0); - sdb_set(res, "memcpy", "func", 0); - sdb_set(res, "strchr", "func", 0); - sdb_set(res, "__stack_chk_fail", "func", 0); - sdb_set(res, "WSAStartup", "func", 0); - return res; -} - -bool test_dll_names(void) { - Sdb *TDB = setup_sdb(); - char *s; - - s = rz_type_func_guess(TDB, "sub.KERNEL32.dll_ExitProcess"); - mu_assert_notnull(s, "dll_ should be ignored"); - mu_assert_streq(s, "ExitProcess", "dll_ should be ignored"); - free(s); - - s = rz_type_func_guess(TDB, "sub.dll_ExitProcess_32"); - mu_assert_notnull(s, "number should be ignored"); - mu_assert_streq(s, "ExitProcess", "number should be ignored"); - free(s); - - s = rz_type_func_guess(TDB, "sym.imp.KERNEL32.dll_ReadFile"); - mu_assert_notnull(s, "dll_ and number should be ignored case 1"); - mu_assert_streq(s, "ReadFile", "dll_ and number should be ignored case 1"); - free(s); - - s = rz_type_func_guess(TDB, "sub.VCRUNTIME14.dll_memcpy"); - mu_assert_notnull(s, "dll_ and number should be ignored case 2"); - mu_assert_streq(s, "memcpy", "dll_ and number should be ignored case 2"); - free(s); - - s = rz_type_func_guess(TDB, "sub.KERNEL32.dll_ExitProcess_32"); - mu_assert_notnull(s, "dll_ and number should be ignored case 3"); - mu_assert_streq(s, "ExitProcess", "dll_ and number should be ignored case 3"); - free(s); - - s = rz_type_func_guess(TDB, "WS2_32.dll_WSAStartup"); - mu_assert_notnull(s, "dll_ and number should be ignored case 4"); - mu_assert_streq(s, "WSAStartup", "dll_ and number should be ignored case 4"); - free(s); - - sdb_free(TDB); - mu_end; -} - -bool test_ignore_prefixes(void) { - Sdb *TDB = setup_sdb(); - char *s; - - s = rz_type_func_guess(TDB, "fcn.KERNEL32.dll_ExitProcess_32"); - mu_assert_null(s, "fcn. names should be ignored"); - free(s); - - s = rz_type_func_guess(TDB, "loc.KERNEL32.dll_ExitProcess_32"); - mu_assert_null(s, "loc. names should be ignored"); - free(s); - - sdb_free(TDB); - mu_end; -} - -bool test_remove_rz_prefixes(void) { - Sdb *TDB = setup_sdb(); - char *s; - - s = rz_type_func_guess(TDB, "sym.imp.ExitProcess"); - mu_assert_notnull(s, "sym.imp should be ignored"); - mu_assert_streq(s, "ExitProcess", "sym.imp should be ignored"); - free(s); - - s = rz_type_func_guess(TDB, "sym.imp.fcn.ExitProcess"); - mu_assert_notnull(s, "sym.imp.fcn should be ignored"); - mu_assert_streq(s, "ExitProcess", "sym.imp.fcn should be ignored"); - free(s); - - s = rz_type_func_guess(TDB, "longprefix.ExitProcess"); - mu_assert_null(s, "prefixes longer than 3 should not be ignored"); - free(s); - - sdb_free(TDB); - mu_end; -} - -bool test_autonames(void) { - Sdb *TDB = setup_sdb(); - char *s; - - s = rz_type_func_guess(TDB, "sub.strchr_123"); - mu_assert_null(s, "function that calls common fcns shouldn't be identified as such"); - free(s); - - s = rz_type_func_guess(TDB, "sub.__strchr_123"); - mu_assert_null(s, "initial _ should not confuse the api"); - free(s); - - s = rz_type_func_guess(TDB, "sub.__stack_chk_fail_740"); - mu_assert_null(s, "initial _ should not confuse the api"); - free(s); - - s = rz_type_func_guess(TDB, "sym.imp.strchr"); - mu_assert_notnull(s, "sym.imp. should be ignored"); - mu_assert_streq(s, "strchr", "strchr should be identified"); - free(s); - - sdb_free(TDB); - mu_end; -} - bool test_file_slurp(void) { #ifdef __WINDOWS__ @@ -151,64 +39,9 @@ bool test_file_slurp(void) { mu_end; } -bool test_initial_underscore(void) { - Sdb *TDB = setup_sdb(); - char *s; - - s = rz_type_func_guess(TDB, "sym._strchr"); - mu_assert_notnull(s, "sym._ should be ignored"); - mu_assert_streq(s, "strchr", "strchr should be identified"); - free(s); - - sdb_free(TDB); - mu_end; -} - -/* references */ -typedef struct { - const char *name; - RZ_REF_TYPE; -} TypeTest; - -static TypeTest *rz_type_test_new(const char *name) { - TypeTest *tt = RZ_NEW0(TypeTest); - if (tt) { - rz_ref_init(tt); - tt->name = name; - } - return tt; -} - -static void rz_type_test_free(TypeTest *tt) { - tt->name = ""; -} - -RZ_REF_FUNCTIONS(TypeTest, rz_type_test); - -bool test_references(void) { - TypeTest *tt = rz_type_test_new("foo"); - mu_assert_eq(tt->refcount, 1, "reference count issue"); - rz_type_test_ref(tt); - mu_assert_eq(tt->refcount, 2, "reference count issue"); - rz_type_test_unref(tt); - mu_assert_streq(tt->name, "foo", "typetest name should be foo"); - mu_assert_eq(tt->refcount, 1, "reference count issue"); - rz_type_test_unref(tt); // tt becomes invalid - mu_assert_eq(tt->refcount, 0, "reference count issue"); - mu_assert_streq(tt->name, "", "typetest name should be foo"); - free(tt); - mu_end; -} - int all_tests() { - mu_run_test(test_ignore_prefixes); - mu_run_test(test_remove_rz_prefixes); - mu_run_test(test_dll_names); - mu_run_test(test_references); - mu_run_test(test_autonames); mu_run_test(test_file_slurp); - mu_run_test(test_initial_underscore); return tests_passed != tests_run; } -mu_main(all_tests) \ No newline at end of file +mu_main(all_tests) From c8e2c86356c126df3e2e99c49f4c83b0d8f65dab Mon Sep 17 00:00:00 2001 From: Anton Kochkov Date: Tue, 23 Mar 2021 11:37:51 +0800 Subject: [PATCH 02/25] Move format processing to RzTypes from RzUtil --- librz/analysis/fcn.c | 12 +- librz/core/canalysis.c | 2 - librz/core/cbin.c | 13 +- librz/core/cmd_meta.c | 11 +- librz/core/cmd_print.c | 59 +- librz/core/core.c | 13 +- librz/core/ctypes.c | 1 - librz/core/disasm.c | 6 +- librz/core/vmenus.c | 2 +- librz/include/rz_type.h | 22 +- librz/include/rz_util/rz_print.h | 5 +- librz/type/base.c | 1 - librz/type/format.c | 913 ++++++++++++++++--------------- librz/type/function.c | 1 - librz/type/link.c | 2 - librz/type/meson.build | 1 + librz/type/serialize_types.c | 2 - librz/type/type.c | 10 +- librz/type/utype.c | 2 - librz/util/print.c | 3 - test/unit/test_type.c | 1 - 21 files changed, 567 insertions(+), 515 deletions(-) diff --git a/librz/analysis/fcn.c b/librz/analysis/fcn.c index d4409e73cde..e7ccbe87ee8 100644 --- a/librz/analysis/fcn.c +++ b/librz/analysis/fcn.c @@ -1719,16 +1719,14 @@ RZ_API char *rz_analysis_function_get_json(RzAnalysisFunction *function) { pj_a(pj); for (i = 0; i < argc; i++) { pj_o(pj); - char *arg_name = rz_type_func_args_name(a->type, function->name, i); - char *arg_type = rz_type_func_args_type(a->type, function->name, i); + const char *arg_name = rz_type_func_args_name(a->type, function->name, i); + const char *arg_type = rz_type_func_args_type(a->type, function->name, i); pj_ks(pj, "name", arg_name); pj_ks(pj, "type", arg_type); const char *cc_arg = rz_reg_get_name(a->reg, rz_reg_get_name_idx(sdb_fmt("A%d", i))); if (cc_arg) { pj_ks(pj, "cc", cc_arg); } - free(arg_type); - free(arg_name); pj_end(pj); } pj_end(pj); @@ -1758,8 +1756,8 @@ RZ_API char *rz_analysis_function_get_signature(RzAnalysisFunction *function) { char *args = strdup(""); for (i = 0; i < argc; i++) { - char *arg_name = rz_type_func_args_name(a->type, function->name, i); - char *arg_type = rz_type_func_args_type(a->type, function->name, i); + const char *arg_name = rz_type_func_args_name(a->type, function->name, i); + const char *arg_type = rz_type_func_args_type(a->type, function->name, i); char *new_args = (i + 1 == argc) ? rz_str_newf("%s%s %s", args, arg_type, arg_name) : rz_str_newf("%s%s %s, ", args, arg_type, arg_name); @@ -2235,5 +2233,3 @@ RZ_API RzList *rz_analysis_types_from_fcn(RzAnalysis *analysis, RzAnalysisFuncti rz_list_free(type_used); return uniq; } - - diff --git a/librz/core/canalysis.c b/librz/core/canalysis.c index 65daaf22f78..9ec3d3e101f 100644 --- a/librz/core/canalysis.c +++ b/librz/core/canalysis.c @@ -7603,5 +7603,3 @@ RZ_API void rz_core_analysis_cc_init(RzCore *core) { free(dbpath); free(dbhomepath); } - - diff --git a/librz/core/cbin.c b/librz/core/cbin.c index c0369b51638..8029cae9893 100644 --- a/librz/core/cbin.c +++ b/librz/core/cbin.c @@ -207,7 +207,7 @@ RZ_API void rz_core_bin_export_info(RzCore *core, int mode) { free(error_msg); } if (out) { - rz_analysis_save_parsed_type(core->analysis, out); + rz_type_save_parsed_type(core->analysis->type, out); free(out); } } @@ -228,7 +228,7 @@ RZ_API void rz_core_bin_export_info(RzCore *core, int mode) { if (IS_MODE_RZCMD(mode)) { rz_cons_printf("pf.%s %s\n", flagname, v); } else if (IS_MODE_SET(mode)) { - sdb_set(core->print->formats, flagname, v, 0); + rz_type_format_set(core->analysis->type, flagname, v); } } free(dup); @@ -243,7 +243,7 @@ RZ_API void rz_core_bin_export_info(RzCore *core, int mode) { offset = strdup("0"); } flagname = dup; - int fmtsize = rz_print_format_struct_size(core->print, v, 0, 0); + int fmtsize = rz_type_format_struct_size(core->analysis->type, v, 0, 0); char *offset_key = rz_str_newf("%s.offset", flagname); const char *off = sdb_const_get(db, offset_key, 0); free(offset_key); @@ -255,11 +255,14 @@ RZ_API void rz_core_bin_export_info(RzCore *core, int mode) { ut8 *buf = malloc(fmtsize); if (buf) { rz_io_read_at(core->io, addr, buf, fmtsize); - int res = rz_print_format(core->print, addr, buf, + char *format = rz_type_format_data(core->analysis->type, core->print, addr, buf, fmtsize, v, 0, NULL, NULL); free(buf); - if (res < 0) { + if (!format) { eprintf("Warning: Cannot register invalid format (%s)\n", v); + } else { + rz_cons_print(format); + free(format); } } } diff --git a/librz/core/cmd_meta.c b/librz/core/cmd_meta.c index ec657983e37..fb6c1397314 100644 --- a/librz/core/cmd_meta.c +++ b/librz/core/cmd_meta.c @@ -554,7 +554,7 @@ static int cmd_meta_others(RzCore *core, const char *input) { if (p) { p = (char *)rz_str_trim_head_ro(p); if (*p == '.') { - const char *realformat = rz_type_format_byname(core->print, p + 1); + const char *realformat = rz_type_format_byname(core->analysis->type, p + 1); if (realformat) { p = (char *)realformat; } else { @@ -563,7 +563,7 @@ static int cmd_meta_others(RzCore *core, const char *input) { } } if (n < 1) { - n = rz_type_format_struct_size(core->print, p, 0, 0); + n = rz_type_format_struct_size(core->analysis->type, p, 0, 0); if (n < 1) { eprintf("Warning: Cannot resolve struct size for '%s'\n", p); n = 32; // @@ -573,10 +573,13 @@ static int cmd_meta_others(RzCore *core, const char *input) { if (n > core->blocksize) { n = core->blocksize; } - int r = rz_type_format(core->print, addr, core->block, + char *format = rz_type_format_data(core->analysis->type, core->print, addr, core->block, n, p, 0, NULL, NULL); - if (r < 0) { + if (!format) { n = -1; + } else { + rz_cons_print(format); + free(format); } } else { eprintf("Usage: Cf [size] [pf-format-string]\n"); diff --git a/librz/core/cmd_print.c b/librz/core/cmd_print.c index 49101cd99b0..0a98c843c86 100644 --- a/librz/core/cmd_print.c +++ b/librz/core/cmd_print.c @@ -5,6 +5,7 @@ #include "rz_core.h" #include "rz_config.h" #include "rz_util.h" +#include "rz_type.h" #include "rz_types.h" #include @@ -1603,9 +1604,9 @@ static void cmd_print_format(RzCore *core, const char *_input, const ut8 *block, _input += 2; if (*_input == '.') { _input++; - val = sdb_get(core->print->formats, _input, NULL); + val = rz_type_format_get(core->analysis->type, _input); if (val) { - rz_cons_printf("%d\n", rz_print_format_struct_size(core->print, val, mode, 0)); + rz_cons_printf("%d\n", rz_type_format_struct_size(core->analysis->type, val, mode, 0)); } else { eprintf("Struct %s not defined\nUsage: pfs.struct_name | pfs format\n", _input); } @@ -1614,7 +1615,7 @@ static void cmd_print_format(RzCore *core, const char *_input, const ut8 *block, _input++; } if (*_input) { - rz_cons_printf("%d\n", rz_print_format_struct_size(core->print, _input, mode, 0)); + rz_cons_printf("%d\n", rz_type_format_struct_size(core->analysis->type, _input, mode, 0)); } else { eprintf("Struct %s not defined\nUsage: pfs.struct_name | pfs format\n", _input); } @@ -1640,7 +1641,7 @@ static void cmd_print_format(RzCore *core, const char *_input, const ut8 *block, } } else { const char *struct_name = rz_str_trim_head_ro(_input); - const char *val = sdb_get(core->print->formats, struct_name, NULL); + const char *val = rz_type_format_get(core->analysis->type, struct_name); if (val) { rz_cons_printf("%s\n", val); } else { @@ -1743,19 +1744,19 @@ static void cmd_print_format(RzCore *core, const char *_input, const ut8 *block, core->print->num = core->num; /* print all stored format */ if (!input[1] || !input[2]) { // "pf." - SdbListIter *iter; - SdbKv *kv; - SdbList *sdbls = sdb_foreach_list(core->print->formats, true); - ls_foreach (sdbls, iter, kv) { - rz_cons_printf("pf.%s %s\n", sdbkv_key(kv), sdbkv_value(kv)); + RzListIter *iter; + char *fmt = NULL; + RzList *fmtl = rz_type_format_all(core->analysis->type); + rz_list_foreach (fmtl, iter, fmt) { + rz_cons_printf("pf.%s\n", fmt); } + rz_list_free(fmtl); /* delete a format */ } else if (input[1] && input[2] == '-') { // "pf-" if (input[3] == '*') { // "pf-*" - sdb_free(core->print->formats); - core->print->formats = sdb_new0(); + rz_type_format_purge(core->analysis->type); } else { // "pf-xxx" - sdb_unset(core->print->formats, input + 3, 0); + rz_type_format_delete(core->analysis->type, input + 3); } } else { char *name = strdup(input + (input[1] ? 2 : 1)); @@ -1776,7 +1777,7 @@ static void cmd_print_format(RzCore *core, const char *_input, const ut8 *block, eprintf("Struct or fields name can not contain dot symbol (.)\n"); } else { // pf.foo=xxx - sdb_set(core->print->formats, name, space, 0); + rz_type_format_set(core->analysis->type, name, space); } free(name); free(input); @@ -1784,7 +1785,7 @@ static void cmd_print_format(RzCore *core, const char *_input, const ut8 *block, } if (!strchr(name, '.') && - !sdb_get(core->print->formats, name, NULL)) { + !rz_type_format_get(core->analysis->type, name)) { eprintf("Cannot find '%s' format.\n", name); free(name); free(input); @@ -1802,9 +1803,9 @@ static void cmd_print_format(RzCore *core, const char *_input, const ut8 *block, /* Load format from name into fmt to get the size */ /* This make sure the whole structure will be printed */ const char *fmt = NULL; - fmt = sdb_get(core->print->formats, name, NULL); + fmt = rz_type_format_get(core->analysis->type, name); if (fmt) { - int size = rz_print_format_struct_size(core->print, fmt, mode, 0) + 10; + int size = rz_type_format_struct_size(core->analysis->type, fmt, mode, 0) + 10; if (size > core->blocksize) { rz_core_block_size(core, size); } @@ -1816,22 +1817,34 @@ static void cmd_print_format(RzCore *core, const char *_input, const ut8 *block, if (eq) { // Write mode (pf.field=value) *eq++ = 0; mode = RZ_PRINT_MUSTSET; - rz_print_format(core->print, core->offset, + char *format = rz_type_format_data(core->analysis->type, core->print, core->offset, core->block, core->blocksize, name, mode, eq, dot); + if (format) { + rz_cons_print(format); + free(format); + } } else { - rz_print_format(core->print, core->offset, + char *format = rz_type_format_data(core->analysis->type, core->print, core->offset, core->block, core->blocksize, name, mode, NULL, dot); + if (format) { + rz_cons_print(format); + free(format); + } } } else { - rz_print_format(core->print, core->offset, + char *format = rz_type_format_data(core->analysis->type, core->print, core->offset, core->block, core->blocksize, name, mode, NULL, NULL); + if (format) { + rz_cons_print(format); + free(format); + } } free(name); } } else { /* This make sure the structure will be printed entirely */ const char *fmt = rz_str_trim_head_ro(input + 1); - int struct_sz = rz_print_format_struct_size(core->print, fmt, mode, 0); + int struct_sz = rz_type_format_struct_size(core->analysis->type, fmt, mode, 0); int size = RZ_MAX(core->blocksize, struct_sz); ut8 *buf = calloc(1, size); if (!buf) { @@ -1854,8 +1867,12 @@ static void cmd_print_format(RzCore *core, const char *_input, const ut8 *block, } free(args); if (syntax_ok) { - rz_print_format(core->print, core->offset, + char *format = rz_type_format_data(core->analysis->type, core->print, core->offset, buf, size, fmt, mode, NULL, NULL); + if (format) { + rz_cons_print(format); + free(format); + } } free(buf); } diff --git a/librz/core/core.c b/librz/core/core.c index fe96243453d..458a59e4a89 100644 --- a/librz/core/core.c +++ b/librz/core/core.c @@ -1152,7 +1152,7 @@ static void autocompleteFilename(RzLineCompletion *completion, RzLineBuffer *buf static int autocomplete_pfele(RzCore *core, RzLineCompletion *completion, char *key, char *pfx, int idx, char *ptr) { int i, ret = 0; int len = strlen(ptr); - char *fmt = sdb_get(core->print->formats, key, NULL); + char *fmt = rz_type_format_get(core->analysis->type, key); if (fmt) { int nargs = rz_str_word_set0_stack(fmt); if (nargs > 1) { @@ -1666,6 +1666,7 @@ RZ_API void rz_core_autocomplete(RZ_NULLABLE RzCore *core, RzLineCompletion *com ADDARG("gui.alt_background") ADDARG("gui.border") } + /* } else if (!strncmp(buf->data, "pf.", 3) || !strncmp(buf->data, "pf*.", 4) || !strncmp(buf->data, "pfd.", 4) || !strncmp(buf->data, "pfv.", 4) || !strncmp(buf->data, "pfj.", 4)) { char pfx[2]; int chr = (buf->data[2] == '.') ? 3 : 4; @@ -1675,10 +1676,10 @@ RZ_API void rz_core_autocomplete(RZ_NULLABLE RzCore *core, RzLineCompletion *com } else { *pfx = 0; } - SdbList *sls = sdb_foreach_list(core->print->formats, false); - SdbListIter *iter; - SdbKv *kv; - ls_foreach (sls, iter, kv) { + // FIXME: FORMATS + RzListIter *iter; + RzList *fmtl = rz_type_format_all(core->analysis->type); + rz_list_foreach (fmtl, iter, kv) { int len = strlen(buf->data + chr); int minlen = RZ_MIN(len, strlen(sdbkv_key(kv))); if (!len || !strncmp(buf->data + chr, sdbkv_key(kv), minlen)) { @@ -1693,6 +1694,7 @@ RZ_API void rz_core_autocomplete(RZ_NULLABLE RzCore *core, RzLineCompletion *com } } } + */ } else if ((!strncmp(buf->data, "afvn ", 5)) || (!strncmp(buf->data, "afan ", 5))) { RzAnalysisFunction *fcn = rz_analysis_get_fcn_in(core->analysis, core->offset, 0); RzList *vars; @@ -2545,6 +2547,7 @@ RZ_API bool rz_core_init(RzCore *core) { rz_io_bind(core->io, &(core->search->iob)); rz_io_bind(core->io, &(core->print->iob)); rz_io_bind(core->io, &(core->analysis->iob)); + rz_io_bind(core->io, &(core->analysis->type->iob)); rz_io_bind(core->io, &(core->bin->iob)); rz_flag_bind(core->flags, &(core->analysis->flb)); core->analysis->flg_class_set = core_flg_class_set; diff --git a/librz/core/ctypes.c b/librz/core/ctypes.c index 4c589c35684..220cb6f949d 100644 --- a/librz/core/ctypes.c +++ b/librz/core/ctypes.c @@ -1098,4 +1098,3 @@ RZ_IPI void rz_types_open_editor(RzCore *core, const char *typename) { } free(str); } - diff --git a/librz/core/disasm.c b/librz/core/disasm.c index 2ac8ae6d443..1f4914d8520 100644 --- a/librz/core/disasm.c +++ b/librz/core/disasm.c @@ -3123,8 +3123,12 @@ static bool ds_print_meta_infos(RDisasmState *ds, ut8 *buf, int len, int idx, in case RZ_META_TYPE_FORMAT: { rz_cons_printf("pf %s # size=%" PFMT64d "\n", mi->str, mi_size); int len_before = rz_cons_get_buffer_len(); - rz_print_format(core->print, ds->at, buf + idx, + char *format = rz_type_format_data(core->analysis->type, core->print, ds->at, buf + idx, len - idx, mi->str, RZ_PRINT_MUSTSEE, NULL, NULL); + if (format) { + rz_cons_print(format); + free(format); + } int len_after = rz_cons_get_buffer_len(); const char *cons_buf = rz_cons_get_buffer(); if (len_after > len_before && buf && cons_buf[len_after - 1] == '\n') { diff --git a/librz/core/vmenus.c b/librz/core/vmenus.c index 531db44dc21..4ba5271a420 100644 --- a/librz/core/vmenus.c +++ b/librz/core/vmenus.c @@ -755,7 +755,7 @@ RZ_API int rz_core_visual_types(RzCore *core) { } } break; case 'd': - rz_analysis_remove_parsed_type(core->analysis, vt.curname); + rz_type_remove_parsed_type(core->analysis->type, vt.curname); break; case '-': rz_types_open_editor(core, NULL); diff --git a/librz/include/rz_type.h b/librz/include/rz_type.h index 044947f26f4..ae8f8acc70d 100644 --- a/librz/include/rz_type.h +++ b/librz/include/rz_type.h @@ -5,6 +5,10 @@ #define RZ_TYPE_H #include +#include +#include +#include +#include #ifdef __cplusplus extern "C" { @@ -16,12 +20,16 @@ typedef struct rz_type_target_t { const char *cpu; int bits; const char *os; + bool big_endian; } RzTypeTarget; typedef struct rz_type_t { void *user; Sdb *sdb_types; + Sdb *formats; // for `pf` formats RzTypeTarget *target; + RNum *num; + RzIOBind iob; // for RzIO in formats } RzType; typedef struct rz_type_enum_case_t { @@ -132,9 +140,18 @@ RZ_API bool rz_type_unlink(RzType *t, ut64 addr); RZ_API bool rz_type_unlink_all(RzType *t); RZ_API bool rz_type_link_offset(RzType *t, const char *val, ut64 addr); +// Type formats (`tp` and `pf` commands) +RZ_API const char *rz_type_format_get(RzType *t, const char *name); +RZ_API void rz_type_format_set(RzType *t, const char *name, const char *fmt); +RZ_API RZ_OWN RzList *rz_type_format_all(RzType *t); +RZ_API void rz_type_format_delete(RzType *t, const char *name); +RZ_API void rz_type_format_purge(RzType *t); + RZ_API char *rz_type_format(RzType *type, const char *t); -RZ_API int rz_type_format_struct_size(RzPrint *p, const char *f, int mode, int n); -RZ_API const char *rz_type_format_byname(RzPrint *p, const char *name); +RZ_API int rz_type_format_struct_size(RzType *t, const char *f, int mode, int n); +RZ_API const char *rz_type_format_byname(RzType *t, const char *name); +RZ_API char *rz_type_format_data(RzType *t, RzPrint *p, ut64 seek, const ut8 *b, const int len, + const char *formatname, int mode, const char *setval, char *ofield); // Function prototypes api RZ_API bool rz_type_func_exist(RzType *t, const char *func_name); @@ -159,7 +176,6 @@ RZ_API RzList *rz_type_links(RzType *type); RZ_API void rz_serialize_types_save(RZ_NONNULL Sdb *db, RZ_NONNULL RzType *types); RZ_API bool rz_serialize_types_load(RZ_NONNULL Sdb *db, RZ_NONNULL RzType *types, RZ_NULLABLE RzSerializeResultInfo *res); - #endif #ifdef __cplusplus diff --git a/librz/include/rz_util/rz_print.h b/librz/include/rz_util/rz_print.h index 9139efa217c..6c2fcaa093f 100644 --- a/librz/include/rz_util/rz_print.h +++ b/librz/include/rz_util/rz_print.h @@ -94,7 +94,6 @@ typedef struct rz_print_t { RzPrintHasRefs hasrefs; RzPrintCommentCallback get_comments; RzPrintSectionGet get_section_name; - Sdb *formats; Sdb *sdb_types; RzCons *cons; RzConsBind consbind; @@ -176,9 +175,7 @@ RZ_API void rz_print_code(RzPrint *p, ut64 addr, const ut8 *buf, int len, char l #define RZ_PRINT_DOT (1 << 7) #define RZ_PRINT_QUIET (1 << 8) #define RZ_PRINT_STRUCT (1 << 9) -RZ_API int rz_print_format_struct_size(RzPrint *p, const char *format, int mode, int n); -RZ_API int rz_print_format(RzPrint *p, ut64 seek, const ut8 *buf, const int len, const char *fmt, int elem, const char *setval, char *field); -RZ_API const char *rz_print_format_byname(RzPrint *p, const char *name); + RZ_API void rz_print_offset(RzPrint *p, ut64 off, int invert, int opt, int dec, int delta, const char *label); RZ_API void rz_print_offset_sg(RzPrint *p, ut64 off, int invert, int offseg, int seggrn, int offdec, int delta, const char *label); #define RZ_PRINT_STRING_WIDE 1 diff --git a/librz/type/base.c b/librz/type/base.c index dde2a02523b..134aea3b5eb 100644 --- a/librz/type/base.c +++ b/librz/type/base.c @@ -563,4 +563,3 @@ RZ_API void rz_type_save_base_type(const RzType *t, const RzBaseType *type) { break; } } - diff --git a/librz/type/format.c b/librz/type/format.c index c2e0d580ee4..5520b0dd242 100644 --- a/librz/type/format.c +++ b/librz/type/format.c @@ -67,29 +67,29 @@ static int rz_get_size(RNum *num, ut8 *buf, int endian, const char *s) { return rz_num_math(num, s); } -static void rz_print_format_u128(const RzPrint *p, int endian, int mode, +static void rz_type_format_u128(RzStrBuf *outbuf, int endian, int mode, const char *setval, ut64 seeki, ut8 *buf, int i, int size) { ut64 low = rz_read_ble64(buf, endian); ut64 hig = rz_read_ble64(buf + 8, endian); if (MUSTSEEJSON) { - p->cb_printf("\""); + rz_strbuf_append(outbuf, "\""); } else if (!SEEVALUE && !ISQUIET) { - p->cb_printf("0x%08" PFMT64x " = (uint128_t)", seeki); + rz_strbuf_appendf(outbuf, "0x%08" PFMT64x " = (uint128_t)", seeki); } if (endian) { - p->cb_printf("0x%016" PFMT64x "", low); - p->cb_printf("%016" PFMT64x, hig); + rz_strbuf_appendf(outbuf, "0x%016" PFMT64x "", low); + rz_strbuf_appendf(outbuf, "%016" PFMT64x, hig); } else { - p->cb_printf("0x%016" PFMT64x "", hig); - p->cb_printf("%016" PFMT64x, low); + rz_strbuf_appendf(outbuf, "0x%016" PFMT64x "", hig); + rz_strbuf_appendf(outbuf, "%016" PFMT64x, low); } if (MUSTSEEJSON) { const char *end = endian ? "big" : "little"; - p->cb_printf("\",\"endian\":\"%s\",\"ctype\":\"uint128_t\"}", end); + rz_strbuf_appendf(outbuf, "\",\"endian\":\"%s\",\"ctype\":\"uint128_t\"}", end); } } -static void rz_print_format_quadword(const RzPrint *p, int endian, int mode, +static void rz_type_format_quadword(RzStrBuf *outbuf, int endian, int mode, const char *setval, ut64 seeki, ut8 *buf, int i, int size) { ut64 addr64; int elem = -1; @@ -99,32 +99,32 @@ static void rz_print_format_quadword(const RzPrint *p, int endian, int mode, } updateAddr(buf + i, size - i, endian, NULL, &addr64); if (MUSTSET) { - p->cb_printf("wv8 %s @ 0x%08" PFMT64x "\n", setval, seeki + ((elem >= 0) ? elem * 8 : 0)); + rz_strbuf_appendf(outbuf, "wv8 %s @ 0x%08" PFMT64x "\n", setval, seeki + ((elem >= 0) ? elem * 8 : 0)); } else if (MUSTSEE) { if (!SEEVALUE && !ISQUIET) { - p->cb_printf("0x%08" PFMT64x " = (qword)", + rz_strbuf_appendf(outbuf, "0x%08" PFMT64x " = (qword)", seeki + ((elem >= 0) ? elem * 8 : 0)); } if (size == -1) { if (addr64 == UT32_MAX || ((st64)addr64 < 0 && (st64)addr64 > -4096)) { - p->cb_printf("%d", (int)(addr64)); + rz_strbuf_appendf(outbuf, "%d", (int)(addr64)); } else { - p->cb_printf("0x%016" PFMT64x, addr64); + rz_strbuf_appendf(outbuf, "0x%016" PFMT64x, addr64); } } else { if (!SEEVALUE) { - p->cb_printf("[ "); + rz_strbuf_append(outbuf, "[ "); } while (size--) { updateAddr(buf + i, size - i, endian, NULL, &addr64); if (elem == -1 || elem == 0) { - p->cb_printf("0x%016" PFMT64x, addr64); + rz_strbuf_appendf(outbuf, "0x%016" PFMT64x, addr64); if (elem == 0) { elem = -2; } } if (size != 0 && elem == -1) { - p->cb_printf(", "); + rz_strbuf_append(outbuf, ", "); } if (elem > -1) { elem--; @@ -132,39 +132,39 @@ static void rz_print_format_quadword(const RzPrint *p, int endian, int mode, i += 8; } if (!SEEVALUE) { - p->cb_printf(" ]"); + rz_strbuf_append(outbuf, " ]"); } } } else if (MUSTSEEJSON || MUSTSEESTRUCT) { if (size == -1) { - p->cb_printf("%" PFMT64d, addr64); + rz_strbuf_appendf(outbuf, "%" PFMT64d, addr64); } else { - p->cb_printf("[ "); + rz_strbuf_append(outbuf, "[ "); while (size--) { updateAddr(buf + i, size - i, endian, NULL, &addr64); if (elem == -1 || elem == 0) { - p->cb_printf("%" PFMT64d, addr64); + rz_strbuf_appendf(outbuf, "%" PFMT64d, addr64); if (elem == 0) { elem = -2; } } if (size != 0 && elem == -1) { - p->cb_printf(", "); + rz_strbuf_append(outbuf, ", "); } if (elem > -1) { elem--; } i += 8; } - p->cb_printf(" ]"); + rz_strbuf_append(outbuf, " ]"); } if (MUSTSEEJSON) { - p->cb_printf("}"); + rz_strbuf_append(outbuf, "}"); } } } -static void rz_print_format_byte(const RzPrint *p, int endian, int mode, +static void rz_type_format_byte(RzStrBuf *outbuf, int endian, int mode, const char *setval, ut64 seeki, ut8 *buf, int i, int size) { int elem = -1; if (size >= ARRAYINDEX_COEF) { @@ -172,26 +172,26 @@ static void rz_print_format_byte(const RzPrint *p, int endian, int mode, size %= ARRAYINDEX_COEF; } if (MUSTSET) { - p->cb_printf("\"w %s\" @ 0x%08" PFMT64x "\n", setval, seeki + ((elem >= 0) ? elem : 0)); + rz_strbuf_appendf(outbuf, "\"w %s\" @ 0x%08" PFMT64x "\n", setval, seeki + ((elem >= 0) ? elem : 0)); } else if (MUSTSEE) { if (!SEEVALUE && !ISQUIET) { - p->cb_printf("0x%08" PFMT64x " = ", seeki + ((elem >= 0) ? elem : 0)); + rz_strbuf_appendf(outbuf, "0x%08" PFMT64x " = ", seeki + ((elem >= 0) ? elem : 0)); } if (size == -1) { - p->cb_printf("0x%02x", buf[i]); + rz_strbuf_appendf(outbuf, "0x%02x", buf[i]); } else { if (!SEEVALUE) { - p->cb_printf("[ "); + rz_strbuf_append(outbuf, "[ "); } while (size--) { if (elem == -1 || elem == 0) { - p->cb_printf("0x%02x", buf[i]); + rz_strbuf_appendf(outbuf, "0x%02x", buf[i]); if (elem == 0) { elem = -2; } } if (size != 0 && elem == -1) { - p->cb_printf(", "); + rz_strbuf_append(outbuf, ", "); } if (elem > -1) { elem--; @@ -199,18 +199,18 @@ static void rz_print_format_byte(const RzPrint *p, int endian, int mode, i++; } if (!SEEVALUE) { - p->cb_printf(" ]"); + rz_strbuf_append(outbuf, " ]"); } } } else if (MUSTSEEJSON || MUSTSEESTRUCT) { if (size == -1) { - p->cb_printf("%d", buf[i]); + rz_strbuf_appendf(outbuf, "%d", buf[i]); } else { - p->cb_printf("[ "); + rz_strbuf_append(outbuf, "[ "); const char *comma = ""; while (size--) { if (elem == -1 || elem == 0) { - p->cb_printf("%s%d", comma, buf[i]); + rz_strbuf_appendf(outbuf, "%s%d", comma, buf[i]); comma = ","; if (elem == 0) { elem = -2; @@ -221,16 +221,17 @@ static void rz_print_format_byte(const RzPrint *p, int endian, int mode, } i++; } - p->cb_printf(" ]"); + rz_strbuf_append(outbuf, " ]"); } if (MUSTSEEJSON) { - p->cb_printf("}"); + rz_strbuf_append(outbuf, "}"); } } } +// FIXME: Port to the PJ API // Return number of consumed bytes -static int rz_print_format_uleb(const RzPrint *p, int endian, int mode, +static int rz_type_format_uleb(RzStrBuf *outbuf, int endian, int mode, const char *setval, ut64 seeki, ut8 *buf, int i, int size) { int elem = -1; int s = 0, offset = 0; @@ -249,74 +250,74 @@ static int rz_print_format_uleb(const RzPrint *p, int endian, int mode, } while (elem--); tmp = (ut8 *)rz_uleb128_encode(rz_num_math(NULL, setval), &s); nbr = rz_hex_bin2strdup(tmp, s); - p->cb_printf("\"wx %s\" @ 0x%08" PFMT64x "\n", nbr, seeki + offset - s); + rz_strbuf_appendf(outbuf, "\"wx %s\" @ 0x%08" PFMT64x "\n", nbr, seeki + offset - s); free(tmp); free(nbr); } else if (MUSTSEE) { if (!SEEVALUE && !ISQUIET) { - p->cb_printf("0x%08" PFMT64x " = ", seeki); + rz_strbuf_appendf(outbuf, "0x%08" PFMT64x " = ", seeki); } if (size == -1) { rz_uleb128_decode(buf + i, &offset, &value); - p->cb_printf("%" PFMT64d, value); + rz_strbuf_appendf(outbuf, "%" PFMT64d, value); } else { if (!SEEVALUE) { - p->cb_printf("[ "); + rz_strbuf_append(outbuf, "[ "); } while (size--) { if (elem == -1 || elem == 0) { rz_uleb128_decode(buf + i, &s, &value); i += s; offset += s; - p->cb_printf("%" PFMT64d, value); + rz_strbuf_appendf(outbuf, "%" PFMT64d, value); if (elem == 0) { elem = -2; } } if (size != 0 && elem == -1) { - p->cb_printf(", "); + rz_strbuf_append(outbuf, ", "); } if (elem > -1) { elem--; } } if (!SEEVALUE) { - p->cb_printf(" ]"); + rz_strbuf_append(outbuf, " ]"); } } } else if (MUSTSEEJSON || MUSTSEESTRUCT) { if (size == -1) { rz_uleb128_decode(buf + i, &offset, &value); - p->cb_printf("\"%" PFMT64d "\"", value); + rz_strbuf_appendf(outbuf, "\"%" PFMT64d "\"", value); } else { - p->cb_printf("[ "); + rz_strbuf_append(outbuf, "[ "); while (size--) { if (elem == -1 || elem == 0) { rz_uleb128_decode(buf + i, &s, &value); i += s; offset += s; - p->cb_printf("\"%" PFMT64d "\"", value); + rz_strbuf_appendf(outbuf, "\"%" PFMT64d "\"", value); if (elem == 0) { elem = -2; } } if (size != 0 && elem == -1) { - p->cb_printf(", "); + rz_strbuf_append(outbuf, ", "); } if (elem > -1) { elem--; } } - p->cb_printf(" ]"); + rz_strbuf_append(outbuf, " ]"); } if (MUSTSEEJSON) { - p->cb_printf("}"); + rz_strbuf_append(outbuf, "}"); } } return offset; } -static void rz_print_format_char(const RzPrint *p, int endian, int mode, +static void rz_type_format_char(RzStrBuf *outbuf, int endian, int mode, const char *setval, ut64 seeki, ut8 *buf, int i, int size) { int elem = -1; if (size >= ARRAYINDEX_COEF) { @@ -324,26 +325,26 @@ static void rz_print_format_char(const RzPrint *p, int endian, int mode, size %= ARRAYINDEX_COEF; } if (MUSTSET) { - p->cb_printf("\"w %s\" @ 0x%08" PFMT64x "\n", setval, seeki + ((elem >= 0) ? elem : 0)); + rz_strbuf_appendf(outbuf, "\"w %s\" @ 0x%08" PFMT64x "\n", setval, seeki + ((elem >= 0) ? elem : 0)); } else if (MUSTSEE) { if (!SEEVALUE && !ISQUIET) { - p->cb_printf("0x%08" PFMT64x " = ", seeki + ((elem >= 0) ? elem * 2 : 0)); //XXX:: shouldn't it be elem*1?? + rz_strbuf_appendf(outbuf, "0x%08" PFMT64x " = ", seeki + ((elem >= 0) ? elem * 2 : 0)); //XXX:: shouldn't it be elem*1?? } if (size == -1) { - p->cb_printf("'%c'", IS_PRINTABLE(buf[i]) ? buf[i] : '.'); + rz_strbuf_appendf(outbuf, "'%c'", IS_PRINTABLE(buf[i]) ? buf[i] : '.'); } else { if (!SEEVALUE) { - p->cb_printf("[ "); + rz_strbuf_append(outbuf, "[ "); } while (size--) { if (elem == -1 || elem == 0) { - p->cb_printf("'%c'", IS_PRINTABLE(buf[i]) ? buf[i] : '.'); + rz_strbuf_appendf(outbuf, "'%c'", IS_PRINTABLE(buf[i]) ? buf[i] : '.'); if (elem == 0) { elem = -2; } } if (size != 0 && elem == -1) { - p->cb_printf(", "); + rz_strbuf_append(outbuf, ", "); } if (elem > -1) { elem--; @@ -351,38 +352,38 @@ static void rz_print_format_char(const RzPrint *p, int endian, int mode, i++; } if (!SEEVALUE) { - p->cb_printf(" ]"); + rz_strbuf_append(outbuf, " ]"); } } } else if (MUSTSEEJSON || MUSTSEESTRUCT) { if (size == -1) { - p->cb_printf("\"%c\"", IS_PRINTABLE(buf[i]) ? buf[i] : '.'); + rz_strbuf_appendf(outbuf, "\"%c\"", IS_PRINTABLE(buf[i]) ? buf[i] : '.'); } else { - p->cb_printf("[ "); + rz_strbuf_append(outbuf, "[ "); while (size--) { if (elem == -1 || elem == 0) { - p->cb_printf("\"%c\"", IS_PRINTABLE(buf[i]) ? buf[i] : '.'); + rz_strbuf_appendf(outbuf, "\"%c\"", IS_PRINTABLE(buf[i]) ? buf[i] : '.'); if (elem == 0) { elem = -2; } } if (size != 0 && elem == -1) { - p->cb_printf(", "); + rz_strbuf_append(outbuf, ", "); } if (elem > -1) { elem--; } i++; } - p->cb_printf(" ]"); + rz_strbuf_append(outbuf, " ]"); } if (MUSTSEEJSON) { - p->cb_printf("}"); + rz_strbuf_append(outbuf, "}"); } } } -static void rz_print_format_decchar(const RzPrint *p, int endian, int mode, +static void rz_type_format_decchar(RzStrBuf *outbuf, int endian, int mode, const char *setval, ut64 seeki, ut8 *buf, int i, int size) { int elem = -1; if (size >= ARRAYINDEX_COEF) { @@ -390,26 +391,26 @@ static void rz_print_format_decchar(const RzPrint *p, int endian, int mode, size %= ARRAYINDEX_COEF; } if (MUSTSET) { - p->cb_printf("\"w %s\" @ 0x%08" PFMT64x "\n", setval, seeki + ((elem >= 0) ? elem : 0)); + rz_strbuf_appendf(outbuf, "\"w %s\" @ 0x%08" PFMT64x "\n", setval, seeki + ((elem >= 0) ? elem : 0)); } else if (MUSTSEE) { if (!SEEVALUE && !ISQUIET) { - p->cb_printf("0x%08" PFMT64x " = ", seeki + ((elem >= 0) ? elem : 0)); + rz_strbuf_appendf(outbuf, "0x%08" PFMT64x " = ", seeki + ((elem >= 0) ? elem : 0)); } if (size == -1) { - p->cb_printf("%d", buf[i]); + rz_strbuf_appendf(outbuf, "%d", buf[i]); } else { if (!SEEVALUE) { - p->cb_printf("[ "); + rz_strbuf_append(outbuf, "[ "); } while (size--) { if (elem == -1 || elem == 0) { - p->cb_printf("%d", buf[i]); + rz_strbuf_appendf(outbuf, "%d", buf[i]); if (elem == 0) { elem = -2; } } if (size != 0 && elem == -1) { - p->cb_printf(", "); + rz_strbuf_appendf(outbuf, ", "); } if (elem > -1) { elem--; @@ -417,83 +418,79 @@ static void rz_print_format_decchar(const RzPrint *p, int endian, int mode, i++; } if (!SEEVALUE) { - p->cb_printf(" ]"); + rz_strbuf_append(outbuf, " ]"); } } } else if (MUSTSEEJSON || MUSTSEESTRUCT) { if (size == -1) { - p->cb_printf("\"%d\"", buf[i]); + rz_strbuf_appendf(outbuf, "\"%d\"", buf[i]); } else { - p->cb_printf("[ "); + rz_strbuf_append(outbuf, "[ "); while (size--) { if (elem == -1 || elem == 0) { - p->cb_printf("\"%d\"", buf[i]); + rz_strbuf_appendf(outbuf, "\"%d\"", buf[i]); if (elem == 0) { elem = -2; } } if (size != 0 && elem == -1) { - p->cb_printf(", "); + rz_strbuf_appendf(outbuf, ", "); } if (elem > -1) { elem--; } i++; } - p->cb_printf(" ]"); + rz_strbuf_append(outbuf, " ]"); } if (MUSTSEEJSON) { - p->cb_printf("}"); + rz_strbuf_append(outbuf, "}"); } } } -static int rz_print_format_string(const RzPrint *p, ut64 seeki, ut64 addr64, ut64 addr, int is64, int mode) { +static int rz_type_format_string(RzType *t, RzStrBuf *outbuf, ut64 seeki, ut64 addr64, ut64 addr, int is64, int mode) { ut8 buffer[255]; buffer[0] = 0; - if (!p->iob.read_at) { - eprintf("(cannot read memory)\n"); - return -1; - } const ut64 at = (is64 == 1) ? addr64 : (ut64)addr; - int res = p->iob.read_at(p->iob.io, at, buffer, sizeof(buffer) - 8); + int res = t->iob.read_at(t->iob.io, at, buffer, sizeof(buffer) - 8); if (MUSTSEEJSON) { char *encstr = rz_str_utf16_encode((const char *)buffer, -1); if (encstr) { - p->cb_printf("%" PFMT64d ",\"string\":\"%s\"}", seeki, encstr); + rz_strbuf_appendf(outbuf, "%" PFMT64d ",\"string\":\"%s\"}", seeki, encstr); free(encstr); } } else if (MUSTSEESTRUCT) { char *encstr = rz_str_utf16_encode((const char *)buffer, -1); if (encstr) { - p->cb_printf("\"%s\"", encstr); + rz_strbuf_appendf(outbuf, "\"%s\"", encstr); free(encstr); } } else if (MUSTSEE) { if (!SEEVALUE && !ISQUIET) { - p->cb_printf("0x%08" PFMT64x " = ", seeki); + rz_strbuf_appendf(outbuf, "0x%08" PFMT64x " = ", seeki); } if (!SEEVALUE) { if (ISQUIET) { if (addr == 0LL) { - p->cb_printf("NULL"); + rz_strbuf_append(outbuf, "NULL"); } else if (addr == UT32_MAX || addr == UT64_MAX) { - p->cb_printf("-1"); + rz_strbuf_append(outbuf, "-1"); } else { - p->cb_printf("0x%08" PFMT64x " ", addr); + rz_strbuf_appendf(outbuf, "0x%08" PFMT64x " ", addr); } } else { - p->cb_printf("0x%08" PFMT64x " -> 0x%08" PFMT64x " ", seeki, addr); + rz_strbuf_appendf(outbuf, "0x%08" PFMT64x " -> 0x%08" PFMT64x " ", seeki, addr); } } if (res > 0 && buffer[0] != 0xff && buffer[1] != 0xff) { - p->cb_printf("\"%s\"", buffer); + rz_strbuf_appendf(outbuf, "\"%s\"", buffer); } } return 0; } -static void rz_print_format_time(const RzPrint *p, int endian, int mode, +static void rz_type_format_time(RzStrBuf *outbuf, int endian, int mode, const char *setval, ut64 seeki, ut8 *buf, int i, int size) { ut64 addr; struct tm timestruct; @@ -504,7 +501,7 @@ static void rz_print_format_time(const RzPrint *p, int endian, int mode, } updateAddr(buf + i, size - i, endian, &addr, NULL); if (MUSTSET) { - p->cb_printf("wv4 %s @ 0x%08" PFMT64x "\n", setval, seeki + ((elem >= 0) ? elem * 4 : 0)); + rz_strbuf_appendf(outbuf, "wv4 %s @ 0x%08" PFMT64x "\n", setval, seeki + ((elem >= 0) ? elem * 4 : 0)); } else if (MUSTSEE) { char *timestr = malloc(ASCTIME_BUF_MINLEN); if (!timestr) { @@ -513,26 +510,26 @@ static void rz_print_format_time(const RzPrint *p, int endian, int mode, rz_asctime_r(gmtime_r((time_t *)&addr, ×truct), timestr); *(timestr + 24) = '\0'; if (!SEEVALUE && !ISQUIET) { - p->cb_printf("0x%08" PFMT64x " = ", seeki + ((elem >= 0) ? elem * 4 : 0)); + rz_strbuf_appendf(outbuf, "0x%08" PFMT64x " = ", seeki + ((elem >= 0) ? elem * 4 : 0)); } if (size == -1) { - p->cb_printf("%s", timestr); + rz_strbuf_appendf(outbuf, "%s", timestr); } else { if (!SEEVALUE) { - p->cb_printf("[ "); + rz_strbuf_appendf(outbuf, "[ "); } while (size--) { updateAddr(buf + i, size - i, endian, &addr, NULL); rz_asctime_r(gmtime_r((time_t *)&addr, ×truct), timestr); *(timestr + 24) = '\0'; if (elem == -1 || elem == 0) { - p->cb_printf("%s", timestr); + rz_strbuf_appendf(outbuf, "%s", timestr); if (elem == 0) { elem = -2; } } if (size != 0 && elem == -1) { - p->cb_printf(", "); + rz_strbuf_appendf(outbuf, ", "); } if (elem > -1) { elem--; @@ -540,7 +537,7 @@ static void rz_print_format_time(const RzPrint *p, int endian, int mode, i += 4; } if (!SEEVALUE) { - p->cb_printf(" ]"); + rz_strbuf_appendf(outbuf, " ]"); } } free(timestr); @@ -552,38 +549,38 @@ static void rz_print_format_time(const RzPrint *p, int endian, int mode, rz_asctime_r(gmtime_r((time_t *)&addr, ×truct), timestr); *(timestr + 24) = '\0'; if (size == -1) { - p->cb_printf("\"%s\"", timestr); + rz_strbuf_appendf(outbuf, "\"%s\"", timestr); } else { - p->cb_printf("[ "); + rz_strbuf_append(outbuf, "[ "); while (size--) { updateAddr(buf + i, size - i, endian, &addr, NULL); rz_asctime_r(gmtime_r((time_t *)&addr, ×truct), timestr); *(timestr + 24) = '\0'; if (elem == -1 || elem == 0) { - p->cb_printf("\"%s\"", timestr); + rz_strbuf_appendf(outbuf, "\"%s\"", timestr); if (elem == 0) { elem = -2; } } if (size != 0 && elem == -1) { - p->cb_printf(", "); + rz_strbuf_append(outbuf, ", "); } if (elem > -1) { elem--; } i += 4; } - p->cb_printf(" ]"); + rz_strbuf_append(outbuf, " ]"); } free(timestr); if (MUSTSEEJSON) { - p->cb_printf("}"); + rz_strbuf_append(outbuf, "}"); } } } // TODO: support unsigned int? -static void rz_print_format_hex(const RzPrint *p, int endian, int mode, +static void rz_type_format_hex(RzStrBuf *outbuf, int endian, int mode, const char *setval, ut64 seeki, ut8 *buf, int i, int size) { ut64 addr; int elem = -1; @@ -593,41 +590,41 @@ static void rz_print_format_hex(const RzPrint *p, int endian, int mode, } updateAddr(buf + i, size - i, endian, &addr, NULL); if (MUSTSET) { - p->cb_printf("wv4 %s @ 0x%08" PFMT64x "\n", setval, seeki + ((elem >= 0) ? elem * 4 : 0)); + rz_strbuf_appendf(outbuf, "wv4 %s @ 0x%08" PFMT64x "\n", setval, seeki + ((elem >= 0) ? elem * 4 : 0)); } else if ((mode & RZ_PRINT_DOT) || MUSTSEESTRUCT) { - p->cb_printf("%" PFMT64d, addr); + rz_strbuf_appendf(outbuf, "%" PFMT64d, addr); } else if (MUSTSEE) { if (!SEEVALUE && !ISQUIET) { - p->cb_printf("0x%08" PFMT64x " = ", seeki + ((elem >= 0) ? elem * 4 : 0)); + rz_strbuf_appendf(outbuf, "0x%08" PFMT64x " = ", seeki + ((elem >= 0) ? elem * 4 : 0)); } if (size == -1) { if (addr == UT64_MAX || addr == UT32_MAX) { - p->cb_printf("-1"); + rz_strbuf_append(outbuf, "-1"); } else { - p->cb_printf("%" PFMT64d, addr); + rz_strbuf_appendf(outbuf, "%" PFMT64d, addr); } } else { if (!SEEVALUE) { - p->cb_printf("[ "); + rz_strbuf_append(outbuf, "[ "); } while (size--) { updateAddr(buf + i, size - i, endian, &addr, NULL); if (elem == -1 || elem == 0) { if (ISQUIET) { if (addr == UT64_MAX || addr == UT32_MAX) { - p->cb_printf("-1"); + rz_strbuf_append(outbuf, "-1"); } else { - p->cb_printf("%" PFMT64d, addr); + rz_strbuf_appendf(outbuf, "%" PFMT64d, addr); } } else { - p->cb_printf("%" PFMT64d, addr); + rz_strbuf_appendf(outbuf, "%" PFMT64d, addr); } if (elem == 0) { elem = -2; } } if (size != 0 && elem == -1) { - p->cb_printf(", "); + rz_strbuf_append(outbuf, ", "); } if (elem > -1) { elem--; @@ -635,37 +632,37 @@ static void rz_print_format_hex(const RzPrint *p, int endian, int mode, i += 4; } if (!SEEVALUE) { - p->cb_printf(" ]"); + rz_strbuf_append(outbuf, " ]"); } } } else if (MUSTSEEJSON) { if (size == -1) { - p->cb_printf("%" PFMT64d, addr); + rz_strbuf_appendf(outbuf, "%" PFMT64d, addr); } else { - p->cb_printf("[ "); + rz_strbuf_append(outbuf, "[ "); while (size--) { updateAddr(buf + i, size - i, endian, &addr, NULL); if (elem == -1 || elem == 0) { - p->cb_printf("%" PFMT64d, addr); + rz_strbuf_appendf(outbuf, "%" PFMT64d, addr); if (elem == 0) { elem = -2; } } if (size != 0 && elem == -1) { - p->cb_printf(", "); + rz_strbuf_append(outbuf, ", "); } if (elem > -1) { elem--; } i += 4; } - p->cb_printf(" ]"); + rz_strbuf_append(outbuf, " ]"); } - p->cb_printf("}"); + rz_strbuf_append(outbuf, "}"); } } -static void rz_print_format_int(const RzPrint *p, int endian, int mode, +static void rz_type_format_int(RzStrBuf *outbuf, int endian, int mode, const char *setval, ut64 seeki, ut8 *buf, int i, int size) { ut64 addr; int elem = -1; @@ -675,29 +672,29 @@ static void rz_print_format_int(const RzPrint *p, int endian, int mode, } updateAddr(buf + i, size - i, endian, &addr, NULL); if (MUSTSET) { - p->cb_printf("wv4 %s @ %" PFMT64d "\n", setval, seeki + ((elem >= 0) ? elem * 4 : 0)); + rz_strbuf_appendf(outbuf, "wv4 %s @ %" PFMT64d "\n", setval, seeki + ((elem >= 0) ? elem * 4 : 0)); } else if ((mode & RZ_PRINT_DOT) || MUSTSEESTRUCT) { - p->cb_printf("0x%08" PFMT64x, addr); + rz_strbuf_appendf(outbuf, "0x%08" PFMT64x, addr); } else if (MUSTSEE) { if (!SEEVALUE && !ISQUIET) { - p->cb_printf("0x%08" PFMT64x " = ", seeki + ((elem >= 0) ? elem * 4 : 0)); + rz_strbuf_appendf(outbuf, "0x%08" PFMT64x " = ", seeki + ((elem >= 0) ? elem * 4 : 0)); } if (size == -1) { - p->cb_printf("%" PFMT64d, (st64)(st32)addr); + rz_strbuf_appendf(outbuf, "%" PFMT64d, (st64)(st32)addr); } else { if (!SEEVALUE) { - p->cb_printf("[ "); + rz_strbuf_append(outbuf, "[ "); } while (size--) { updateAddr(buf + i, size - i, endian, &addr, NULL); if (elem == -1 || elem == 0) { - p->cb_printf("%" PFMT64d, (st64)(st32)addr); + rz_strbuf_appendf(outbuf, "%" PFMT64d, (st64)(st32)addr); if (elem == 0) { elem = -2; } } if (size != 0 && elem == -1) { - p->cb_printf(", "); + rz_strbuf_append(outbuf, ", "); } if (elem > -1) { elem--; @@ -705,37 +702,38 @@ static void rz_print_format_int(const RzPrint *p, int endian, int mode, i += 4; } if (!SEEVALUE) { - p->cb_printf(" ]"); + rz_strbuf_append(outbuf, " ]"); } } } else if (MUSTSEEJSON) { if (size == -1) { - p->cb_printf("%" PFMT64d, addr); + rz_strbuf_appendf(outbuf, "%" PFMT64d, addr); } else { - p->cb_printf("[ "); + rz_strbuf_append(outbuf, "[ "); while (size--) { updateAddr(buf + i, size - i, endian, &addr, NULL); if (elem == -1 || elem == 0) { - p->cb_printf("%" PFMT64d, addr); + rz_strbuf_appendf(outbuf, "%" PFMT64d, addr); if (elem == 0) { elem = -2; } } if (size != 0 && elem == -1) { - p->cb_printf(", "); + rz_strbuf_append(outbuf, ", "); } if (elem > -1) { elem--; } i += 4; } - p->cb_printf(" ]"); + rz_strbuf_append(outbuf, " ]"); } - p->cb_printf("}"); + rz_strbuf_append(outbuf, "}"); } } -static int rz_print_format_disasm(const RzPrint *p, ut64 seeki, int size) { +/* +static int rz_type_format_disasm(const RzPrint *p, ut64 seeki, int size) { ut64 prevseeki = seeki; if (!p->disasm || !p->user) { @@ -750,8 +748,9 @@ static int rz_print_format_disasm(const RzPrint *p, ut64 seeki, int size) { return seeki - prevseeki; } +*/ -static void rz_print_format_octal(const RzPrint *p, int endian, int mode, +static void rz_type_format_octal(RzStrBuf *outbuf, int endian, int mode, const char *setval, ut64 seeki, ut8 *buf, int i, int size) { ut64 addr; int elem = -1; @@ -761,32 +760,32 @@ static void rz_print_format_octal(const RzPrint *p, int endian, int mode, } updateAddr(buf + i, size - i, endian, &addr, NULL); if (MUSTSET) { - p->cb_printf("wv4 %s @ 0x%08" PFMT64x "\n", setval, seeki + ((elem >= 0) ? elem * 4 : 0)); + rz_strbuf_appendf(outbuf, "wv4 %s @ 0x%08" PFMT64x "\n", setval, seeki + ((elem >= 0) ? elem * 4 : 0)); } else if ((mode & RZ_PRINT_DOT) || MUSTSEESTRUCT) { - p->cb_printf("0%" PFMT64o, addr); + rz_strbuf_appendf(outbuf, "0%" PFMT64o, addr); } else if (MUSTSEE) { if (!SEEVALUE && !ISQUIET) { - p->cb_printf("0x%08" PFMT64x " = ", seeki + ((elem >= 0) ? elem * 4 : 0)); + rz_strbuf_appendf(outbuf, "0x%08" PFMT64x " = ", seeki + ((elem >= 0) ? elem * 4 : 0)); } if (!SEEVALUE) { - p->cb_printf("(octal) "); + rz_strbuf_append(outbuf, "(octal) "); } if (size == -1) { - p->cb_printf(" 0%08" PFMT64o, addr); + rz_strbuf_appendf(outbuf, " 0%08" PFMT64o, addr); } else { if (!SEEVALUE) { - p->cb_printf("[ "); + rz_strbuf_append(outbuf, "[ "); } while (size--) { updateAddr(buf + i, size - i, endian, &addr, NULL); if (elem == -1 || elem == 0) { - p->cb_printf("0%08" PFMT64o, addr); + rz_strbuf_appendf(outbuf, "0%08" PFMT64o, addr); if (elem == 0) { elem = -2; } } if (size != 0 && elem == -1) { - p->cb_printf(", "); + rz_strbuf_append(outbuf, ", "); } if (elem > -1) { elem--; @@ -794,37 +793,37 @@ static void rz_print_format_octal(const RzPrint *p, int endian, int mode, i += 4; } if (!SEEVALUE) { - p->cb_printf(" ]"); + rz_strbuf_append(outbuf, " ]"); } } } else if (MUSTSEEJSON) { if (size == -1) { - p->cb_printf("%" PFMT64d, addr); + rz_strbuf_appendf(outbuf, "%" PFMT64d, addr); } else { - p->cb_printf("[ "); + rz_strbuf_append(outbuf, "[ "); while (size--) { updateAddr(buf, i, endian, &addr, NULL); if (elem == -1 || elem == 0) { - p->cb_printf("%" PFMT64d, addr); + rz_strbuf_appendf(outbuf, "%" PFMT64d, addr); if (elem == 0) { elem = -2; } } if (size != 0 && elem == -1) { - p->cb_printf(", "); + rz_strbuf_append(outbuf, ", "); } if (elem > -1) { elem--; } i += 4; } - p->cb_printf(" ]"); + rz_strbuf_append(outbuf, " ]"); } - p->cb_printf("}"); + rz_strbuf_append(outbuf, "}"); } } -static void rz_print_format_hexflag(const RzPrint *p, int endian, int mode, +static void rz_type_format_hexflag(RzStrBuf *outbuf, int endian, int mode, const char *setval, ut64 seeki, ut8 *buf, int i, int size) { ut64 addr = 0; int elem = -1; @@ -834,34 +833,34 @@ static void rz_print_format_hexflag(const RzPrint *p, int endian, int mode, } updateAddr(buf + i, size - i, endian, &addr, NULL); if (MUSTSET) { - p->cb_printf("wv4 %s @ 0x%08" PFMT64x "\n", setval, seeki + ((elem >= 0) ? elem * 4 : 0)); + rz_strbuf_appendf(outbuf, "wv4 %s @ 0x%08" PFMT64x "\n", setval, seeki + ((elem >= 0) ? elem * 4 : 0)); } else if ((mode & RZ_PRINT_DOT) || MUSTSEESTRUCT) { - p->cb_printf("0x%08" PFMT64x, addr & UT32_MAX); + rz_strbuf_appendf(outbuf, "0x%08" PFMT64x, addr & UT32_MAX); } else if (MUSTSEE) { ut32 addr32 = (ut32)addr; if (!SEEVALUE && !ISQUIET) { - p->cb_printf("0x%08" PFMT64x " = ", seeki + ((elem >= 0) ? elem * 4 : 0)); + rz_strbuf_appendf(outbuf, "0x%08" PFMT64x " = ", seeki + ((elem >= 0) ? elem * 4 : 0)); } if (size == -1) { if (ISQUIET && (addr32 == UT32_MAX)) { - p->cb_printf("-1"); + rz_strbuf_append(outbuf, "-1"); } else { - p->cb_printf("0x%08" PFMT64x, (ut64)addr32); + rz_strbuf_appendf(outbuf, "0x%08" PFMT64x, (ut64)addr32); } } else { if (!SEEVALUE) { - p->cb_printf("[ "); + rz_strbuf_append(outbuf, "[ "); } while (size--) { updateAddr(buf + i, size - i, endian, &addr, NULL); if (elem == -1 || elem == 0) { - p->cb_printf("0x%08" PFMT64x, addr); + rz_strbuf_appendf(outbuf, "0x%08" PFMT64x, addr); if (elem == 0) { elem = -2; } } if (size != 0 && elem == -1) { - p->cb_printf(", "); + rz_strbuf_append(outbuf, ", "); } if (elem > -1) { elem--; @@ -869,139 +868,130 @@ static void rz_print_format_hexflag(const RzPrint *p, int endian, int mode, i += 4; } if (!SEEVALUE) { - p->cb_printf(" ]"); + rz_strbuf_append(outbuf, " ]"); } } } else if (MUSTSEEJSON) { if (size == -1) { - p->cb_printf("%" PFMT64d, addr); + rz_strbuf_appendf(outbuf, "%" PFMT64d, addr); } else { - p->cb_printf("[ "); + rz_strbuf_append(outbuf, "[ "); while (size--) { updateAddr(buf + i, size - i, endian, &addr, NULL); if (elem == -1 || elem == 0) { - p->cb_printf("%" PFMT64d, addr); + rz_strbuf_appendf(outbuf, "%" PFMT64d, addr); if (elem == 0) { elem = -2; } } if (size != 0 && elem == -1) { - p->cb_printf(","); + rz_strbuf_append(outbuf, ","); } if (elem > -1) { elem--; } i += 4; } - p->cb_printf(" ]"); + rz_strbuf_append(outbuf, " ]"); } - p->cb_printf("}"); + rz_strbuf_append(outbuf, "}"); } } -static int rz_print_format_10bytes(const RzPrint *p, int mode, const char *setval, +static int rz_type_format_10bytes(RzType *t, RzStrBuf *outbuf, int mode, const char *setval, ut64 seeki, ut64 addr, ut8 *buf) { ut8 buffer[255]; int j; if (MUSTSET) { - p->cb_printf("?e pf B not yet implemented\n"); + rz_strbuf_append(outbuf, "?e pf B not yet implemented\n"); } else if (mode & RZ_PRINT_DOT) { for (j = 0; j < 10; j++) { - p->cb_printf("%02x ", buf[j]); + rz_strbuf_appendf(outbuf, "%02x ", buf[j]); } } else if (MUSTSEE) { - if (!p->iob.read_at) { - printf("(cannot read memory)\n"); - return -1; - } - p->iob.read_at(p->iob.io, (ut64)addr, buffer, 248); + t->iob.read_at(t->iob.io, (ut64)addr, buffer, 248); if (!SEEVALUE && !ISQUIET) { - p->cb_printf("0x%08" PFMT64x " = ", seeki); + rz_strbuf_appendf(outbuf, "0x%08" PFMT64x " = ", seeki); } for (j = 0; j < 10; j++) { - p->cb_printf("%02x ", buf[j]); + rz_strbuf_appendf(outbuf, "%02x ", buf[j]); } if (!SEEVALUE) { - p->cb_printf(" ... ("); + rz_strbuf_append(outbuf, " ... ("); } for (j = 0; j < 10; j++) { if (!SEEVALUE) { if (IS_PRINTABLE(buf[j])) { - p->cb_printf("%c", buf[j]); + rz_strbuf_appendf(outbuf, "%c", buf[j]); } else { - p->cb_printf("."); + rz_strbuf_append(outbuf, "."); } } } if (!SEEVALUE) { - p->cb_printf(")"); + rz_strbuf_append(outbuf, ")"); } } else if (MUSTSEEJSON) { - if (!p->iob.read_at) { - printf("(cannot read memory)\n"); - return -1; - } else { - p->iob.read_at(p->iob.io, (ut64)addr, buffer, 248); - } - p->cb_printf("[ %d", buf[0]); + t->iob.read_at(t->iob.io, (ut64)addr, buffer, 248); + rz_strbuf_appendf(outbuf, "[ %d", buf[0]); j = 1; for (; j < 10; j++) { - p->cb_printf(", %d", buf[j]); + rz_strbuf_appendf(outbuf, ", %d", buf[j]); } - p->cb_printf("]"); + rz_strbuf_append(outbuf, "]"); return 0; } return 0; } -static int rz_print_format_hexpairs(const RzPrint *p, int endian, int mode, +static int rz_type_format_hexpairs(RzStrBuf *outbuf, int endian, int mode, const char *setval, ut64 seeki, ut8 *buf, int i, int size) { int j; size = (size == -1) ? 1 : size; if (MUSTSET) { - p->cb_printf("?e pf X not yet implemented\n"); + rz_strbuf_append(outbuf, "?e pf X not yet implemented\n"); } else if (mode & RZ_PRINT_DOT) { for (j = 0; j < size; j++) { - p->cb_printf("%02x", buf[i + j]); + rz_strbuf_appendf(outbuf, "%02x", buf[i + j]); } } else if (MUSTSEE) { size = (size < 1) ? 1 : size; if (!SEEVALUE && !ISQUIET) { - p->cb_printf("0x%08" PFMT64x " = ", seeki); + rz_strbuf_appendf(outbuf, "0x%08" PFMT64x " = ", seeki); } for (j = 0; j < size; j++) { - p->cb_printf("%02x ", buf[i + j]); + rz_strbuf_appendf(outbuf, "%02x ", buf[i + j]); } if (!SEEVALUE) { - p->cb_printf(" ... ("); + rz_strbuf_append(outbuf, " ... ("); } for (j = 0; j < size; j++) { if (!SEEVALUE) { if (IS_PRINTABLE(buf[j])) { - p->cb_printf("%c", buf[i + j]); + rz_strbuf_appendf(outbuf, "%c", buf[i + j]); } else { - p->cb_printf("."); + rz_strbuf_append(outbuf, "."); } } } - p->cb_printf(")"); + rz_strbuf_append(outbuf, ")"); } else if (MUSTSEEJSON || MUSTSEESTRUCT) { size = (size < 1) ? 1 : size; - p->cb_printf("[ %d", buf[0]); + rz_strbuf_appendf(outbuf, "[ %d", buf[0]); j = 1; for (; j < 10; j++) { - p->cb_printf(", %d", buf[j]); + rz_strbuf_appendf(outbuf, ", %d", buf[j]); } - p->cb_printf("]"); + rz_strbuf_append(outbuf, "]"); if (MUSTSEEJSON) { - p->cb_printf("}"); + rz_strbuf_append(outbuf, "}"); } return size; } return size; } -static void rz_print_format_float(const RzPrint *p, int endian, int mode, +static void rz_type_format_float(RzStrBuf *outbuf, int endian, int mode, const char *setval, ut64 seeki, ut8 *buf, int i, int size) { float val_f = 0.0f; ut64 addr = 0; @@ -1012,33 +1002,33 @@ static void rz_print_format_float(const RzPrint *p, int endian, int mode, } val_f = updateAddr(buf + i, 999, endian, &addr, NULL); if (MUSTSET) { - p->cb_printf("wv4 %s @ 0x%08" PFMT64x "\n", setval, + rz_strbuf_appendf(outbuf, "wv4 %s @ 0x%08" PFMT64x "\n", setval, seeki + ((elem >= 0) ? elem * 4 : 0)); } else if ((mode & RZ_PRINT_DOT) || MUSTSEESTRUCT) { - p->cb_printf("%.9g", val_f); + rz_strbuf_appendf(outbuf, "%.9g", val_f); } else { if (MUSTSEE) { if (!SEEVALUE && !ISQUIET) { - p->cb_printf("0x%08" PFMT64x " = ", + rz_strbuf_appendf(outbuf, "0x%08" PFMT64x " = ", seeki + ((elem >= 0) ? elem * 4 : 0)); } } if (size == -1) { - p->cb_printf("%.9g", val_f); + rz_strbuf_appendf(outbuf, "%.9g", val_f); } else { if (!SEEVALUE) { - p->cb_printf("[ "); + rz_strbuf_append(outbuf, "[ "); } while (size--) { val_f = updateAddr(buf + i, 9999, endian, &addr, NULL); if (elem == -1 || elem == 0) { - p->cb_printf("%.9g", val_f); + rz_strbuf_appendf(outbuf, "%.9g", val_f); if (elem == 0) { elem = -2; } } if (size != 0 && elem == -1) { - p->cb_printf(", "); + rz_strbuf_append(outbuf, ", "); } if (elem > -1) { elem--; @@ -1046,16 +1036,16 @@ static void rz_print_format_float(const RzPrint *p, int endian, int mode, i += 4; } if (!SEEVALUE) { - p->cb_printf(" ]"); + rz_strbuf_append(outbuf, " ]"); } } if (MUSTSEEJSON) { - p->cb_printf("}"); + rz_strbuf_append(outbuf, "}"); } } } -static void rz_print_format_double(const RzPrint *p, int endian, int mode, +static void rz_type_format_double(RzStrBuf *outbuf, int endian, int mode, const char *setval, ut64 seeki, ut8 *buf, int i, int size) { double val_f = 0.0; ut64 addr = 0; @@ -1067,35 +1057,35 @@ static void rz_print_format_double(const RzPrint *p, int endian, int mode, updateAddr(buf + i, 999, endian, &addr, NULL); rz_mem_swaporcopy((ut8 *)&val_f, buf + i, sizeof(double), endian); if (MUSTSET) { - p->cb_printf("wv8 %s @ 0x%08" PFMT64x "\n", setval, + rz_strbuf_appendf(outbuf, "wv8 %s @ 0x%08" PFMT64x "\n", setval, seeki + ((elem >= 0) ? elem * 8 : 0)); } else if ((mode & RZ_PRINT_DOT) || MUSTSEESTRUCT) { - p->cb_printf("%.17g", val_f); + rz_strbuf_appendf(outbuf, "%.17g", val_f); } else { if (MUSTSEE) { if (!SEEVALUE && !ISQUIET) { - p->cb_printf("0x%08" PFMT64x " = ", + rz_strbuf_appendf(outbuf, "0x%08" PFMT64x " = ", seeki + ((elem >= 0) ? elem * 8 : 0)); } } if (size == -1) { - p->cb_printf("%.17g", val_f); + rz_strbuf_appendf(outbuf, "%.17g", val_f); } else { if (!SEEVALUE) { - p->cb_printf("[ "); + rz_strbuf_append(outbuf, "[ "); } while (size--) { // XXX this 999 is scary updateAddr(buf + i, 9999, endian, &addr, NULL); rz_mem_swaporcopy((ut8 *)&val_f, buf + i, sizeof(double), endian); if (elem == -1 || elem == 0) { - p->cb_printf("%.17g", val_f); + rz_strbuf_appendf(outbuf, "%.17g", val_f); if (elem == 0) { elem = -2; } } if (size != 0 && elem == -1) { - p->cb_printf(", "); + rz_strbuf_append(outbuf, ", "); } if (elem > -1) { elem--; @@ -1103,16 +1093,16 @@ static void rz_print_format_double(const RzPrint *p, int endian, int mode, i += 8; } if (!SEEVALUE) { - p->cb_printf(" ]"); + rz_strbuf_append(outbuf, " ]"); } } if (MUSTSEEJSON) { - p->cb_printf("}"); + rz_strbuf_appendf(outbuf, "}"); } } } -static void rz_print_format_word(const RzPrint *p, int endian, int mode, +static void rz_type_format_word(RzStrBuf *outbuf, int endian, int mode, const char *setval, ut64 seeki, ut8 *buf, int i, int size) { ut64 addr; int elem = -1; @@ -1124,23 +1114,23 @@ static void rz_print_format_word(const RzPrint *p, int endian, int mode, ? (*(buf + i)) << 8 | (*(buf + i + 1)) : (*(buf + i + 1)) << 8 | (*(buf + i)); if (MUSTSET) { - p->cb_printf("wv2 %s @ 0x%08" PFMT64x "\n", setval, seeki + ((elem >= 0) ? elem * 2 : 0)); + rz_strbuf_appendf(outbuf, "wv2 %s @ 0x%08" PFMT64x "\n", setval, seeki + ((elem >= 0) ? elem * 2 : 0)); } else if ((mode & RZ_PRINT_DOT) || MUSTSEESTRUCT) { if (size == -1) { - p->cb_printf("0x%04" PFMT64x, addr); + rz_strbuf_appendf(outbuf, "0x%04" PFMT64x, addr); } while ((size -= 2) > 0) { addr = endian ? (*(buf + i)) << 8 | (*(buf + i + 1)) : (*(buf + i + 1)) << 8 | (*(buf + i)); if (elem == -1 || elem == 0) { - p->cb_printf("%" PFMT64d, addr); + rz_strbuf_appendf(outbuf, "%" PFMT64d, addr); if (elem == 0) { elem = -2; } } if (size != 0 && elem == -1) { - p->cb_printf(","); + rz_strbuf_append(outbuf, ","); } if (elem > -1) { elem--; @@ -1149,26 +1139,26 @@ static void rz_print_format_word(const RzPrint *p, int endian, int mode, } } else if (MUSTSEE) { if (!SEEVALUE && !ISQUIET) { - p->cb_printf("0x%08" PFMT64x " = ", seeki + ((elem >= 0) ? elem * 2 : 0)); + rz_strbuf_appendf(outbuf, "0x%08" PFMT64x " = ", seeki + ((elem >= 0) ? elem * 2 : 0)); } if (size == -1) { - p->cb_printf("0x%04" PFMT64x, addr); + rz_strbuf_appendf(outbuf, "0x%04" PFMT64x, addr); } else { if (!SEEVALUE) { - p->cb_printf("[ "); + rz_strbuf_append(outbuf, "[ "); } while (size--) { addr = endian ? (*(buf + i)) << 8 | (*(buf + i + 1)) : (*(buf + i + 1)) << 8 | (*(buf + i)); if (elem == -1 || elem == 0) { - p->cb_printf("0x%04" PFMT64x, addr); + rz_strbuf_appendf(outbuf, "0x%04" PFMT64x, addr); if (elem == 0) { elem = -2; } } if (size != 0 && elem == -1) { - p->cb_printf(", "); + rz_strbuf_append(outbuf, ", "); } if (elem > -1) { elem--; @@ -1176,63 +1166,63 @@ static void rz_print_format_word(const RzPrint *p, int endian, int mode, i += 2; } if (!SEEVALUE) { - p->cb_printf(" ]"); + rz_strbuf_append(outbuf, " ]"); } } } else if (MUSTSEEJSON) { if (size == -1) { - p->cb_printf("%" PFMT64d, addr); + rz_strbuf_appendf(outbuf, "%" PFMT64d, addr); } else { - p->cb_printf("[ "); + rz_strbuf_append(outbuf, "[ "); while ((size -= 2) > 0) { addr = endian ? (*(buf + i)) << 8 | (*(buf + i + 1)) : (*(buf + i + 1)) << 8 | (*(buf + i)); if (elem == -1 || elem == 0) { - p->cb_printf("%" PFMT64d, addr); + rz_strbuf_appendf(outbuf, "%" PFMT64d, addr); if (elem == 0) { elem = -2; } } if (size != 0 && elem == -1) { - p->cb_printf(","); + rz_strbuf_append(outbuf, ","); } if (elem > -1) { elem--; } i += 2; } - p->cb_printf(" ]"); + rz_strbuf_append(outbuf, " ]"); } - p->cb_printf("}"); + rz_strbuf_append(outbuf, "}"); } } -static void rz_print_byte_escape(const RzPrint *p, const char *src, char **dst, int dot_nl) { +static void rz_type_byte_escape(const RzPrint *p, const char *src, char **dst, int dot_nl) { rz_return_if_fail(p->strconv_mode); rz_str_byte_escape(src, dst, dot_nl, !strcmp(p->strconv_mode, "asciidot"), p->esc_bslash); } -static void rz_print_format_nulltermstring(const RzPrint *p, int len, int endian, int mode, +static void rz_type_format_nulltermstring(RzType *t, RzPrint *p, RzStrBuf *outbuf, int len, int endian, int mode, const char *setval, ut64 seeki, ut8 *buf, int i, int size) { - if (!p->iob.is_valid_offset(p->iob.io, seeki, 1)) { + if (!t->iob.is_valid_offset(t->iob.io, seeki, 1)) { ut8 ch = 0xff; // XXX there are some cases where the memory is there but is_valid_offset fails - if (p->iob.read_at(p->iob.io, seeki, &ch, 1) != 1 && ch != 0xff) { - p->cb_printf("-1"); + if (t->iob.read_at(t->iob.io, seeki, &ch, 1) != 1 && ch != 0xff) { + rz_strbuf_append(outbuf, "-1"); return; } } - if (p->flags & RZ_PRINT_FLAGS_UNALLOC && !(p->iob.io->cached & RZ_PERM_R)) { + if (p->flags & RZ_PRINT_FLAGS_UNALLOC && !(t->iob.io->cached & RZ_PERM_R)) { ut64 total_map_left = 0; ut64 addr = seeki; RzIOMap *map; - while (total_map_left < len && (map = p->iob.io->va ? p->iob.map_get(p->iob.io, addr) : p->iob.map_get_paddr(p->iob.io, addr)) && map->perm & RZ_PERM_R) { + while (total_map_left < len && (map = t->iob.io->va ? t->iob.map_get(t->iob.io, addr) : t->iob.map_get_paddr(t->iob.io, addr)) && map->perm & RZ_PERM_R) { if (!map->itv.size) { total_map_left = addr == 0 ? UT64_MAX : UT64_MAX - addr + 1; break; } - total_map_left += map->itv.size - (addr - (p->iob.io->va ? map->itv.addr : map->delta)); + total_map_left += map->itv.size - (addr - (t->iob.io->va ? map->itv.addr : map->delta)); addr += total_map_left; } if (total_map_left < len) { @@ -1253,62 +1243,62 @@ static void rz_print_format_nulltermstring(const RzPrint *p, int len, int endian if (vallen > buflen) { eprintf("Warning: new string is longer than previous one\n"); } - p->cb_printf("wx "); + rz_strbuf_append(outbuf, "wx "); for (i = 0; i < vallen; i++) { if (i < vallen - 3 && newstring[i] == '\\' && newstring[i + 1] == 'x') { - p->cb_printf("%c%c", newstring[i + 2], newstring[i + 3]); + rz_strbuf_appendf(outbuf, "%c%c", newstring[i + 2], newstring[i + 3]); i += 3; } else { - p->cb_printf("%2x", newstring[i]); + rz_strbuf_appendf(outbuf, "%2x", newstring[i]); } } - p->cb_printf(" @ 0x%08" PFMT64x "\n", seeki); + rz_strbuf_appendf(outbuf, " @ 0x%08" PFMT64x "\n", seeki); free(ons); } else if ((mode & RZ_PRINT_DOT) || MUSTSEESTRUCT) { int j = i; - (MUSTSEESTRUCT) ? p->cb_printf("\"") : p->cb_printf("\\\""); + (MUSTSEESTRUCT) ? rz_strbuf_append(outbuf, "\"") : rz_strbuf_append(outbuf, "\\\""); for (; j < len && ((size == -1 || size-- > 0) && buf[j]); j++) { char ch = buf[j]; if (ch == '"') { - p->cb_printf("\\\""); + rz_strbuf_append(outbuf, "\\\""); } else if (IS_PRINTABLE(ch)) { - p->cb_printf("%c", ch); + rz_strbuf_appendf(outbuf, "%c", ch); } else { - p->cb_printf("."); + rz_strbuf_append(outbuf, "."); } } - (MUSTSEESTRUCT) ? p->cb_printf("\"") : p->cb_printf("\\\""); + (MUSTSEESTRUCT) ? rz_strbuf_append(outbuf, "\"") : rz_strbuf_append(outbuf, "\\\""); } else if (MUSTSEE) { int j = i; if (!SEEVALUE && !ISQUIET) { - p->cb_printf("0x%08" PFMT64x " = %s", seeki, overflow ? "ovf " : ""); + rz_strbuf_appendf(outbuf, "0x%08" PFMT64x " = %s", seeki, overflow ? "ovf " : ""); } - p->cb_printf("\""); + rz_strbuf_append(outbuf, "\""); for (; j < len && ((size == -1 || size-- > 0) && buf[j]); j++) { char esc_str[5] = { 0 }; char *ptr = esc_str; - rz_print_byte_escape(p, (char *)&buf[j], &ptr, false); - p->cb_printf("%s", esc_str); + rz_type_byte_escape(p, (char *)&buf[j], &ptr, false); + rz_strbuf_appendf(outbuf, "%s", esc_str); } - p->cb_printf("\""); + rz_strbuf_append(outbuf, "\""); } else if (MUSTSEEJSON) { char *utf_encoded_buf = NULL; - p->cb_printf("\""); + rz_strbuf_append(outbuf, "\""); utf_encoded_buf = rz_str_escape_utf8_for_json( (char *)buf + i, size == -1 ? str_len : RZ_MIN(size, str_len)); if (utf_encoded_buf) { - p->cb_printf("%s", utf_encoded_buf); + rz_strbuf_appendf(outbuf, "%s", utf_encoded_buf); free(utf_encoded_buf); } - p->cb_printf("\""); + rz_strbuf_append(outbuf, "\""); if (overflow) { - p->cb_printf(",\"overflow\":true"); + rz_strbuf_append(outbuf, ",\"overflow\":true"); } - p->cb_printf("}"); + rz_strbuf_append(outbuf, "}"); } } -static void rz_print_format_nulltermwidestring(const RzPrint *p, const int len, int endian, int mode, +static void rz_type_format_nulltermwidestring(RzPrint *p, RzStrBuf *outbuf, const int len, int endian, int mode, const char *setval, ut64 seeki, ut8 *buf, int i, int size) { if (MUSTSET) { int vallen = strlen(setval); @@ -1322,91 +1312,91 @@ static void rz_print_format_nulltermwidestring(const RzPrint *p, const int len, if (vallen > rz_wstr_clen((char *)(buf + seeki))) { eprintf("Warning: new string is longer than previous one\n"); } - p->cb_printf("ww %s @ 0x%08" PFMT64x "\n", newstring, seeki); + rz_strbuf_appendf(outbuf, "ww %s @ 0x%08" PFMT64x "\n", newstring, seeki); free(ons); } else if (MUSTSEE) { int j = i; if (!SEEVALUE && !ISQUIET) { - p->cb_printf("0x%08" PFMT64x " = ", seeki); + rz_strbuf_appendf(outbuf, "0x%08" PFMT64x " = ", seeki); } for (; j < len && ((size == -1 || size-- > 0) && buf[j]); j += 2) { if (IS_PRINTABLE(buf[j])) { - p->cb_printf("%c", buf[j]); + rz_strbuf_appendf(outbuf, "%c", buf[j]); } else { - p->cb_printf("."); + rz_strbuf_append(outbuf, "."); } } } else if (MUSTSEEJSON) { int j = i; - p->cb_printf("%" PFMT64d ",\"string\":\"", seeki); + rz_strbuf_appendf(outbuf, "%" PFMT64d ",\"string\":\"", seeki); for (; j < len && ((size == -1 || size-- > 0) && buf[j]); j += 2) { if (IS_PRINTABLE(buf[j])) { - p->cb_printf("%c", buf[j]); + rz_strbuf_appendf(outbuf, "%c", buf[j]); } else { - p->cb_printf("."); + rz_strbuf_append(outbuf, "."); } } - p->cb_printf("\"}"); + rz_strbuf_append(outbuf, "\"}"); } } -static void rz_print_format_bitfield(const RzPrint *p, ut64 seeki, char *fmtname, +static void rz_type_format_bitfield(RzType *t, RzStrBuf *outbuf, ut64 seeki, char *fmtname, char *fieldname, ut64 addr, int mode, int size) { char *bitfield = NULL; addr &= (1ULL << (size * 8)) - 1; if (MUSTSEE && !SEEVALUE) { - p->cb_printf("0x%08" PFMT64x " = ", seeki); + rz_strbuf_appendf(outbuf, "0x%08" PFMT64x " = ", seeki); } - bitfield = rz_type_enum_getbitfield(p->sdb_types, fmtname, addr); + bitfield = rz_type_enum_getbitfield(t, fmtname, addr); if (bitfield && *bitfield) { if (MUSTSEEJSON) { - p->cb_printf("\"%s\"}", bitfield); + rz_strbuf_appendf(outbuf, "\"%s\"}", bitfield); } else if (MUSTSEE) { - p->cb_printf("%s (bitfield) = %s\n", fieldname, bitfield); + rz_strbuf_appendf(outbuf, "%s (bitfield) = %s\n", fieldname, bitfield); } } else { if (MUSTSEEJSON) { - p->cb_printf("\"`tb %s 0x%" PFMT64x "`\"}", fmtname, addr); + rz_strbuf_appendf(outbuf, "\"`tb %s 0x%" PFMT64x "`\"}", fmtname, addr); } else if (MUSTSEE) { - p->cb_printf("%s (bitfield) = `tb %s 0x%" PFMT64x "`\n", + rz_strbuf_appendf(outbuf, "%s (bitfield) = `tb %s 0x%" PFMT64x "`\n", fieldname, fmtname, addr); } } free(bitfield); } -static void rz_print_format_enum(const RzPrint *p, ut64 seeki, char *fmtname, +static void rz_type_format_enum(RzType *t, RzStrBuf *outbuf, ut64 seeki, char *fmtname, char *fieldname, ut64 addr, int mode, int size) { char *enumvalue = NULL; addr &= (1ULL << (size * 8)) - 1; if (MUSTSEE && !SEEVALUE) { - p->cb_printf("0x%08" PFMT64x " = ", seeki); + rz_strbuf_appendf(outbuf, "0x%08" PFMT64x " = ", seeki); } - enumvalue = rz_type_enum_member(p->sdb_types, fmtname, NULL, addr); + enumvalue = rz_type_enum_member(t, fmtname, NULL, addr); if (enumvalue && *enumvalue) { if (mode & RZ_PRINT_DOT) { - p->cb_printf("%s.%s", fmtname, enumvalue); + rz_strbuf_appendf(outbuf, "%s.%s", fmtname, enumvalue); } else if (MUSTSEEJSON) { - p->cb_printf("%" PFMT64d ",\"label\":\"%s\",\"enum\":\"%s\"}", + rz_strbuf_appendf(outbuf, "%" PFMT64d ",\"label\":\"%s\",\"enum\":\"%s\"}", addr, enumvalue, fmtname); } else if (MUSTSEE) { - p->cb_printf("%s (enum %s) = 0x%" PFMT64x " ; %s\n", + rz_strbuf_appendf(outbuf, "%s (enum %s) = 0x%" PFMT64x " ; %s\n", fieldname, fmtname, addr, enumvalue); } else if (MUSTSEESTRUCT) { - p->cb_printf("%s", enumvalue); + rz_strbuf_appendf(outbuf, "%s", enumvalue); } } else { if (MUSTSEEJSON) { - p->cb_printf("%" PFMT64d ",\"enum\":\"%s\"}", addr, fmtname); + rz_strbuf_appendf(outbuf, "%" PFMT64d ",\"enum\":\"%s\"}", addr, fmtname); } else if (MUSTSEE) { - p->cb_printf("%s (enum %s) = 0x%" PFMT64x "\n", //`te %s 0x%x`\n", + rz_strbuf_appendf(outbuf, "%s (enum %s) = 0x%" PFMT64x "\n", //`te %s 0x%x`\n", fieldname, fmtname, addr); //enumvalue); //fmtname, addr); } } free(enumvalue); } -static void rz_print_format_register(const RzPrint *p, int mode, +static void rz_print_format_register(RzStrBuf *outbuf, const RzPrint *p, int mode, const char *name, const char *setval) { if (!p || !p->get_register || !p->reg) { return; @@ -1414,38 +1404,38 @@ static void rz_print_format_register(const RzPrint *p, int mode, RzRegItem *ri = p->get_register(p->reg, name, RZ_REG_TYPE_ALL); if (ri) { if (MUSTSET) { - p->cb_printf("dr %s=%s\n", name, setval); + rz_strbuf_appendf(outbuf, "dr %s=%s\n", name, setval); } else if (MUSTSEE) { if (!SEEVALUE) { - p->cb_printf("%s : 0x%08" PFMT64x "\n", ri->name, p->get_register_value(p->reg, ri)); + rz_strbuf_appendf(outbuf, "%s : 0x%08" PFMT64x "\n", ri->name, p->get_register_value(p->reg, ri)); } else { - p->cb_printf("0x%08" PFMT64x "\n", p->get_register_value(p->reg, ri)); + rz_strbuf_appendf(outbuf, "0x%08" PFMT64x "\n", p->get_register_value(p->reg, ri)); } } else if (MUSTSEEJSON) { - p->cb_printf("%" PFMT64d "}", p->get_register_value(p->reg, ri)); + rz_strbuf_appendf(outbuf, "%" PFMT64d "}", p->get_register_value(p->reg, ri)); } } else { - p->cb_printf("Register %s does not exists\n", name); + rz_strbuf_appendf(outbuf, "Register %s does not exists\n", name); } } -static void rz_print_format_num_specifier(const RzPrint *p, ut64 addr, int bytes, int sign) { +static void rz_type_format_num_specifier(RzStrBuf *outbuf, ut64 addr, int bytes, int sign) { #define EXT(T) (sign ? (signed T)(addr) : (unsigned T)(addr)) const char *fs64 = sign ? "%" PFMT64d : "%" PFMT64u; const char *fs = sign ? "%d" : "%u"; if (bytes == 1) { - p->cb_printf(fs, EXT(char)); + rz_strbuf_appendf(outbuf, fs, EXT(char)); } else if (bytes == 2) { - p->cb_printf(fs, EXT(short)); + rz_strbuf_appendf(outbuf, fs, EXT(short)); } else if (bytes == 4) { - p->cb_printf(fs, EXT(int)); //XXX: int is not necessarily 4 bytes I guess. + rz_strbuf_appendf(outbuf, fs, EXT(int)); //XXX: int is not necessarily 4 bytes I guess. } else if (bytes == 8) { - p->cb_printf(fs64, addr); + rz_strbuf_appendf(outbuf, fs64, addr); } #undef EXT } -static void rz_print_format_num(const RzPrint *p, int endian, int mode, const char *setval, ut64 seeki, ut8 *buf, int i, int bytes, int sign, int size) { +static void rz_type_format_num(RzStrBuf *outbuf, int endian, int mode, const char *setval, ut64 seeki, ut8 *buf, int i, int bytes, int sign, int size) { ut64 addr = 0LL; int elem = -1; if (size >= ARRAYINDEX_COEF) { @@ -1458,18 +1448,18 @@ static void rz_print_format_num(const RzPrint *p, int endian, int mode, const ch updateAddr(buf + i, size - i, endian, &addr, NULL); } if (MUSTSET) { - p->cb_printf("wv%d %s @ 0x%08" PFMT64x "\n", bytes, setval, seeki + ((elem >= 0) ? elem * (bytes) : 0)); + rz_strbuf_appendf(outbuf, "wv%d %s @ 0x%08" PFMT64x "\n", bytes, setval, seeki + ((elem >= 0) ? elem * (bytes) : 0)); } else if ((mode & RZ_PRINT_DOT) || MUSTSEESTRUCT) { - rz_print_format_num_specifier(p, addr, bytes, sign); + rz_type_format_num_specifier(outbuf, addr, bytes, sign); } else if (MUSTSEE) { if (!SEEVALUE && !ISQUIET) { - p->cb_printf("0x%08" PFMT64x " = ", seeki + ((elem >= 0) ? elem * bytes : 0)); + rz_strbuf_appendf(outbuf, "0x%08" PFMT64x " = ", seeki + ((elem >= 0) ? elem * bytes : 0)); } if (size == -1) { - rz_print_format_num_specifier(p, addr, bytes, sign); + rz_type_format_num_specifier(outbuf, addr, bytes, sign); } else { if (!SEEVALUE) { - p->cb_printf("[ "); + rz_strbuf_append(outbuf, "[ "); } while (size--) { if (bytes == 8) { @@ -1478,13 +1468,13 @@ static void rz_print_format_num(const RzPrint *p, int endian, int mode, const ch updateAddr(buf + i, size - i, endian, &addr, NULL); } if (elem == -1 || elem == 0) { - rz_print_format_num_specifier(p, addr, bytes, sign); + rz_type_format_num_specifier(outbuf, addr, bytes, sign); if (elem == 0) { elem = -2; } } if (size != 0 && elem == -1) { - p->cb_printf(", "); + rz_strbuf_append(outbuf, ", "); } if (elem > -1) { elem--; @@ -1492,14 +1482,14 @@ static void rz_print_format_num(const RzPrint *p, int endian, int mode, const ch i += bytes; } if (!SEEVALUE) { - p->cb_printf(" ]"); + rz_strbuf_append(outbuf, " ]"); } } } else if (MUSTSEEJSON) { if (size == -1) { - rz_print_format_num_specifier(p, addr, bytes, sign); + rz_type_format_num_specifier(outbuf, addr, bytes, sign); } else { - p->cb_printf("[ "); + rz_strbuf_append(outbuf, "[ "); while (size--) { if (bytes == 8) { updateAddr(buf + i, size, endian, NULL, &addr); @@ -1507,27 +1497,27 @@ static void rz_print_format_num(const RzPrint *p, int endian, int mode, const ch updateAddr(buf + i, size, endian, &addr, NULL); } if (elem == -1 || elem == 0) { - rz_print_format_num_specifier(p, addr, bytes, sign); + rz_type_format_num_specifier(outbuf, addr, bytes, sign); if (elem == 0) { elem = -2; } } if (size != 0 && elem == -1) { - p->cb_printf(", "); + rz_strbuf_append(outbuf, ", "); } if (elem > -1) { elem--; } i += bytes; } - p->cb_printf(" ]"); + rz_strbuf_append(outbuf, " ]"); } - p->cb_printf("}"); + rz_strbuf_append(outbuf, "}"); } } -RZ_API const char *rz_type_format_byname(RzPrint *p, const char *name) { - return sdb_const_get(p->formats, name, NULL); +RZ_API const char *rz_type_format_byname(RzType *t, const char *name) { + return sdb_const_get(t->formats, name, NULL); } static char *fmt_struct_union(Sdb *TDB, char *var, bool is_typedef) { @@ -1613,7 +1603,7 @@ static char *fmt_struct_union(Sdb *TDB, char *var, bool is_typedef) { RZ_API char *rz_type_format(RzType *type, const char *t) { char var[130], var2[132]; - Sdb *TDB = type->sdb_types + Sdb *TDB = type->sdb_types; const char *kind = sdb_const_get(TDB, t, NULL); if (!kind) { return NULL; @@ -1640,7 +1630,7 @@ RZ_API char *rz_type_format(RzType *type, const char *t) { } // XXX: this is somewhat incomplete. must be updated to handle all format chars -RZ_API int rz_type_format_struct_size(RzPrint *p, const char *f, int mode, int n) { +RZ_API int rz_type_format_struct_size(RzType *t, const char *f, int mode, int n) { char *end, *args, *fmt; int size = 0, tabsize = 0, i, idx = 0, biggest = 0, fmt_len = 0, times = 1; bool tabsize_set = false; @@ -1650,7 +1640,7 @@ RZ_API int rz_type_format_struct_size(RzPrint *p, const char *f, int mode, int n if (n >= 5) { // This is the nesting level, is this not a bit arbitrary?! return 0; } - const char *fmt2 = sdb_get(p->formats, f, NULL); + const char *fmt2 = sdb_get(t->formats, f, NULL); if (!fmt2) { fmt2 = f; } @@ -1745,7 +1735,7 @@ RZ_API int rz_type_format_struct_size(RzPrint *p, const char *f, int mode, int n size += tabsize; break; case '*': - size += tabsize * (p->bits / 8); + size += tabsize * (t->target->bits / 8); i++; idx--; //no need to go ahead for args break; @@ -1792,14 +1782,14 @@ RZ_API int rz_type_format_struct_size(RzPrint *p, const char *f, int mode, int n tmp = *format; } } else { - format = sdb_get(p->formats, structname + 1, NULL); + format = sdb_get(t->formats, structname + 1, NULL); if (format && !strncmp(format, f, strlen(format) - 1)) { // Avoid recursion here free(o); free(structname); return -1; } if (!format) { // Fetch format from types db - format = rz_type_format(p->sdb_types, structname + 1); + format = rz_type_format(t, structname + 1); } } if (!format) { @@ -1808,7 +1798,7 @@ RZ_API int rz_type_format_struct_size(RzPrint *p, const char *f, int mode, int n free(o); return 0; } - int newsize = rz_print_format_struct_size(p, format, mode, n + 1); + int newsize = rz_type_format_struct_size(t, format, mode, n + 1); if (newsize < 1) { eprintf("Cannot find size for `%s'\n", format); free(structname); @@ -1848,7 +1838,7 @@ RZ_API int rz_type_format_struct_size(RzPrint *p, const char *f, int mode, int n } else if (fmt[i + 1] == '8') { size += tabsize * 8; } else { - size += tabsize * (p->bits / 8); + size += tabsize * (t->target->bits / 8); break; } i++; @@ -1895,7 +1885,7 @@ RZ_API int rz_type_format_struct_size(RzPrint *p, const char *f, int mode, int n return (mode & RZ_PRINT_UNIONMODE) ? biggest : size; } -static int rz_print_format_struct(RzPrint *p, ut64 seek, const ut8 *b, int len, const char *name, +static int rz_type_format_struct(RzType *t, RzPrint *p, RzStrBuf *outbuf, ut64 seek, const ut8 *b, int len, const char *name, int slide, int mode, const char *setval, char *field, int anon) { const char *fmt; char namefmt[128]; @@ -1907,9 +1897,9 @@ static int rz_print_format_struct(RzPrint *p, ut64 seek, const ut8 *b, int len, if (anon) { fmt = name; } else { - fmt = sdb_get(p->formats, name, NULL); + fmt = sdb_get(t->formats, name, NULL); if (!fmt) { // Fetch struct info from types DB - fmt = rz_type_format(p->sdb_types, name); + fmt = rz_type_format(t, name); } } if (!fmt || !*fmt) { @@ -1919,14 +1909,14 @@ static int rz_print_format_struct(RzPrint *p, ut64 seek, const ut8 *b, int len, if (MUSTSEE && !SEEVALUE) { snprintf(namefmt, sizeof(namefmt), "%%%ds", 10 + 6 * slide % STRUCTPTR); if (fmt[0] == '0') { - p->cb_printf(namefmt, "union"); + rz_strbuf_appendf(outbuf, namefmt, "union"); } else { - p->cb_printf(namefmt, "struct"); + rz_strbuf_appendf(outbuf, namefmt, "struct"); } - p->cb_printf("<%s>\n", name); + rz_strbuf_appendf(outbuf, "<%s>\n", name); } - rz_print_format(p, seek, b, len, fmt, mode, setval, field); - return rz_print_format_struct_size(p, fmt, mode, 0); + rz_type_format_data(t, p, seek, b, len, fmt, mode, setval, field); + return rz_type_format_struct_size(t, fmt, mode, 0); } static char *get_args_offset(const char *arg) { @@ -2013,10 +2003,40 @@ static char *get_format_type(const char fmt, const char arg) { #define MINUSONE ((void *)(size_t)-1) #define ISSTRUCT (tmp == '?' || (tmp == '*' && *(arg + 1) == '?')) -RZ_API int rz_print_format(RzPrint *p, ut64 seek, const ut8 *b, const int len, + +RZ_API const char *rz_type_db_format_get(RzTypeDB *typedb, const char *name) { + return sdb_get(typedb->formats, name, NULL); +} + +RZ_API void rz_type_db_format_set(RzTypeDB *typedb, const char *name, const char *fmt) { + sdb_set(typedb->formats, name, fmt, 0); +} + +RZ_API RZ_OWN RzList *rz_type_db_format_all(RzTypeDB *typedb) { + SdbListIter *iter; + SdbKv *kv; + RzList *fmtl = rz_list_newf(free); + SdbList *sdbls = sdb_foreach_list(typedb->formats, true); + ls_foreach (sdbls, iter, kv) { + char *fmt = rz_str_newf("%s %s", sdbkv_key(kv), sdbkv_value(kv)); + rz_list_append(fmtl, fmt); + } + return fmtl; +} + +RZ_API void rz_type_db_format_delete(RzTypeDB *typedb, const char *name) { + sdb_unset(typedb->formats, name, 0); +} + +RZ_API void rz_type_db_format_purge(RzTypeDB *typedb) { + sdb_free(typedb->formats); + typedb->formats = sdb_new0(); +} + +RZ_API char *rz_type_format_data(RzType *t, RzPrint *p, ut64 seek, const ut8 *b, const int len, const char *formatname, int mode, const char *setval, char *ofield) { int nargs, i, invalid, nexti, idx, times, otimes, endian, isptr = 0; - const int old_bits = p->bits; + const int old_bits = t->target->bits; char *args = NULL, *bracket, tmp, last = 0; ut64 addr = 0, addr64 = 0, seeki = 0; static int slide = 0, oldslide = 0, ident = 4; @@ -2032,7 +2052,7 @@ RZ_API int rz_print_format(RzPrint *p, ut64 seek, const ut8 *b, const int len, if (!formatname) { return 0; } - fmt = sdb_get(p->formats, formatname, NULL); + fmt = sdb_get(t->formats, formatname, NULL); if (!fmt) { fmt = formatname; } @@ -2050,6 +2070,8 @@ RZ_API int rz_print_format(RzPrint *p, ut64 seek, const ut8 *b, const int len, free(internal_format); return 0; } + RzStrBuf *outbuf = rz_strbuf_new(""); + // len+2 to save space for the null termination in wide strings ut8 *buf = calloc(1, len + 2); if (!buf) { @@ -2057,7 +2079,7 @@ RZ_API int rz_print_format(RzPrint *p, ut64 seek, const ut8 *b, const int len, return 0; } memcpy(buf, b, len); - endian = p->big_endian; + endian = t->target->big_endian; if (ofield && ofield != MINUSONE) { field = strdup(ofield); @@ -2117,17 +2139,17 @@ RZ_API int rz_print_format(RzPrint *p, ut64 seek, const ut8 *b, const int len, #define ISPOINTED ((slide % STRUCTFLAG) / STRUCTPTR <= (oldslide % STRUCTFLAG) / STRUCTPTR) #define ISNESTED ((slide % STRUCTPTR) <= (oldslide % STRUCTPTR)) if (mode == RZ_PRINT_JSON && slide == 0) { - p->cb_printf("["); + rz_strbuf_append(outbuf, "["); } if (mode == RZ_PRINT_STRUCT) { if (formatname && *formatname) { if (strchr(formatname, ' ')) { - p->cb_printf("struct {\n"); + rz_strbuf_append(outbuf, "struct {\n"); } else { - p->cb_printf("struct %s {\n", formatname); + rz_strbuf_appendf(outbuf, "struct %s {\n", formatname); } } else { - p->cb_printf("struct {\n"); + rz_strbuf_append(outbuf, "struct {\n"); } } if (mode && arg[0] == '0') { @@ -2147,8 +2169,8 @@ RZ_API int rz_print_format(RzPrint *p, ut64 seek, const ut8 *b, const int len, } else { fmtname = rz_str_newf("0x%" PFMT64x, seek); } - p->cb_printf("digraph g { graph [ rank=same; rankdir=LR; ];\n"); - p->cb_printf("root [ rank=1; shape=record\nlabel=\"%s", fmtname); + rz_strbuf_append(outbuf, "digraph g { graph [ rank=same; rankdir=LR; ];\n"); + rz_strbuf_appendf(outbuf, "root [ rank=1; shape=record\nlabel=\"%s", fmtname); } /* go format */ @@ -2162,11 +2184,11 @@ RZ_API int rz_print_format(RzPrint *p, ut64 seek, const ut8 *b, const int len, if (otimes > 1) { if (mode & RZ_PRINT_JSON) { if (otimes > times) { - p->cb_printf(","); + rz_strbuf_append(outbuf, ","); } - p->cb_printf("[{\"index\":%d,\"offset\":%" PFMT64d "},", otimes - times, seek + i); + rz_strbuf_appendf(outbuf, "[{\"index\":%d,\"offset\":%" PFMT64d "},", otimes - times, seek + i); } else if (mode) { - p->cb_printf("0x%08" PFMT64x " [%d] {\n", seek + i, otimes - times); + rz_strbuf_appendf(outbuf, "0x%08" PFMT64x " [%d] {\n", seek + i, otimes - times); } } arg = orig; @@ -2179,7 +2201,7 @@ RZ_API int rz_print_format(RzPrint *p, ut64 seek, const ut8 *b, const int len, seeki = seek + i; addr = 0LL; invalid = 0; - p->bits = old_bits; + t->target->bits = old_bits; if (arg[0] == '[') { char *end = strchr(arg, ']'); if (!end) { @@ -2187,13 +2209,13 @@ RZ_API int rz_print_format(RzPrint *p, ut64 seek, const ut8 *b, const int len, goto beach; } *end = '\0'; - size = rz_get_size(p->num, buf, endian, arg + 1); + size = rz_get_size(t->num, buf, endian, arg + 1); arg = end + 1; *end = ']'; } else { size = -1; } - int fs = rz_print_format_struct_size(p, arg, 0, idx); + int fs = rz_type_format_struct_size(t, arg, 0, idx); if (fs == -2) { i = -1; goto beach; @@ -2208,7 +2230,7 @@ RZ_API int rz_print_format(RzPrint *p, ut64 seek, const ut8 *b, const int len, } else { updateAddr(buf + i, len - i, endian, &addr, &addr64); } - if (p->bits == 64) { + if (t->target->bits == 64) { addr = addr64; } } else { @@ -2223,7 +2245,7 @@ RZ_API int rz_print_format(RzPrint *p, ut64 seek, const ut8 *b, const int len, } if (!(mode & RZ_PRINT_QUIET)) { if (mode & RZ_PRINT_MUSTSEE && otimes > 1) { - p->cb_printf(" "); + rz_strbuf_append(outbuf, " "); } } if (idx < nargs && tmp != 'e' && isptr == 0) { @@ -2277,7 +2299,7 @@ RZ_API int rz_print_format(RzPrint *p, ut64 seek, const ut8 *b, const int len, idx++; if (MUSTSEE && !SEEVALUE) { if (!ISQUIET) { - p->cb_printf(namefmt, fieldname); + rz_strbuf_appendf(outbuf, namefmt, fieldname); } } } @@ -2285,31 +2307,26 @@ RZ_API int rz_print_format(RzPrint *p, ut64 seek, const ut8 *b, const int len, feed_me_again: switch (isptr) { case PTRSEEK: { - nexti = i + (p->bits / 8); + nexti = i + (t->target->bits / 8); i = 0; if (tmp == '?') { seeki = addr; } memset(buf, '\0', len); if (MUSTSEE && !ISQUIET) { - p->cb_printf("(*0x%" PFMT64x ")", addr); + rz_strbuf_appendf(outbuf, "(*0x%" PFMT64x ")", addr); } isptr = (addr) ? PTRBACK : NULLPTR; - if (p->iob.read_at) { - p->iob.read_at(p->iob.io, (ut64)addr, buf, len - 4); - if (((i + 3) < len) || ((i + 7) < len)) { - // XXX this breaks pf *D - if (tmp != 'D') { - updateAddr(buf + i, len - i, endian, &addr, &addr64); - } - } else { - eprintf("Likely a heap buffer overflow.\n"); - goto beach; + t->iob.read_at(t->iob.io, (ut64)addr, buf, len - 4); + if (((i + 3) < len) || ((i + 7) < len)) { + // XXX this breaks pf *D + if (tmp != 'D') { + updateAddr(buf + i, len - i, endian, &addr, &addr64); } } else { eprintf("(cannot read at 0x%08" PFMT64x ", block: %s, blocksize: 0x%x)\n", addr, b, len); - p->cb_printf("\n"); + rz_strbuf_append(outbuf, "\n"); goto beach; } } break; @@ -2361,7 +2378,7 @@ RZ_API int rz_print_format(RzPrint *p, ut64 seek, const ut8 *b, const int len, tmp = 'q'; arg++; } else { //If pointer reference is not mentioned explicitly - switch (p->bits) { + switch (t->target->bits) { case 16: tmp = 'w'; break; case 32: tmp = 'x'; break; default: tmp = 'q'; break; @@ -2377,16 +2394,16 @@ RZ_API int rz_print_format(RzPrint *p, ut64 seek, const ut8 *b, const int len, newname = fieldname = rz_str_newf("pf.%" PFMT64u, seeki); } if (mode & RZ_PRINT_UNIONMODE) { - p->cb_printf("f %s=0x%08" PFMT64x "\n", formatname, seeki); + rz_strbuf_appendf(outbuf, "f %s=0x%08" PFMT64x "\n", formatname, seeki); goto beach; } else if (tmp == '?') { - p->cb_printf("f %s.%s_", fmtname, fieldname); + rz_strbuf_appendf(outbuf, "f %s.%s_", fmtname, fieldname); } else if (tmp == 'E') { - p->cb_printf("f %s=0x%08" PFMT64x "\n", fieldname, seeki); + rz_strbuf_appendf(outbuf, "f %s=0x%08" PFMT64x "\n", fieldname, seeki); } else if (slide / STRUCTFLAG > 0 && idx == 1) { - p->cb_printf("%s=0x%08" PFMT64x "\n", fieldname, seeki); + rz_strbuf_appendf(outbuf, "%s=0x%08" PFMT64x "\n", fieldname, seeki); } else { - p->cb_printf("f %s=0x%08" PFMT64x "\n", fieldname, seeki); + rz_strbuf_appendf(outbuf, "f %s=0x%08" PFMT64x "\n", fieldname, seeki); } if (newname) { RZ_FREE(newname); @@ -2397,10 +2414,10 @@ RZ_API int rz_print_format(RzPrint *p, ut64 seek, const ut8 *b, const int len, /* dot */ if (mode & RZ_PRINT_DOT) { if (fieldname) { - p->cb_printf("|{0x%" PFMT64x "|%c|%s|<%s>", + rz_strbuf_appendf(outbuf, "|{0x%" PFMT64x "|%c|%s|<%s>", seeki, tmp, fieldname, fieldname); } else { - p->cb_printf("|{0x%" PFMT64x "|%c|", + rz_strbuf_appendf(outbuf, "|{0x%" PFMT64x "|%c|", seeki, tmp); } } @@ -2411,40 +2428,40 @@ RZ_API int rz_print_format(RzPrint *p, ut64 seek, const ut8 *b, const int len, if (first) { first = 0; } else { - p->cb_printf(","); + rz_strbuf_append(outbuf, ","); } } else if (oldslide) { - p->cb_printf("]},"); + rz_strbuf_append(outbuf, "]},"); oldslide -= NESTEDSTRUCT; } if (fieldname) { - p->cb_printf("{\"name\":\"%s\",\"type\":\"", fieldname); + rz_strbuf_appendf(outbuf, "{\"name\":\"%s\",\"type\":\"", fieldname); } else { - p->cb_printf("{\"type\":\""); + rz_strbuf_append(outbuf, "{\"type\":\""); } if (ISSTRUCT) { - p->cb_printf("%s", fmtname); + rz_strbuf_appendf(outbuf, "%s", fmtname); } else { if (tmp == 'n' || tmp == 'N') { - p->cb_printf("%c%c", tmp, *(arg + 1)); + rz_strbuf_appendf(outbuf, "%c%c", tmp, *(arg + 1)); } else { - p->cb_printf("%c", tmp); + rz_strbuf_appendf(outbuf, "%c", tmp); } } if (isptr) { - p->cb_printf("*"); + rz_strbuf_append(outbuf, "*"); } - p->cb_printf("\",\"offset\":%" PFMT64d ",\"value\":", - isptr ? (seek + nexti - (p->bits / 8)) : seek + i); + rz_strbuf_appendf(outbuf, "\",\"offset\":%" PFMT64d ",\"value\":", + isptr ? (seek + nexti - (t->target->bits / 8)) : seek + i); } /* c struct */ if (MUSTSEESTRUCT) { char *type = get_format_type(tmp, (tmp == 'n' || tmp == 'N') ? arg[1] : 0); if (type) { - p->cb_printf("%*c%s %s; // ", ident, ' ', type, fieldname); + rz_strbuf_appendf(outbuf, "%*c%s %s; // ", ident, ' ', type, fieldname); } else { - p->cb_printf("%*cstruct %s {", ident, ' ', fieldname); + rz_strbuf_appendf(outbuf, "%*cstruct %s {", ident, ' ', fieldname); } free(type); } @@ -2453,9 +2470,9 @@ RZ_API int rz_print_format(RzPrint *p, ut64 seek, const ut8 *b, const int len, int oi = i; if (isptr == NULLPTR) { if (MUSTSEEJSON) { - p->cb_printf("\"NULL\"}"); + rz_strbuf_append(outbuf, "\"NULL\"}"); } else if (MUSTSEE) { - p->cb_printf(" NULL\n"); + rz_strbuf_append(outbuf, " NULL\n"); } isptr = PTRBACK; } else { @@ -2464,58 +2481,59 @@ RZ_API int rz_print_format(RzPrint *p, ut64 seek, const ut8 *b, const int len, // might go beyond its len and it's usually called in each of the following functions switch (tmp) { case 'u': - i += rz_print_format_uleb(p, endian, mode, setval, seeki, buf, i, size); + i += rz_type_format_uleb(outbuf, endian, mode, setval, seeki, buf, i, size); break; case 't': - rz_print_format_time(p, endian, mode, setval, seeki, buf, i, size); + rz_type_format_time(outbuf, endian, mode, setval, seeki, buf, i, size); i += (size == -1) ? 4 : 4 * size; break; case 'q': - rz_print_format_quadword(p, endian, mode, setval, seeki, buf, i, size); + rz_type_format_quadword(outbuf, endian, mode, setval, seeki, buf, i, size); i += (size == -1) ? 8 : 8 * size; break; case 'Q': - rz_print_format_u128(p, endian, mode, setval, seeki, buf, i, size); + rz_type_format_u128(outbuf, endian, mode, setval, seeki, buf, i, size); i += (size == -1) ? 16 : 16 * size; break; case 'b': - rz_print_format_byte(p, endian, mode, setval, seeki, buf, i, size); + rz_type_format_byte(outbuf, endian, mode, setval, seeki, buf, i, size); i += (size == -1) ? 1 : size; break; case 'C': - rz_print_format_decchar(p, endian, mode, setval, seeki, buf, i, size); + rz_type_format_decchar(outbuf, endian, mode, setval, seeki, buf, i, size); i += (size == -1) ? 1 : size; break; case 'c': - rz_print_format_char(p, endian, mode, setval, seeki, buf, i, size); + rz_type_format_char(outbuf, endian, mode, setval, seeki, buf, i, size); i += (size == -1) ? 1 : size; break; case 'X': - size = rz_print_format_hexpairs(p, endian, mode, setval, seeki, buf, i, size); + size = rz_type_format_hexpairs(outbuf, endian, mode, setval, seeki, buf, i, size); i += size; break; case 'T': - if (rz_print_format_10bytes(p, mode, + if (rz_type_format_10bytes(typedb, outbuf, mode, setval, seeki, addr, buf) == 0) { i += (size == -1) ? 4 : 4 * size; } break; case 'f': - rz_print_format_float(p, endian, mode, setval, seeki, buf, i, size); + rz_type_format_float(outbuf, endian, mode, setval, seeki, buf, i, size); i += (size == -1) ? 4 : 4 * size; break; case 'F': - rz_print_format_double(p, endian, mode, setval, seeki, buf, i, size); + rz_type_format_double(outbuf, endian, mode, setval, seeki, buf, i, size); i += (size == -1) ? 8 : 8 * size; break; case 'i': - rz_print_format_int(p, endian, mode, setval, seeki, buf, i, size); + rz_type_format_int(outbuf, endian, mode, setval, seeki, buf, i, size); i += (size == -1) ? 4 : 4 * size; break; case 'd': //WHY?? help says: 0x%%08x hexadecimal value (4 bytes) - rz_print_format_hex(p, endian, mode, setval, seeki, buf, i, size); + rz_type_format_hex(outbuf, endian, mode, setval, seeki, buf, i, size); i += (size == -1) ? 4 : 4 * size; break; + /* case 'D': if (isptr) { if (p->bits == 64) { @@ -2527,8 +2545,9 @@ RZ_API int rz_print_format(RzPrint *p, ut64 seek, const ut8 *b, const int len, i += rz_print_format_disasm(p, seeki, size); } break; + */ case 'o': - rz_print_format_octal(p, endian, mode, setval, seeki, buf, i, size); + rz_type_format_octal(outbuf, endian, mode, setval, seeki, buf, i, size); i += (size == -1) ? 4 : 4 * size; break; case ';': @@ -2546,15 +2565,15 @@ RZ_API int rz_print_format(RzPrint *p, ut64 seek, const ut8 *b, const int len, } break; case 'x': - rz_print_format_hexflag(p, endian, mode, setval, seeki, buf, i, size); + rz_type_format_hexflag(outbuf, endian, mode, setval, seeki, buf, i, size); i += (size == -1) ? 4 : 4 * size; break; case 'w': - rz_print_format_word(p, endian, mode, setval, seeki, buf, i, size); + rz_type_format_word(outbuf, endian, mode, setval, seeki, buf, i, size); i += (size == -1) ? 2 : 2 * size; break; case 'z': // zero terminated string - rz_print_format_nulltermstring(p, len, endian, mode, setval, seeki, buf, i, size); + rz_type_format_nulltermstring(typedb, p, outbuf, len, endian, mode, setval, seeki, buf, i, size); if (size == -1) { i += strlen((char *)buf + i) + 1; } else { @@ -2564,7 +2583,7 @@ RZ_API int rz_print_format(RzPrint *p, ut64 seek, const ut8 *b, const int len, } break; case 'Z': // zero terminated wide string - rz_print_format_nulltermwidestring(p, len, endian, mode, setval, seeki, buf, i, size); + rz_type_format_nulltermwidestring(p, outbuf, len, endian, mode, setval, seeki, buf, i, size); if (size == -1) { i += rz_wstr_clen((char *)(buf + i)) * 2 + 2; } else { @@ -2574,12 +2593,12 @@ RZ_API int rz_print_format(RzPrint *p, ut64 seek, const ut8 *b, const int len, } break; case 's': - if (rz_print_format_string(p, seeki, addr64, addr, 0, mode) == 0) { + if (rz_type_format_string(typedb, outbuf, seeki, addr64, addr, 0, mode) == 0) { i += (size == -1) ? 4 : 4 * size; } break; case 'S': - if (rz_print_format_string(p, seeki, addr64, addr, 1, mode) == 0) { + if (rz_type_format_string(typedb, outbuf, seeki, addr64, addr, 1, mode) == 0) { i += (size == -1) ? 8 : 8 * size; } break; @@ -2587,19 +2606,19 @@ RZ_API int rz_print_format(RzPrint *p, ut64 seek, const ut8 *b, const int len, if (size >= ARRAYINDEX_COEF) { size %= ARRAYINDEX_COEF; } - rz_print_format_bitfield(p, seeki, fmtname, fieldname, addr, mode, size); + rz_type_format_bitfield(typedb, outbuf, seeki, fmtname, fieldname, addr, mode, size); i += (size == -1) ? 1 : size; break; case 'E': // resolve enum if (size >= ARRAYINDEX_COEF) { size %= ARRAYINDEX_COEF; } - rz_print_format_enum(p, seeki, fmtname, fieldname, addr, mode, size); + rz_type_format_enum(typedb, outbuf, seeki, fmtname, fieldname, addr, mode, size); i += (size == -1) ? 1 : size; break; case 'r': if (fmtname) { - rz_print_format_register(p, mode, fmtname, setval); + rz_print_format_register(outbuf, p, mode, fmtname, setval); } else { eprintf("Unknown register\n"); } @@ -2624,22 +2643,22 @@ RZ_API int rz_print_format(RzPrint *p, ut64 seek, const ut8 *b, const int len, if (MUSTSEE) { if (!SEEVALUE) { - p->cb_printf("\n"); + rz_strbuf_append(outbuf, "\n"); } } if (MUSTSEEJSON) { if (isptr) { - p->cb_printf("%" PFMT64d "},", seeki); + rz_strbuf_appendf(outbuf, "%" PFMT64d "},", seeki); } else { - p->cb_printf("["); + rz_strbuf_append(outbuf, "["); } } if (MUSTSEESTRUCT) { if (isptr) { - p->cb_printf("%" PFMT64d, seeki); + rz_strbuf_appendf(outbuf, "%" PFMT64d, seeki); } else { ident += 4; - p->cb_printf("\n"); + rz_strbuf_append(outbuf, "\n"); } } if (mode & RZ_PRINT_SEEFLAGS) { @@ -2660,19 +2679,19 @@ RZ_API int rz_print_format(RzPrint *p, ut64 seek, const ut8 *b, const int len, //slide += (isptr) ? STRUCTPTR : NESTEDSTRUCT; slide += NESTEDSTRUCT; if (size == -1) { - s = rz_print_format_struct(p, seeki, + s = rz_type_format_struct(typedb, p, outbuf, seeki, buf + i, len - i, fmtname, slide, mode, setval, nxtfield, anon); i += (isptr) ? (p->bits / 8) : s; if (MUSTSEEJSON) { if (!isptr && (!arg[1] || arg[1] == ' ')) { - p->cb_printf("]}"); + rz_strbuf_append(outbuf, "]}"); } } } else { if (mode & RZ_PRINT_ISFIELD) { if (!SEEVALUE) { - p->cb_printf("[\n"); + rz_strbuf_append(outbuf, "[\n"); } } while (size--) { @@ -2684,13 +2703,13 @@ RZ_API int rz_print_format(RzPrint *p, ut64 seek, const ut8 *b, const int len, } else { mode &= ~RZ_PRINT_MUSTSEE; } - s = rz_print_format_struct(p, seek + i, + s = rz_type_format_struct(typedb, p, outbuf, seek + i, buf + i, len - i, fmtname, slide, mode, setval, nxtfield, anon); if ((MUSTSEE || MUSTSEEJSON || MUSTSEESTRUCT) && size != 0 && elem == -1) { if (MUSTSEEJSON) { - p->cb_printf(","); + rz_strbuf_append(outbuf, ","); } else if (MUSTSEE || MUSTSEESTRUCT) { - p->cb_printf("\n"); + rz_strbuf_append(outbuf, "\n"); } } if (elem > -1) { @@ -2700,11 +2719,11 @@ RZ_API int rz_print_format(RzPrint *p, ut64 seek, const ut8 *b, const int len, } if (mode & RZ_PRINT_ISFIELD) { if (!SEEVALUE) { - p->cb_printf("]\n"); + rz_strbuf_append(outbuf, "]\n"); } } if (MUSTSEEJSON) { - p->cb_printf("]}"); + rz_strbuf_append(outbuf, "]}"); } } oldslide = slide; @@ -2733,7 +2752,7 @@ RZ_API int rz_print_format(RzPrint *p, ut64 seek, const ut8 *b, const int len, break; //or goto beach;??? } - rz_print_format_num(p, endian, mode, setval, seeki, buf, i, bytes, sign, size); + rz_type_format_num(outbuf, endian, mode, setval, seeki, buf, i, bytes, sign, size); i += (size == -1) ? bytes : size * bytes; arg++; break; @@ -2747,33 +2766,33 @@ RZ_API int rz_print_format(RzPrint *p, ut64 seek, const ut8 *b, const int len, if (MUSTSEESTRUCT) { if (oldslide) { ident -= 4; - p->cb_printf("%*c}", ident, ' '); + rz_strbuf_appendf(outbuf, "%*c}", ident, ' '); oldslide -= NESTEDSTRUCT; } - p->cb_printf("\n"); + rz_strbuf_append(outbuf, "\n"); } if (mode & RZ_PRINT_DOT) { - p->cb_printf("}"); + rz_strbuf_append(outbuf, "}"); } if (mode & RZ_PRINT_SEEFLAGS && isptr != NULLPTR) { int sz = i - oi; if (sz > 1) { - p->cb_printf("fl %d @ 0x%08" PFMT64x "\n", sz, seeki); - p->cb_printf("Cd %d @ 0x%08" PFMT64x "\n", sz, seeki); + rz_strbuf_appendf(outbuf, "fl %d @ 0x%08" PFMT64x "\n", sz, seeki); + rz_strbuf_appendf(outbuf, "Cd %d @ 0x%08" PFMT64x "\n", sz, seeki); } } if (viewflags && p->offname) { const char *s = p->offname(p->user, seeki); if (s) { - p->cb_printf("@(%s)", s); + rz_strbuf_appendf(outbuf, "@(%s)", s); } s = p->offname(p->user, addr); if (s) { - p->cb_printf("*(%s)", s); + rz_strbuf_appendf(outbuf, "*(%s)", s); } } if (!noline && tmp != 'D' && !invalid && !fmtname && MUSTSEE) { - p->cb_printf("\n"); + rz_strbuf_append(outbuf, "\n"); } last = tmp; @@ -2796,22 +2815,22 @@ RZ_API int rz_print_format(RzPrint *p, ut64 seek, const ut8 *b, const int len, } if (otimes > 1) { if (MUSTSEEJSON) { - p->cb_printf("]"); + rz_strbuf_append(outbuf, "]"); } else if (mode) { - p->cb_printf("}\n"); + rz_strbuf_append(outbuf, "}\n"); } } arg = orig; oldslide = 0; } if (mode & RZ_PRINT_JSON && slide == 0) { - p->cb_printf("]\n"); + rz_strbuf_append(outbuf, "]\n"); } if (MUSTSEESTRUCT && slide == 0) { - p->cb_printf("}\n"); + rz_strbuf_append(outbuf, "}\n"); } if (mode & RZ_PRINT_DOT) { - p->cb_printf("\"];\n}\n"); + rz_strbuf_append(outbuf, "\"];\n}\n"); // TODO: show nested structs and field reference lines } beach: @@ -2823,5 +2842,7 @@ RZ_API int rz_print_format(RzPrint *p, ut64 seek, const ut8 *b, const int len, free(buf); free(field); free(args); - return i; + //return i; + char *outstr = rz_strbuf_drain(outbuf); + return outstr; } diff --git a/librz/type/function.c b/librz/type/function.c index ddf35941757..354be132e74 100644 --- a/librz/type/function.c +++ b/librz/type/function.c @@ -261,4 +261,3 @@ RZ_API RzList *rz_type_noreturn_functions(RzType *type) { ls_free(l); return noretl; } - diff --git a/librz/type/link.c b/librz/type/link.c index 34592af48da..ed65cc9c8d9 100644 --- a/librz/type/link.c +++ b/librz/type/link.c @@ -117,5 +117,3 @@ RZ_API bool rz_type_unlink_all(RzType *t) { sdb_foreach(TDB, sdbdeletelink, TDB); return true; } - - diff --git a/librz/type/meson.build b/librz/type/meson.build index bbdf1566c75..b4c9951e4c0 100644 --- a/librz/type/meson.build +++ b/librz/type/meson.build @@ -1,6 +1,7 @@ rz_type_sources = [ 'base.c', 'code.c', + 'format.c', 'function.c', 'link.c', 'serialize_types.c', diff --git a/librz/type/serialize_types.c b/librz/type/serialize_types.c index 7c3b51fd834..39e73aa5c2a 100644 --- a/librz/type/serialize_types.c +++ b/librz/type/serialize_types.c @@ -15,5 +15,3 @@ RZ_API bool rz_serialize_types_load(RZ_NONNULL Sdb *db, RZ_NONNULL RzType *types sdb_copy(db, types->sdb_types); return true; } - - diff --git a/librz/type/type.c b/librz/type/type.c index 661d490e2b5..849b830a494 100644 --- a/librz/type/type.c +++ b/librz/type/type.c @@ -15,13 +15,21 @@ RZ_API RzType *rz_type_new() { if (!type) { return NULL; } + type->target = RZ_NEW0(RzTypeTarget); + if (!type->target) { + return NULL; + } Sdb *sdb = sdb_new0(); type->sdb_types = sdb_ns(sdb, "types", 1); + type->formats = sdb_new0(); + rz_io_bind_init(type->iob); return type; } RZ_API void rz_type_free(RzType *t) { sdb_free(t->sdb_types); + sdb_free(t->formats); + free(t->target); free(t); } @@ -275,5 +283,3 @@ RZ_API RzList *rz_type_links(RzType *type) { ls_free(l); return ccl; } - - diff --git a/librz/type/utype.c b/librz/type/utype.c index 4e9eb433d29..127204c2eac 100644 --- a/librz/type/utype.c +++ b/librz/type/utype.c @@ -337,5 +337,3 @@ RZ_API RzList *rz_type_get_by_offset(RzType *t, ut64 offset) { ls_free(ls); return offtypes; } - - diff --git a/librz/util/print.c b/librz/util/print.c index b60daefd687..bef4df84483 100644 --- a/librz/util/print.c +++ b/librz/util/print.c @@ -172,7 +172,6 @@ RZ_API RzPrint *rz_print_new(void) { p->cols = 16; p->cur_enabled = false; p->cur = p->ocur = -1; - p->formats = sdb_new0(); p->addrmod = 4; p->flags = RZ_PRINT_FLAGS_COLOR | @@ -200,8 +199,6 @@ RZ_API RzPrint *rz_print_free(RzPrint *p) { if (!p) { return NULL; } - sdb_free(p->formats); - p->formats = NULL; RZ_FREE(p->strconv_mode); if (p->zoom) { free(p->zoom->buf); diff --git a/test/unit/test_type.c b/test/unit/test_type.c index cf3f2c8a8ad..767f1fd93b5 100644 --- a/test/unit/test_type.c +++ b/test/unit/test_type.c @@ -351,7 +351,6 @@ static bool test_types_get_base_type_not_found(void) { mu_end; } - bool test_dll_names(void) { RzType *T = rz_type_new(); T->sdb_types = setup_sdb_for_function(); From 115b71262faae3e5bed6d3cedf722677757a6be6 Mon Sep 17 00:00:00 2001 From: Anton Kochkov Date: Thu, 25 Mar 2021 16:18:50 +0800 Subject: [PATCH 03/25] Restore CType --- librz/include/rz_type.h | 43 ++++++++ librz/type/ctype.c | 231 ++++++++++++++++++++++++++++++++++++++++ librz/type/meson.build | 1 + 3 files changed, 275 insertions(+) create mode 100644 librz/type/ctype.c diff --git a/librz/include/rz_type.h b/librz/include/rz_type.h index ae8f8acc70d..08c8af3b398 100644 --- a/librz/include/rz_type.h +++ b/librz/include/rz_type.h @@ -113,6 +113,49 @@ RZ_API void rz_type_base_struct_member_free(void *e, void *user); RZ_API void rz_type_base_union_member_free(void *e, void *user); RZ_API void rz_type_save_base_type(const RzType *t, const RzBaseType *type); +/* ctype */ +// Parses strings like "const char * [0x42] const * [23]" to RzTypeCTypeType + +typedef struct rz_type_ctype_t RzTypeCType; + +typedef enum { + RZ_TYPE_CTYPE_TYPE_KIND_IDENTIFIER, + RZ_TYPE_CTYPE_TYPE_KIND_POINTER, + RZ_TYPE_CTYPE_TYPE_KIND_ARRAY +} RzTypeCTypeTypeKind; + +typedef enum { + RZ_TYPE_CTYPE_IDENTIFIER_KIND_UNSPECIFIED, + RZ_TYPE_CTYPE_IDENTIFIER_KIND_STRUCT, + RZ_TYPE_CTYPE_IDENTIFIER_KIND_UNION, + RZ_TYPE_CTYPE_IDENTIFIER_KIND_ENUM +} RzTypeCTypeTypeIdentifierKind; + +typedef struct rz_type_ctype_type_t RzTypeCTypeType; +struct rz_type_ctype_type_t { + RzTypeCTypeTypeKind kind; + union { + struct { + RzTypeCTypeTypeIdentifierKind kind; + char *name; + bool is_const; + } identifier; + struct { + RzTypeCTypeType *type; + bool is_const; + } pointer; + struct { + RzTypeCTypeType *type; + ut64 count; + } array; + }; +}; + +RZ_API RzTypeCType *rz_type_ctype_new(void); +RZ_API void rz_type_ctype_free(RzTypeCType *ctype); +RZ_API RzTypeCTypeType *rz_type_ctype_parse(RzTypeCType *ctype, const char *str, char **error); +RZ_API void rz_type_ctype_type_free(RzTypeCTypeType *type); + /* c */ RZ_API char *rz_type_parse_c_string(RzType *type, const char *code, char **error_msg); RZ_API char *rz_type_parse_c_file(RzType *type, const char *path, const char *dir, char **error_msg); diff --git a/librz/type/ctype.c b/librz/type/ctype.c new file mode 100644 index 00000000000..c6b34172b4e --- /dev/null +++ b/librz/type/ctype.c @@ -0,0 +1,231 @@ +// SPDX-FileCopyrightText: 2019 thestr4ng3r +// SPDX-License-Identifier: LGPL-3.0-only + +#include +#include + +#include + +struct rz_type_ctype_t { + mpc_parser_t *integerlit; + mpc_parser_t *identifier; + mpc_parser_t *qualifier; + mpc_parser_t *pointer; + mpc_parser_t *array; + mpc_parser_t *type; +}; + +#define ALL_PARSERS(ctype) ctype->integerlit, ctype->identifier, ctype->qualifier, ctype->pointer, ctype->array, ctype->type +#define ALL_PARSERS_COUNT 6 + +static const char *lang = + "integerlit : /0x[0-9A-Fa-f]+/ | /[0-9]+/;" + "identifier : (\"struct\" | \"union\" | \"enum\")? /[a-zA-Z_][0-9a-zA-Z_]+/;" + "qualifier : \"const\";" + "pointer : ? '*';" + "array : '[' ']';" + "type : ? ( | )*;"; + +RZ_API RzTypeCType *rz_type_ctype_new(void) { + RzTypeCType *ctype = RZ_NEW(RzTypeCType); + if (!ctype) { + return NULL; + } + + ctype->integerlit = mpc_new("integerlit"); + ctype->identifier = mpc_new("identifier"); + ctype->qualifier = mpc_new("qualifier"); + ctype->pointer = mpc_new("pointer"); + ctype->array = mpc_new("array"); + ctype->type = mpc_new("type"); + + mpc_err_t *err = mpca_lang(MPCA_LANG_DEFAULT, lang, ALL_PARSERS(ctype), NULL); + if (err) { + mpc_err_print(err); + mpc_err_delete(err); + rz_type_ctype_free(ctype); + return NULL; + } + + return ctype; +} + +RZ_API void rz_type_ctype_free(RzTypeCType *ctype) { + if (!ctype) { + return; + } + mpc_cleanup(ALL_PARSERS_COUNT, ALL_PARSERS(ctype)); + free(ctype); +} + +static bool is_qualifier_const(mpc_ast_t *a) { + return strcmp(a->tag, "qualifier|string") == 0 && a->contents && strcmp(a->contents, "const") == 0; +} + +static bool is_identifier_string(mpc_ast_t *a) { + return strcmp(a->tag, "identifier|regex") == 0 && a->contents; +} + +static bool is_identifier_kind(mpc_ast_t *a) { + return strcmp(a->tag, "identifier|>") == 0 && a->children_num == 2 && strcmp(a->children[0]->tag, "string") == 0 && a->children[0]->contents && strcmp(a->children[1]->tag, "regex") == 0 && a->children[1]->contents; +} + +static bool is_non_const_pointer(mpc_ast_t *a) { + return strcmp(a->tag, "pointer|char") == 0 && a->contents && strcmp(a->contents, "*") == 0; +} + +static bool is_const_pointer(mpc_ast_t *a) { + return strcmp(a->tag, "pointer|>") == 0 && a->children_num == 2 && is_qualifier_const(a->children[0]) && strcmp(a->children[1]->tag, "char") == 0 && a->children[1]->contents && strcmp(a->children[1]->contents, "*") == 0; +} + +static bool is_array(mpc_ast_t *a) { + return strcmp(a->tag, "array|>") == 0 && a->children_num == 3 && strcmp(a->children[0]->tag, "char") == 0 && a->children[0]->contents && strcmp(a->children[0]->contents, "[") == 0 && strcmp(a->children[1]->tag, "integerlit|regex") == 0 && a->children[1]->contents && strcmp(a->children[2]->tag, "char") == 0 && a->children[2]->contents && strcmp(a->children[2]->contents, "]") == 0; +} + +static RzTypeCTypeType *ctype_convert_ast(mpc_ast_t *a) { + bool is_const = false; + RzTypeCTypeType *cur = NULL; + int i; + for (i = 0; i < a->children_num; i++) { + mpc_ast_t *child = a->children[i]; + + // const + if (is_qualifier_const(child)) { + is_const = true; + } + + // (struct|union|enum)? + else if (rz_str_startswith(child->tag, "identifier|")) { + if (cur) { + // identifier should always be the innermost type + goto beach; + } + cur = RZ_NEW0(RzTypeCTypeType); + if (!cur) { + goto beach; + } + cur->kind = RZ_TYPE_CTYPE_TYPE_KIND_IDENTIFIER; + cur->identifier.is_const = is_const; + cur->identifier.kind = RZ_TYPE_CTYPE_IDENTIFIER_KIND_UNSPECIFIED; + if (is_identifier_string(child)) { + cur->identifier.name = strdup(child->contents); + } else if (is_identifier_kind(child)) { + if (strcmp(child->children[0]->contents, "struct") == 0) { + cur->identifier.kind = RZ_TYPE_CTYPE_IDENTIFIER_KIND_STRUCT; + } else if (strcmp(child->children[0]->contents, "union") == 0) { + cur->identifier.kind = RZ_TYPE_CTYPE_IDENTIFIER_KIND_UNION; + } else if (strcmp(child->children[0]->contents, "enum") == 0) { + cur->identifier.kind = RZ_TYPE_CTYPE_IDENTIFIER_KIND_ENUM; + } + cur->identifier.name = strdup(child->children[1]->contents); + } else { + goto beach; + } + if (!cur->identifier.name) { + goto beach; + } + is_const = false; + } + + // + else if (is_identifier_string(child)) { + if (cur) { + // identifier should always be the innermost type + goto beach; + } + cur = RZ_NEW0(RzTypeCTypeType); + if (!cur) { + goto beach; + } + cur->kind = RZ_TYPE_CTYPE_TYPE_KIND_IDENTIFIER; + cur->identifier.kind = RZ_TYPE_CTYPE_IDENTIFIER_KIND_UNSPECIFIED; + cur->identifier.is_const = is_const; + cur->identifier.name = strdup(child->contents); + if (!cur->identifier.name) { + goto beach; + } + is_const = false; + } + + // * + else if (is_non_const_pointer(child)) { + RzTypeCTypeType *pointer = RZ_NEW0(RzTypeCTypeType); + if (!pointer) { + goto beach; + } + pointer->kind = RZ_TYPE_CTYPE_TYPE_KIND_POINTER; + pointer->pointer.is_const = false; + pointer->pointer.type = cur; + cur = pointer; + } + + // const * + else if (is_const_pointer(child)) { + RzTypeCTypeType *pointer = RZ_NEW0(RzTypeCTypeType); + if (!pointer) { + goto beach; + } + pointer->kind = RZ_TYPE_CTYPE_TYPE_KIND_POINTER; + pointer->pointer.is_const = true; + pointer->pointer.type = cur; + cur = pointer; + } + + // + else if (is_array(child)) { + RzTypeCTypeType *array = RZ_NEW0(RzTypeCTypeType); + if (!array) { + goto beach; + } + array->kind = RZ_TYPE_CTYPE_TYPE_KIND_ARRAY; + array->array.count = strtoull(child->children[1]->contents, NULL, 0); + array->array.type = cur; + cur = array; + } + + else { + goto beach; + } + } + + return cur; +beach: + rz_type_ctype_type_free(cur); + return NULL; +} + +RZ_API RzTypeCTypeType *rz_type_ctype_parse(RzTypeCType *ctype, const char *str, char **error) { + mpc_result_t r; + if (mpc_parse("", str, ctype->type, &r)) { + RzTypeCTypeType *ret = ctype_convert_ast(r.output); + if (error) { + *error = !ret ? strdup("internal error") : NULL; + } + mpc_ast_delete(r.output); + return ret; + } else { + if (error) { + *error = mpc_err_string(r.error); + } + mpc_err_delete(r.error); + return NULL; + } +} + +RZ_API void rz_type_ctype_type_free(RzTypeCTypeType *type) { + if (!type) { + return; + } + switch (type->kind) { + case RZ_TYPE_CTYPE_TYPE_KIND_IDENTIFIER: + free(type->identifier.name); + break; + case RZ_TYPE_CTYPE_TYPE_KIND_POINTER: + rz_type_ctype_type_free(type->pointer.type); + break; + case RZ_TYPE_CTYPE_TYPE_KIND_ARRAY: + rz_type_ctype_type_free(type->array.type); + break; + } + free(type); +} diff --git a/librz/type/meson.build b/librz/type/meson.build index b4c9951e4c0..b2a8de872b6 100644 --- a/librz/type/meson.build +++ b/librz/type/meson.build @@ -1,6 +1,7 @@ rz_type_sources = [ 'base.c', 'code.c', + 'ctype.c', 'format.c', 'function.c', 'link.c', From b398f720673f7032d98a592842759e5afd3cdeda Mon Sep 17 00:00:00 2001 From: Anton Kochkov Date: Fri, 26 Mar 2021 14:32:02 +0800 Subject: [PATCH 04/25] Rename RzType to RzTypeDB --- librz/analysis/analysis.c | 18 +-- librz/analysis/cc.c | 2 +- librz/analysis/dwarf_process.c | 8 +- librz/analysis/fcn.c | 20 +-- librz/analysis/serialize_analysis.c | 4 +- librz/analysis/sign.c | 6 +- librz/analysis/type_pdb.c | 34 ++--- librz/analysis/var.c | 58 ++++---- librz/core/analysis_tp.c | 16 +-- librz/core/canalysis.c | 10 +- librz/core/carg.c | 16 +-- librz/core/cautocmpl.c | 10 +- librz/core/cbin.c | 12 +- librz/core/cconfig.c | 2 +- librz/core/cmd.c | 4 +- librz/core/cmd_analysis.c | 14 +- librz/core/cmd_meta.c | 6 +- librz/core/cmd_print.c | 36 ++--- librz/core/cmd_type.c | 142 +++++++++---------- librz/core/cmd_zign.c | 2 +- librz/core/core.c | 7 +- librz/core/core_private.h | 23 ++-- librz/core/ctypes.c | 146 ++++++++------------ librz/core/disasm.c | 24 ++-- librz/core/vmenus.c | 6 +- librz/include/rz_analysis.h | 4 +- librz/include/rz_type.h | 131 +++++++++--------- librz/type/base.c | 126 ++++++++--------- librz/type/code.c | 22 +-- librz/type/format.c | 86 ++++++------ librz/type/function.c | 73 +++++----- librz/type/link.c | 32 ++--- librz/type/serialize_types.c | 10 +- librz/type/type.c | 178 +++++++++++++++++------- librz/type/utype.c | 92 +++++-------- test/unit/test_dwarf_integration.c | 2 +- test/unit/test_pdb.c | 4 +- test/unit/test_serialize_analysis.c | 4 +- test/unit/test_serialize_types.c | 32 ++--- test/unit/test_type.c | 206 ++++++++++++++-------------- 40 files changed, 826 insertions(+), 802 deletions(-) diff --git a/librz/analysis/analysis.c b/librz/analysis/analysis.c index 2a95b63d7cd..62fef6eb682 100644 --- a/librz/analysis/analysis.c +++ b/librz/analysis/analysis.c @@ -110,7 +110,7 @@ RZ_API RzAnalysis *rz_analysis_new(void) { rz_event_hook(analysis->zign_spaces.event, RZ_SPACE_EVENT_RENAME, zign_rename_for, NULL); rz_analysis_hint_storage_init(analysis); rz_interval_tree_init(&analysis->meta, rz_meta_item_free); - analysis->type = rz_type_new(); + analysis->typedb = rz_type_db_new(); analysis->sdb_fmts = sdb_ns(analysis->sdb, "spec", 1); analysis->sdb_cc = sdb_ns(analysis->sdb, "cc", 1); analysis->sdb_zigns = sdb_ns(analysis->sdb, "zigns", 1); @@ -246,7 +246,7 @@ static bool analysis_set_os(RzAnalysis *analysis, const char *os) { } free(analysis->os); analysis->os = strdup(os); - rz_type_set_os(analysis->type, os); + rz_type_db_set_os(analysis->typedb, os); return true; } @@ -267,7 +267,7 @@ RZ_API bool rz_analysis_set_os(RzAnalysis *analysis, const char *os) { const char *dir_prefix = rz_sys_prefix(NULL); const char *dbpath = sdb_fmt(RZ_JOIN_3_PATHS("%s", RZ_SDB_FCNSIGN, "types-%s.sdb"), dir_prefix, os); - rz_type_load_sdb(analysis->type, dbpath); + rz_type_db_load_sdb(analysis->typedb, dbpath); return rz_analysis_set_triplet(analysis, os, NULL, -1); } @@ -280,7 +280,7 @@ RZ_API bool rz_analysis_set_bits(RzAnalysis *analysis, int bits) { case 64: if (analysis->bits != bits) { analysis->bits = bits; - rz_type_set_bits(analysis->type, bits); + rz_type_db_set_bits(analysis->typedb, bits); rz_analysis_set_reg_profile(analysis); } return true; @@ -295,7 +295,7 @@ RZ_API void rz_analysis_set_cpu(RzAnalysis *analysis, const char *cpu) { if (v != -1) { analysis->pcalign = v; } - rz_type_set_cpu(analysis->type, cpu); + rz_type_db_set_cpu(analysis->typedb, cpu); } RZ_API int rz_analysis_set_big_endian(RzAnalysis *analysis, int bigend) { @@ -406,7 +406,7 @@ RZ_API void rz_analysis_purge(RzAnalysis *analysis) { rz_analysis_hint_clear(analysis); rz_interval_tree_fini(&analysis->meta); rz_interval_tree_init(&analysis->meta, rz_meta_item_free); - rz_type_purge(analysis->type); + rz_type_db_purge(analysis->typedb); sdb_reset(analysis->sdb_zigns); sdb_reset(analysis->sdb_classes); sdb_reset(analysis->sdb_classes_attrs); @@ -462,9 +462,9 @@ RZ_API bool rz_analysis_noreturn_add(RzAnalysis *analysis, const char *name, ut6 fcn->is_noreturn = true; } } - if (rz_type_func_exist(analysis->type, tmp_name)) { + if (rz_type_func_exist(analysis->typedb, tmp_name)) { fnl_name = strdup(tmp_name); - } else if (!(fnl_name = rz_type_func_guess(analysis->type, (char *)tmp_name))) { + } else if (!(fnl_name = rz_type_func_guess(analysis->typedb, (char *)tmp_name))) { if (addr == UT64_MAX) { if (name) { sdb_bool_set(NDB, K_NORET_FUNC(name), true, 0); @@ -520,7 +520,7 @@ static bool rz_analysis_noreturn_at_name(RzAnalysis *analysis, const char *name) if (sdb_bool_get(analysis->sdb_noret, K_NORET_FUNC(name), NULL)) { return true; } - char *tmp = rz_type_func_guess(analysis->type, (char *)name); + char *tmp = rz_type_func_guess(analysis->typedb, (char *)name); if (tmp) { if (sdb_bool_get(analysis->sdb_noret, K_NORET_FUNC(tmp), NULL)) { free(tmp); diff --git a/librz/analysis/cc.c b/librz/analysis/cc.c index 6d71e2031c0..d33abdcb2c5 100644 --- a/librz/analysis/cc.c +++ b/librz/analysis/cc.c @@ -219,7 +219,7 @@ RZ_API void rz_analysis_set_syscc_default(RzAnalysis *analysis, const char *cc) RZ_API const char *rz_analysis_cc_func(RzAnalysis *analysis, const char *func_name) { rz_return_val_if_fail(analysis && func_name, NULL); - const char *cc = rz_type_func_cc(analysis->type, func_name); + const char *cc = rz_type_func_cc(analysis->typedb, func_name); return cc ? cc : rz_analysis_cc_default(analysis); } diff --git a/librz/analysis/dwarf_process.c b/librz/analysis/dwarf_process.c index 49be4bfeeca..43ab8466e64 100644 --- a/librz/analysis/dwarf_process.c +++ b/librz/analysis/dwarf_process.c @@ -578,7 +578,7 @@ static void parse_structure_type(Context *ctx, ut64 idx) { } } } - rz_type_save_base_type(ctx->analysis->type, base_type); + rz_type_db_save_base_type(ctx->analysis->typedb, base_type); cleanup: rz_type_base_type_free(base_type); } @@ -641,7 +641,7 @@ static void parse_enum_type(Context *ctx, ut64 idx) { } } } - rz_type_save_base_type(ctx->analysis->type, base_type); + rz_type_db_save_base_type(ctx->analysis->typedb, base_type); cleanup: rz_type_base_type_free(base_type); } @@ -694,7 +694,7 @@ static void parse_typedef(Context *ctx, ut64 idx) { } base_type->name = name; base_type->type = type; - rz_type_save_base_type(ctx->analysis->type, base_type); + rz_type_db_save_base_type(ctx->analysis->typedb, base_type); rz_type_base_type_free(base_type); rz_strbuf_fini(&strbuf); return; @@ -748,7 +748,7 @@ static void parse_atomic_type(Context *ctx, ut64 idx) { } base_type->name = name; base_type->size = size; - rz_type_save_base_type(ctx->analysis->type, base_type); + rz_type_db_save_base_type(ctx->analysis->typedb, base_type); rz_type_base_type_free(base_type); } diff --git a/librz/analysis/fcn.c b/librz/analysis/fcn.c index e7ccbe87ee8..1cdb12291fe 100644 --- a/librz/analysis/fcn.c +++ b/librz/analysis/fcn.c @@ -1704,8 +1704,8 @@ RZ_API char *rz_analysis_function_get_json(RzAnalysisFunction *function) { RzAnalysis *a = function->analysis; PJ *pj = a->coreb.pjWithEncoding(a->coreb.core); unsigned int i; - const char *ret_type = rz_type_func_ret(a->type, function->name); - int argc = rz_type_func_args_count(a->type, function->name); + const char *ret_type = rz_type_func_ret(a->typedb, function->name); + int argc = rz_type_func_args_count(a->typedb, function->name); pj_o(pj); pj_ks(pj, "name", function->name); @@ -1719,8 +1719,8 @@ RZ_API char *rz_analysis_function_get_json(RzAnalysisFunction *function) { pj_a(pj); for (i = 0; i < argc; i++) { pj_o(pj); - const char *arg_name = rz_type_func_args_name(a->type, function->name, i); - const char *arg_type = rz_type_func_args_type(a->type, function->name, i); + const char *arg_name = rz_type_func_args_name(a->typedb, function->name, i); + const char *arg_type = rz_type_func_args_type(a->typedb, function->name, i); pj_ks(pj, "name", arg_name); pj_ks(pj, "type", arg_type); const char *cc_arg = rz_reg_get_name(a->reg, rz_reg_get_name_idx(sdb_fmt("A%d", i))); @@ -1751,13 +1751,13 @@ RZ_API char *rz_analysis_function_get_signature(RzAnalysisFunction *function) { } unsigned int i; - const char *ret_type = rz_type_func_ret(a->type, function->name); - int argc = rz_type_func_args_count(a->type, function->name); + const char *ret_type = rz_type_func_ret(a->typedb, function->name); + int argc = rz_type_func_args_count(a->typedb, function->name); char *args = strdup(""); for (i = 0; i < argc; i++) { - const char *arg_name = rz_type_func_args_name(a->type, function->name, i); - const char *arg_type = rz_type_func_args_type(a->type, function->name, i); + const char *arg_name = rz_type_func_args_name(a->typedb, function->name, i); + const char *arg_type = rz_type_func_args_type(a->typedb, function->name, i); char *new_args = (i + 1 == argc) ? rz_str_newf("%s%s %s", args, arg_type, arg_name) : rz_str_newf("%s%s %s, ", args, arg_type, arg_name); @@ -1771,9 +1771,9 @@ RZ_API char *rz_analysis_function_get_signature(RzAnalysisFunction *function) { RZ_API int rz_analysis_str_to_fcn(RzAnalysis *a, RzAnalysisFunction *f, const char *sig) { rz_return_val_if_fail(a || f || sig, false); char *error_msg = NULL; - const char *out = rz_type_parse_c_string(a->type, sig, &error_msg); + const char *out = rz_type_parse_c_string(a->typedb, sig, &error_msg); if (out) { - rz_type_save_parsed_type(a->type, out); + rz_type_db_save_parsed_type(a->typedb, out); } if (error_msg) { eprintf("%s", error_msg); diff --git a/librz/analysis/serialize_analysis.c b/librz/analysis/serialize_analysis.c index 10216f475c5..61f052b101b 100644 --- a/librz/analysis/serialize_analysis.c +++ b/librz/analysis/serialize_analysis.c @@ -1930,11 +1930,11 @@ RZ_API bool rz_serialize_analysis_classes_load(RZ_NONNULL Sdb *db, RZ_NONNULL Rz } RZ_API void rz_serialize_analysis_types_save(RZ_NONNULL Sdb *db, RZ_NONNULL RzAnalysis *analysis) { - rz_serialize_types_save(db, analysis->type); + rz_serialize_types_save(db, analysis->typedb); } RZ_API bool rz_serialize_analysis_types_load(RZ_NONNULL Sdb *db, RZ_NONNULL RzAnalysis *analysis, RZ_NULLABLE RzSerializeResultInfo *res) { - return rz_serialize_types_load(db, analysis->type, res); + return rz_serialize_types_load(db, analysis->typedb, res); return true; } diff --git a/librz/analysis/sign.c b/librz/analysis/sign.c index a49d233dbd9..7c9563f61bb 100644 --- a/librz/analysis/sign.c +++ b/librz/analysis/sign.c @@ -83,8 +83,8 @@ RZ_API RzList *rz_sign_fcn_types(RzAnalysis *a, RzAnalysisFunction *fcn) { return NULL; } - int fcnargs = rz_type_func_args_count(a->type, fcn->name); - const char *ret_type = rz_type_func_ret(a->type, fcn->name); + int fcnargs = rz_type_func_args_count(a->typedb, fcn->name); + const char *ret_type = rz_type_func_ret(a->typedb, fcn->name); if (fcnargs) { if (ret_type) { @@ -93,7 +93,7 @@ RZ_API RzList *rz_sign_fcn_types(RzAnalysis *a, RzAnalysisFunction *fcn) { rz_list_append(ret, rz_str_newf("func.%s.args=%d", fcn->name, fcnargs)); int i; for (i = 0; i < fcnargs; i++) { - const char *arg = rz_type_func_args_name(a->type, fcn->name, i); + const char *arg = rz_type_func_args_name(a->typedb, fcn->name, i); rz_list_append(ret, rz_str_newf("func.%s.arg.%d=\"%s\"", fcn->name, i, arg)); } } diff --git a/librz/analysis/type_pdb.c b/librz/analysis/type_pdb.c index 86bc07f6f11..d560c708c45 100644 --- a/librz/analysis/type_pdb.c +++ b/librz/analysis/type_pdb.c @@ -94,12 +94,12 @@ static RzTypeEnumCase *parse_enumerate(STypeInfo *type_info, RzList *types) { /** * @brief Parses enum into BaseType and saves it into SDB * - * @param t RzType instance + * @param t RzTypeDB instance * @param type Current type * @param types List of all types */ -static void parse_enum(const RzType *t, SType *type, RzList *types) { - rz_return_if_fail(t && type && types); +static void parse_enum(const RzTypeDB *typedb, SType *type, RzList *types) { + rz_return_if_fail(typedb && type && types); STypeInfo *type_info = &type->type_data; // assert all member functions we need info from rz_return_if_fail(type_info->get_members && @@ -146,7 +146,7 @@ static void parse_enum(const RzType *t, SType *type, RzList *types) { base_type->size = size; base_type->type = strdup(type_name); // we assume it's sanitized - rz_type_save_base_type(t, base_type); + rz_type_db_save_base_type(typedb, base_type); cleanup: if (to_free_name) { RZ_FREE(name); @@ -158,12 +158,12 @@ static void parse_enum(const RzType *t, SType *type, RzList *types) { /** * @brief Parses classes, unions and structures into BaseType and saves them into SDB * - * @param t RzType instance + * @param t RzTypeDB instance * @param type Current type * @param types List of all types */ -static void parse_structure(const RzType *t, SType *type, RzList *types) { - rz_return_if_fail(t && type && types); +static void parse_structure(const RzTypeDB *typedb, SType *type, RzList *types) { + rz_return_if_fail(typedb && type && types); STypeInfo *type_info = &type->type_data; // assert all member functions we need info from rz_return_if_fail(type_info->get_members && @@ -209,7 +209,7 @@ static void parse_structure(const RzType *t, SType *type, RzList *types) { char *sname = rz_str_sanitize_sdb_key(name); base_type->name = sname; base_type->size = size; - rz_type_save_base_type(t, base_type); + rz_type_db_save_base_type(typedb, base_type); cleanup: if (to_free_name) { RZ_FREE(name); @@ -221,12 +221,12 @@ static void parse_structure(const RzType *t, SType *type, RzList *types) { /** * @brief Delegate the type parsing to appropriate function * - * @param t RzType instance + * @param t RzTypeDB instance * @param type Current type * @param types List of all types */ -static void parse_type(const RzType *t, SType *type, RzList *types) { - rz_return_if_fail(t && type && types); +static void parse_type(const RzTypeDB *typedb, SType *type, RzList *types) { + rz_return_if_fail(typedb && type && types); int is_forward_decl; if (type->type_data.is_fwdref) { @@ -239,10 +239,10 @@ static void parse_type(const RzType *t, SType *type, RzList *types) { case eLF_CLASS: case eLF_STRUCTURE: case eLF_UNION: - parse_structure(t, type, types); + parse_structure(typedb, type, types); break; case eLF_ENUM: - parse_enum(t, type, types); + parse_enum(typedb, type, types); break; default: // shouldn't happen, happens when someone modifies leafs that get here @@ -255,11 +255,11 @@ static void parse_type(const RzType *t, SType *type, RzList *types) { /** * @brief Saves PDB types from TPI stream into the SDB * - * @param t RzType instance + * @param t RzTypeDB instance * @param pdb PDB information */ -RZ_API void rz_parse_pdb_types(const RzType *t, const RzPdb *pdb) { - rz_return_if_fail(t && pdb); +RZ_API void rz_parse_pdb_types(const RzTypeDB *typedb, const RzPdb *pdb) { + rz_return_if_fail(typedb && pdb); RzList *plist = pdb->pdb_streams; // getting the TPI stream from the streams list STpiStream *tpi_stream = rz_list_get_n(plist, ePDB_STREAM_TPI); @@ -271,7 +271,7 @@ RZ_API void rz_parse_pdb_types(const RzType *t, const RzPdb *pdb) { while (rz_list_iter_next(iter)) { // iterate all types SType *type = rz_list_iter_get(iter); if (type && is_parsable_type(type->type_data.leaf_type)) { - parse_type(t, type, tpi_stream->types); + parse_type(typedb, type, tpi_stream->types); } } } diff --git a/librz/analysis/var.c b/librz/analysis/var.c index a01db56ac6d..07070261abb 100644 --- a/librz/analysis/var.c +++ b/librz/analysis/var.c @@ -46,7 +46,7 @@ RZ_API bool rz_analysis_function_rebase_vars(RzAnalysis *a, RzAnalysisFunction * // If the type of var is a struct, // remove all other vars that are overlapped by var and are at the offset of one of its struct members static void shadow_var_struct_members(RzAnalysisVar *var) { - Sdb *TDB = var->fcn->analysis->type->sdb_types; + Sdb *TDB = var->fcn->analysis->typedb->sdb_types; const char *type_kind = sdb_const_get(TDB, var->type, 0); if (type_kind && rz_str_startswith(type_kind, "struct")) { char *field; @@ -557,7 +557,7 @@ RZ_API int rz_analysis_var_count(RzAnalysis *a, RzAnalysisFunction *fcn, int kin } static bool var_add_structure_fields_to_list(RzAnalysis *a, RzAnalysisVar *av, RzList *list) { - Sdb *TDB = a->type->sdb_types; + Sdb *TDB = a->typedb->sdb_types; const char *type_kind = sdb_const_get(TDB, av->type, 0); if (type_kind && !strcmp(type_kind, "struct")) { char *field_name, *new_name; @@ -726,30 +726,30 @@ static void extract_arg(RzAnalysis *analysis, RzAnalysisFunction *fcn, RzAnalysi if (isarg) { const char *place = fcn->cc ? rz_analysis_cc_arg(analysis, fcn->cc, ST32_MAX) : NULL; bool stack_rev = place ? !strcmp(place, "stack_rev") : false; - char *fname = rz_type_func_guess(analysis->type, fcn->name); + char *fname = rz_type_func_guess(analysis->typedb, fcn->name); if (fname) { ut64 sum_sz = 0; size_t from, to, i; if (stack_rev) { - const size_t cnt = rz_type_func_args_count(analysis->type, fname); + const size_t cnt = rz_type_func_args_count(analysis->typedb, fname); from = cnt ? cnt - 1 : cnt; to = fcn->cc ? rz_analysis_cc_max_arg(analysis, fcn->cc) : 0; } else { from = fcn->cc ? rz_analysis_cc_max_arg(analysis, fcn->cc) : 0; - to = rz_type_func_args_count(analysis->type, fname); + to = rz_type_func_args_count(analysis->typedb, fname); } const int bytes = (fcn->bits ? fcn->bits : analysis->bits) / 8; for (i = from; stack_rev ? i >= to : i < to; stack_rev ? i-- : i++) { - char *tp = rz_type_func_args_type(analysis->type, fname, i); + char *tp = rz_type_func_args_type(analysis->typedb, fname, i); if (!tp) { break; } if (sum_sz == frame_off) { vartype = tp; - varname = strdup(rz_type_func_args_name(analysis->type, fname, i)); + varname = strdup(rz_type_func_args_name(analysis->typedb, fname, i)); break; } - ut64 bit_sz = rz_type_get_bitsize(analysis->type, tp); + ut64 bit_sz = rz_type_db_get_bitsize(analysis->typedb, tp); sum_sz += bit_sz ? bit_sz / 8 : bytes; sum_sz = RZ_ROUND(sum_sz, bytes); free(tp); @@ -884,14 +884,14 @@ RZ_API void rz_analysis_extract_rarg(RzAnalysis *analysis, RzAnalysisOp *op, RzA RZ_LOG_DEBUG("No calling convention for function '%s' to extract register arguments\n", fcn->name); return; } - char *fname = rz_type_func_guess(analysis->type, fcn->name); + char *fname = rz_type_func_guess(analysis->typedb, fcn->name); int max_count = rz_analysis_cc_max_arg(analysis, fcn->cc); if (!max_count || (*count >= max_count)) { free(fname); return; } if (fname) { - argc = rz_type_func_args_count(analysis->type, fname); + argc = rz_type_func_args_count(analysis->typedb, fname); } bool is_call = (op->type & 0xf) == RZ_ANALYSIS_OP_TYPE_CALL || (op->type & 0xf) == RZ_ANALYSIS_OP_TYPE_UCALL; @@ -905,18 +905,18 @@ RZ_API void rz_analysis_extract_rarg(RzAnalysis *analysis, RzAnalysisOp *op, RzA RzCore *core = (RzCore *)analysis->coreb.core; RzFlagItem *flag = rz_flag_get_by_spaces(core->flags, offset, RZ_FLAGS_FS_IMPORTS, NULL); if (flag) { - callee = rz_type_func_guess(analysis->type, flag->name); + callee = rz_type_func_guess(analysis->typedb, flag->name); if (callee) { const char *cc = rz_analysis_cc_func(analysis, callee); if (cc && !strcmp(fcn->cc, cc)) { - callee_rargs = RZ_MIN(max_count, rz_type_func_args_count(analysis->type, callee)); + callee_rargs = RZ_MIN(max_count, rz_type_func_args_count(analysis->typedb, callee)); } } } } else if (!f->is_variadic && !strcmp(fcn->cc, f->cc)) { - callee = rz_type_func_guess(analysis->type, f->name); + callee = rz_type_func_guess(analysis->typedb, f->name); if (callee) { - callee_rargs = RZ_MIN(max_count, rz_type_func_args_count(analysis->type, callee)); + callee_rargs = RZ_MIN(max_count, rz_type_func_args_count(analysis->typedb, callee)); } callee_rargs = callee_rargs ? callee_rargs @@ -938,12 +938,12 @@ RZ_API void rz_analysis_extract_rarg(RzAnalysis *analysis, RzAnalysisOp *op, RzA delta = ri->index; } if (fname) { - type = rz_type_func_args_type(analysis->type, fname, i); - vname = rz_type_func_args_name(analysis->type, fname, i); + type = rz_type_func_args_type(analysis->typedb, fname, i); + vname = rz_type_func_args_name(analysis->typedb, fname, i); } if (!vname && callee) { - type = rz_type_func_args_type(analysis->type, callee, i); - vname = rz_type_func_args_name(analysis->type, callee, i); + type = rz_type_func_args_type(analysis->typedb, callee, i); + vname = rz_type_func_args_name(analysis->typedb, callee, i); } if (vname) { reg_set[i] = 1; @@ -996,8 +996,8 @@ RZ_API void rz_analysis_extract_rarg(RzAnalysis *analysis, RzAnalysisOp *op, RzA char *type = NULL; char *name = NULL; if ((i < argc) && fname) { - type = rz_type_func_args_type(analysis->type, fname, i); - vname = rz_type_func_args_name(analysis->type, fname, i); + type = rz_type_func_args_type(analysis->typedb, fname, i); + vname = rz_type_func_args_name(analysis->typedb, fname, i); } if (!vname) { name = rz_str_newf("arg%d", i + 1); @@ -1355,9 +1355,9 @@ RZ_API char *rz_analysis_fcn_format_sig(RZ_NONNULL RzAnalysis *analysis, RZ_NONN return NULL; } - char *type_fcn_name = rz_type_func_guess(analysis->type, fcn_name); - if (type_fcn_name && rz_type_func_exist(analysis->type, type_fcn_name)) { - const char *fcn_type = rz_type_func_ret(analysis->type, type_fcn_name); + char *type_fcn_name = rz_type_func_guess(analysis->typedb, fcn_name); + if (type_fcn_name && rz_type_func_exist(analysis->typedb, type_fcn_name)) { + const char *fcn_type = rz_type_func_ret(analysis->typedb, type_fcn_name); if (fcn_type) { const char *sp = " "; if (*fcn_type && (fcn_type[strlen(fcn_type) - 1] == '*')) { @@ -1376,14 +1376,14 @@ RZ_API char *rz_analysis_fcn_format_sig(RZ_NONNULL RzAnalysis *analysis, RZ_NONN } rz_strbuf_append(buf, " ("); - if (type_fcn_name && rz_type_func_exist(analysis->type, type_fcn_name)) { - int i, argc = rz_type_func_args_count(analysis->type, type_fcn_name); + if (type_fcn_name && rz_type_func_exist(analysis->typedb, type_fcn_name)) { + int i, argc = rz_type_func_args_count(analysis->typedb, type_fcn_name); bool comma = true; // This avoids false positives present in argument recovery // and straight away print arguments fetched from types db for (i = 0; i < argc; i++) { - char *type = rz_type_func_args_type(analysis->type, type_fcn_name, i); - const char *name = rz_type_func_args_name(analysis->type, type_fcn_name, i); + char *type = rz_type_func_args_type(analysis->typedb, type_fcn_name, i); + const char *name = rz_type_func_args_name(analysis->typedb, type_fcn_name, i); if (!type || !name) { eprintf("Missing type for %s\n", type_fcn_name); goto beach; @@ -1487,12 +1487,12 @@ RZ_API void rz_analysis_fcn_vars_add_types(RzAnalysis *analysis, RzAnalysisFunct rz_list_foreach (all_vars, iter, var) { if (var->isarg) { - rz_type_func_arg_set(analysis->type, fcn->name, arg_count, var->name, var->type); + rz_type_func_arg_set(analysis->typedb, fcn->name, arg_count, var->name, var->type); arg_count++; } } if (arg_count > 0) { - rz_type_func_arg_count_set(analysis->type, fcn->name, arg_count); + rz_type_func_arg_count_set(analysis->typedb, fcn->name, arg_count); } rz_analysis_fcn_vars_cache_fini(&cache); } diff --git a/librz/core/analysis_tp.c b/librz/core/analysis_tp.c index d088cb532f7..5b289e89c9f 100644 --- a/librz/core/analysis_tp.c +++ b/librz/core/analysis_tp.c @@ -297,7 +297,7 @@ RzAnalysisOp *op_cache_get(HtUP *cache, RzCore *core, ut64 addr) { static void type_match(RzCore *core, char *fcn_name, ut64 addr, ut64 baddr, const char *cc, int prev_idx, bool userfnc, ut64 caddr, HtUP *op_cache) { Sdb *trace = core->analysis->esil->trace->db; - RzType *T = core->analysis->type; + RzTypeDB *typedb = core->analysis->typedb; RzAnalysis *analysis = core->analysis; RzList *types = NULL; int idx = sdb_num_get(trace, "idx", 0); @@ -307,7 +307,7 @@ static void type_match(RzCore *core, char *fcn_name, ut64 addr, ut64 baddr, cons if (!fcn_name || !cc) { return; } - int i, j, pos = 0, size = 0, max = rz_type_func_args_count(T, fcn_name); + int i, j, pos = 0, size = 0, max = rz_type_func_args_count(typedb, fcn_name); const char *place = rz_analysis_cc_arg(analysis, cc, ST32_MAX); rz_cons_break_push(NULL, NULL); @@ -338,8 +338,8 @@ static void type_match(RzCore *core, char *fcn_name, ut64 addr, ut64 baddr, cons } type = rz_str_new(rz_list_get_n(types, pos++)); } else { - type = rz_type_func_args_type(T, fcn_name, arg_num); - name = rz_type_func_args_name(T, fcn_name, arg_num); + type = rz_type_func_args_type(typedb, fcn_name, arg_num); + name = rz_type_func_args_name(typedb, fcn_name, arg_num); } if (!type && !userfnc) { continue; @@ -474,7 +474,7 @@ RZ_API void rz_core_analysis_type_match(RzCore *core, RzAnalysisFunction *fcn) { } RzAnalysis *analysis = core->analysis; - RzType *T = analysis->type; + RzTypeDB *typedb = analysis->typedb; bool chk_constraint = rz_config_get_i(core->config, "analysis.types.constraint"); const int mininstrsz = rz_analysis_archinfo(analysis, RZ_ANALYSIS_ARCHINFO_MIN_OP_SIZE); const int minopcode = RZ_MAX(1, mininstrsz); @@ -579,10 +579,10 @@ RZ_API void rz_core_analysis_type_match(RzCore *core, RzAnalysisFunction *fcn) { } } if (full_name) { - if (rz_type_func_exist(T, full_name)) { + if (rz_type_func_exist(typedb, full_name)) { fcn_name = strdup(full_name); } else { - fcn_name = rz_type_func_guess(T, full_name); + fcn_name = rz_type_func_guess(typedb, full_name); } if (!fcn_name) { fcn_name = strdup(full_name); @@ -594,7 +594,7 @@ RZ_API void rz_core_analysis_type_match(RzCore *core, RzAnalysisFunction *fcn) { type_match(core, fcn_name, addr, bb->addr, cc, prev_idx, userfnc, callee_addr, op_cache); prev_idx = cur_idx; RZ_FREE(ret_type); - const char *rt = rz_type_func_ret(T, fcn_name); + const char *rt = rz_type_func_ret(typedb, fcn_name); if (rt) { ret_type = strdup(rt); } diff --git a/librz/core/canalysis.c b/librz/core/canalysis.c index 9ec3d3e101f..0ce49cccbb6 100644 --- a/librz/core/canalysis.c +++ b/librz/core/canalysis.c @@ -6622,8 +6622,8 @@ RZ_IPI char *rz_core_analysis_function_signature(RzCore *core, RzOutputMode mode } if (key) { - const char *fcn_type = rz_type_func_ret(core->analysis->type, key); - int nargs = rz_type_func_args_count(core->analysis->type, key); + const char *fcn_type = rz_type_func_ret(core->analysis->typedb, key); + int nargs = rz_type_func_args_count(core->analysis->typedb, key); if (fcn_type) { pj_o(j); pj_ks(j, "name", rz_str_get_null(key)); @@ -6813,7 +6813,7 @@ RZ_API void rz_core_analysis_propagate_noreturn_relocs(RzCore *core, ut64 addr) int bits1 = core->analysis->bits; int bits2 = core->rasm->bits; // find known noreturn functions to propagate - RzList *noretl = rz_type_noreturn_functions(core->analysis->type); + RzList *noretl = rz_type_noreturn_functions(core->analysis->typedb); // List of the potentially noreturn functions SetU *todo = set_u_new(); struct core_noretl u = { core, noretl, todo }; @@ -7186,7 +7186,7 @@ RZ_IPI bool rz_core_analysis_function_delete_var(RzCore *core, RzAnalysisFunctio RZ_IPI char *rz_core_analysis_var_display(RzCore *core, RzAnalysisVar *var, bool add_name) { RzAnalysis *analysis = core->analysis; RzStrBuf *sb = rz_strbuf_new(NULL); - char *fmt = rz_type_format(analysis->type, var->type); + char *fmt = rz_type_format(analysis->typedb, var->type); RzRegItem *i; if (!fmt) { RZ_LOG_DEBUG("type:%s doesn't exist\n", var->type); @@ -7546,7 +7546,7 @@ RZ_API void rz_core_analysis_type_init(RzCore *core) { const char *analysis_arch = rz_config_get(core->config, "analysis.arch"); const char *os = rz_config_get(core->config, "asm.os"); - rz_type_db_init(core->analysis->type, dir_prefix, analysis_arch, bits, os); + rz_type_db_init(core->analysis->typedb, dir_prefix, analysis_arch, bits, os); } static void sdb_concat_by_path(Sdb *s, const char *path) { diff --git a/librz/core/carg.c b/librz/core/carg.c index 2f68d2b15bb..6c493f1bdd5 100644 --- a/librz/core/carg.c +++ b/librz/core/carg.c @@ -9,8 +9,8 @@ static void set_fcn_args_info(RzAnalysisFuncArg *arg, RzAnalysis *analysis, cons if (!fcn_name || !arg || !analysis) { return; } - arg->name = rz_type_func_args_name(analysis->type, fcn_name, arg_num); - arg->orig_c_type = rz_type_func_args_type(analysis->type, fcn_name, arg_num); + arg->name = rz_type_func_args_name(analysis->typedb, fcn_name, arg_num); + arg->orig_c_type = rz_type_func_args_type(analysis->typedb, fcn_name, arg_num); if (!arg->name || !arg->orig_c_type) { eprintf("Missing type for function argument (%s)\n", fcn_name); return; @@ -20,25 +20,25 @@ static void set_fcn_args_info(RzAnalysisFuncArg *arg, RzAnalysis *analysis, cons } else { arg->c_type = arg->orig_c_type; } - arg->fmt = rz_type_get(analysis->type, arg->c_type); - arg->size = rz_type_get_bitsize(analysis->type, arg->c_type) / 8; + arg->fmt = rz_type_db_get(analysis->typedb, arg->c_type); + arg->size = rz_type_db_get_bitsize(analysis->typedb, arg->c_type) / 8; arg->cc_source = rz_analysis_cc_arg(analysis, cc, arg_num); } RZ_API char *resolve_fcn_name(RzAnalysis *analysis, const char *func_name) { const char *str = func_name; const char *name = func_name; - if (rz_type_func_exist(analysis->type, func_name)) { + if (rz_type_func_exist(analysis->typedb, func_name)) { return strdup(func_name); } while ((str = strchr(str, '.'))) { name = str + 1; str++; } - if (rz_type_func_exist(analysis->type, name)) { + if (rz_type_func_exist(analysis->typedb, name)) { return strdup(name); } - return rz_type_func_guess(analysis->type, (char *)func_name); + return rz_type_func_guess(analysis->typedb, (char *)func_name); } static ut64 get_buf_val(ut8 *buf, int endian, int width) { @@ -226,7 +226,7 @@ RZ_API RzList *rz_core_get_func_args(RzCore *core, const char *fcn_name) { return NULL; } const char *sp = rz_reg_get_name(core->analysis->reg, RZ_REG_NAME_SP); - int nargs = rz_type_func_args_count(core->analysis->type, key); + int nargs = rz_type_func_args_count(core->analysis->typedb, key); if (!rz_analysis_cc_func(core->analysis, key)) { return NULL; } diff --git a/librz/core/cautocmpl.c b/librz/core/cautocmpl.c index a56d175ca9c..ebe844a6ba5 100644 --- a/librz/core/cautocmpl.c +++ b/librz/core/cautocmpl.c @@ -219,7 +219,7 @@ static void autocmplt_cmd_arg_fcn(RzCore *core, RzLineNSCompletionResult *res, c static void autocmplt_cmd_arg_enum_type(RzCore *core, RzLineNSCompletionResult *res, const char *s, size_t len) { char *item; RzListIter *iter; - RzList *list = rz_type_enums(core->analysis->type); + RzList *list = rz_type_db_enums(core->analysis->typedb); rz_list_foreach (list, iter, item) { if (!strncmp(item, s, len)) { rz_line_ns_completion_result_add(res, item); @@ -231,7 +231,7 @@ static void autocmplt_cmd_arg_enum_type(RzCore *core, RzLineNSCompletionResult * static void autocmplt_cmd_arg_struct_type(RzCore *core, RzLineNSCompletionResult *res, const char *s, size_t len) { char *item; RzListIter *iter; - RzList *list = rz_types_structs(core->analysis->type); + RzList *list = rz_type_db_structs(core->analysis->typedb); rz_list_foreach (list, iter, item) { if (!strncmp(item, s, len)) { rz_line_ns_completion_result_add(res, item); @@ -243,7 +243,7 @@ static void autocmplt_cmd_arg_struct_type(RzCore *core, RzLineNSCompletionResult static void autocmplt_cmd_arg_union_type(RzCore *core, RzLineNSCompletionResult *res, const char *s, size_t len) { char *item; RzListIter *iter; - RzList *list = rz_types_unions(core->analysis->type); + RzList *list = rz_type_db_unions(core->analysis->typedb); rz_list_foreach (list, iter, item) { if (!strncmp(item, s, len)) { rz_line_ns_completion_result_add(res, item); @@ -255,7 +255,7 @@ static void autocmplt_cmd_arg_union_type(RzCore *core, RzLineNSCompletionResult static void autocmplt_cmd_arg_alias_type(RzCore *core, RzLineNSCompletionResult *res, const char *s, size_t len) { char *item; RzListIter *iter; - RzList *list = rz_type_typedefs(core->analysis->type); + RzList *list = rz_type_db_typedefs(core->analysis->typedb); rz_list_foreach (list, iter, item) { if (!strncmp(item, s, len)) { rz_line_ns_completion_result_add(res, item); @@ -267,7 +267,7 @@ static void autocmplt_cmd_arg_alias_type(RzCore *core, RzLineNSCompletionResult static void autocmplt_cmd_arg_any_type(RzCore *core, RzLineNSCompletionResult *res, const char *s, size_t len) { char *item; RzListIter *iter; - RzList *list = rz_types_all(core->analysis->type); + RzList *list = rz_type_db_all(core->analysis->typedb); rz_list_foreach (list, iter, item) { if (!strncmp(item, s, len)) { rz_line_ns_completion_result_add(res, item); diff --git a/librz/core/cbin.c b/librz/core/cbin.c index 8029cae9893..9d12ac858e7 100644 --- a/librz/core/cbin.c +++ b/librz/core/cbin.c @@ -200,14 +200,14 @@ RZ_API void rz_core_bin_export_info(RzCore *core, int mode) { } else if (IS_MODE_SET(mode)) { char *code = rz_str_newf("%s;", v); char *error_msg = NULL; - char *out = rz_type_parse_c_string(core->analysis->type, code, &error_msg); + char *out = rz_type_parse_c_string(core->analysis->typedb, code, &error_msg); free(code); if (error_msg) { eprintf("%s", error_msg); free(error_msg); } if (out) { - rz_type_save_parsed_type(core->analysis->type, out); + rz_type_db_save_parsed_type(core->analysis->typedb, out); free(out); } } @@ -228,7 +228,7 @@ RZ_API void rz_core_bin_export_info(RzCore *core, int mode) { if (IS_MODE_RZCMD(mode)) { rz_cons_printf("pf.%s %s\n", flagname, v); } else if (IS_MODE_SET(mode)) { - rz_type_format_set(core->analysis->type, flagname, v); + rz_type_db_format_set(core->analysis->typedb, flagname, v); } } free(dup); @@ -243,7 +243,7 @@ RZ_API void rz_core_bin_export_info(RzCore *core, int mode) { offset = strdup("0"); } flagname = dup; - int fmtsize = rz_type_format_struct_size(core->analysis->type, v, 0, 0); + int fmtsize = rz_type_format_struct_size(core->analysis->typedb, v, 0, 0); char *offset_key = rz_str_newf("%s.offset", flagname); const char *off = sdb_const_get(db, offset_key, 0); free(offset_key); @@ -255,7 +255,7 @@ RZ_API void rz_core_bin_export_info(RzCore *core, int mode) { ut8 *buf = malloc(fmtsize); if (buf) { rz_io_read_at(core->io, addr, buf, fmtsize); - char *format = rz_type_format_data(core->analysis->type, core->print, addr, buf, + char *format = rz_type_format_data(core->analysis->typedb, core->print, addr, buf, fmtsize, v, 0, NULL, NULL); free(buf); if (!format) { @@ -2069,7 +2069,7 @@ RZ_API bool rz_core_pdb_info(RzCore *core, const char *file, PJ *pj, int mode) { pdb.print_types(&pdb, pj, mode); pdb.print_gvars(&pdb, baddr, pj, mode); // Save compound types into types database - rz_parse_pdb_types(core->analysis->type, &pdb); + rz_parse_pdb_types(core->analysis->typedb, &pdb); pdb.finish_pdb_parse(&pdb); if (mode == 'j') { diff --git a/librz/core/cconfig.c b/librz/core/cconfig.c index be6be407997..023fc43dd6e 100644 --- a/librz/core/cconfig.c +++ b/librz/core/cconfig.c @@ -692,7 +692,7 @@ static bool cb_asmarch(void *user, void *data) { // changing analysis.arch sets types db // so ressetting is redundant and may lead to bugs // 1 case this is usefull is when types is null - if (!core->analysis || !core->analysis->type) { + if (!core->analysis || !core->analysis->typedb) { rz_core_analysis_type_init(core); } rz_core_analysis_cc_init(core); diff --git a/librz/core/cmd.c b/librz/core/cmd.c index d9cd77defb1..f48cd40d01f 100644 --- a/librz/core/cmd.c +++ b/librz/core/cmd.c @@ -757,10 +757,10 @@ RZ_API bool rz_core_run_script(RzCore *core, const char *file) { ret = true; } else if (rz_file_is_c(file)) { const char *dir = rz_config_get(core->config, "dir.types"); - char *out = rz_type_parse_c_file(core->analysis->type, file, dir, NULL); + char *out = rz_type_parse_c_file(core->analysis->typedb, file, dir, NULL); if (out) { rz_cons_strcat(out); - rz_type_save_parsed_type(core->analysis->type, out); + rz_type_db_save_parsed_type(core->analysis->typedb, out); free(out); } ret = out != NULL; diff --git a/librz/core/cmd_analysis.c b/librz/core/cmd_analysis.c index 6d68f6a563b..d8339e0659e 100644 --- a/librz/core/cmd_analysis.c +++ b/librz/core/cmd_analysis.c @@ -2951,7 +2951,7 @@ RZ_IPI int rz_cmd_analysis_fcn(void *data, const char *input) { case 'r': { // "afsr" RzAnalysisFunction *fcn = rz_analysis_get_fcn_in(core->analysis, core->offset, -1); if (fcn) { - rz_type_func_ret_set(core->analysis->type, fcn->name, input + 3); + rz_type_func_ret_set(core->analysis->typedb, fcn->name, input + 3); } else { eprintf("There's no function defined in here.\n"); } @@ -6902,7 +6902,7 @@ static void cmd_analysis_hint(RzCore *core, const char *input) { rz_str_trim(off); int toff = rz_num_math(NULL, off); if (toff) { - RzList *typeoffs = rz_type_get_by_offset(core->analysis->type, toff); + RzList *typeoffs = rz_type_get_by_offset(core->analysis->typedb, toff); RzListIter *iter; char *ty; rz_list_foreach (typeoffs, iter, ty) { @@ -6971,14 +6971,14 @@ static void cmd_analysis_hint(RzCore *core, const char *input) { offimm += rz_num_math(NULL, off); } // TODO: Allow to select from multiple choices - RzList *otypes = rz_type_get_by_offset(core->analysis->type, offimm); + RzList *otypes = rz_type_get_by_offset(core->analysis->typedb, offimm); RzListIter *iter; char *otype = NULL; rz_list_foreach (otypes, iter, otype) { // TODO: I don't think we should silently error, it is confusing if (!strcmp(type, otype)) { //eprintf ("Adding type offset %s\n", type); - rz_type_link_offset(core->analysis->type, type, addr); + rz_type_link_offset(core->analysis->typedb, type, addr); rz_analysis_hint_set_offset(core->analysis, addr, otype); break; } @@ -8752,8 +8752,8 @@ static void cmd_analysis_aC(RzCore *core, const char *input) { } char *key = (fcn_name) ? resolve_fcn_name(core->analysis, fcn_name) : NULL; if (key) { - const char *fcn_type = rz_type_func_ret(core->analysis->type, key); - int nargs = rz_type_func_args_count(core->analysis->type, key); + const char *fcn_type = rz_type_func_ret(core->analysis->typedb, key); + int nargs = rz_type_func_args_count(core->analysis->typedb, key); // remove other comments if (fcn_type) { rz_strbuf_appendf(sb, "%s%s%s(", rz_str_get_null(fcn_type), @@ -9251,7 +9251,7 @@ RZ_IPI RzCmdStatus rz_analysis_function_signature_type_handler(RzCore *core, int return RZ_CMD_STATUS_ERROR; } - if (!rz_type_func_ret_set(core->analysis->type, fcn->name, argv[1])) { + if (!rz_type_func_ret_set(core->analysis->typedb, fcn->name, argv[1])) { eprintf("Cannot find type %s\n", argv[1]); return RZ_CMD_STATUS_ERROR; } diff --git a/librz/core/cmd_meta.c b/librz/core/cmd_meta.c index fb6c1397314..d151d9d7db6 100644 --- a/librz/core/cmd_meta.c +++ b/librz/core/cmd_meta.c @@ -554,7 +554,7 @@ static int cmd_meta_others(RzCore *core, const char *input) { if (p) { p = (char *)rz_str_trim_head_ro(p); if (*p == '.') { - const char *realformat = rz_type_format_byname(core->analysis->type, p + 1); + const char *realformat = rz_type_db_format_byname(core->analysis->typedb, p + 1); if (realformat) { p = (char *)realformat; } else { @@ -563,7 +563,7 @@ static int cmd_meta_others(RzCore *core, const char *input) { } } if (n < 1) { - n = rz_type_format_struct_size(core->analysis->type, p, 0, 0); + n = rz_type_format_struct_size(core->analysis->typedb, p, 0, 0); if (n < 1) { eprintf("Warning: Cannot resolve struct size for '%s'\n", p); n = 32; // @@ -573,7 +573,7 @@ static int cmd_meta_others(RzCore *core, const char *input) { if (n > core->blocksize) { n = core->blocksize; } - char *format = rz_type_format_data(core->analysis->type, core->print, addr, core->block, + char *format = rz_type_format_data(core->analysis->typedb, core->print, addr, core->block, n, p, 0, NULL, NULL); if (!format) { n = -1; diff --git a/librz/core/cmd_print.c b/librz/core/cmd_print.c index 0a98c843c86..5b951cb7ebd 100644 --- a/librz/core/cmd_print.c +++ b/librz/core/cmd_print.c @@ -1604,9 +1604,9 @@ static void cmd_print_format(RzCore *core, const char *_input, const ut8 *block, _input += 2; if (*_input == '.') { _input++; - val = rz_type_format_get(core->analysis->type, _input); + val = rz_type_db_format_get(core->analysis->typedb, _input); if (val) { - rz_cons_printf("%d\n", rz_type_format_struct_size(core->analysis->type, val, mode, 0)); + rz_cons_printf("%d\n", rz_type_format_struct_size(core->analysis->typedb, val, mode, 0)); } else { eprintf("Struct %s not defined\nUsage: pfs.struct_name | pfs format\n", _input); } @@ -1615,7 +1615,7 @@ static void cmd_print_format(RzCore *core, const char *_input, const ut8 *block, _input++; } if (*_input) { - rz_cons_printf("%d\n", rz_type_format_struct_size(core->analysis->type, _input, mode, 0)); + rz_cons_printf("%d\n", rz_type_format_struct_size(core->analysis->typedb, _input, mode, 0)); } else { eprintf("Struct %s not defined\nUsage: pfs.struct_name | pfs format\n", _input); } @@ -1641,7 +1641,7 @@ static void cmd_print_format(RzCore *core, const char *_input, const ut8 *block, } } else { const char *struct_name = rz_str_trim_head_ro(_input); - const char *val = rz_type_format_get(core->analysis->type, struct_name); + const char *val = rz_type_db_format_get(core->analysis->typedb, struct_name); if (val) { rz_cons_printf("%s\n", val); } else { @@ -1668,9 +1668,9 @@ static void cmd_print_format(RzCore *core, const char *_input, const ut8 *block, if (rz_str_endswith(_input, ".h")) { char *error_msg = NULL; const char *dir = rz_config_get(core->config, "dir.types"); - char *out = rz_type_parse_c_file(core->analysis->type, path, dir, &error_msg); + char *out = rz_type_parse_c_file(core->analysis->typedb, path, dir, &error_msg); if (out) { - rz_type_save_parsed_type(core->analysis->type, out); + rz_type_db_save_parsed_type(core->analysis->typedb, out); rz_core_cmd0(core, ".ts*"); free(out); } else { @@ -1746,7 +1746,7 @@ static void cmd_print_format(RzCore *core, const char *_input, const ut8 *block, if (!input[1] || !input[2]) { // "pf." RzListIter *iter; char *fmt = NULL; - RzList *fmtl = rz_type_format_all(core->analysis->type); + RzList *fmtl = rz_type_db_format_all(core->analysis->typedb); rz_list_foreach (fmtl, iter, fmt) { rz_cons_printf("pf.%s\n", fmt); } @@ -1754,9 +1754,9 @@ static void cmd_print_format(RzCore *core, const char *_input, const ut8 *block, /* delete a format */ } else if (input[1] && input[2] == '-') { // "pf-" if (input[3] == '*') { // "pf-*" - rz_type_format_purge(core->analysis->type); + rz_type_db_format_purge(core->analysis->typedb); } else { // "pf-xxx" - rz_type_format_delete(core->analysis->type, input + 3); + rz_type_db_format_delete(core->analysis->typedb, input + 3); } } else { char *name = strdup(input + (input[1] ? 2 : 1)); @@ -1777,7 +1777,7 @@ static void cmd_print_format(RzCore *core, const char *_input, const ut8 *block, eprintf("Struct or fields name can not contain dot symbol (.)\n"); } else { // pf.foo=xxx - rz_type_format_set(core->analysis->type, name, space); + rz_type_db_format_set(core->analysis->typedb, name, space); } free(name); free(input); @@ -1785,7 +1785,7 @@ static void cmd_print_format(RzCore *core, const char *_input, const ut8 *block, } if (!strchr(name, '.') && - !rz_type_format_get(core->analysis->type, name)) { + !rz_type_db_format_get(core->analysis->typedb, name)) { eprintf("Cannot find '%s' format.\n", name); free(name); free(input); @@ -1803,9 +1803,9 @@ static void cmd_print_format(RzCore *core, const char *_input, const ut8 *block, /* Load format from name into fmt to get the size */ /* This make sure the whole structure will be printed */ const char *fmt = NULL; - fmt = rz_type_format_get(core->analysis->type, name); + fmt = rz_type_db_format_get(core->analysis->typedb, name); if (fmt) { - int size = rz_type_format_struct_size(core->analysis->type, fmt, mode, 0) + 10; + int size = rz_type_format_struct_size(core->analysis->typedb, fmt, mode, 0) + 10; if (size > core->blocksize) { rz_core_block_size(core, size); } @@ -1817,14 +1817,14 @@ static void cmd_print_format(RzCore *core, const char *_input, const ut8 *block, if (eq) { // Write mode (pf.field=value) *eq++ = 0; mode = RZ_PRINT_MUSTSET; - char *format = rz_type_format_data(core->analysis->type, core->print, core->offset, + char *format = rz_type_format_data(core->analysis->typedb, core->print, core->offset, core->block, core->blocksize, name, mode, eq, dot); if (format) { rz_cons_print(format); free(format); } } else { - char *format = rz_type_format_data(core->analysis->type, core->print, core->offset, + char *format = rz_type_format_data(core->analysis->typedb, core->print, core->offset, core->block, core->blocksize, name, mode, NULL, dot); if (format) { rz_cons_print(format); @@ -1832,7 +1832,7 @@ static void cmd_print_format(RzCore *core, const char *_input, const ut8 *block, } } } else { - char *format = rz_type_format_data(core->analysis->type, core->print, core->offset, + char *format = rz_type_format_data(core->analysis->typedb, core->print, core->offset, core->block, core->blocksize, name, mode, NULL, NULL); if (format) { rz_cons_print(format); @@ -1844,7 +1844,7 @@ static void cmd_print_format(RzCore *core, const char *_input, const ut8 *block, } else { /* This make sure the structure will be printed entirely */ const char *fmt = rz_str_trim_head_ro(input + 1); - int struct_sz = rz_type_format_struct_size(core->analysis->type, fmt, mode, 0); + int struct_sz = rz_type_format_struct_size(core->analysis->typedb, fmt, mode, 0); int size = RZ_MAX(core->blocksize, struct_sz); ut8 *buf = calloc(1, size); if (!buf) { @@ -1867,7 +1867,7 @@ static void cmd_print_format(RzCore *core, const char *_input, const ut8 *block, } free(args); if (syntax_ok) { - char *format = rz_type_format_data(core->analysis->type, core->print, core->offset, + char *format = rz_type_format_data(core->analysis->typedb, core->print, core->offset, buf, size, fmt, mode, NULL, NULL); if (format) { rz_cons_print(format); diff --git a/librz/core/cmd_type.c b/librz/core/cmd_type.c index f342ed77399..31342376ca3 100644 --- a/librz/core/cmd_type.c +++ b/librz/core/cmd_type.c @@ -43,7 +43,7 @@ static void types_cc_print(RzCore *core, const char *cc, RzOutputMode mode) { static RzCmdStatus types_enum_member_find(RzCore *core, const char *enum_name, const char *enum_value) { rz_return_val_if_fail(enum_name || enum_value, RZ_CMD_STATUS_ERROR); ut64 value = rz_num_math(core->num, enum_value); - char *enum_member = rz_type_enum_member(core->analysis->type, enum_name, NULL, value); + char *enum_member = rz_type_db_enum_member(core->analysis->typedb, enum_name, NULL, value); if (!enum_member) { eprintf("Cannot find matching enum member"); return RZ_CMD_STATUS_ERROR; @@ -56,7 +56,7 @@ static RzCmdStatus types_enum_member_find(RzCore *core, const char *enum_name, c static RzCmdStatus types_enum_member_find_all(RzCore *core, const char *enum_value) { rz_return_val_if_fail(enum_value, RZ_CMD_STATUS_ERROR); ut64 value = rz_num_math(core->num, enum_value); - RzList *matches = rz_type_enum_find_member(core->analysis->type, value); + RzList *matches = rz_type_db_enum_find_member(core->analysis->typedb, value); if (!matches || rz_list_empty(matches)) { eprintf("Cannot find matching enum member"); return RZ_CMD_STATUS_ERROR; @@ -76,15 +76,15 @@ static bool print_type_c(RzCore *core, const char *ctype) { if (name && type) { name++; // skip the '.' if (rz_str_startswith(type, "struct")) { - rz_types_struct_print_c(core->analysis->type, name, true); + rz_types_struct_print_c(core->analysis->typedb, name, true); } else if (rz_str_startswith(type, "union")) { - rz_types_union_print_c(core->analysis->type, name, true); + rz_types_union_print_c(core->analysis->typedb, name, true); } else if (rz_str_startswith(type, "enum")) { - rz_types_enum_print_c(core->analysis->type, name, true); + rz_types_enum_print_c(core->analysis->typedb, name, true); } else if (rz_str_startswith(type, "typedef")) { - rz_types_typedef_print_c(core->analysis->type, name); + rz_types_typedef_print_c(core->analysis->typedb, name); } else if (rz_str_startswith(type, "func")) { - rz_types_function_print(core->analysis->type, name, RZ_OUTPUT_MODE_STANDARD, NULL); + rz_types_function_print(core->analysis->typedb, name, RZ_OUTPUT_MODE_STANDARD, NULL); } return true; } @@ -93,28 +93,28 @@ static bool print_type_c(RzCore *core, const char *ctype) { static void type_list_c_all(RzCore *core) { // List all unions in the C format with newlines - rz_types_union_print_c(core->analysis->type, NULL, true); + rz_types_union_print_c(core->analysis->typedb, NULL, true); // List all structures in the C format with newlines - rz_types_struct_print_c(core->analysis->type, NULL, true); + rz_types_struct_print_c(core->analysis->typedb, NULL, true); // List all typedefs in the C format with newlines - rz_types_typedef_print_c(core->analysis->type, NULL); + rz_types_typedef_print_c(core->analysis->typedb, NULL); // List all enums in the C format with newlines - rz_types_enum_print_c(core->analysis->type, NULL, true); + rz_types_enum_print_c(core->analysis->typedb, NULL, true); } static void type_list_c_all_nl(RzCore *core) { // List all unions in the C format without newlines - rz_types_union_print_c(core->analysis->type, NULL, false); + rz_types_union_print_c(core->analysis->typedb, NULL, false); // List all structures in the C format without newlines - rz_types_struct_print_c(core->analysis->type, NULL, false); + rz_types_struct_print_c(core->analysis->typedb, NULL, false); // List all typedefs in the C format without newlines - rz_types_typedef_print_c(core->analysis->type, NULL); + rz_types_typedef_print_c(core->analysis->typedb, NULL); // List all enums in the C format without newlines - rz_types_enum_print_c(core->analysis->type, NULL, false); + rz_types_enum_print_c(core->analysis->typedb, NULL, false); } static RzCmdStatus type_format_print(RzCore *core, const char *type, ut64 address) { - char *fmt = rz_type_format(core->analysis->type, type); + char *fmt = rz_type_format(core->analysis->typedb, type); if (RZ_STR_ISEMPTY(fmt)) { eprintf("Cannot find type %s\n", type); return RZ_CMD_STATUS_ERROR; @@ -124,7 +124,7 @@ static RzCmdStatus type_format_print(RzCore *core, const char *type, ut64 addres } static RzCmdStatus type_format_print_variable(RzCore *core, const char *type, const char *varname) { - char *fmt = rz_type_format(core->analysis->type, type); + char *fmt = rz_type_format(core->analysis->typedb, type); if (RZ_STR_ISEMPTY(fmt)) { eprintf("Cannot find type \"%s\"\n", type); return RZ_CMD_STATUS_ERROR; @@ -145,7 +145,7 @@ static RzCmdStatus type_format_print_variable(RzCore *core, const char *type, co } static RzCmdStatus type_format_print_value(RzCore *core, const char *type, ut64 val) { - char *fmt = rz_type_format(core->analysis->type, type); + char *fmt = rz_type_format(core->analysis->typedb, type); if (RZ_STR_ISEMPTY(fmt)) { eprintf("Cannot find type %s\n", type); return RZ_CMD_STATUS_ERROR; @@ -155,7 +155,7 @@ static RzCmdStatus type_format_print_value(RzCore *core, const char *type, ut64 } static RzCmdStatus type_format_print_hexstring(RzCore *core, const char *type, const char *hexpairs) { - char *fmt = rz_type_format(core->analysis->type, type); + char *fmt = rz_type_format(core->analysis->typedb, type); if (RZ_STR_ISEMPTY(fmt)) { eprintf("Cannot find type %s\n", type); return RZ_CMD_STATUS_ERROR; @@ -467,7 +467,7 @@ static void cmd_type_noreturn(RzCore *core, const char *input) { switch (input[0]) { case '-': // "tn-" if (input[1] == '*') { - RzList *noretl = rz_type_noreturn_functions(core->analysis->type); + RzList *noretl = rz_type_noreturn_functions(core->analysis->typedb); RzListIter *iter; char *name; rz_list_foreach (noretl, iter, name) { @@ -539,7 +539,7 @@ static void types_list(RzCore *core, int mode) { RZ_IPI int rz_cmd_type(void *data, const char *input) { RzCore *core = (RzCore *)data; - RzType *T = core->analysis->type; + RzTypeDB *typedb = core->analysis->typedb; char *res; switch (input[0]) { @@ -564,27 +564,27 @@ RZ_IPI int rz_cmd_type(void *data, const char *input) { rz_core_types_show_format(core, rz_str_trim_head_ro(input + 2), RZ_OUTPUT_MODE_JSON); rz_cons_newline(); } else { - rz_types_union_print_json(T); + rz_types_union_print_json(typedb); } break; case 'c': // "tuc" - rz_types_union_print_c(T, rz_str_trim_head_ro(input + 2), true); + rz_types_union_print_c(typedb, rz_str_trim_head_ro(input + 2), true); break; case 'd': // "tud" - rz_types_union_print_c(T, rz_str_trim_head_ro(input + 2), false); + rz_types_union_print_c(typedb, rz_str_trim_head_ro(input + 2), false); break; case ' ': // "tu " rz_core_types_show_format(core, rz_str_trim_head_ro(input + 1), RZ_OUTPUT_MODE_STANDARD); break; case 0: - rz_types_union_print_sdb(T); + rz_types_union_print_sdb(typedb); break; } } break; case 'k': // "tk" res = (input[1] == ' ') - ? rz_type_kuery(T, input + 2) - : rz_type_kuery(T, "*"); + ? rz_type_db_kuery(typedb, input + 2) + : rz_type_db_kuery(typedb, "*"); if (res) { rz_cons_print(res); free(res); @@ -632,19 +632,19 @@ RZ_IPI int rz_cmd_type(void *data, const char *input) { break; case 's': if (input[2] == ' ') { - rz_cons_printf("%" PFMT64u "\n", (rz_type_get_bitsize(T, input + 3) / 8)); + rz_cons_printf("%" PFMT64u "\n", (rz_type_db_get_bitsize(typedb, input + 3) / 8)); } else { rz_core_cmd_help(core, help_msg_ts); } break; case 0: - rz_types_struct_print_sdb(T); + rz_types_struct_print_sdb(typedb); break; case 'c': // "tsc" - rz_types_struct_print_c(T, rz_str_trim_head_ro(input + 2), true); + rz_types_struct_print_c(typedb, rz_str_trim_head_ro(input + 2), true); break; case 'd': // "tsd" - rz_types_struct_print_c(T, rz_str_trim_head_ro(input + 2), false); + rz_types_struct_print_c(typedb, rz_str_trim_head_ro(input + 2), false); break; case 'j': // "tsj" // TODO: current output is a bit poor, will be good to improve @@ -652,21 +652,21 @@ RZ_IPI int rz_cmd_type(void *data, const char *input) { rz_core_types_show_format(core, rz_str_trim_head_ro(input + 2), RZ_OUTPUT_MODE_JSON); rz_cons_newline(); } else { - rz_types_struct_print_json(T); + rz_types_struct_print_json(typedb); } break; } } break; case 'e': { // "te" char *res = NULL, *temp = strchr(input, ' '); - RzType *T = core->analysis->type; + RzTypeDB *typedb = core->analysis->typedb; char *name = temp ? strdup(temp + 1) : NULL; char *member_value = name ? strchr(name, ' ') : NULL; if (member_value) { *member_value++ = 0; } - if (name && (rz_type_kind(T, name) != RZ_BASE_TYPE_KIND_ENUM)) { + if (name && (rz_type_kind(typedb, name) != RZ_BASE_TYPE_KIND_ENUM)) { eprintf("%s is not an enum\n", name); free(name); break; @@ -698,13 +698,13 @@ RZ_IPI int rz_cmd_type(void *data, const char *input) { } break; case 'b': // "teb" - res = rz_type_enum_member(T, name, member_value, 0); + res = rz_type_db_enum_member(typedb, name, member_value, 0); break; case 'c': // "tec" - rz_types_enum_print_c(T, rz_str_trim_head_ro(input + 2), true); + rz_types_enum_print_c(typedb, rz_str_trim_head_ro(input + 2), true); break; case 'd': // "ted" - rz_types_enum_print_c(T, rz_str_trim_head_ro(input + 2), false); + rz_types_enum_print_c(typedb, rz_str_trim_head_ro(input + 2), false); break; case 'f': // "tef" if (member_value) { @@ -746,7 +746,7 @@ RZ_IPI int rz_cmd_type(void *data, const char *input) { if (input[1] == ' ') { rz_types_open_file(core, input + 2); } else if (input[1] == 's') { // "tos" - rz_type_load_sdb(core->analysis->type, input + 3); + rz_type_db_load_sdb(core->analysis->typedb, input + 3); } else if (input[1] == 'e') { // "toe" rz_types_open_editor(core, input + 2); } @@ -840,12 +840,12 @@ RZ_IPI int rz_cmd_type(void *data, const char *input) { case '-': switch (input[2]) { case '*': - rz_type_unlink_all(T); + rz_type_unlink_all(typedb); break; case ' ': { const char *ptr = input + 3; ut64 addr = rz_num_math(core->num, ptr); - rz_type_unlink(T, addr); + rz_type_unlink(typedb, addr); break; } } @@ -910,12 +910,12 @@ RZ_IPI int rz_cmd_type(void *data, const char *input) { if (input[1] == '?') { rz_core_cmd_help(core, help_msg_t_minus); } else if (input[1] == '*') { - rz_type_purge(core->analysis->type); - rz_type_parse_c_reset(core->analysis->type); + rz_type_db_purge(core->analysis->typedb); + rz_type_parse_c_reset(core->analysis->typedb); } else { const char *name = rz_str_trim_head_ro(input + 1); if (*name) { - rz_type_remove_parsed_type(core->analysis->type, name); + rz_type_db_remove_parsed_type(core->analysis->typedb, name); } else { eprintf("Invalid use of t- . See t-? for help.\n"); } @@ -930,7 +930,7 @@ RZ_IPI int rz_cmd_type(void *data, const char *input) { case 'k': // "tfk" if (input[2] == ' ') { const char *name = rz_str_trim_head_ro(input + 3); - rz_types_function_print(T, name, RZ_OUTPUT_MODE_SDB, NULL); + rz_types_function_print(typedb, name, RZ_OUTPUT_MODE_SDB, NULL); } else { rz_core_types_function_print_all(core, RZ_OUTPUT_MODE_SDB); } @@ -939,7 +939,7 @@ RZ_IPI int rz_cmd_type(void *data, const char *input) { if (input[2] == ' ') { const char *name = rz_str_trim_head_ro(input + 2); PJ *pj = rz_core_pj_new(core); - rz_types_function_print(T, name, RZ_OUTPUT_MODE_JSON, pj); + rz_types_function_print(typedb, name, RZ_OUTPUT_MODE_JSON, pj); pj_end(pj); rz_cons_println(pj_string(pj)); pj_free(pj); @@ -949,7 +949,7 @@ RZ_IPI int rz_cmd_type(void *data, const char *input) { break; case ' ': { const char *name = rz_str_trim_head_ro(input + 2); - rz_types_function_print(T, name, RZ_OUTPUT_MODE_SDB, NULL); + rz_types_function_print(typedb, name, RZ_OUTPUT_MODE_SDB, NULL); break; } default: @@ -965,7 +965,7 @@ RZ_IPI int rz_cmd_type(void *data, const char *input) { break; } if (input[1] == 'c') { // "ttc" - rz_types_typedef_print_c(T, input + 2); + rz_types_typedef_print_c(typedb, input + 2); break; } if (input[1] == '?') { // "tt?" @@ -1001,13 +1001,13 @@ RZ_IPI RzCmdStatus rz_type_handler(RzCore *core, int argc, const char **argv, Rz } RZ_IPI RzCmdStatus rz_type_del_handler(RzCore *core, int argc, const char **argv) { - rz_type_remove_parsed_type(core->analysis->type, argv[1]); + rz_type_db_remove_parsed_type(core->analysis->typedb, argv[1]); return RZ_CMD_STATUS_OK; } RZ_IPI RzCmdStatus rz_type_del_all_handler(RzCore *core, int argc, const char **argv) { - rz_type_purge(core->analysis->type); - rz_type_parse_c_reset(core->analysis->type); + rz_type_db_purge(core->analysis->typedb); + rz_type_parse_c_reset(core->analysis->typedb); return RZ_CMD_STATUS_OK; } @@ -1084,7 +1084,7 @@ RZ_IPI RzCmdStatus rz_type_list_enum_handler(RzCore *core, int argc, const char RZ_IPI RzCmdStatus rz_type_enum_bitfield_handler(RzCore *core, int argc, const char **argv) { const char *enum_name = argc > 1 ? argv[1] : NULL; const char *enum_member = argc > 2 ? argv[2] : NULL; - char *output = rz_type_enum_member(core->analysis->type, enum_name, enum_member, 0); + char *output = rz_type_db_enum_member(core->analysis->typedb, enum_name, enum_member, 0); if (!output) { eprintf("Cannot find anything matching the specified bitfield"); return RZ_CMD_STATUS_ERROR; @@ -1096,13 +1096,13 @@ RZ_IPI RzCmdStatus rz_type_enum_bitfield_handler(RzCore *core, int argc, const c RZ_IPI RzCmdStatus rz_type_enum_c_handler(RzCore *core, int argc, const char **argv) { const char *enum_name = argc > 1 ? argv[1] : NULL; - rz_types_enum_print_c(core->analysis->type, enum_name, true); + rz_types_enum_print_c(core->analysis->typedb, enum_name, true); return RZ_CMD_STATUS_OK; } RZ_IPI RzCmdStatus rz_type_enum_c_nl_handler(RzCore *core, int argc, const char **argv) { const char *enum_name = argc > 1 ? argv[1] : NULL; - rz_types_enum_print_c(core->analysis->type, enum_name, false); + rz_types_enum_print_c(core->analysis->typedb, enum_name, false); return RZ_CMD_STATUS_OK; } @@ -1115,7 +1115,7 @@ RZ_IPI RzCmdStatus rz_type_list_function_handler(RzCore *core, int argc, const c const char *function = argc > 1 ? argv[1] : NULL; if (function) { PJ *pj = (mode == RZ_OUTPUT_MODE_JSON) ? rz_core_pj_new(core) : NULL; - rz_types_function_print(core->analysis->type, function, mode, pj); + rz_types_function_print(core->analysis->typedb, function, mode, pj); if (mode == RZ_OUTPUT_MODE_JSON) { rz_cons_println(pj_string(pj)); pj_free(pj); @@ -1128,7 +1128,7 @@ RZ_IPI RzCmdStatus rz_type_list_function_handler(RzCore *core, int argc, const c RZ_IPI RzCmdStatus rz_type_kuery_handler(RzCore *core, int argc, const char **argv) { const char *query = argc > 1 ? argv[1] : NULL; - char *output = rz_type_kuery(core->analysis->type, query); + char *output = rz_type_db_kuery(core->analysis->typedb, query); if (!output) { eprintf("Cannot find anything matching your query"); return RZ_CMD_STATUS_ERROR; @@ -1157,12 +1157,12 @@ RZ_IPI RzCmdStatus rz_type_link_show_handler(RzCore *core, int argc, const char RZ_IPI RzCmdStatus rz_type_link_del_handler(RzCore *core, int argc, const char **argv) { ut64 addr = rz_num_math(core->num, argv[1]); - rz_type_unlink(core->analysis->type, addr); + rz_type_unlink(core->analysis->typedb, addr); return RZ_CMD_STATUS_OK; } RZ_IPI RzCmdStatus rz_type_link_del_all_handler(RzCore *core, int argc, const char **argv) { - rz_type_unlink_all(core->analysis->type); + rz_type_unlink_all(core->analysis->typedb); return RZ_CMD_STATUS_OK; } @@ -1189,7 +1189,7 @@ RZ_IPI RzCmdStatus rz_type_noreturn_del_handler(RzCore *core, int argc, const ch } RZ_IPI RzCmdStatus rz_type_noreturn_del_all_handler(RzCore *core, int argc, const char **argv) { - RzList *noretl = rz_type_noreturn_functions(core->analysis->type); + RzList *noretl = rz_type_noreturn_functions(core->analysis->typedb); RzListIter *iter; char *name; rz_list_foreach (noretl, iter, name) { @@ -1210,7 +1210,7 @@ RZ_IPI RzCmdStatus rz_type_open_editor_handler(RzCore *core, int argc, const cha } RZ_IPI RzCmdStatus rz_type_open_sdb_handler(RzCore *core, int argc, const char **argv) { - rz_type_load_sdb(core->analysis->type, argv[1]); + rz_type_db_load_sdb(core->analysis->typedb, argv[1]); return RZ_CMD_STATUS_OK; } @@ -1246,9 +1246,9 @@ RZ_IPI RzCmdStatus rz_type_list_structure_handler(RzCore *core, int argc, const if (mode == RZ_OUTPUT_MODE_RIZIN) { rz_core_types_struct_print_format_all(core); } else if (mode == RZ_OUTPUT_MODE_JSON) { - rz_types_struct_print_json(core->analysis->type); + rz_types_struct_print_json(core->analysis->typedb); } else { - rz_types_struct_print_sdb(core->analysis->type); + rz_types_struct_print_sdb(core->analysis->typedb); } } return RZ_CMD_STATUS_OK; @@ -1256,13 +1256,13 @@ RZ_IPI RzCmdStatus rz_type_list_structure_handler(RzCore *core, int argc, const RZ_IPI RzCmdStatus rz_type_structure_c_handler(RzCore *core, int argc, const char **argv) { const char *typename = argc > 1 ? argv[1] : NULL; - rz_types_struct_print_c(core->analysis->type, typename, true); + rz_types_struct_print_c(core->analysis->typedb, typename, true); return RZ_CMD_STATUS_OK; } RZ_IPI RzCmdStatus rz_type_structure_c_nl_handler(RzCore *core, int argc, const char **argv) { const char *typename = argc > 1 ? argv[1] : NULL; - rz_types_struct_print_c(core->analysis->type, typename, false); + rz_types_struct_print_c(core->analysis->typedb, typename, false); return RZ_CMD_STATUS_OK; } @@ -1281,27 +1281,27 @@ RZ_IPI RzCmdStatus rz_type_list_typedef_handler(RzCore *core, int argc, const ch RZ_IPI RzCmdStatus rz_type_typedef_c_handler(RzCore *core, int argc, const char **argv) { const char *typename = argc > 1 ? argv[1] : NULL; - RzType *T = core->analysis->type; + RzTypeDB *typedb = core->analysis->typedb; if (!typename) { - rz_types_typedef_print_c(T, NULL); + rz_types_typedef_print_c(typedb, NULL); return RZ_CMD_STATUS_OK; } - rz_types_typedef_print_c(T, typename); + rz_types_typedef_print_c(typedb, typename); return RZ_CMD_STATUS_OK; } RZ_IPI RzCmdStatus rz_type_list_union_handler(RzCore *core, int argc, const char **argv, RzOutputMode mode) { const char *typename = argc > 1 ? argv[1] : NULL; - RzType *T = core->analysis->type; + RzTypeDB *typedb = core->analysis->typedb; if (typename) { rz_core_types_show_format(core, typename, mode); } else { if (mode == RZ_OUTPUT_MODE_RIZIN) { rz_core_types_union_print_format_all(core); } else if (mode == RZ_OUTPUT_MODE_JSON) { - rz_types_union_print_json(T); + rz_types_union_print_json(typedb); } else { - rz_types_union_print_sdb(T); + rz_types_union_print_sdb(typedb); } } return RZ_CMD_STATUS_OK; @@ -1309,13 +1309,13 @@ RZ_IPI RzCmdStatus rz_type_list_union_handler(RzCore *core, int argc, const char RZ_IPI RzCmdStatus rz_type_union_c_handler(RzCore *core, int argc, const char **argv) { const char *typename = argc > 1 ? argv[1] : NULL; - rz_types_union_print_c(core->analysis->type, typename, true); + rz_types_union_print_c(core->analysis->typedb, typename, true); return RZ_CMD_STATUS_OK; } RZ_IPI RzCmdStatus rz_type_union_c_nl_handler(RzCore *core, int argc, const char **argv) { const char *typename = argc > 1 ? argv[1] : NULL; - rz_types_union_print_c(core->analysis->type, typename, false); + rz_types_union_print_c(core->analysis->typedb, typename, false); return RZ_CMD_STATUS_OK; } diff --git a/librz/core/cmd_zign.c b/librz/core/cmd_zign.c index b25fc27c939..d4e13319fe9 100644 --- a/librz/core/cmd_zign.c +++ b/librz/core/cmd_zign.c @@ -627,7 +627,7 @@ static void apply_types(RzCore *core, RzAnalysisFunction *fcn, RzSignItem *it) { } } rz_str_remove_char(alltypes, '"'); - rz_type_save_parsed_type(core->analysis->type, alltypes); + rz_type_db_save_parsed_type(core->analysis->typedb, alltypes); free(start); free(alltypes); } diff --git a/librz/core/core.c b/librz/core/core.c index 458a59e4a89..55ed1a380e9 100644 --- a/librz/core/core.c +++ b/librz/core/core.c @@ -1152,7 +1152,7 @@ static void autocompleteFilename(RzLineCompletion *completion, RzLineBuffer *buf static int autocomplete_pfele(RzCore *core, RzLineCompletion *completion, char *key, char *pfx, int idx, char *ptr) { int i, ret = 0; int len = strlen(ptr); - char *fmt = rz_type_format_get(core->analysis->type, key); + const char *fmt = rz_type_db_format_get(core->analysis->typedb, key); if (fmt) { int nargs = rz_str_word_set0_stack(fmt); if (nargs > 1) { @@ -1173,7 +1173,6 @@ static int autocomplete_pfele(RzCore *core, RzLineCompletion *completion, char * } } } - free(fmt); return ret; } @@ -1678,7 +1677,7 @@ RZ_API void rz_core_autocomplete(RZ_NULLABLE RzCore *core, RzLineCompletion *com } // FIXME: FORMATS RzListIter *iter; - RzList *fmtl = rz_type_format_all(core->analysis->type); + RzList *fmtl = rz_type_db_format_all(core->analysis->typedb); rz_list_foreach (fmtl, iter, kv) { int len = strlen(buf->data + chr); int minlen = RZ_MIN(len, strlen(sdbkv_key(kv))); @@ -2547,7 +2546,7 @@ RZ_API bool rz_core_init(RzCore *core) { rz_io_bind(core->io, &(core->search->iob)); rz_io_bind(core->io, &(core->print->iob)); rz_io_bind(core->io, &(core->analysis->iob)); - rz_io_bind(core->io, &(core->analysis->type->iob)); + rz_io_bind(core->io, &(core->analysis->typedb->iob)); rz_io_bind(core->io, &(core->bin->iob)); rz_flag_bind(core->flags, &(core->analysis->flb)); core->analysis->flg_class_set = core_flg_class_set; diff --git a/librz/core/core_private.h b/librz/core/core_private.h index 2b1b0f3e794..0a02f44a7ea 100644 --- a/librz/core/core_private.h +++ b/librz/core/core_private.h @@ -48,26 +48,23 @@ RZ_IPI void rz_core_analysis_value_pointers(RzCore *core, RzOutputMode mode); RZ_IPI void rz_core_types_calling_conventions_print(RzCore *core, RzOutputMode mode); RZ_IPI void rz_core_types_enum_print(RzCore *core, const char *enum_name, RzOutputMode mode, PJ *pj); RZ_IPI void rz_core_types_enum_print_all(RzCore *core, RzOutputMode mode); -RZ_IPI void rz_types_enum_print_c(RzType *type, const char *arg, bool multiline); +RZ_IPI void rz_types_enum_print_c(RzTypeDB *typedb, const char *arg, bool multiline); RZ_IPI bool rz_core_types_typedef_info(RzCore *core, const char *name); -RZ_IPI void rz_types_typedef_print_c(RzType *type, const char *typedef_name); +RZ_IPI void rz_types_typedef_print_c(RzTypeDB *typedb, const char *typedef_name); RZ_IPI void rz_core_list_loaded_typedefs(RzCore *core, RzOutputMode mode); -RZ_IPI RzList *rz_types_unions(RzType *type); -RZ_IPI RzList *rz_types_structs(RzType *type); -RZ_IPI RzList *rz_types_all(RzType *type); // Structured types JSON RZ_IPI void rz_types_structured_print_json(SdbList *l); -RZ_IPI void rz_types_union_print_json(RzType *type); -RZ_IPI void rz_types_struct_print_json(RzType *type); +RZ_IPI void rz_types_union_print_json(RzTypeDB *typedb); +RZ_IPI void rz_types_struct_print_json(RzTypeDB *typedb); // Structured types SDB RZ_IPI void rz_types_structured_print_sdb(SdbList *l); -RZ_IPI void rz_types_union_print_sdb(RzType *type); -RZ_IPI void rz_types_struct_print_sdb(RzType *type); +RZ_IPI void rz_types_union_print_sdb(RzTypeDB *typedb); +RZ_IPI void rz_types_struct_print_sdb(RzTypeDB *typedb); // Structured types C format -RZ_IPI void rz_types_union_print_c(RzType *type, const char *name, bool multiline); -RZ_IPI void rz_types_struct_print_c(RzType *type, const char *name, bool multiline); -RZ_IPI void rz_types_function_print(RzType *type, const char *function, RzOutputMode mode, PJ *pj); +RZ_IPI void rz_types_union_print_c(RzTypeDB *typedb, const char *name, bool multiline); +RZ_IPI void rz_types_struct_print_c(RzTypeDB *typedb, const char *name, bool multiline); +RZ_IPI void rz_types_function_print(RzTypeDB *typedb, const char *function, RzOutputMode mode, PJ *pj); RZ_IPI void rz_core_types_function_print_all(RzCore *core, RzOutputMode mode); RZ_IPI void rz_core_types_function_noreturn_print(RzCore *core, RzOutputMode mode); RZ_IPI void rz_core_types_show_format(RzCore *core, const char *name, RzOutputMode mode); @@ -81,7 +78,7 @@ RZ_IPI void rz_core_types_print_all(RzCore *core, RzOutputMode mode); RZ_IPI void rz_types_define(RzCore *core, const char *type); RZ_IPI void rz_types_open_file(RzCore *core, const char *path); RZ_IPI void rz_types_open_editor(RzCore *core, const char *typename); -RZ_IPI void rz_types_open_sdb(RzType *type, const char *path); +RZ_IPI void rz_types_open_sdb(RzTypeDB *typedb, const char *path); /* agraph.c */ RZ_IPI void rz_core_agraph_add_node(RzCore *core, const char *title, const char *body, int color); diff --git a/librz/core/ctypes.c b/librz/core/ctypes.c index 220cb6f949d..102f4a419d7 100644 --- a/librz/core/ctypes.c +++ b/librz/core/ctypes.c @@ -80,13 +80,13 @@ RZ_IPI void rz_core_types_calling_conventions_print(RzCore *core, RzOutputMode m RZ_IPI void rz_core_types_enum_print(RzCore *core, const char *enum_name, RzOutputMode mode, PJ *pj) { rz_return_if_fail(enum_name); - RzType *T = core->analysis->type; + RzTypeDB *typedb = core->analysis->typedb; switch (mode) { case RZ_OUTPUT_MODE_JSON: { rz_return_if_fail(pj); RzTypeEnum *member; RzListIter *iter; - RzList *list = rz_type_get_enum(T, enum_name); + RzList *list = rz_type_db_get_enum(typedb, enum_name); pj_o(pj); if (list && !rz_list_empty(list)) { pj_ks(pj, "name", enum_name); @@ -102,7 +102,7 @@ RZ_IPI void rz_core_types_enum_print(RzCore *core, const char *enum_name, RzOutp break; } case RZ_OUTPUT_MODE_STANDARD: { - RzList *list = rz_type_get_enum(T, enum_name); + RzList *list = rz_type_db_get_enum(typedb, enum_name); RzListIter *iter; RzTypeEnum *member; rz_list_foreach (list, iter, member) { @@ -115,7 +115,7 @@ RZ_IPI void rz_core_types_enum_print(RzCore *core, const char *enum_name, RzOutp rz_cons_println(enum_name); break; case RZ_OUTPUT_MODE_SDB: { - Sdb *TDB = T->sdb_types; + Sdb *TDB = typedb->sdb_types; char *keys = sdb_querys(TDB, NULL, -1, sdb_fmt("~~enum.%s", enum_name)); if (keys) { kv_lines_print_sorted(keys); @@ -129,7 +129,7 @@ RZ_IPI void rz_core_types_enum_print(RzCore *core, const char *enum_name, RzOutp } RZ_IPI void rz_core_types_enum_print_all(RzCore *core, RzOutputMode mode) { - RzList *enumlist = rz_type_enums(core->analysis->type); + RzList *enumlist = rz_type_db_enums(core->analysis->typedb); RzListIter *it; char *e; PJ *pj = (mode == RZ_OUTPUT_MODE_JSON) ? rz_core_pj_new(core) : NULL; @@ -147,11 +147,11 @@ RZ_IPI void rz_core_types_enum_print_all(RzCore *core, RzOutputMode mode) { } } -RZ_IPI void rz_types_enum_print_c(RzType *type, const char *arg, bool multiline) { +RZ_IPI void rz_types_enum_print_c(RzTypeDB *typedb, const char *arg, bool multiline) { char *name = NULL; SdbKv *kv; SdbListIter *iter; - SdbList *l = sdb_foreach_list(type->sdb_types, true); + SdbList *l = sdb_foreach_list(typedb->sdb_types, true); const char *separator = ""; bool match = false; ls_foreach (l, iter, kv) { @@ -168,7 +168,7 @@ RZ_IPI void rz_types_enum_print_c(RzType *type, const char *arg, bool multiline) } rz_cons_printf("%s %s {%s", sdbkv_value(kv), name, multiline ? "\n" : ""); { - RzList *list = rz_type_get_enum(type, name); + RzList *list = rz_type_db_get_enum(typedb, name); if (list && !rz_list_empty(list)) { RzListIter *iter; RzTypeEnum *member; @@ -237,15 +237,15 @@ RZ_IPI void rz_types_structured_print_json(SdbList *l) { pj_free(pj); } -RZ_IPI void rz_types_union_print_json(RzType *type) { - Sdb *TDB = type->sdb_types; +RZ_IPI void rz_types_union_print_json(RzTypeDB *typedb) { + Sdb *TDB = typedb->sdb_types; SdbList *l = sdb_foreach_list_filter(TDB, sdb_if_union_cb, true); rz_types_structured_print_json(l); ls_free(l); } -RZ_IPI void rz_types_struct_print_json(RzType *type) { - Sdb *TDB = type->sdb_types; +RZ_IPI void rz_types_struct_print_json(RzTypeDB *typedb) { + Sdb *TDB = typedb->sdb_types; SdbList *l = sdb_foreach_list_filter_user(TDB, sdb_if_struct_cb, true, TDB); rz_types_structured_print_json(l); ls_free(l); @@ -259,15 +259,15 @@ RZ_IPI void rz_types_structured_print_sdb(SdbList *l) { } } -RZ_IPI void rz_types_union_print_sdb(RzType *type) { - Sdb *TDB = type->sdb_types; +RZ_IPI void rz_types_union_print_sdb(RzTypeDB *typedb) { + Sdb *TDB = typedb->sdb_types; SdbList *l = sdb_foreach_list_filter(TDB, sdb_if_union_cb, true); rz_types_structured_print_sdb(l); ls_free(l); } -RZ_IPI void rz_types_struct_print_sdb(RzType *type) { - Sdb *TDB = type->sdb_types; +RZ_IPI void rz_types_struct_print_sdb(RzTypeDB *typedb) { + Sdb *TDB = typedb->sdb_types; SdbList *l = sdb_foreach_list_filter_user(TDB, sdb_if_struct_cb, true, TDB); rz_types_structured_print_sdb(l); ls_free(l); @@ -337,41 +337,25 @@ RZ_IPI void rz_types_structured_print_c(Sdb *TDB, SdbList *l, const char *arg, b free(name); } -RZ_IPI void rz_types_union_print_c(RzType *type, const char *name, bool multiline) { - Sdb *TDB = type->sdb_types; +RZ_IPI void rz_types_union_print_c(RzTypeDB *typedb, const char *name, bool multiline) { + Sdb *TDB = typedb->sdb_types; SdbList *l = sdb_foreach_list_filter(TDB, sdb_if_union_cb, true); rz_types_structured_print_c(TDB, l, name, multiline); ls_free(l); } -RZ_IPI void rz_types_struct_print_c(RzType *type, const char *name, bool multiline) { - Sdb *TDB = type->sdb_types; +RZ_IPI void rz_types_struct_print_c(RzTypeDB *typedb, const char *name, bool multiline) { + Sdb *TDB = typedb->sdb_types; SdbList *l = sdb_foreach_list_filter_user(TDB, sdb_if_struct_cb, true, TDB); rz_types_structured_print_c(TDB, l, name, multiline); ls_free(l); } -RZ_IPI RzList *rz_types_unions(RzType *type) { - Sdb *TDB = type->sdb_types; - SdbList *sl = sdb_foreach_list_filter_user(TDB, sdb_if_union_cb, true, TDB); - RzList *l = rz_list_of_sdblist(sl); - ls_free(sl); - return l; -} - -RZ_IPI RzList *rz_types_structs(RzType *type) { - Sdb *TDB = type->sdb_types; - SdbList *sl = sdb_foreach_list_filter_user(TDB, sdb_if_struct_cb, true, TDB); - RzList *l = rz_list_of_sdblist(sl); - ls_free(sl); - return l; -} - // Typedefs RZ_IPI bool rz_core_types_typedef_info(RzCore *core, const char *name) { const char *istypedef; - Sdb *TDB = core->analysis->type->sdb_types; + Sdb *TDB = core->analysis->typedb->sdb_types; istypedef = sdb_const_get(TDB, name, 0); if (istypedef && !strncmp(istypedef, "typedef", 7)) { const char *q = sdb_fmt("typedef.%s", name); @@ -390,7 +374,7 @@ RZ_IPI bool rz_core_types_typedef_info(RzCore *core, const char *name) { RZ_IPI void rz_core_list_loaded_typedefs(RzCore *core, RzOutputMode mode) { PJ *pj = NULL; - Sdb *TDB = core->analysis->type->sdb_types; + Sdb *TDB = core->analysis->typedb->sdb_types; if (mode == RZ_OUTPUT_MODE_JSON) { pj = rz_core_pj_new(core); if (!pj) { @@ -426,11 +410,11 @@ RZ_IPI void rz_core_list_loaded_typedefs(RzCore *core, RzOutputMode mode) { ls_free(l); } -RZ_IPI void rz_types_typedef_print_c(RzType *types, const char *typedef_name) { +RZ_IPI void rz_types_typedef_print_c(RzTypeDB *typedb, const char *typedef_name) { char *name = NULL; SdbKv *kv; SdbListIter *iter; - SdbList *l = sdb_foreach_list(types->sdb_types, true); + SdbList *l = sdb_foreach_list(typedb->sdb_types, true); bool match = false; ls_foreach (l, iter, kv) { if (!strcmp(sdbkv_value(kv), "typedef")) { @@ -445,7 +429,7 @@ RZ_IPI void rz_types_typedef_print_c(RzType *types, const char *typedef_name) { } } const char *q = sdb_fmt("typedef.%s", name); - const char *res = sdb_const_get(types->sdb_types, q, 0); + const char *res = sdb_const_get(typedb->sdb_types, q, 0); if (res) { rz_cons_printf("%s %s %s;\n", sdbkv_value(kv), res, name); } @@ -461,9 +445,9 @@ RZ_IPI void rz_types_typedef_print_c(RzType *types, const char *typedef_name) { // Function types -RZ_IPI void rz_types_function_print(RzType *type, const char *function, RzOutputMode mode, PJ *pj) { +RZ_IPI void rz_types_function_print(RzTypeDB *typedb, const char *function, RzOutputMode mode, PJ *pj) { rz_return_if_fail(function); - Sdb *TDB = type->sdb_types; + Sdb *TDB = typedb->sdb_types; char *res = sdb_querys(TDB, NULL, -1, sdb_fmt("func.%s.args", function)); int i, args = sdb_num_get(TDB, sdb_fmt("func.%s.args", function), 0); const char *ret = sdb_const_get(TDB, sdb_fmt("func.%s.ret", function), 0); @@ -523,7 +507,7 @@ RZ_IPI void rz_types_function_print(RzType *type, const char *function, RzOutput } RZ_IPI void rz_core_types_function_print_all(RzCore *core, RzOutputMode mode) { - Sdb *TDB = core->analysis->type->sdb_types; + Sdb *TDB = core->analysis->typedb->sdb_types; SdbKv *kv; SdbListIter *iter; PJ *pj = (mode == RZ_OUTPUT_MODE_JSON) ? rz_core_pj_new(core) : NULL; @@ -534,7 +518,7 @@ RZ_IPI void rz_core_types_function_print_all(RzCore *core, RzOutputMode mode) { ls_foreach (l, iter, kv) { if (!strcmp(sdbkv_value(kv), "func")) { const char *name = sdbkv_key(kv); - rz_types_function_print(core->analysis->type, name, mode, pj); + rz_types_function_print(core->analysis->typedb, name, mode, pj); } } ls_free(l); @@ -549,7 +533,7 @@ RZ_IPI void rz_core_types_function_print_all(RzCore *core, RzOutputMode mode) { static bool nonreturn_print_rizin(void *p, const char *k, const char *v) { RzCore *core = (RzCore *)p; - Sdb *TDB = core->analysis->type->sdb_types; + Sdb *TDB = core->analysis->typedb->sdb_types; if (!strncmp(v, "func", strlen("func") + 1)) { char *query = sdb_fmt("func.%s.noreturn", k); if (sdb_bool_get(TDB, query, NULL)) { @@ -586,10 +570,10 @@ static bool nonreturn_print_json(RzCore *core, RzList *noretl) { } RZ_IPI void rz_core_types_function_noreturn_print(RzCore *core, RzOutputMode mode) { - RzList *noretl = rz_type_noreturn_functions(core->analysis->type); + RzList *noretl = rz_type_noreturn_functions(core->analysis->typedb); switch (mode) { case RZ_OUTPUT_MODE_RIZIN: { - Sdb *TDB = core->analysis->type->sdb_types; + Sdb *TDB = core->analysis->typedb->sdb_types; sdb_foreach(TDB, nonreturn_print_rizin, core); break; } @@ -605,7 +589,7 @@ RZ_IPI void rz_core_types_function_noreturn_print(RzCore *core, RzOutputMode mod // Type formatting RZ_IPI void rz_core_types_show_format(RzCore *core, const char *name, RzOutputMode mode) { - char *fmt = rz_type_format(core->analysis->type, name); + char *fmt = rz_type_format(core->analysis->typedb, name); if (fmt) { rz_str_trim(fmt); switch (mode) { @@ -639,7 +623,7 @@ RZ_IPI void rz_core_types_show_format(RzCore *core, const char *name, RzOutputMo } static void print_all_format(RzCore *core, SdbForeachCallback sdbcb) { - Sdb *TDB = core->analysis->type->sdb_types; + Sdb *TDB = core->analysis->typedb->sdb_types; SdbList *l = sdb_foreach_list(TDB, true); SdbListIter *it; SdbKv *kv; @@ -686,8 +670,8 @@ static void set_retval(RzCore *core, ut64 at) { } static void set_offset_hint(RzCore *core, RzAnalysisOp *op, const char *type, ut64 laddr, ut64 at, int offimm) { - Sdb *TDB = core->analysis->type->sdb_types; - char *res = rz_type_get_struct_memb(core->analysis->type, type, offimm); + Sdb *TDB = core->analysis->typedb->sdb_types; + char *res = rz_type_get_struct_memb(core->analysis->typedb, type, offimm); const char *cmt = ((offimm == 0) && res) ? res : type; if (offimm > 0) { // set hint only if link is present @@ -710,7 +694,7 @@ RZ_API void rz_core_link_stroff(RzCore *core, RzAnalysisFunction *fcn) { bool resolved = false; const char *varpfx; int dbg_follow = rz_config_get_i(core->config, "dbg.follow"); - RzType *T = core->analysis->type; + RzTypeDB *typedb = core->analysis->typedb; RzAnalysisEsil *esil; int iotrap = rz_config_get_i(core->config, "esil.iotrap"); int stacksize = rz_config_get_i(core->config, "esil.stack.depth"); @@ -805,12 +789,12 @@ RZ_API void rz_core_link_stroff(RzCore *core, RzAnalysisFunction *fcn) { rz_analysis_op_fini(&aop); continue; } - char *slink = rz_type_link_at(T, src_addr); - char *vlink = rz_type_link_at(T, src_addr + src_imm); - char *dlink = rz_type_link_at(T, dst_addr); + char *slink = rz_type_link_at(typedb, src_addr); + char *vlink = rz_type_link_at(typedb, src_addr + src_imm); + char *dlink = rz_type_link_at(typedb, dst_addr); //TODO: Handle register based arg for struct offset propgation if (vlink && var && var->kind != 'r') { - if (rz_type_kind(T, vlink) == RZ_BASE_TYPE_KIND_UNION) { + if (rz_type_kind(typedb, vlink) == RZ_BASE_TYPE_KIND_UNION) { varpfx = "union"; } else { varpfx = "struct"; @@ -873,7 +857,7 @@ RZ_IPI void rz_core_types_link_print(RzCore *core, const char *type, ut64 addr, rz_cons_printf("tl %s 0x%" PFMT64x "\n", type, addr); break; case RZ_OUTPUT_MODE_LONG: { - char *fmt = rz_type_format(core->analysis->type, type); + char *fmt = rz_type_format(core->analysis->typedb, type); if (!fmt) { eprintf("Can't fint type %s", type); } @@ -888,7 +872,7 @@ RZ_IPI void rz_core_types_link_print(RzCore *core, const char *type, ut64 addr, } RZ_IPI void rz_core_types_link_print_all(RzCore *core, RzOutputMode mode) { - Sdb *TDB = core->analysis->type->sdb_types; + Sdb *TDB = core->analysis->typedb->sdb_types; SdbKv *kv; SdbListIter *iter; PJ *pj = (mode == RZ_OUTPUT_MODE_JSON) ? rz_core_pj_new(core) : NULL; @@ -914,14 +898,14 @@ RZ_IPI void rz_core_types_link_print_all(RzCore *core, RzOutputMode mode) { } RZ_IPI void rz_core_types_link(RzCore *core, const char *type, ut64 addr) { - Sdb *TDB = core->analysis->type->sdb_types; + Sdb *TDB = core->analysis->typedb->sdb_types; char *tmp = sdb_get(TDB, type, 0); if (RZ_STR_ISEMPTY(tmp)) { eprintf("unknown type %s\n", type); free(tmp); return; } - rz_type_set_link(core->analysis->type, type, addr); + rz_type_set_link(core->analysis->typedb, type, addr); RzList *fcns = rz_analysis_get_functions_in(core->analysis, core->offset); if (rz_list_length(fcns) > 1) { eprintf("Multiple functions found in here.\n"); @@ -934,7 +918,7 @@ RZ_IPI void rz_core_types_link(RzCore *core, const char *type, ut64 addr) { } RZ_IPI void rz_core_types_link_show(RzCore *core, ut64 addr) { - Sdb *TDB = core->analysis->type->sdb_types; + Sdb *TDB = core->analysis->typedb->sdb_types; const char *query = sdb_fmt("link.%08" PFMT64x, addr); const char *link = sdb_const_get(TDB, query, 0); if (link) { @@ -951,7 +935,7 @@ static bool sdb_if_type_cb(void *p, const char *k, const char *v) { RZ_IPI void rz_core_types_print_all(RzCore *core, RzOutputMode mode) { SdbListIter *it; SdbKv *kv; - Sdb *TDB = core->analysis->type->sdb_types; + Sdb *TDB = core->analysis->typedb->sdb_types; SdbList *l = sdb_foreach_list_filter(TDB, sdb_if_type_cb, true); switch (mode) { case RZ_OUTPUT_MODE_JSON: { @@ -1003,18 +987,6 @@ RZ_IPI void rz_core_types_print_all(RzCore *core, RzOutputMode mode) { ls_free(l); } -static bool sdb_if_c_type_cb(void *p, const char *k, const char *v) { - return sdb_if_union_cb(p, k, v) || sdb_if_struct_cb(p, k, v) || sdb_if_type_cb(p, k, v); -} - -RZ_IPI RzList *rz_types_all(RzType *type) { - Sdb *TDB = type->sdb_types; - SdbList *sl = sdb_foreach_list_filter_user(TDB, sdb_if_c_type_cb, true, TDB); - RzList *l = rz_list_of_sdblist(sl); - ls_free(sl); - return l; -} - RZ_IPI void rz_types_define(RzCore *core, const char *type) { // Add trailing semicolon to force the valid C syntax // It allows us to skip the trailing semicolon in the input @@ -1024,10 +996,10 @@ RZ_IPI void rz_types_define(RzCore *core, const char *type) { return; } char *error_msg = NULL; - char *out = rz_type_parse_c_string(core->analysis->type, tmp, &error_msg); + char *out = rz_type_parse_c_string(core->analysis->typedb, tmp, &error_msg); free(tmp); if (out) { - rz_type_save_parsed_type(core->analysis->type, out); + rz_type_db_save_parsed_type(core->analysis->typedb, out); free(out); } if (error_msg) { @@ -1039,7 +1011,7 @@ RZ_IPI void rz_types_define(RzCore *core, const char *type) { RZ_IPI void rz_types_open_file(RzCore *core, const char *path) { const char *dir = rz_config_get(core->config, "dir.types"); char *homefile = NULL; - RzType *type = core->analysis->type; + RzTypeDB *typedb = core->analysis->typedb; if (*path == '~') { if (path[1] && path[2]) { homefile = rz_str_home(path + 2); @@ -1050,9 +1022,9 @@ RZ_IPI void rz_types_open_file(RzCore *core, const char *path) { char *tmp = rz_core_editor(core, "*.h", ""); if (tmp) { char *error_msg = NULL; - char *out = rz_type_parse_c_string(type, tmp, &error_msg); + char *out = rz_type_parse_c_string(typedb, tmp, &error_msg); if (out) { - rz_type_save_parsed_type(type, out); + rz_type_db_save_parsed_type(typedb, out); free(out); } if (error_msg) { @@ -1063,9 +1035,9 @@ RZ_IPI void rz_types_open_file(RzCore *core, const char *path) { } } else { char *error_msg = NULL; - char *out = rz_type_parse_c_file(type, path, dir, &error_msg); + char *out = rz_type_parse_c_file(typedb, path, dir, &error_msg); if (out) { - rz_type_save_parsed_type(type, out); + rz_type_db_save_parsed_type(typedb, out); free(out); } if (error_msg) { @@ -1077,17 +1049,17 @@ RZ_IPI void rz_types_open_file(RzCore *core, const char *path) { } RZ_IPI void rz_types_open_editor(RzCore *core, const char *typename) { - RzType *type = core->analysis->type; + RzTypeDB *typedb = core->analysis->typedb; char *str = rz_core_cmd_strf(core, "tc %s", typename ? typename : ""); char *tmp = rz_core_editor(core, "*.h", str); if (tmp) { char *error_msg = NULL; - char *out = rz_type_parse_c_string(type, tmp, &error_msg); + char *out = rz_type_parse_c_string(typedb, tmp, &error_msg); if (out) { // remove previous types and save new edited types - rz_type_purge(type); - rz_type_parse_c_reset(type); - rz_type_save_parsed_type(type, out); + rz_type_db_purge(typedb); + rz_type_parse_c_reset(typedb); + rz_type_db_save_parsed_type(typedb, out); free(out); } if (error_msg) { diff --git a/librz/core/disasm.c b/librz/core/disasm.c index 1f4914d8520..8aaafeebde0 100644 --- a/librz/core/disasm.c +++ b/librz/core/disasm.c @@ -3123,7 +3123,7 @@ static bool ds_print_meta_infos(RDisasmState *ds, ut8 *buf, int len, int idx, in case RZ_META_TYPE_FORMAT: { rz_cons_printf("pf %s # size=%" PFMT64d "\n", mi->str, mi_size); int len_before = rz_cons_get_buffer_len(); - char *format = rz_type_format_data(core->analysis->type, core->print, ds->at, buf + idx, + char *format = rz_type_format_data(core->analysis->typedb, core->print, ds->at, buf + idx, len - idx, mi->str, RZ_PRINT_MUSTSEE, NULL, NULL); if (format) { rz_cons_print(format); @@ -4728,8 +4728,8 @@ static void ds_print_esil_analysis(RDisasmState *ds) { if (ds->asm_types < 1) { break; } - const char *fcn_type = rz_type_func_ret(core->analysis->type, key); - int nargs = rz_type_func_args_count(core->analysis->type, key); + const char *fcn_type = rz_type_func_ret(core->analysis->typedb, key); + int nargs = rz_type_func_args_count(core->analysis->typedb, key); // remove other comments delete_last_comment(ds); // ds_comment_start (ds, ""); @@ -4846,13 +4846,13 @@ static void ds_print_calls_hints(RDisasmState *ds) { if (!full_name) { return; } - if (rz_type_func_exist(analysis->type, full_name)) { + if (rz_type_func_exist(analysis->typedb, full_name)) { name = strdup(full_name); - } else if (!(name = rz_type_func_guess(analysis->type, full_name))) { + } else if (!(name = rz_type_func_guess(analysis->typedb, full_name))) { return; } ds_begin_comment(ds); - const char *fcn_type = rz_type_func_ret(analysis->type, name); + const char *fcn_type = rz_type_func_ret(analysis->typedb, name); if (!fcn_type || !*fcn_type) { free(name); return; @@ -4860,13 +4860,13 @@ static void ds_print_calls_hints(RDisasmState *ds) { char *cmt = rz_str_newf("; %s%s%s(", fcn_type, fcn_type[strlen(fcn_type) - 1] == '*' ? "" : " ", name); - int i, arg_max = rz_type_func_args_count(analysis->type, name); + int i, arg_max = rz_type_func_args_count(analysis->typedb, name); if (!arg_max) { cmt = rz_str_append(cmt, "void)"); } else { for (i = 0; i < arg_max; i++) { - char *type = rz_type_func_args_type(analysis->type, name, i); - const char *tname = rz_type_func_args_name(analysis->type, name, i); + char *type = rz_type_func_args_type(analysis->typedb, name, i); + const char *tname = rz_type_func_args_name(analysis->typedb, name, i); if (type && *type) { cmt = rz_str_appendf(cmt, "%s%s%s%s%s", i == 0 ? "" : " ", type, type[strlen(type) - 1] == '*' ? "" : " ", @@ -5289,13 +5289,13 @@ RZ_API int rz_core_print_disasm(RzPrint *p, RzCore *core, ut64 addr, ut8 *buf, i f = ds->fcn = fcnIn(ds, ds->at, RZ_ANALYSIS_FCN_TYPE_NULL); ds_show_comments_right(ds); // TRY adding here - char *link_type = rz_type_link_at(core->analysis->type, ds->addr + idx); + char *link_type = rz_type_link_at(core->analysis->typedb, ds->addr + idx); if (link_type) { - char *fmt = rz_type_format(core->analysis->type, link_type); + char *fmt = rz_type_format(core->analysis->typedb, link_type); if (fmt) { rz_cons_printf("(%s)\n", link_type); rz_core_cmdf(core, "pf %s @ 0x%08" PFMT64x "\n", fmt, ds->addr + idx); - const ut32 type_bitsize = rz_type_get_bitsize(core->analysis->type, link_type); + const ut32 type_bitsize = rz_type_db_get_bitsize(core->analysis->typedb, link_type); // always round up when calculating byte_size from bit_size of types // could be struct with a bitfield entry inc = (type_bitsize >> 3) + (!!(type_bitsize & 0x7)); diff --git a/librz/core/vmenus.c b/librz/core/vmenus.c index 4ba5271a420..c9cc11b1ad2 100644 --- a/librz/core/vmenus.c +++ b/librz/core/vmenus.c @@ -584,7 +584,7 @@ static bool sdbforcb(void *p, const char *k, const char *v) { } } else if (!strcmp(v, vt->type)) { if (!strcmp(vt->type, "type")) { - const char *fmt = rz_type_get(vt->core->analysis->type, k); + const char *fmt = rz_type_db_get(vt->core->analysis->typedb, k); if (vt->t_idx == vt->t_ctr) { free(vt->curname); vt->curname = strdup(k); @@ -670,7 +670,7 @@ RZ_API int rz_core_visual_types(RzCore *core) { vt.t_ctr = 0; vt.type = opts[h_opt]; vt.optword = optword; - sdb_foreach(core->analysis->type->sdb_types, sdbforcb, &vt); + sdb_foreach(core->analysis->typedb->sdb_types, sdbforcb, &vt); } rz_cons_visual_flush(); @@ -755,7 +755,7 @@ RZ_API int rz_core_visual_types(RzCore *core) { } } break; case 'd': - rz_type_remove_parsed_type(core->analysis->type, vt.curname); + rz_type_db_remove_parsed_type(core->analysis->typedb, vt.curname); break; case '-': rz_types_open_editor(core, NULL); diff --git a/librz/include/rz_analysis.h b/librz/include/rz_analysis.h index 6dd1a566aba..688bc289c8d 100644 --- a/librz/include/rz_analysis.h +++ b/librz/include/rz_analysis.h @@ -613,7 +613,7 @@ typedef struct rz_analysis_t { RHintCb hint_cbs; RzIntervalTree meta; RzSpaces meta_spaces; - RzType *type; // Types management + RzTypeDB *typedb; // Types management Sdb *sdb_cc; // calling conventions Sdb *sdb_classes; Sdb *sdb_classes_attrs; @@ -2009,7 +2009,7 @@ RZ_API RzStrBuf *rz_analysis_esil_dfg_filter_expr(RzAnalysis *analysis, const ch RZ_API RzList *rz_analysis_types_from_fcn(RzAnalysis *analysis, RzAnalysisFunction *fcn); /* PDB */ -RZ_API void rz_parse_pdb_types(const RzType *type, const RzPdb *pdb); +RZ_API void rz_parse_pdb_types(const RzTypeDB *typedb, const RzPdb *pdb); /* DWARF */ RZ_API void rz_analysis_dwarf_process_info(const RzAnalysis *analysis, RzAnalysisDwarfContext *ctx); diff --git a/librz/include/rz_type.h b/librz/include/rz_type.h index 08c8af3b398..22e0c360ed2 100644 --- a/librz/include/rz_type.h +++ b/librz/include/rz_type.h @@ -30,7 +30,7 @@ typedef struct rz_type_t { RzTypeTarget *target; RNum *num; RzIOBind iob; // for RzIO in formats -} RzType; +} RzTypeDB; typedef struct rz_type_enum_case_t { char *name; @@ -90,28 +90,33 @@ typedef struct rz_type_enum { #ifdef RZ_API -RZ_API RzType *rz_type_new(); -RZ_API void rz_type_free(RzType *t); -RZ_API void rz_type_load_sdb(RzType *t, const char *dpath); -RZ_API void rz_type_purge(RzType *t); -RZ_API void rz_type_set_bits(RzType *t, int bits); -RZ_API void rz_type_set_os(RzType *t, const char *os); -RZ_API void rz_type_set_cpu(RzType *t, const char *cpu); -RZ_API char *rz_type_kuery(RzType *t, const char *query); +RZ_API RzTypeDB *rz_type_db_new(); +RZ_API void rz_type_db_free(RzTypeDB *typedb); +RZ_API void rz_type_db_load_sdb(RzTypeDB *typedb, const char *dpath); +RZ_API void rz_type_db_purge(RzTypeDB *typedb); +RZ_API void rz_type_db_set_bits(RzTypeDB *typedb, int bits); +RZ_API void rz_type_db_set_os(RzTypeDB *typedb, const char *os); +RZ_API void rz_type_db_set_cpu(RzTypeDB *typedb, const char *cpu); +RZ_API char *rz_type_db_kuery(RzTypeDB *typedb, const char *query); -RZ_API void rz_type_db_init(RzType *types, const char *dir_prefix, const char *arch, int bits, const char *os); +RZ_API const char *rz_type_db_get(RzTypeDB *typedb, const char *name); +RZ_API bool rz_type_db_set(RzTypeDB *typedb, ut64 at, const char *field, ut64 val); +RZ_API bool rz_type_db_del(RzTypeDB *typedb, RZ_NONNULL const char *name); + +RZ_API void rz_type_db_init(RzTypeDB *typedb, const char *dir_prefix, const char *arch, int bits, const char *os); // Base types -RZ_API RzBaseType *rz_type_get_base_type(RzType *type, const char *name); -RZ_API void rz_type_base_type(const RzType *t, const RzBaseType *type); +RZ_API void rz_type_base_type(const RzTypeDB *typedb, const RzBaseType *type); RZ_API void rz_type_base_type_free(RzBaseType *type); RZ_API RzBaseType *rz_type_base_type_new(RzBaseTypeKind kind); RZ_API void rz_type_base_enum_case_free(void *e, void *user); RZ_API void rz_type_base_struct_member_free(void *e, void *user); RZ_API void rz_type_base_union_member_free(void *e, void *user); -RZ_API void rz_type_save_base_type(const RzType *t, const RzBaseType *type); + +RZ_API RzBaseType *rz_type_db_get_base_type(RzTypeDB *typedb, const char *name); +RZ_API void rz_type_db_save_base_type(const RzTypeDB *typedb, const RzBaseType *type); /* ctype */ // Parses strings like "const char * [0x42] const * [23]" to RzTypeCTypeType @@ -157,67 +162,67 @@ RZ_API RzTypeCTypeType *rz_type_ctype_parse(RzTypeCType *ctype, const char *str, RZ_API void rz_type_ctype_type_free(RzTypeCTypeType *type); /* c */ -RZ_API char *rz_type_parse_c_string(RzType *type, const char *code, char **error_msg); -RZ_API char *rz_type_parse_c_file(RzType *type, const char *path, const char *dir, char **error_msg); -RZ_API void rz_type_parse_c_reset(RzType *p); - -RZ_API void rz_type_remove_parsed_type(RzType *t, const char *name); -RZ_API void rz_type_save_parsed_type(RzType *t, const char *parsed); - -RZ_API const char *rz_type_get(RzType *t, const char *name); -RZ_API bool rz_type_set(RzType *t, ut64 at, const char *field, ut64 val); -RZ_API bool rz_type_del(RzType *t, const char *name); -RZ_API int rz_type_kind(RzType *t, const char *name); -RZ_API char *rz_type_enum_member(RzType *t, const char *name, const char *member, ut64 val); -RZ_API RzList *rz_type_enum_find_member(RzType *t, ut64 val); -RZ_API char *rz_type_enum_getbitfield(RzType *t, const char *name, ut64 val); -RZ_API RzList *rz_type_get_enum(RzType *t, const char *name); -RZ_API ut64 rz_type_get_bitsize(RzType *t, const char *type); -RZ_API RzList *rz_type_get_by_offset(RzType *t, ut64 offset); -RZ_API char *rz_type_get_struct_memb(RzType *t, const char *type, int offset); +RZ_API char *rz_type_parse_c_string(RzTypeDB *typedb, const char *code, char **error_msg); +RZ_API char *rz_type_parse_c_file(RzTypeDB *typedb, const char *path, const char *dir, char **error_msg); +RZ_API void rz_type_parse_c_reset(RzTypeDB *typedb); + +RZ_API void rz_type_db_remove_parsed_type(RzTypeDB *typedb, const char *name); +RZ_API void rz_type_db_save_parsed_type(RzTypeDB *typedb, const char *parsed); + +RZ_API int rz_type_kind(RzTypeDB *typedb, const char *name); +RZ_API char *rz_type_db_enum_member(RzTypeDB *typedb, const char *name, const char *member, ut64 val); +RZ_API RzList *rz_type_db_enum_find_member(RzTypeDB *typedb, ut64 val); +RZ_API char *rz_type_enum_getbitfield(RzTypeDB *typedb, const char *name, ut64 val); +RZ_API RzList *rz_type_db_get_enum(RzTypeDB *typedb, const char *name); +RZ_API ut64 rz_type_db_get_bitsize(RzTypeDB *typedb, const char *type); +RZ_API RzList *rz_type_get_by_offset(RzTypeDB *typedb, ut64 offset); +RZ_API char *rz_type_get_struct_memb(RzTypeDB *typedb, const char *type, int offset); // Maintaining type links -RZ_API char *rz_type_link_at(RzType *t, ut64 addr); -RZ_API bool rz_type_set_link(RzType *t, const char *val, ut64 addr); -RZ_API bool rz_type_unlink(RzType *t, ut64 addr); -RZ_API bool rz_type_unlink_all(RzType *t); -RZ_API bool rz_type_link_offset(RzType *t, const char *val, ut64 addr); +RZ_API char *rz_type_link_at(RzTypeDB *typedb, ut64 addr); +RZ_API bool rz_type_set_link(RzTypeDB *typedb, const char *val, ut64 addr); +RZ_API bool rz_type_unlink(RzTypeDB *typedb, ut64 addr); +RZ_API bool rz_type_unlink_all(RzTypeDB *typedb); +RZ_API bool rz_type_link_offset(RzTypeDB *typedb, const char *val, ut64 addr); // Type formats (`tp` and `pf` commands) -RZ_API const char *rz_type_format_get(RzType *t, const char *name); -RZ_API void rz_type_format_set(RzType *t, const char *name, const char *fmt); -RZ_API RZ_OWN RzList *rz_type_format_all(RzType *t); -RZ_API void rz_type_format_delete(RzType *t, const char *name); -RZ_API void rz_type_format_purge(RzType *t); - -RZ_API char *rz_type_format(RzType *type, const char *t); -RZ_API int rz_type_format_struct_size(RzType *t, const char *f, int mode, int n); -RZ_API const char *rz_type_format_byname(RzType *t, const char *name); -RZ_API char *rz_type_format_data(RzType *t, RzPrint *p, ut64 seek, const ut8 *b, const int len, +RZ_API const char *rz_type_db_format_get(RzTypeDB *typedb, const char *name); +RZ_API const char *rz_type_db_format_byname(RzTypeDB *typedb, const char *name); +RZ_API void rz_type_db_format_set(RzTypeDB *typedb, const char *name, const char *fmt); +RZ_API RZ_OWN RzList *rz_type_db_format_all(RzTypeDB *typedb); +RZ_API void rz_type_db_format_delete(RzTypeDB *typedb, const char *name); +RZ_API void rz_type_db_format_purge(RzTypeDB *typedb); + +RZ_API char *rz_type_format(RzTypeDB *typedb, const char *type); +RZ_API int rz_type_format_struct_size(RzTypeDB *typedb, const char *f, int mode, int n); +RZ_API char *rz_type_format_data(RzTypeDB *t, RzPrint *p, ut64 seek, const ut8 *b, const int len, const char *formatname, int mode, const char *setval, char *ofield); // Function prototypes api -RZ_API bool rz_type_func_exist(RzType *t, const char *func_name); -RZ_API const char *rz_type_func_cc(RzType *t, const char *func_name); -RZ_API const char *rz_type_func_ret(RzType *t, const char *func_name); -RZ_API const char *rz_type_func_cc(RzType *t, const char *func_name); -RZ_API int rz_type_func_args_count(RzType *t, RZ_NONNULL const char *func_name); -RZ_API RZ_OWN char *rz_type_func_args_type(RzType *t, RZ_NONNULL const char *func_name, int i); -RZ_API const char *rz_type_func_args_name(RzType *t, RZ_NONNULL const char *func_name, int i); -RZ_API bool rz_type_func_arg_count_set(RzType *t, RZ_NONNULL const char *func_name, int arg_count); -RZ_API bool rz_type_func_arg_set(RzType *t, RZ_NONNULL const char *func_name, int i, RZ_NONNULL const char *arg_name, RZ_NONNULL const char *arg_type); -RZ_API bool rz_type_func_ret_set(RzType *t, const char *func_name, const char *type); -RZ_API RZ_OWN char *rz_type_func_guess(RzType *t, RZ_NONNULL char *func_name); -RZ_API RzList *rz_type_noreturn_functions(RzType *type); +RZ_API bool rz_type_func_exist(RzTypeDB *typedb, const char *func_name); +RZ_API const char *rz_type_func_cc(RzTypeDB *typedb, const char *func_name); +RZ_API const char *rz_type_func_ret(RzTypeDB *typedb, const char *func_name); +RZ_API const char *rz_type_func_cc(RzTypeDB *typedb, const char *func_name); +RZ_API int rz_type_func_args_count(RzTypeDB *typedb, RZ_NONNULL const char *func_name); +RZ_API RZ_OWN char *rz_type_func_args_type(RzTypeDB *typedb, RZ_NONNULL const char *func_name, int i); +RZ_API const char *rz_type_func_args_name(RzTypeDB *typedb, RZ_NONNULL const char *func_name, int i); +RZ_API bool rz_type_func_arg_count_set(RzTypeDB *typedb, RZ_NONNULL const char *func_name, int arg_count); +RZ_API bool rz_type_func_arg_set(RzTypeDB *typedb, RZ_NONNULL const char *func_name, int i, RZ_NONNULL const char *arg_name, RZ_NONNULL const char *arg_type); +RZ_API bool rz_type_func_ret_set(RzTypeDB *typedb, const char *func_name, const char *type); +RZ_API RZ_OWN char *rz_type_func_guess(RzTypeDB *typedb, RZ_NONNULL char *func_name); +RZ_API RzList *rz_type_noreturn_functions(RzTypeDB *typedb); // Listing API -RZ_API RzList *rz_type_enums(RzType *type); -RZ_API RzList *rz_type_typedefs(RzType *type); -RZ_API RzList *rz_type_links(RzType *type); +RZ_API RzList *rz_type_db_enums(RzTypeDB *typedb); +RZ_API RzList *rz_type_db_structs(RzTypeDB *typedb); +RZ_API RzList *rz_type_db_unions(RzTypeDB *typedb); +RZ_API RzList *rz_type_db_typedefs(RzTypeDB *typedb); +RZ_API RzList *rz_type_db_links(RzTypeDB *typedb); +RZ_API RzList *rz_type_db_all(RzTypeDB *typedb); // Serialization API -RZ_API void rz_serialize_types_save(RZ_NONNULL Sdb *db, RZ_NONNULL RzType *types); -RZ_API bool rz_serialize_types_load(RZ_NONNULL Sdb *db, RZ_NONNULL RzType *types, RZ_NULLABLE RzSerializeResultInfo *res); +RZ_API void rz_serialize_types_save(RZ_NONNULL Sdb *db, RZ_NONNULL RzTypeDB *typedb); +RZ_API bool rz_serialize_types_load(RZ_NONNULL Sdb *db, RZ_NONNULL RzTypeDB *typedb, RZ_NULLABLE RzSerializeResultInfo *res); #endif diff --git a/librz/type/base.c b/librz/type/base.c index 134aea3b5eb..62b2c91e1cc 100644 --- a/librz/type/base.c +++ b/librz/type/base.c @@ -38,15 +38,15 @@ static char *get_type_data(Sdb *sdb_types, const char *type, const char *sname) return members; } -static RzBaseType *get_enum_type(RzType *type, const char *sname) { - rz_return_val_if_fail(type && sname, NULL); +static RzBaseType *get_enum_type(RzTypeDB *typedb, const char *sname) { + rz_return_val_if_fail(typedb && sname, NULL); RzBaseType *base_type = rz_type_base_type_new(RZ_BASE_TYPE_KIND_ENUM); if (!base_type) { return NULL; } - char *members = get_type_data(type->sdb_types, "enum", sname); + char *members = get_type_data(typedb->sdb_types, "enum", sname); if (!members) { goto error; } @@ -62,7 +62,7 @@ static RzBaseType *get_enum_type(RzType *type, const char *sname) { if (!val_key) { goto error; } - const char *value = sdb_const_get(type->sdb_types, val_key, NULL); + const char *value = sdb_const_get(typedb->sdb_types, val_key, NULL); free(val_key); if (!value) { // if nothing is found, ret NULL @@ -88,15 +88,15 @@ static RzBaseType *get_enum_type(RzType *type, const char *sname) { return NULL; } -static RzBaseType *get_struct_type(RzType *type, const char *sname) { - rz_return_val_if_fail(type && sname, NULL); +static RzBaseType *get_struct_type(RzTypeDB *typedb, const char *sname) { + rz_return_val_if_fail(typedb && sname, NULL); RzBaseType *base_type = rz_type_base_type_new(RZ_BASE_TYPE_KIND_STRUCT); if (!base_type) { return NULL; } - char *sdb_members = get_type_data(type->sdb_types, "struct", sname); + char *sdb_members = get_type_data(typedb->sdb_types, "struct", sname); if (!sdb_members) { goto error; } @@ -112,7 +112,7 @@ static RzBaseType *get_struct_type(RzType *type, const char *sname) { if (!type_key) { goto error; } - char *values = sdb_get(type->sdb_types, type_key, NULL); + char *values = sdb_get(typedb->sdb_types, type_key, NULL); free(type_key); if (!values) { @@ -150,15 +150,15 @@ static RzBaseType *get_struct_type(RzType *type, const char *sname) { return NULL; } -static RzBaseType *get_union_type(RzType *type, const char *sname) { - rz_return_val_if_fail(type && sname, NULL); +static RzBaseType *get_union_type(RzTypeDB *typedb, const char *sname) { + rz_return_val_if_fail(typedb && sname, NULL); RzBaseType *base_type = rz_type_base_type_new(RZ_BASE_TYPE_KIND_UNION); if (!base_type) { return NULL; } - char *sdb_members = get_type_data(type->sdb_types, "union", sname); + char *sdb_members = get_type_data(typedb->sdb_types, "union", sname); if (!sdb_members) { goto error; } @@ -174,7 +174,7 @@ static RzBaseType *get_union_type(RzType *type, const char *sname) { if (!type_key) { goto error; } - char *values = sdb_get(type->sdb_types, type_key, NULL); + char *values = sdb_get(typedb->sdb_types, type_key, NULL); free(type_key); if (!values) { @@ -201,15 +201,15 @@ static RzBaseType *get_union_type(RzType *type, const char *sname) { return NULL; } -static RzBaseType *get_typedef_type(RzType *type, const char *sname) { - rz_return_val_if_fail(type && RZ_STR_ISNOTEMPTY(sname), NULL); +static RzBaseType *get_typedef_type(RzTypeDB *typedb, const char *sname) { + rz_return_val_if_fail(typedb && RZ_STR_ISNOTEMPTY(sname), NULL); RzBaseType *base_type = rz_type_base_type_new(RZ_BASE_TYPE_KIND_TYPEDEF); if (!base_type) { return NULL; } - base_type->type = get_type_data(type->sdb_types, "typedef", sname); + base_type->type = get_type_data(typedb->sdb_types, "typedef", sname); if (!base_type->type) { goto error; } @@ -220,21 +220,21 @@ static RzBaseType *get_typedef_type(RzType *type, const char *sname) { return NULL; } -static RzBaseType *get_atomic_type(RzType *type, const char *sname) { - rz_return_val_if_fail(type && RZ_STR_ISNOTEMPTY(sname), NULL); +static RzBaseType *get_atomic_type(RzTypeDB *typedb, const char *sname) { + rz_return_val_if_fail(typedb && RZ_STR_ISNOTEMPTY(sname), NULL); RzBaseType *base_type = rz_type_base_type_new(RZ_BASE_TYPE_KIND_ATOMIC); if (!base_type) { return NULL; } - base_type->type = get_type_data(type->sdb_types, "type", sname); + base_type->type = get_type_data(typedb->sdb_types, "type", sname); if (!base_type->type) { goto error; } RzStrBuf key; - base_type->size = sdb_num_get(type->sdb_types, rz_strbuf_initf(&key, "type.%s.size", sname), 0); + base_type->size = sdb_num_get(typedb->sdb_types, rz_strbuf_initf(&key, "type.%s.size", sname), 0); rz_strbuf_fini(&key); return base_type; @@ -245,11 +245,11 @@ static RzBaseType *get_atomic_type(RzType *type, const char *sname) { } // returns NULL if name is not found or any failure happened -RZ_API RzBaseType *rz_type_get_base_type(RzType *t, const char *name) { - rz_return_val_if_fail(t && name, NULL); +RZ_API RzBaseType *rz_type_db_get_base_type(RzTypeDB *typedb, const char *name) { + rz_return_val_if_fail(typedb && name, NULL); char *sname = rz_str_sanitize_sdb_key(name); - const char *type = sdb_const_get(t->sdb_types, sname, NULL); + const char *type = sdb_const_get(typedb->sdb_types, sname, NULL); if (!type) { free(sname); return NULL; @@ -257,15 +257,15 @@ RZ_API RzBaseType *rz_type_get_base_type(RzType *t, const char *name) { RzBaseType *base_type = NULL; if (!strcmp(type, "struct")) { - base_type = get_struct_type(t, sname); + base_type = get_struct_type(typedb, sname); } else if (!strcmp(type, "enum")) { - base_type = get_enum_type(t, sname); + base_type = get_enum_type(typedb, sname); } else if (!strcmp(type, "union")) { - base_type = get_union_type(t, sname); + base_type = get_union_type(typedb, sname); } else if (!strcmp(type, "typedef")) { - base_type = get_typedef_type(t, sname); + base_type = get_typedef_type(typedb, sname); } else if (!strcmp(type, "type")) { - base_type = get_atomic_type(t, sname); + base_type = get_atomic_type(typedb, sname); } if (base_type) { @@ -277,8 +277,8 @@ RZ_API RzBaseType *rz_type_get_base_type(RzType *t, const char *name) { return base_type; } -static void save_struct(const RzType *t, const RzBaseType *type) { - rz_return_if_fail(t && type && type->name && type->kind == RZ_BASE_TYPE_KIND_STRUCT); +static void save_struct(const RzTypeDB *typedb, const RzBaseType *type) { + rz_return_if_fail(typedb && type && type->name && type->kind == RZ_BASE_TYPE_KIND_STRUCT); char *kind = "struct"; /* C: @@ -292,7 +292,7 @@ static void save_struct(const RzType *t, const RzBaseType *type) { */ char *sname = rz_str_sanitize_sdb_key(type->name); // name=struct - sdb_set(t->sdb_types, sname, kind, 0); + sdb_set(typedb->sdb_types, sname, kind, 0); RzStrBuf arglist; RzStrBuf param_key; @@ -306,7 +306,7 @@ static void save_struct(const RzType *t, const RzBaseType *type) { rz_vector_foreach(&type->struct_data.members, member) { // struct.name.param=type,offset,argsize char *member_sname = rz_str_sanitize_sdb_key(member->name); - sdb_set(t->sdb_types, + sdb_set(typedb->sdb_types, rz_strbuf_setf(¶m_key, "%s.%s.%s", kind, sname, member_sname), rz_strbuf_setf(¶m_val, "%s,%zu,%u", member->type, member->offset, 0), 0ULL); free(member_sname); @@ -315,7 +315,7 @@ static void save_struct(const RzType *t, const RzBaseType *type) { } // struct.name=param1,param2,paramN char *key = rz_str_newf("%s.%s", kind, sname); - sdb_set(t->sdb_types, key, rz_strbuf_get(&arglist), 0); + sdb_set(typedb->sdb_types, key, rz_strbuf_get(&arglist), 0); free(key); free(sname); @@ -325,8 +325,8 @@ static void save_struct(const RzType *t, const RzBaseType *type) { rz_strbuf_fini(¶m_val); } -static void save_union(const RzType *t, const RzBaseType *type) { - rz_return_if_fail(t && type && type->name && type->kind == RZ_BASE_TYPE_KIND_UNION); +static void save_union(const RzTypeDB *typedb, const RzBaseType *type) { + rz_return_if_fail(typedb && type && type->name && type->kind == RZ_BASE_TYPE_KIND_UNION); const char *kind = "union"; /* C: @@ -340,7 +340,7 @@ static void save_union(const RzType *t, const RzBaseType *type) { */ char *sname = rz_str_sanitize_sdb_key(type->name); // name=union - sdb_set(t->sdb_types, sname, kind, 0); + sdb_set(typedb->sdb_types, sname, kind, 0); RzStrBuf arglist; RzStrBuf param_key; @@ -354,7 +354,7 @@ static void save_union(const RzType *t, const RzBaseType *type) { rz_vector_foreach(&type->union_data.members, member) { // union.name.arg1=type,offset,argsize char *member_sname = rz_str_sanitize_sdb_key(member->name); - sdb_set(t->sdb_types, + sdb_set(typedb->sdb_types, rz_strbuf_setf(¶m_key, "%s.%s.%s", kind, sname, member_sname), rz_strbuf_setf(¶m_val, "%s,%zu,%u", member->type, member->offset, 0), 0ULL); free(member_sname); @@ -363,7 +363,7 @@ static void save_union(const RzType *t, const RzBaseType *type) { } // union.name=arg1,arg2,argN char *key = rz_str_newf("%s.%s", kind, sname); - sdb_set(t->sdb_types, key, rz_strbuf_get(&arglist), 0); + sdb_set(typedb->sdb_types, key, rz_strbuf_get(&arglist), 0); free(key); free(sname); @@ -373,8 +373,8 @@ static void save_union(const RzType *t, const RzBaseType *type) { rz_strbuf_fini(¶m_val); } -static void save_enum(const RzType *t, const RzBaseType *type) { - rz_return_if_fail(t && type && type->name && type->kind == RZ_BASE_TYPE_KIND_ENUM); +static void save_enum(const RzTypeDB *typedb, const RzBaseType *type) { + rz_return_if_fail(typedb && type && type->name && type->kind == RZ_BASE_TYPE_KIND_ENUM); /* C: enum name {case1 = 1, case2 = 2, caseN = 3}; @@ -389,7 +389,7 @@ static void save_enum(const RzType *t, const RzBaseType *type) { enum.MyEnum.argN=0x3 */ char *sname = rz_str_sanitize_sdb_key(type->name); - sdb_set(t->sdb_types, sname, "enum", 0); + sdb_set(typedb->sdb_types, sname, "enum", 0); RzStrBuf arglist; RzStrBuf param_key; @@ -403,11 +403,11 @@ static void save_enum(const RzType *t, const RzBaseType *type) { rz_vector_foreach(&type->enum_data.cases, cas) { // enum.name.arg1=type,offset,??? char *case_sname = rz_str_sanitize_sdb_key(cas->name); - sdb_set(t->sdb_types, + sdb_set(typedb->sdb_types, rz_strbuf_setf(¶m_key, "enum.%s.%s", sname, case_sname), rz_strbuf_setf(¶m_val, "0x%" PFMT32x "", cas->val), 0); - sdb_set(t->sdb_types, + sdb_set(typedb->sdb_types, rz_strbuf_setf(¶m_key, "enum.%s.0x%" PFMT32x "", sname, cas->val), case_sname, 0); free(case_sname); @@ -416,7 +416,7 @@ static void save_enum(const RzType *t, const RzBaseType *type) { } // enum.name=arg1,arg2,argN char *key = rz_str_newf("enum.%s", sname); - sdb_set(t->sdb_types, key, rz_strbuf_get(&arglist), 0); + sdb_set(typedb->sdb_types, key, rz_strbuf_get(&arglist), 0); free(key); free(sname); @@ -426,8 +426,8 @@ static void save_enum(const RzType *t, const RzBaseType *type) { rz_strbuf_fini(¶m_val); } -static void save_atomic_type(const RzType *t, const RzBaseType *type) { - rz_return_if_fail(t && type && type->name && type->kind == RZ_BASE_TYPE_KIND_ATOMIC); +static void save_atomic_type(const RzTypeDB *typedb, const RzBaseType *type) { + rz_return_if_fail(typedb && type && type->name && type->kind == RZ_BASE_TYPE_KIND_ATOMIC); /* C: (cannot define a custom atomic type) Sdb: @@ -436,18 +436,18 @@ static void save_atomic_type(const RzType *t, const RzBaseType *type) { type.char.size=8 */ char *sname = rz_str_sanitize_sdb_key(type->name); - sdb_set(t->sdb_types, sname, "type", 0); + sdb_set(typedb->sdb_types, sname, "type", 0); RzStrBuf key; RzStrBuf val; rz_strbuf_init(&key); rz_strbuf_init(&val); - sdb_set(t->sdb_types, + sdb_set(typedb->sdb_types, rz_strbuf_setf(&key, "type.%s.size", sname), rz_strbuf_setf(&val, "%" PFMT64u "", type->size), 0); - sdb_set(t->sdb_types, + sdb_set(typedb->sdb_types, rz_strbuf_setf(&key, "type.%s", sname), type->type, 0); @@ -457,8 +457,8 @@ static void save_atomic_type(const RzType *t, const RzBaseType *type) { rz_strbuf_fini(&val); } -static void save_typedef(const RzType *t, const RzBaseType *type) { - rz_return_if_fail(t && type && type->name && type->kind == RZ_BASE_TYPE_KIND_TYPEDEF); +static void save_typedef(const RzTypeDB *typedb, const RzBaseType *type) { + rz_return_if_fail(typedb && type && type->name && type->kind == RZ_BASE_TYPE_KIND_TYPEDEF); /* C: typedef char byte; @@ -467,14 +467,14 @@ static void save_typedef(const RzType *t, const RzBaseType *type) { typedef.byte=char */ char *sname = rz_str_sanitize_sdb_key(type->name); - sdb_set(t->sdb_types, sname, "typedef", 0); + sdb_set(typedb->sdb_types, sname, "typedef", 0); RzStrBuf key; RzStrBuf val; rz_strbuf_init(&key); rz_strbuf_init(&val); - sdb_set(t->sdb_types, + sdb_set(typedb->sdb_types, rz_strbuf_setf(&key, "typedef.%s", sname), rz_strbuf_setf(&val, "%s", type->type), 0); @@ -532,32 +532,32 @@ RZ_API RzBaseType *rz_type_base_type_new(RzBaseTypeKind kind) { } /** - * @brief Saves RzBaseType into the SDB + * \brief Saves RzBaseType into the Types DB * - * @param t - * @param type RzBaseType to save - * @param name Name of the type + * \param t + * \param type RzBaseType to save + * \param name Name of the type */ -RZ_API void rz_type_save_base_type(const RzType *t, const RzBaseType *type) { - rz_return_if_fail(t && type && type->name); +RZ_API void rz_type_db_save_base_type(const RzTypeDB *typedb, const RzBaseType *type) { + rz_return_if_fail(typedb && type && type->name); // TODO, solve collisions, if there are 2 types with the same name and kind switch (type->kind) { case RZ_BASE_TYPE_KIND_STRUCT: - save_struct(t, type); + save_struct(typedb, type); break; case RZ_BASE_TYPE_KIND_ENUM: - save_enum(t, type); + save_enum(typedb, type); break; case RZ_BASE_TYPE_KIND_UNION: - save_union(t, type); + save_union(typedb, type); break; case RZ_BASE_TYPE_KIND_TYPEDEF: - save_typedef(t, type); + save_typedef(typedb, type); break; case RZ_BASE_TYPE_KIND_ATOMIC: - save_atomic_type(t, type); + save_atomic_type(typedb, type); break; default: break; diff --git a/librz/type/code.c b/librz/type/code.c index f87cca082ae..f129429d0a1 100644 --- a/librz/type/code.c +++ b/librz/type/code.c @@ -31,7 +31,7 @@ static bool __typeLoad(void *p, const char *k, const char *v) { return false; } int btype = 0; - RzType *t = (RzType *)p; + RzTypeDB *typedb = (RzTypeDB *)p; //rz_cons_printf ("tk %s=%s\n", k, v); // TODO: Add unions support if (!strncmp(v, "struct", 6) && strncmp(k, "struct.", 7)) { @@ -41,7 +41,7 @@ static bool __typeLoad(void *p, const char *k, const char *v) { int typesize = 0; // TODO: Add typesize here char *query = sdb_fmt("struct.%s", k); - char *members = sdb_get(t->sdb_types, query, 0); + char *members = sdb_get(typedb->sdb_types, query, 0); char *next, *ptr = members; if (members) { do { @@ -50,7 +50,7 @@ static bool __typeLoad(void *p, const char *k, const char *v) { break; } query = sdb_fmt("struct.%s.%s", k, name); - char *subtype = sdb_get(t->sdb_types, query, 0); + char *subtype = sdb_get(typedb->sdb_types, query, 0); if (!subtype) { break; } @@ -64,7 +64,7 @@ static bool __typeLoad(void *p, const char *k, const char *v) { char *subname = tmp; // TODO: Go recurse here query = sdb_fmt("struct.%s.%s.meta", subtype, subname); - btype = sdb_num_get(t->sdb_types, query, 0); + btype = sdb_num_get(typedb->sdb_types, query, 0); tcc_sym_push(subtype, 0, btype); } free(subtype); @@ -94,15 +94,15 @@ static void __errorFunc(void *opaque, const char *msg) { } } -RZ_API char *rz_type_parse_c_file(RzType *t, const char *path, const char *dir, char **error_msg) { +RZ_API char *rz_type_parse_c_file(RzTypeDB *typedb, const char *path, const char *dir, char **error_msg) { char *str = NULL; - TCCState *T = tcc_new(t->target->cpu, t->target->bits, t->target->os); + TCCState *T = tcc_new(typedb->target->cpu, typedb->target->bits, typedb->target->os); if (!T) { return NULL; } tcc_set_callback(T, &__appendString, &str); tcc_set_error_func(T, (void *)error_msg, __errorFunc); - sdb_foreach(t->sdb_types, __typeLoad, t); + sdb_foreach(typedb->sdb_types, __typeLoad, typedb); if (tcc_add_file(T, path, dir) == -1) { free(str); str = NULL; @@ -111,15 +111,15 @@ RZ_API char *rz_type_parse_c_file(RzType *t, const char *path, const char *dir, return str; } -RZ_API char *rz_type_parse_c_string(RzType *t, const char *code, char **error_msg) { +RZ_API char *rz_type_parse_c_string(RzTypeDB *typedb, const char *code, char **error_msg) { char *str = NULL; - TCCState *T = tcc_new(t->target->cpu, t->target->bits, t->target->os); + TCCState *T = tcc_new(typedb->target->cpu, typedb->target->bits, typedb->target->os); if (!T) { return NULL; } tcc_set_callback(T, &__appendString, &str); tcc_set_error_func(T, (void *)error_msg, __errorFunc); - sdb_foreach(t->sdb_types, __typeLoad, NULL); + sdb_foreach(typedb->sdb_types, __typeLoad, NULL); if (tcc_compile_string(T, code) != 0) { free(str); str = NULL; @@ -129,6 +129,6 @@ RZ_API char *rz_type_parse_c_string(RzType *t, const char *code, char **error_ms } // XXX do not use globals -RZ_API void rz_type_parse_c_reset(RzType *p) { +RZ_API void rz_type_parse_c_reset(RzTypeDB *typedb) { anon_sym = SYM_FIRST_ANOM; } diff --git a/librz/type/format.c b/librz/type/format.c index 5520b0dd242..2bbaf29e7c8 100644 --- a/librz/type/format.c +++ b/librz/type/format.c @@ -449,11 +449,11 @@ static void rz_type_format_decchar(RzStrBuf *outbuf, int endian, int mode, } } -static int rz_type_format_string(RzType *t, RzStrBuf *outbuf, ut64 seeki, ut64 addr64, ut64 addr, int is64, int mode) { +static int rz_type_format_string(RzTypeDB *typedb, RzStrBuf *outbuf, ut64 seeki, ut64 addr64, ut64 addr, int is64, int mode) { ut8 buffer[255]; buffer[0] = 0; const ut64 at = (is64 == 1) ? addr64 : (ut64)addr; - int res = t->iob.read_at(t->iob.io, at, buffer, sizeof(buffer) - 8); + int res = typedb->iob.read_at(typedb->iob.io, at, buffer, sizeof(buffer) - 8); if (MUSTSEEJSON) { char *encstr = rz_str_utf16_encode((const char *)buffer, -1); if (encstr) { @@ -898,7 +898,7 @@ static void rz_type_format_hexflag(RzStrBuf *outbuf, int endian, int mode, } } -static int rz_type_format_10bytes(RzType *t, RzStrBuf *outbuf, int mode, const char *setval, +static int rz_type_format_10bytes(RzTypeDB *typedb, RzStrBuf *outbuf, int mode, const char *setval, ut64 seeki, ut64 addr, ut8 *buf) { ut8 buffer[255]; int j; @@ -909,7 +909,7 @@ static int rz_type_format_10bytes(RzType *t, RzStrBuf *outbuf, int mode, const c rz_strbuf_appendf(outbuf, "%02x ", buf[j]); } } else if (MUSTSEE) { - t->iob.read_at(t->iob.io, (ut64)addr, buffer, 248); + typedb->iob.read_at(typedb->iob.io, (ut64)addr, buffer, 248); if (!SEEVALUE && !ISQUIET) { rz_strbuf_appendf(outbuf, "0x%08" PFMT64x " = ", seeki); } @@ -932,7 +932,7 @@ static int rz_type_format_10bytes(RzType *t, RzStrBuf *outbuf, int mode, const c rz_strbuf_append(outbuf, ")"); } } else if (MUSTSEEJSON) { - t->iob.read_at(t->iob.io, (ut64)addr, buffer, 248); + typedb->iob.read_at(typedb->iob.io, (ut64)addr, buffer, 248); rz_strbuf_appendf(outbuf, "[ %d", buf[0]); j = 1; for (; j < 10; j++) { @@ -1203,26 +1203,26 @@ static void rz_type_byte_escape(const RzPrint *p, const char *src, char **dst, i rz_str_byte_escape(src, dst, dot_nl, !strcmp(p->strconv_mode, "asciidot"), p->esc_bslash); } -static void rz_type_format_nulltermstring(RzType *t, RzPrint *p, RzStrBuf *outbuf, int len, int endian, int mode, +static void rz_type_format_nulltermstring(RzTypeDB *typedb, RzPrint *p, RzStrBuf *outbuf, int len, int endian, int mode, const char *setval, ut64 seeki, ut8 *buf, int i, int size) { - if (!t->iob.is_valid_offset(t->iob.io, seeki, 1)) { + if (!typedb->iob.is_valid_offset(typedb->iob.io, seeki, 1)) { ut8 ch = 0xff; // XXX there are some cases where the memory is there but is_valid_offset fails - if (t->iob.read_at(t->iob.io, seeki, &ch, 1) != 1 && ch != 0xff) { + if (typedb->iob.read_at(typedb->iob.io, seeki, &ch, 1) != 1 && ch != 0xff) { rz_strbuf_append(outbuf, "-1"); return; } } - if (p->flags & RZ_PRINT_FLAGS_UNALLOC && !(t->iob.io->cached & RZ_PERM_R)) { + if (p->flags & RZ_PRINT_FLAGS_UNALLOC && !(typedb->iob.io->cached & RZ_PERM_R)) { ut64 total_map_left = 0; ut64 addr = seeki; RzIOMap *map; - while (total_map_left < len && (map = t->iob.io->va ? t->iob.map_get(t->iob.io, addr) : t->iob.map_get_paddr(t->iob.io, addr)) && map->perm & RZ_PERM_R) { + while (total_map_left < len && (map = typedb->iob.io->va ? typedb->iob.map_get(typedb->iob.io, addr) : typedb->iob.map_get_paddr(typedb->iob.io, addr)) && map->perm & RZ_PERM_R) { if (!map->itv.size) { total_map_left = addr == 0 ? UT64_MAX : UT64_MAX - addr + 1; break; } - total_map_left += map->itv.size - (addr - (t->iob.io->va ? map->itv.addr : map->delta)); + total_map_left += map->itv.size - (addr - (typedb->iob.io->va ? map->itv.addr : map->delta)); addr += total_map_left; } if (total_map_left < len) { @@ -1340,14 +1340,14 @@ static void rz_type_format_nulltermwidestring(RzPrint *p, RzStrBuf *outbuf, cons } } -static void rz_type_format_bitfield(RzType *t, RzStrBuf *outbuf, ut64 seeki, char *fmtname, +static void rz_type_format_bitfield(RzTypeDB *typedb, RzStrBuf *outbuf, ut64 seeki, char *fmtname, char *fieldname, ut64 addr, int mode, int size) { char *bitfield = NULL; addr &= (1ULL << (size * 8)) - 1; if (MUSTSEE && !SEEVALUE) { rz_strbuf_appendf(outbuf, "0x%08" PFMT64x " = ", seeki); } - bitfield = rz_type_enum_getbitfield(t, fmtname, addr); + bitfield = rz_type_enum_getbitfield(typedb, fmtname, addr); if (bitfield && *bitfield) { if (MUSTSEEJSON) { rz_strbuf_appendf(outbuf, "\"%s\"}", bitfield); @@ -1365,14 +1365,14 @@ static void rz_type_format_bitfield(RzType *t, RzStrBuf *outbuf, ut64 seeki, cha free(bitfield); } -static void rz_type_format_enum(RzType *t, RzStrBuf *outbuf, ut64 seeki, char *fmtname, +static void rz_type_format_enum(RzTypeDB *typedb, RzStrBuf *outbuf, ut64 seeki, char *fmtname, char *fieldname, ut64 addr, int mode, int size) { char *enumvalue = NULL; addr &= (1ULL << (size * 8)) - 1; if (MUSTSEE && !SEEVALUE) { rz_strbuf_appendf(outbuf, "0x%08" PFMT64x " = ", seeki); } - enumvalue = rz_type_enum_member(t, fmtname, NULL, addr); + enumvalue = rz_type_db_enum_member(typedb, fmtname, NULL, addr); if (enumvalue && *enumvalue) { if (mode & RZ_PRINT_DOT) { rz_strbuf_appendf(outbuf, "%s.%s", fmtname, enumvalue); @@ -1516,8 +1516,8 @@ static void rz_type_format_num(RzStrBuf *outbuf, int endian, int mode, const cha } } -RZ_API const char *rz_type_format_byname(RzType *t, const char *name) { - return sdb_const_get(t->formats, name, NULL); +RZ_API const char *rz_type_db_format_byname(RzTypeDB *typedb, const char *name) { + return sdb_const_get(typedb->formats, name, NULL); } static char *fmt_struct_union(Sdb *TDB, char *var, bool is_typedef) { @@ -1601,9 +1601,9 @@ static char *fmt_struct_union(Sdb *TDB, char *var, bool is_typedef) { return fmt; } -RZ_API char *rz_type_format(RzType *type, const char *t) { +RZ_API char *rz_type_format(RzTypeDB *typedb, const char *t) { char var[130], var2[132]; - Sdb *TDB = type->sdb_types; + Sdb *TDB = typedb->sdb_types; const char *kind = sdb_const_get(TDB, t, NULL); if (!kind) { return NULL; @@ -1630,7 +1630,7 @@ RZ_API char *rz_type_format(RzType *type, const char *t) { } // XXX: this is somewhat incomplete. must be updated to handle all format chars -RZ_API int rz_type_format_struct_size(RzType *t, const char *f, int mode, int n) { +RZ_API int rz_type_format_struct_size(RzTypeDB *typedb, const char *f, int mode, int n) { char *end, *args, *fmt; int size = 0, tabsize = 0, i, idx = 0, biggest = 0, fmt_len = 0, times = 1; bool tabsize_set = false; @@ -1640,7 +1640,7 @@ RZ_API int rz_type_format_struct_size(RzType *t, const char *f, int mode, int n) if (n >= 5) { // This is the nesting level, is this not a bit arbitrary?! return 0; } - const char *fmt2 = sdb_get(t->formats, f, NULL); + const char *fmt2 = sdb_get(typedb->formats, f, NULL); if (!fmt2) { fmt2 = f; } @@ -1735,7 +1735,7 @@ RZ_API int rz_type_format_struct_size(RzType *t, const char *f, int mode, int n) size += tabsize; break; case '*': - size += tabsize * (t->target->bits / 8); + size += tabsize * (typedb->target->bits / 8); i++; idx--; //no need to go ahead for args break; @@ -1782,14 +1782,14 @@ RZ_API int rz_type_format_struct_size(RzType *t, const char *f, int mode, int n) tmp = *format; } } else { - format = sdb_get(t->formats, structname + 1, NULL); + format = sdb_get(typedb->formats, structname + 1, NULL); if (format && !strncmp(format, f, strlen(format) - 1)) { // Avoid recursion here free(o); free(structname); return -1; } if (!format) { // Fetch format from types db - format = rz_type_format(t, structname + 1); + format = rz_type_format(typedb, structname + 1); } } if (!format) { @@ -1798,7 +1798,7 @@ RZ_API int rz_type_format_struct_size(RzType *t, const char *f, int mode, int n) free(o); return 0; } - int newsize = rz_type_format_struct_size(t, format, mode, n + 1); + int newsize = rz_type_format_struct_size(typedb, format, mode, n + 1); if (newsize < 1) { eprintf("Cannot find size for `%s'\n", format); free(structname); @@ -1838,7 +1838,7 @@ RZ_API int rz_type_format_struct_size(RzType *t, const char *f, int mode, int n) } else if (fmt[i + 1] == '8') { size += tabsize * 8; } else { - size += tabsize * (t->target->bits / 8); + size += tabsize * (typedb->target->bits / 8); break; } i++; @@ -1885,7 +1885,7 @@ RZ_API int rz_type_format_struct_size(RzType *t, const char *f, int mode, int n) return (mode & RZ_PRINT_UNIONMODE) ? biggest : size; } -static int rz_type_format_struct(RzType *t, RzPrint *p, RzStrBuf *outbuf, ut64 seek, const ut8 *b, int len, const char *name, +static int rz_type_format_struct(RzTypeDB *typedb, RzPrint *p, RzStrBuf *outbuf, ut64 seek, const ut8 *b, int len, const char *name, int slide, int mode, const char *setval, char *field, int anon) { const char *fmt; char namefmt[128]; @@ -1897,9 +1897,9 @@ static int rz_type_format_struct(RzType *t, RzPrint *p, RzStrBuf *outbuf, ut64 s if (anon) { fmt = name; } else { - fmt = sdb_get(t->formats, name, NULL); + fmt = sdb_get(typedb->formats, name, NULL); if (!fmt) { // Fetch struct info from types DB - fmt = rz_type_format(t, name); + fmt = rz_type_format(typedb, name); } } if (!fmt || !*fmt) { @@ -1915,8 +1915,8 @@ static int rz_type_format_struct(RzType *t, RzPrint *p, RzStrBuf *outbuf, ut64 s } rz_strbuf_appendf(outbuf, "<%s>\n", name); } - rz_type_format_data(t, p, seek, b, len, fmt, mode, setval, field); - return rz_type_format_struct_size(t, fmt, mode, 0); + rz_type_format_data(typedb, p, seek, b, len, fmt, mode, setval, field); + return rz_type_format_struct_size(typedb, fmt, mode, 0); } static char *get_args_offset(const char *arg) { @@ -2033,10 +2033,10 @@ RZ_API void rz_type_db_format_purge(RzTypeDB *typedb) { typedb->formats = sdb_new0(); } -RZ_API char *rz_type_format_data(RzType *t, RzPrint *p, ut64 seek, const ut8 *b, const int len, +RZ_API char *rz_type_format_data(RzTypeDB *typedb, RzPrint *p, ut64 seek, const ut8 *b, const int len, const char *formatname, int mode, const char *setval, char *ofield) { int nargs, i, invalid, nexti, idx, times, otimes, endian, isptr = 0; - const int old_bits = t->target->bits; + const int old_bits = typedb->target->bits; char *args = NULL, *bracket, tmp, last = 0; ut64 addr = 0, addr64 = 0, seeki = 0; static int slide = 0, oldslide = 0, ident = 4; @@ -2052,7 +2052,7 @@ RZ_API char *rz_type_format_data(RzType *t, RzPrint *p, ut64 seek, const ut8 *b, if (!formatname) { return 0; } - fmt = sdb_get(t->formats, formatname, NULL); + fmt = sdb_get(typedb->formats, formatname, NULL); if (!fmt) { fmt = formatname; } @@ -2079,7 +2079,7 @@ RZ_API char *rz_type_format_data(RzType *t, RzPrint *p, ut64 seek, const ut8 *b, return 0; } memcpy(buf, b, len); - endian = t->target->big_endian; + endian = typedb->target->big_endian; if (ofield && ofield != MINUSONE) { field = strdup(ofield); @@ -2201,7 +2201,7 @@ RZ_API char *rz_type_format_data(RzType *t, RzPrint *p, ut64 seek, const ut8 *b, seeki = seek + i; addr = 0LL; invalid = 0; - t->target->bits = old_bits; + typedb->target->bits = old_bits; if (arg[0] == '[') { char *end = strchr(arg, ']'); if (!end) { @@ -2209,13 +2209,13 @@ RZ_API char *rz_type_format_data(RzType *t, RzPrint *p, ut64 seek, const ut8 *b, goto beach; } *end = '\0'; - size = rz_get_size(t->num, buf, endian, arg + 1); + size = rz_get_size(typedb->num, buf, endian, arg + 1); arg = end + 1; *end = ']'; } else { size = -1; } - int fs = rz_type_format_struct_size(t, arg, 0, idx); + int fs = rz_type_format_struct_size(typedb, arg, 0, idx); if (fs == -2) { i = -1; goto beach; @@ -2230,7 +2230,7 @@ RZ_API char *rz_type_format_data(RzType *t, RzPrint *p, ut64 seek, const ut8 *b, } else { updateAddr(buf + i, len - i, endian, &addr, &addr64); } - if (t->target->bits == 64) { + if (typedb->target->bits == 64) { addr = addr64; } } else { @@ -2307,7 +2307,7 @@ RZ_API char *rz_type_format_data(RzType *t, RzPrint *p, ut64 seek, const ut8 *b, feed_me_again: switch (isptr) { case PTRSEEK: { - nexti = i + (t->target->bits / 8); + nexti = i + (typedb->target->bits / 8); i = 0; if (tmp == '?') { seeki = addr; @@ -2317,7 +2317,7 @@ RZ_API char *rz_type_format_data(RzType *t, RzPrint *p, ut64 seek, const ut8 *b, rz_strbuf_appendf(outbuf, "(*0x%" PFMT64x ")", addr); } isptr = (addr) ? PTRBACK : NULLPTR; - t->iob.read_at(t->iob.io, (ut64)addr, buf, len - 4); + typedb->iob.read_at(typedb->iob.io, (ut64)addr, buf, len - 4); if (((i + 3) < len) || ((i + 7) < len)) { // XXX this breaks pf *D if (tmp != 'D') { @@ -2378,7 +2378,7 @@ RZ_API char *rz_type_format_data(RzType *t, RzPrint *p, ut64 seek, const ut8 *b, tmp = 'q'; arg++; } else { //If pointer reference is not mentioned explicitly - switch (t->target->bits) { + switch (typedb->target->bits) { case 16: tmp = 'w'; break; case 32: tmp = 'x'; break; default: tmp = 'q'; break; @@ -2452,7 +2452,7 @@ RZ_API char *rz_type_format_data(RzType *t, RzPrint *p, ut64 seek, const ut8 *b, rz_strbuf_append(outbuf, "*"); } rz_strbuf_appendf(outbuf, "\",\"offset\":%" PFMT64d ",\"value\":", - isptr ? (seek + nexti - (t->target->bits / 8)) : seek + i); + isptr ? (seek + nexti - (typedb->target->bits / 8)) : seek + i); } /* c struct */ diff --git a/librz/type/function.c b/librz/type/function.c index 354be132e74..ef275b61b9e 100644 --- a/librz/type/function.c +++ b/librz/type/function.c @@ -10,45 +10,45 @@ #include // Function prototypes api -RZ_API bool rz_type_func_exist(RzType *t, const char *func_name) { - rz_return_val_if_fail(t, false); - Sdb *TDB = t->sdb_types; +RZ_API bool rz_type_func_exist(RzTypeDB *typedb, const char *func_name) { + rz_return_val_if_fail(typedb && func_name, false); + Sdb *TDB = typedb->sdb_types; const char *fcn = sdb_const_get(TDB, func_name, 0); return fcn && !strcmp(fcn, "func"); } -RZ_API bool rz_type_func_has_args(RzType *t, const char *func_name) { - rz_return_val_if_fail(t, false); - Sdb *TDB = t->sdb_types; +RZ_API bool rz_type_func_has_args(RzTypeDB *typedb, const char *func_name) { + rz_return_val_if_fail(typedb && func_name, false); + Sdb *TDB = typedb->sdb_types; const char *query = sdb_fmt("func.%s.args", func_name); const char *fcn = sdb_const_get(TDB, query, 0); return (fcn != NULL); } -RZ_API const char *rz_type_func_ret(RzType *t, const char *func_name) { - rz_return_val_if_fail(t, NULL); - Sdb *TDB = t->sdb_types; +RZ_API const char *rz_type_func_ret(RzTypeDB *typedb, const char *func_name) { + rz_return_val_if_fail(typedb && func_name, NULL); + Sdb *TDB = typedb->sdb_types; const char *query = sdb_fmt("func.%s.ret", func_name); return sdb_const_get(TDB, query, 0); } -RZ_API const char *rz_type_func_cc(RzType *t, const char *func_name) { - rz_return_val_if_fail(t, NULL); - Sdb *TDB = t->sdb_types; +RZ_API const char *rz_type_func_cc(RzTypeDB *typedb, const char *func_name) { + rz_return_val_if_fail(typedb && func_name, NULL); + Sdb *TDB = typedb->sdb_types; const char *query = sdb_fmt("func.%s.cc", func_name); return sdb_const_get(TDB, query, 0); } -RZ_API int rz_type_func_args_count(RzType *t, const char *func_name) { - rz_return_val_if_fail(t, 0); - Sdb *TDB = t->sdb_types; +RZ_API int rz_type_func_args_count(RzTypeDB *typedb, const char *func_name) { + rz_return_val_if_fail(typedb && func_name, 0); + Sdb *TDB = typedb->sdb_types; const char *query = sdb_fmt("func.%s.args", func_name); return sdb_num_get(TDB, query, 0); } -RZ_API RZ_OWN char *rz_type_func_args_type(RzType *t, RZ_NONNULL const char *func_name, int i) { - rz_return_val_if_fail(t, NULL); - Sdb *TDB = t->sdb_types; +RZ_API RZ_OWN char *rz_type_func_args_type(RzTypeDB *typedb, RZ_NONNULL const char *func_name, int i) { + rz_return_val_if_fail(typedb && func_name, NULL); + Sdb *TDB = typedb->sdb_types; const char *query = sdb_fmt("func.%s.arg.%d", func_name, i); char *ret = sdb_get(TDB, query, 0); if (ret) { @@ -62,9 +62,9 @@ RZ_API RZ_OWN char *rz_type_func_args_type(RzType *t, RZ_NONNULL const char *fun return NULL; } -RZ_API const char *rz_type_func_args_name(RzType *t, RZ_NONNULL const char *func_name, int i) { - rz_return_val_if_fail(t, NULL); - Sdb *TDB = t->sdb_types; +RZ_API const char *rz_type_func_args_name(RzTypeDB *typedb, RZ_NONNULL const char *func_name, int i) { + rz_return_val_if_fail(typedb && func_name, NULL); + Sdb *TDB = typedb->sdb_types; const char *query = sdb_fmt("func.%s.arg.%d", func_name, i); const char *get = sdb_const_get(TDB, query, 0); if (get) { @@ -74,9 +74,9 @@ RZ_API const char *rz_type_func_args_name(RzType *t, RZ_NONNULL const char *func return NULL; } -RZ_API bool rz_type_func_arg_count_set(RzType *t, RZ_NONNULL const char *func_name, int arg_count) { - rz_return_val_if_fail(t, NULL); - Sdb *TDB = t->sdb_types; +RZ_API bool rz_type_func_arg_count_set(RzTypeDB *typedb, RZ_NONNULL const char *func_name, int arg_count) { + rz_return_val_if_fail(typedb && func_name, NULL); + Sdb *TDB = typedb->sdb_types; bool result = false; RzStrBuf key, value; rz_strbuf_init(&key); @@ -92,9 +92,9 @@ RZ_API bool rz_type_func_arg_count_set(RzType *t, RZ_NONNULL const char *func_na return result; } -RZ_API bool rz_type_func_arg_set(RzType *t, RZ_NONNULL const char *func_name, int i, RZ_NONNULL const char *arg_name, RZ_NONNULL const char *arg_type) { - rz_return_val_if_fail(t, NULL); - Sdb *TDB = t->sdb_types; +RZ_API bool rz_type_func_arg_set(RzTypeDB *typedb, RZ_NONNULL const char *func_name, int i, RZ_NONNULL const char *arg_name, RZ_NONNULL const char *arg_type) { + rz_return_val_if_fail(typedb && func_name, NULL); + Sdb *TDB = typedb->sdb_types; bool result = false; RzStrBuf key, value; rz_strbuf_init(&key); @@ -110,9 +110,9 @@ RZ_API bool rz_type_func_arg_set(RzType *t, RZ_NONNULL const char *func_name, in return result; } -RZ_API bool rz_type_func_ret_set(RzType *t, const char *func_name, const char *type) { - rz_return_val_if_fail(t && func_name && type, NULL); - Sdb *TDB = t->sdb_types; +RZ_API bool rz_type_func_ret_set(RzTypeDB *typedb, const char *func_name, const char *type) { + rz_return_val_if_fail(typedb && func_name && type, NULL); + Sdb *TDB = typedb->sdb_types; char *sdb_type = rz_str_newf("type.%s", type); if (!sdb_exists(TDB, sdb_type)) { free(sdb_type); @@ -195,13 +195,11 @@ static void clean_function_name(char *func_name) { // TODO: // - symbol names are long and noisy, some of them might not be matched due // to additional information added around name -RZ_API RZ_OWN char *rz_type_func_guess(RzType *t, RZ_NONNULL char *func_name) { - rz_return_val_if_fail(t, NULL); - Sdb *TDB = t->sdb_types; +RZ_API RZ_OWN char *rz_type_func_guess(RzTypeDB *typedb, RZ_NONNULL char *func_name) { + rz_return_val_if_fail(typedb && func_name, NULL); + Sdb *TDB = typedb->sdb_types; char *str = func_name; char *result = NULL; - rz_return_val_if_fail(TDB, false); - rz_return_val_if_fail(func_name, false); size_t slen = strlen(str); if (slen < MIN_MATCH_LEN || is_auto_named(str, slen)) { @@ -228,11 +226,12 @@ RZ_API RZ_OWN char *rz_type_func_guess(RzType *t, RZ_NONNULL char *func_name) { return result; } -RZ_API RzList *rz_type_noreturn_functions(RzType *type) { +RZ_API RzList *rz_type_noreturn_functions(RzTypeDB *typedb) { + rz_return_val_if_fail(typedb, NULL); RzList *noretl = rz_list_newf(free); SdbKv *kv; SdbListIter *iter; - SdbList *l = sdb_foreach_list(type->sdb_types, true); + SdbList *l = sdb_foreach_list(typedb->sdb_types, true); ls_foreach (l, iter, kv) { const char *k = sdbkv_key(kv); if (!strncmp(k, "func.", 5) && strstr(k, ".noreturn")) { diff --git a/librz/type/link.c b/librz/type/link.c index ed65cc9c8d9..b44d673ad41 100644 --- a/librz/type/link.c +++ b/librz/type/link.c @@ -39,9 +39,9 @@ static void types_range_add(Sdb *db, ut64 addr) { (void)sdb_array_add_num(db, k, addr, 0); } -RZ_API char *rz_type_link_at(RzType *t, ut64 addr) { - rz_return_val_if_fail(t, NULL); - Sdb *TDB = t->sdb_types; +RZ_API char *rz_type_link_at(RzTypeDB *typedb, ut64 addr) { + rz_return_val_if_fail(typedb, NULL); + Sdb *TDB = typedb->sdb_types; if (addr == UT64_MAX) { return NULL; } @@ -57,7 +57,7 @@ RZ_API char *rz_type_link_at(RzType *t, ut64 addr) { int delta = addr - laddr; const char *lk = sdb_fmt("link.%08" PFMT64x, laddr); char *k = sdb_get(TDB, lk, 0); - res = rz_type_get_struct_memb(t, k, delta); + res = rz_type_get_struct_memb(typedb, k, delta); if (res) { break; } @@ -68,9 +68,9 @@ RZ_API char *rz_type_link_at(RzType *t, ut64 addr) { return res; } -RZ_API bool rz_type_set_link(RzType *t, const char *type, ut64 addr) { - rz_return_val_if_fail(t, false); - Sdb *TDB = t->sdb_types; +RZ_API bool rz_type_set_link(RzTypeDB *typedb, const char *type, ut64 addr) { + rz_return_val_if_fail(typedb, false); + Sdb *TDB = typedb->sdb_types; if (sdb_const_get(TDB, type, 0)) { char *laddr = rz_str_newf("link.%08" PFMT64x, addr); sdb_set(TDB, laddr, type, 0); @@ -81,9 +81,9 @@ RZ_API bool rz_type_set_link(RzType *t, const char *type, ut64 addr) { return false; } -RZ_API bool rz_type_link_offset(RzType *t, const char *type, ut64 addr) { - rz_return_val_if_fail(t, false); - Sdb *TDB = t->sdb_types; +RZ_API bool rz_type_link_offset(RzTypeDB *typedb, const char *type, ut64 addr) { + rz_return_val_if_fail(typedb, false); + Sdb *TDB = typedb->sdb_types; if (sdb_const_get(TDB, type, 0)) { char *laddr = rz_str_newf("offset.%08" PFMT64x, addr); sdb_set(TDB, laddr, type, 0); @@ -93,9 +93,9 @@ RZ_API bool rz_type_link_offset(RzType *t, const char *type, ut64 addr) { return false; } -RZ_API bool rz_type_unlink(RzType *t, ut64 addr) { - rz_return_val_if_fail(t, false); - Sdb *TDB = t->sdb_types; +RZ_API bool rz_type_unlink(RzTypeDB *typedb, ut64 addr) { + rz_return_val_if_fail(typedb, false); + Sdb *TDB = typedb->sdb_types; char *laddr = sdb_fmt("link.%08" PFMT64x, addr); sdb_unset(TDB, laddr, 0); types_range_del(TDB, addr); @@ -111,9 +111,9 @@ static bool sdbdeletelink(void *p, const char *k, const char *v) { return true; } -RZ_API bool rz_type_unlink_all(RzType *t) { - rz_return_val_if_fail(t, false); - Sdb *TDB = t->sdb_types; +RZ_API bool rz_type_unlink_all(RzTypeDB *typedb) { + rz_return_val_if_fail(typedb, false); + Sdb *TDB = typedb->sdb_types; sdb_foreach(TDB, sdbdeletelink, TDB); return true; } diff --git a/librz/type/serialize_types.c b/librz/type/serialize_types.c index 39e73aa5c2a..da1575bb378 100644 --- a/librz/type/serialize_types.c +++ b/librz/type/serialize_types.c @@ -6,12 +6,12 @@ #include #include -RZ_API void rz_serialize_types_save(RZ_NONNULL Sdb *db, RZ_NONNULL RzType *types) { - sdb_copy(types->sdb_types, db); +RZ_API void rz_serialize_types_save(RZ_NONNULL Sdb *db, RZ_NONNULL RzTypeDB *typedb) { + sdb_copy(typedb->sdb_types, db); } -RZ_API bool rz_serialize_types_load(RZ_NONNULL Sdb *db, RZ_NONNULL RzType *types, RZ_NULLABLE RzSerializeResultInfo *res) { - sdb_reset(types->sdb_types); - sdb_copy(db, types->sdb_types); +RZ_API bool rz_serialize_types_load(RZ_NONNULL Sdb *db, RZ_NONNULL RzTypeDB *typedb, RZ_NULLABLE RzSerializeResultInfo *res) { + sdb_reset(typedb->sdb_types); + sdb_copy(db, typedb->sdb_types); return true; } diff --git a/librz/type/type.c b/librz/type/type.c index 849b830a494..6a6e0f5b762 100644 --- a/librz/type/type.c +++ b/librz/type/type.c @@ -10,27 +10,27 @@ #include "type_internal.h" -RZ_API RzType *rz_type_new() { - RzType *type = RZ_NEW0(RzType); - if (!type) { +RZ_API RzTypeDB *rz_type_db_new() { + RzTypeDB *typedb = RZ_NEW0(RzTypeDB); + if (!typedb) { return NULL; } - type->target = RZ_NEW0(RzTypeTarget); - if (!type->target) { + typedb->target = RZ_NEW0(RzTypeTarget); + if (!typedb->target) { return NULL; } Sdb *sdb = sdb_new0(); - type->sdb_types = sdb_ns(sdb, "types", 1); - type->formats = sdb_new0(); - rz_io_bind_init(type->iob); - return type; + typedb->sdb_types = sdb_ns(sdb, "types", 1); + typedb->formats = sdb_new0(); + rz_io_bind_init(typedb->iob); + return typedb; } -RZ_API void rz_type_free(RzType *t) { - sdb_free(t->sdb_types); - sdb_free(t->formats); - free(t->target); - free(t); +RZ_API void rz_type_db_free(RzTypeDB *typedb) { + sdb_free(typedb->sdb_types); + sdb_free(typedb->formats); + free(typedb->target); + free(typedb); } // copypasta from core/cbin.c @@ -41,34 +41,34 @@ static void sdb_concat_by_path(Sdb *s, const char *path) { sdb_free(db); } -RZ_API void rz_type_load_sdb(RzType *t, const char *path) { +RZ_API void rz_type_db_load_sdb(RzTypeDB *typedb, const char *path) { if (rz_file_exists(path)) { - sdb_concat_by_path(t->sdb_types, path); + sdb_concat_by_path(typedb->sdb_types, path); } } -RZ_API void rz_type_purge(RzType *t) { - sdb_reset(t->sdb_types); +RZ_API void rz_type_db_purge(RzTypeDB *typedb) { + sdb_reset(typedb->sdb_types); } -RZ_API void rz_type_set_bits(RzType *t, int bits) { - t->target->bits = bits; +RZ_API void rz_type_db_set_bits(RzTypeDB *typedb, int bits) { + typedb->target->bits = bits; } -RZ_API void rz_type_set_os(RzType *t, const char *os) { - t->target->os = os; +RZ_API void rz_type_db_set_os(RzTypeDB *typedb, const char *os) { + typedb->target->os = os; } -RZ_API void rz_type_set_cpu(RzType *t, const char *cpu) { - t->target->cpu = cpu; +RZ_API void rz_type_db_set_cpu(RzTypeDB *typedb, const char *cpu) { + typedb->target->cpu = cpu; } -RZ_API char *rz_type_kuery(RzType *t, const char *query) { +RZ_API char *rz_type_db_kuery(RzTypeDB *typedb, const char *query) { char *output = NULL; if (query) { - output = sdb_querys(t->sdb_types, NULL, -1, query); + output = sdb_querys(typedb->sdb_types, NULL, -1, query); } else { - output = sdb_querys(t->sdb_types, NULL, -1, "*"); + output = sdb_querys(typedb->sdb_types, NULL, -1, "*"); } return output; } @@ -86,9 +86,37 @@ static char *is_ctype(char *type) { return NULL; } -RZ_API bool rz_type_del(RzType *t, RZ_NONNULL const char *name) { - rz_return_val_if_fail(t && name, false); - Sdb *TDB = t->sdb_types; +RZ_API const char *rz_type_db_get(RzTypeDB *typedb, const char *name) { + rz_return_val_if_fail(typedb && name, NULL); + Sdb *TDB = typedb->sdb_types; + const char *query = sdb_fmt("type.%s", name); + return sdb_const_get(TDB, query, 0); +} + +RZ_API bool rz_type_db_set(RzTypeDB *typedb, ut64 at, RZ_NONNULL const char *field, ut64 val) { + rz_return_val_if_fail(typedb && field, false); + Sdb *TDB = typedb->sdb_types; + const char *kind; + char var[128]; + sprintf(var, "link.%08" PFMT64x, at); + kind = sdb_const_get(TDB, var, NULL); + if (kind) { + const char *p = sdb_const_get(TDB, kind, NULL); + if (p) { + snprintf(var, sizeof(var), "%s.%s.%s", p, kind, field); + int off = sdb_array_get_num(TDB, var, 1, NULL); + //int siz = sdb_array_get_num (DB, var, 2, NULL); + eprintf("wv 0x%08" PFMT64x " @ 0x%08" PFMT64x, val, at + off); + return true; + } + eprintf("Invalid kind of type\n"); + } + return false; +} + +RZ_API bool rz_type_db_del(RzTypeDB *typedb, RZ_NONNULL const char *name) { + rz_return_val_if_fail(typedb && name, false); + Sdb *TDB = typedb->sdb_types; const char *kind = sdb_const_get(TDB, name, 0); if (!kind) { return false; @@ -120,7 +148,7 @@ RZ_API bool rz_type_del(RzType *t, RZ_NONNULL const char *name) { sdb_unset(TDB, sdb_fmt("func.%s.args", name), 0); sdb_unset(TDB, name, 0); } else if (!strcmp(kind, "enum")) { - RzList *list = rz_type_get_enum(t, name); + RzList *list = rz_type_db_get_enum(typedb, name); RzTypeEnum *member; RzListIter *iter; rz_list_foreach (list, iter, member) { @@ -143,9 +171,9 @@ RZ_API bool rz_type_del(RzType *t, RZ_NONNULL const char *name) { return true; } -RZ_API void rz_type_remove_parsed_type(RzType *t, const char *name) { - rz_return_if_fail(t && name); - Sdb *TDB = t->sdb_types; +RZ_API void rz_type_db_remove_parsed_type(RzTypeDB *typedb, const char *name) { + rz_return_if_fail(typedb && name); + Sdb *TDB = typedb->sdb_types; SdbKv *kv; SdbListIter *iter; const char *type = sdb_const_get(TDB, name, 0); @@ -154,13 +182,13 @@ RZ_API void rz_type_remove_parsed_type(RzType *t, const char *name) { } int tmp_len = strlen(name) + strlen(type); char *tmp = malloc(tmp_len + 1); - rz_type_del(t, name); + rz_type_db_del(typedb, name); if (tmp) { snprintf(tmp, tmp_len + 1, "%s.%s.", type, name); SdbList *l = sdb_foreach_list(TDB, true); ls_foreach (l, iter, kv) { if (!strncmp(sdbkv_key(kv), tmp, tmp_len)) { - rz_type_del(t, sdbkv_key(kv)); + rz_type_db_del(typedb, sdbkv_key(kv)); } } ls_free(l); @@ -168,8 +196,8 @@ RZ_API void rz_type_remove_parsed_type(RzType *t, const char *name) { } } -RZ_API void rz_type_save_parsed_type(RzType *t, const char *parsed) { - rz_return_if_fail(t && parsed); +RZ_API void rz_type_db_save_parsed_type(RzTypeDB *typedb, const char *parsed) { + rz_return_if_fail(typedb && parsed); // First, if any parsed types exist, let's remove them. char *type = strdup(parsed); @@ -185,18 +213,18 @@ RZ_API void rz_type_save_parsed_type(RzType *t, const char *parsed) { while (name > type && *(name - 1) != '\n') { name--; } - rz_type_remove_parsed_type(t, name); + rz_type_db_remove_parsed_type(typedb, name); } free(type); } // Now add the type to sdb. - sdb_query_lines(t->sdb_types, parsed); + sdb_query_lines(typedb->sdb_types, parsed); } -RZ_API void rz_type_db_init(RzType *types, const char *dir_prefix, const char *arch, int bits, const char *os) { - rz_return_if_fail(types); - Sdb *TDB = types->sdb_types; +RZ_API void rz_type_db_init(RzTypeDB *typedb, const char *dir_prefix, const char *arch, int bits, const char *os) { + rz_return_if_fail(typedb); + Sdb *TDB = typedb->sdb_types; // make sure they are empty this is initializing sdb_reset(TDB); @@ -244,11 +272,11 @@ RZ_API void rz_type_db_init(RzType *types, const char *dir_prefix, const char *a // Listing all available types by category -RZ_API RzList *rz_type_enums(RzType *type) { +RZ_API RzList *rz_type_db_enums(RzTypeDB *typedb) { RzList *ccl = rz_list_new(); SdbKv *kv; SdbListIter *iter; - SdbList *l = sdb_foreach_list(type->sdb_types, true); + SdbList *l = sdb_foreach_list(typedb->sdb_types, true); ls_foreach (l, iter, kv) { if (!strcmp(sdbkv_value(kv), "enum")) { rz_list_append(ccl, strdup(sdbkv_key(kv))); @@ -258,23 +286,75 @@ RZ_API RzList *rz_type_enums(RzType *type) { return ccl; } +static bool sdb_if_union_cb(void *p, const char *k, const char *v) { + return !strncmp(v, "union", strlen("union") + 1); +} + +RZ_API RzList *rz_type_db_unions(RzTypeDB *typedb) { + Sdb *TDB = typedb->sdb_types; + SdbList *sl = sdb_foreach_list_filter_user(TDB, sdb_if_union_cb, true, TDB); + RzList *l = rz_list_of_sdblist(sl); + ls_free(sl); + return l; +} + +static bool sdb_if_struct_cb(void *user, const char *k, const char *v) { + rz_return_val_if_fail(user, false); + Sdb *TDB = (Sdb *)user; + if (!strcmp(v, "struct") && !rz_str_startswith(k, "typedef")) { + return true; + } + if (!strcmp(v, "typedef")) { + const char *typedef_key = sdb_fmt("typedef.%s", k); + const char *type = sdb_const_get(TDB, typedef_key, NULL); + if (type && rz_str_startswith(type, "struct")) { + return true; + } + } + return false; +} + +RZ_API RzList *rz_type_db_structs(RzTypeDB *typedb) { + Sdb *TDB = typedb->sdb_types; + SdbList *sl = sdb_foreach_list_filter_user(TDB, sdb_if_struct_cb, true, TDB); + RzList *l = rz_list_of_sdblist(sl); + ls_free(sl); + return l; +} + static bool sdb_if_typedef_cb(void *p, const char *k, const char *v) { return !strncmp(v, "typedef", strlen("typedef") + 1); } -RZ_API RzList *rz_type_typedefs(RzType *type) { - Sdb *TDB = type->sdb_types; +RZ_API RzList *rz_type_db_typedefs(RzTypeDB *typedb) { + Sdb *TDB = typedb->sdb_types; SdbList *sl = sdb_foreach_list_filter_user(TDB, sdb_if_typedef_cb, true, TDB); RzList *l = rz_list_of_sdblist(sl); ls_free(sl); return l; } -RZ_API RzList *rz_type_links(RzType *type) { +static bool sdb_if_type_cb(void *p, const char *k, const char *v) { + return !strncmp(v, "type", strlen("type") + 1); +} + +static bool sdb_if_c_type_cb(void *p, const char *k, const char *v) { + return sdb_if_union_cb(p, k, v) || sdb_if_struct_cb(p, k, v) || sdb_if_type_cb(p, k, v); +} + +RZ_API RzList *rz_type_db_all(RzTypeDB *typedb) { + Sdb *TDB = typedb->sdb_types; + SdbList *sl = sdb_foreach_list_filter_user(TDB, sdb_if_c_type_cb, true, TDB); + RzList *l = rz_list_of_sdblist(sl); + ls_free(sl); + return l; +} + +RZ_API RzList *rz_type_db_links(RzTypeDB *typedb) { RzList *ccl = rz_list_new(); SdbKv *kv; SdbListIter *iter; - SdbList *l = sdb_foreach_list(type->sdb_types, true); + SdbList *l = sdb_foreach_list(typedb->sdb_types, true); ls_foreach (l, iter, kv) { if (!strcmp(sdbkv_value(kv), "link")) { rz_list_append(ccl, strdup(sdbkv_key(kv))); diff --git a/librz/type/utype.c b/librz/type/utype.c index 127204c2eac..3a242a8f78a 100644 --- a/librz/type/utype.c +++ b/librz/type/utype.c @@ -7,37 +7,9 @@ #include #include -RZ_API const char *rz_type_get(RzType *t, const char *name) { - rz_return_val_if_fail(t, NULL); - Sdb *TDB = t->sdb_types; - const char *query = sdb_fmt("type.%s", name); - return sdb_const_get(TDB, query, 0); -} - -RZ_API bool rz_type_set(RzType *t, ut64 at, RZ_NONNULL const char *field, ut64 val) { - rz_return_val_if_fail(t && field, false); - Sdb *TDB = t->sdb_types; - const char *kind; - char var[128]; - sprintf(var, "link.%08" PFMT64x, at); - kind = sdb_const_get(TDB, var, NULL); - if (kind) { - const char *p = sdb_const_get(TDB, kind, NULL); - if (p) { - snprintf(var, sizeof(var), "%s.%s.%s", p, kind, field); - int off = sdb_array_get_num(TDB, var, 1, NULL); - //int siz = sdb_array_get_num (DB, var, 2, NULL); - eprintf("wv 0x%08" PFMT64x " @ 0x%08" PFMT64x, val, at + off); - return true; - } - eprintf("Invalid kind of type\n"); - } - return false; -} - -RZ_API int rz_type_kind(RzType *t, RZ_NONNULL const char *name) { - rz_return_val_if_fail(t && name, -1); - Sdb *TDB = t->sdb_types; +RZ_API int rz_type_kind(RzTypeDB *typedb, RZ_NONNULL const char *name) { + rz_return_val_if_fail(typedb && name, -1); + Sdb *TDB = typedb->sdb_types; const char *type = sdb_const_get(TDB, name, 0); if (!type) { return -1; @@ -60,13 +32,13 @@ RZ_API int rz_type_kind(RzType *t, RZ_NONNULL const char *name) { return -1; } -RZ_API RzList *rz_type_get_enum(RzType *t, RZ_NONNULL const char *name) { - rz_return_val_if_fail(t && name, NULL); - Sdb *TDB = t->sdb_types; +RZ_API RzList *rz_type_db_get_enum(RzTypeDB *typedb, RZ_NONNULL const char *name) { + rz_return_val_if_fail(typedb && name, NULL); + Sdb *TDB = typedb->sdb_types; char *p, var[130]; int n; - if (rz_type_kind(t, name) != RZ_BASE_TYPE_KIND_ENUM) { + if (rz_type_kind(typedb, name) != RZ_BASE_TYPE_KIND_ENUM) { return NULL; } RzList *res = rz_list_new(); @@ -93,10 +65,10 @@ RZ_API RzList *rz_type_get_enum(RzType *t, RZ_NONNULL const char *name) { return res; } -RZ_API char *rz_type_enum_member(RzType *t, RZ_NONNULL const char *name, const char *member, ut64 val) { - rz_return_val_if_fail(t && name, NULL); - Sdb *TDB = t->sdb_types; - if (rz_type_kind(t, name) != RZ_BASE_TYPE_KIND_ENUM) { +RZ_API char *rz_type_db_enum_member(RzTypeDB *typedb, RZ_NONNULL const char *name, const char *member, ut64 val) { + rz_return_val_if_fail(typedb && name, NULL); + Sdb *TDB = typedb->sdb_types; + if (rz_type_kind(typedb, name) != RZ_BASE_TYPE_KIND_ENUM) { return NULL; } const char *q = member @@ -105,9 +77,9 @@ RZ_API char *rz_type_enum_member(RzType *t, RZ_NONNULL const char *name, const c return sdb_get(TDB, q, 0); } -RZ_API RzList *rz_type_enum_find_member(RzType *t, ut64 val) { - rz_return_val_if_fail(t, NULL); - Sdb *TDB = t->sdb_types; +RZ_API RzList *rz_type_db_enum_find_member(RzTypeDB *typedb, ut64 val) { + rz_return_val_if_fail(typedb, NULL); + Sdb *TDB = typedb->sdb_types; SdbKv *kv; SdbListIter *iter; SdbList *l = sdb_foreach_list(TDB, true); @@ -130,14 +102,14 @@ RZ_API RzList *rz_type_enum_find_member(RzType *t, ut64 val) { return res; } -RZ_API char *rz_type_enum_getbitfield(RzType *t, RZ_NONNULL const char *name, ut64 val) { - rz_return_val_if_fail(t && name, NULL); - Sdb *TDB = t->sdb_types; +RZ_API char *rz_type_enum_getbitfield(RzTypeDB *typedb, RZ_NONNULL const char *name, ut64 val) { + rz_return_val_if_fail(typedb && name, NULL); + Sdb *TDB = typedb->sdb_types; char *q, *ret = NULL; const char *res; int i; - if (rz_type_kind(t, name) != RZ_BASE_TYPE_KIND_ENUM) { + if (rz_type_kind(typedb, name) != RZ_BASE_TYPE_KIND_ENUM) { return NULL; } bool isFirst = true; @@ -163,9 +135,9 @@ RZ_API char *rz_type_enum_getbitfield(RzType *t, RZ_NONNULL const char *name, ut return ret; } -RZ_API ut64 rz_type_get_bitsize(RzType *types, RZ_NONNULL const char *type) { - rz_return_val_if_fail(types && type, 0); - Sdb *TDB = types->sdb_types; +RZ_API ut64 rz_type_db_get_bitsize(RzTypeDB *typedb, RZ_NONNULL const char *type) { + rz_return_val_if_fail(typedb && type, 0); + Sdb *TDB = typedb->sdb_types; char *query; /* Filter out the structure keyword if type looks like "struct mystruc" */ const char *tmptype; @@ -223,9 +195,9 @@ RZ_API ut64 rz_type_get_bitsize(RzType *types, RZ_NONNULL const char *type) { elements = 1; } if (!strcmp(t, "struct")) { - ret += rz_type_get_bitsize(types, subtype) * elements; + ret += rz_type_db_get_bitsize(typedb, subtype) * elements; } else { - ut64 sz = rz_type_get_bitsize(types, subtype) * elements; + ut64 sz = rz_type_db_get_bitsize(typedb, subtype) * elements; ret = sz > ret ? sz : ret; } } @@ -240,9 +212,9 @@ RZ_API ut64 rz_type_get_bitsize(RzType *types, RZ_NONNULL const char *type) { return 0; } -RZ_API char *rz_type_get_struct_memb(RzType *t, RZ_NONNULL const char *type, int offset) { - rz_return_val_if_fail(t && type, NULL); - Sdb *TDB = t->sdb_types; +RZ_API char *rz_type_get_struct_memb(RzTypeDB *typedb, RZ_NONNULL const char *type, int offset) { + rz_return_val_if_fail(typedb && type, NULL); + Sdb *TDB = typedb->sdb_types; int i, cur_offset, next_offset = 0; char *res = NULL; @@ -285,7 +257,7 @@ RZ_API char *rz_type_get_struct_memb(RzType *t, RZ_NONNULL const char *type, int break; } int arrsz = rz_num_math(NULL, rz_str_word_get0(subtype, len - 1)); - int fsize = (rz_type_get_bitsize(t, subtype) * (arrsz ? arrsz : 1)) / 8; + int fsize = (rz_type_db_get_bitsize(typedb, subtype) * (arrsz ? arrsz : 1)) / 8; if (!fsize) { free(subtype); break; @@ -301,7 +273,7 @@ RZ_API char *rz_type_get_struct_memb(RzType *t, RZ_NONNULL const char *type, int break; } nested_type = (char *)rz_str_word_get0(nested_type, 1); - char *nested_res = rz_type_get_struct_memb(t, nested_type, offset - cur_offset); + char *nested_res = rz_type_get_struct_memb(typedb, nested_type, offset - cur_offset); if (nested_res) { len = rz_str_split(nested_res, '.'); res = rz_str_newf("%s.%s.%s", type, name, rz_str_word_get0(nested_res, len - 1)); @@ -318,9 +290,9 @@ RZ_API char *rz_type_get_struct_memb(RzType *t, RZ_NONNULL const char *type, int } // XXX this function is slow! -RZ_API RzList *rz_type_get_by_offset(RzType *t, ut64 offset) { - rz_return_val_if_fail(t, NULL); - Sdb *TDB = t->sdb_types; +RZ_API RzList *rz_type_get_by_offset(RzTypeDB *typedb, ut64 offset) { + rz_return_val_if_fail(typedb, NULL); + Sdb *TDB = typedb->sdb_types; RzList *offtypes = rz_list_new(); SdbList *ls = sdb_foreach_list(TDB, true); SdbListIter *lsi; @@ -328,7 +300,7 @@ RZ_API RzList *rz_type_get_by_offset(RzType *t, ut64 offset) { ls_foreach (ls, lsi, kv) { // TODO: Add unions support if (!strncmp(sdbkv_value(kv), "struct", 6) && strncmp(sdbkv_key(kv), "struct.", 7)) { - char *res = rz_type_get_struct_memb(t, sdbkv_key(kv), offset); + char *res = rz_type_get_struct_memb(typedb, sdbkv_key(kv), offset); if (res) { rz_list_append(offtypes, res); } diff --git a/test/unit/test_dwarf_integration.c b/test/unit/test_dwarf_integration.c index 23ac89448aa..cd2e762d351 100644 --- a/test/unit/test_dwarf_integration.c +++ b/test/unit/test_dwarf_integration.c @@ -39,7 +39,7 @@ static bool test_parse_dwarf_types(void) { rz_analysis_dwarf_process_info(analysis, &ctx); char *value = NULL; - Sdb *sdb = analysis->type->sdb_types; + Sdb *sdb = analysis->typedb->sdb_types; check_kv("_cairo_status", "enum"); check_kv("enum._cairo_status.0x0", "CAIRO_STATUS_SUCCESS"); check_kv("enum._cairo_status.CAIRO_STATUS_SUCCESS", "0x0"); diff --git a/test/unit/test_pdb.c b/test/unit/test_pdb.c index 6372fc42bba..30c4a23cdb1 100644 --- a/test/unit/test_pdb.c +++ b/test/unit/test_pdb.c @@ -12,7 +12,7 @@ #define check_kv(k, v) \ do { \ - char *value = sdb_get(analysis->type->sdb_types, k, NULL); \ + char *value = sdb_get(analysis->typedb->sdb_types, k, NULL); \ mu_assert_nullable_streq(value, v, "Wrong key - value pair"); \ } while (0) @@ -40,7 +40,7 @@ int pdb_info_save_types(RzAnalysis *analysis, const char *file, RzPdb *pdb) { pdb->finish_pdb_parse(pdb); return false; } - rz_parse_pdb_types(analysis->type, pdb); + rz_parse_pdb_types(analysis->typedb, pdb); pdb->finish_pdb_parse(pdb); return true; } diff --git a/test/unit/test_serialize_analysis.c b/test/unit/test_serialize_analysis.c index 3b253c13fab..fb5ade8aafc 100644 --- a/test/unit/test_serialize_analysis.c +++ b/test/unit/test_serialize_analysis.c @@ -1532,7 +1532,7 @@ bool test_analysis_save() { type->name = strdup("badchar"); type->size = 16; type->type = strdup("c"); - rz_type_save_base_type(analysis->type, type); + rz_type_db_save_base_type(analysis->typedb, type); rz_type_base_type_free(type); rz_spaces_set(&analysis->zign_spaces, "koridai"); @@ -1598,7 +1598,7 @@ bool test_analysis_load() { mu_assert_streq(meth->name, "some_meth", "method name"); rz_vector_free(vals); - RzBaseType *type = rz_type_get_base_type(analysis->type, "badchar"); + RzBaseType *type = rz_type_db_get_base_type(analysis->typedb, "badchar"); mu_assert_notnull(type, "get type"); mu_assert_eq(type->kind, RZ_BASE_TYPE_KIND_ATOMIC, "type kind"); mu_assert_eq(type->size, 16, "atomic type size"); diff --git a/test/unit/test_serialize_types.c b/test/unit/test_serialize_types.c index 213aa78ade2..17413896b71 100644 --- a/test/unit/test_serialize_types.c +++ b/test/unit/test_serialize_types.c @@ -34,7 +34,7 @@ Sdb *types_ref_db() { } bool test_types_save() { - RzType *types = rz_type_new(); + RzTypeDB *typedb = rz_type_db_new(); // struct RzBaseType *type = rz_type_base_type_new(RZ_BASE_TYPE_KIND_STRUCT); @@ -51,7 +51,7 @@ bool test_types_save() { member.type = strdup("uint64_t"); rz_vector_push(&type->struct_data.members, &member); - rz_type_save_base_type(types, type); + rz_type_db_save_base_type(typedb, type); rz_type_base_type_free(type); // union @@ -69,7 +69,7 @@ bool test_types_save() { mumber.type = strdup("uint32_t"); rz_vector_push(&type->union_data.members, &mumber); - rz_type_save_base_type(types, type); + rz_type_db_save_base_type(typedb, type); rz_type_base_type_free(type); // enum @@ -85,14 +85,14 @@ bool test_types_save() { cas.val = 1337; rz_vector_push(&type->enum_data.cases, &cas); - rz_type_save_base_type(types, type); + rz_type_db_save_base_type(typedb, type); rz_type_base_type_free(type); // typedef type = rz_type_base_type_new(RZ_BASE_TYPE_KIND_TYPEDEF); type->name = strdup("human"); type->type = strdup("union snatcher"); - rz_type_save_base_type(types, type); + rz_type_db_save_base_type(typedb, type); rz_type_base_type_free(type); // atomic @@ -100,29 +100,29 @@ bool test_types_save() { type->name = strdup("badchar"); type->size = 16; type->type = strdup("c"); - rz_type_save_base_type(types, type); + rz_type_db_save_base_type(typedb, type); rz_type_base_type_free(type); Sdb *db = sdb_new0(); - rz_serialize_types_save(db, types); + rz_serialize_types_save(db, typedb); Sdb *expected = types_ref_db(); assert_sdb_eq(db, expected, "types save"); sdb_free(db); sdb_free(expected); - rz_type_free(types); + rz_type_db_free(typedb); mu_end; } bool test_types_load() { - RzType *types = rz_type_new(); + RzTypeDB *typedb = rz_type_db_new(); Sdb *db = types_ref_db(); - bool succ = rz_serialize_types_load(db, types, NULL); + bool succ = rz_serialize_types_load(db, typedb, NULL); sdb_free(db); mu_assert("load success", succ); // struct - RzBaseType *type = rz_type_get_base_type(types, "junker"); + RzBaseType *type = rz_type_db_get_base_type(typedb, "junker"); mu_assert_notnull(type, "get type"); mu_assert_eq(type->kind, RZ_BASE_TYPE_KIND_STRUCT, "type kind"); mu_assert_eq(type->struct_data.members.len, 2, "members count"); @@ -140,7 +140,7 @@ bool test_types_load() { rz_type_base_type_free(type); // union - type = rz_type_get_base_type(types, "snatcher"); + type = rz_type_db_get_base_type(typedb, "snatcher"); mu_assert_notnull(type, "get type"); mu_assert_eq(type->kind, RZ_BASE_TYPE_KIND_UNION, "type kind"); mu_assert_eq(type->union_data.members.len, 2, "members count"); @@ -156,7 +156,7 @@ bool test_types_load() { rz_type_base_type_free(type); // enum - type = rz_type_get_base_type(types, "mika"); + type = rz_type_db_get_base_type(typedb, "mika"); mu_assert_notnull(type, "get type"); mu_assert_eq(type->kind, RZ_BASE_TYPE_KIND_ENUM, "type kind"); mu_assert_eq(type->enum_data.cases.len, 2, "cases count"); @@ -172,21 +172,21 @@ bool test_types_load() { rz_type_base_type_free(type); // typedef - type = rz_type_get_base_type(types, "human"); + type = rz_type_db_get_base_type(typedb, "human"); mu_assert_notnull(type, "get type"); mu_assert_eq(type->kind, RZ_BASE_TYPE_KIND_TYPEDEF, "type kind"); mu_assert_streq(type->type, "union snatcher", "typedefd type"); rz_type_base_type_free(type); // atomic - type = rz_type_get_base_type(types, "badchar"); + type = rz_type_db_get_base_type(typedb, "badchar"); mu_assert_notnull(type, "get type"); mu_assert_eq(type->kind, RZ_BASE_TYPE_KIND_ATOMIC, "type kind"); mu_assert_eq(type->size, 16, "atomic type size"); mu_assert_streq(type->type, "c", "atomic type"); rz_type_base_type_free(type); - rz_type_free(types); + rz_type_db_free(typedb); mu_end; } diff --git a/test/unit/test_type.c b/test/unit/test_type.c index 767f1fd93b5..53f8f369284 100644 --- a/test/unit/test_type.c +++ b/test/unit/test_type.c @@ -73,13 +73,13 @@ static void setup_sdb_for_not_found(Sdb *res) { } static bool test_types_get_base_type_struct(void) { - RzType *types = rz_type_new(); - mu_assert_notnull(types, "Couldn't create new RzType"); - mu_assert_notnull(types->sdb_types, "Couldn't create new RzType.sdb_types"); + RzTypeDB *typedb = rz_type_db_new(); + mu_assert_notnull(typedb, "Couldn't create new RzTypeDb"); + mu_assert_notnull(typedb->sdb_types, "Couldn't create new RzTypeDB.sdb_types"); - setup_sdb_for_struct(types->sdb_types); + setup_sdb_for_struct(typedb->sdb_types); - RzBaseType *base = rz_type_get_base_type(types, "kappa"); + RzBaseType *base = rz_type_db_get_base_type(typedb, "kappa"); mu_assert_notnull(base, "Couldn't create get base type of struct \"kappa\""); mu_assert_eq(RZ_BASE_TYPE_KIND_STRUCT, base->kind, "Wrong base type"); @@ -98,14 +98,14 @@ static bool test_types_get_base_type_struct(void) { mu_assert_streq(member->name, "cow", "Incorrect name for struct member"); rz_type_base_type_free(base); - rz_type_free(types); + rz_type_db_free(typedb); mu_end; } static bool test_types_save_base_type_struct(void) { - RzType *types = rz_type_new(); - mu_assert_notnull(types, "Couldn't create new RzType"); - mu_assert_notnull(types->sdb_types, "Couldn't create new RzType.sdb_types"); + RzTypeDB *typedb = rz_type_db_new(); + mu_assert_notnull(typedb, "Couldn't create new RzTypeDB"); + mu_assert_notnull(typedb->sdb_types, "Couldn't create new RzTypeDB.sdb_types"); RzBaseType *base = rz_type_base_type_new(RZ_BASE_TYPE_KIND_STRUCT); base->name = strdup("kappa"); @@ -122,26 +122,26 @@ static bool test_types_save_base_type_struct(void) { member.name = strdup("cow"); rz_vector_push(&base->struct_data.members, &member); - rz_type_save_base_type(types, base); + rz_type_db_save_base_type(typedb, base); rz_type_base_type_free(base); Sdb *reg = sdb_new0(); setup_sdb_for_struct(reg); - assert_sdb_eq(types->sdb_types, reg, "save struct type"); + assert_sdb_eq(typedb->sdb_types, reg, "save struct type"); sdb_free(reg); - rz_type_free(types); + rz_type_db_free(typedb); mu_end; } static bool test_types_get_base_type_union(void) { - RzType *types = rz_type_new(); - mu_assert_notnull(types, "Couldn't create new RzType"); - mu_assert_notnull(types->sdb_types, "Couldn't create new RzType.sdb_types"); + RzTypeDB *typedb = rz_type_db_new(); + mu_assert_notnull(typedb, "Couldn't create new RzTypeDB"); + mu_assert_notnull(typedb->sdb_types, "Couldn't create new RzTypeDB.sdb_types"); - setup_sdb_for_union(types->sdb_types); + setup_sdb_for_union(typedb->sdb_types); - RzBaseType *base = rz_type_get_base_type(types, "kappa"); + RzBaseType *base = rz_type_db_get_base_type(typedb, "kappa"); mu_assert_notnull(base, "Couldn't create get base type of union \"kappa\""); mu_assert_eq(RZ_BASE_TYPE_KIND_UNION, base->kind, "Wrong base type"); @@ -158,14 +158,14 @@ static bool test_types_get_base_type_union(void) { mu_assert_streq(member->name, "cow", "Incorrect name for union member"); rz_type_base_type_free(base); - rz_type_free(types); + rz_type_db_free(typedb); mu_end; } static bool test_types_save_base_type_union(void) { - RzType *types = rz_type_new(); - mu_assert_notnull(types, "Couldn't create new RzType"); - mu_assert_notnull(types->sdb_types, "Couldn't create new RzType.sdb_types"); + RzTypeDB *typedb = rz_type_db_new(); + mu_assert_notnull(typedb, "Couldn't create new RzTypeDB"); + mu_assert_notnull(typedb->sdb_types, "Couldn't create new RzTypeDB.sdb_types"); RzBaseType *base = rz_type_base_type_new(RZ_BASE_TYPE_KIND_UNION); base->name = strdup("kappa"); @@ -182,25 +182,25 @@ static bool test_types_save_base_type_union(void) { member.name = strdup("cow"); rz_vector_push(&base->union_data.members, &member); - rz_type_save_base_type(types, base); + rz_type_db_save_base_type(typedb, base); rz_type_base_type_free(base); Sdb *reg = sdb_new0(); setup_sdb_for_union(reg); - assert_sdb_eq(types->sdb_types, reg, "save union type"); + assert_sdb_eq(typedb->sdb_types, reg, "save union type"); sdb_free(reg); - rz_type_free(types); + rz_type_db_free(typedb); mu_end; } static bool test_types_get_base_type_enum(void) { - RzType *types = rz_type_new(); - mu_assert_notnull(types, "Couldn't create new RzType"); + RzTypeDB *typedb = rz_type_db_new(); + mu_assert_notnull(typedb, "Couldn't create new RzTypeDB"); - setup_sdb_for_enum(types->sdb_types); + setup_sdb_for_enum(typedb->sdb_types); - RzBaseType *base = rz_type_get_base_type(types, "foo"); + RzBaseType *base = rz_type_db_get_base_type(typedb, "foo"); mu_assert_notnull(base, "Couldn't create get base type of enum \"foo\""); mu_assert_eq(RZ_BASE_TYPE_KIND_ENUM, base->kind, "Wrong base type"); @@ -215,13 +215,13 @@ static bool test_types_get_base_type_enum(void) { mu_assert_streq(cas->name, "secondCase", "Incorrect name for enum case"); rz_type_base_type_free(base); - rz_type_free(types); + rz_type_db_free(typedb); mu_end; } static bool test_types_save_base_type_enum(void) { - RzType *types = rz_type_new(); - mu_assert_notnull(types, "Couldn't create new RzType"); + RzTypeDB *typedb = rz_type_db_new(); + mu_assert_notnull(typedb, "Couldn't create new RzTypeDb"); RzBaseType *base = rz_type_base_type_new(RZ_BASE_TYPE_KIND_ENUM); base->name = strdup("foo"); @@ -236,25 +236,25 @@ static bool test_types_save_base_type_enum(void) { cas.val = 2; rz_vector_push(&base->enum_data.cases, &cas); - rz_type_save_base_type(types, base); + rz_type_db_save_base_type(typedb, base); rz_type_base_type_free(base); Sdb *reg = sdb_new0(); setup_sdb_for_enum(reg); - assert_sdb_eq(types->sdb_types, reg, "save enum type"); + assert_sdb_eq(typedb->sdb_types, reg, "save enum type"); sdb_free(reg); - rz_type_free(types); + rz_type_db_free(typedb); mu_end; } static bool test_types_get_base_type_typedef(void) { - RzType *types = rz_type_new(); - mu_assert_notnull(types, "Couldn't create new RzType"); + RzTypeDB *typedb = rz_type_db_new(); + mu_assert_notnull(typedb, "Couldn't create new RzTypeDB"); - setup_sdb_for_typedef(types->sdb_types); + setup_sdb_for_typedef(typedb->sdb_types); - RzBaseType *base = rz_type_get_base_type(types, "string"); + RzBaseType *base = rz_type_db_get_base_type(typedb, "string"); mu_assert_notnull(base, "Couldn't create get base type of typedef \"string\""); mu_assert_eq(RZ_BASE_TYPE_KIND_TYPEDEF, base->kind, "Wrong base type"); @@ -262,39 +262,39 @@ static bool test_types_get_base_type_typedef(void) { mu_assert_streq(base->type, "char *", "typedefd type"); rz_type_base_type_free(base); - rz_type_free(types); + rz_type_db_free(typedb); mu_end; } static bool test_types_save_base_type_typedef(void) { - RzType *types = rz_type_new(); - mu_assert_notnull(types, "Couldn't create new RzType"); - mu_assert_notnull(types->sdb_types, "Couldn't create new RzType.sdb_types"); + RzTypeDB *typedb = rz_type_db_new(); + mu_assert_notnull(typedb, "Couldn't create new RzTypeDB"); + mu_assert_notnull(typedb->sdb_types, "Couldn't create new RzTypeDB.sdb_types"); RzBaseType *base = rz_type_base_type_new(RZ_BASE_TYPE_KIND_TYPEDEF); base->name = strdup("string"); base->type = strdup("char *"); - rz_type_save_base_type(types, base); + rz_type_db_save_base_type(typedb, base); rz_type_base_type_free(base); Sdb *reg = sdb_new0(); setup_sdb_for_typedef(reg); - assert_sdb_eq(types->sdb_types, reg, "save typedef type"); + assert_sdb_eq(typedb->sdb_types, reg, "save typedef type"); sdb_free(reg); - rz_type_free(types); + rz_type_db_free(typedb); mu_end; } static bool test_types_get_base_type_atomic(void) { - RzType *types = rz_type_new(); - mu_assert_notnull(types, "Couldn't create new RzType"); - mu_assert_notnull(types->sdb_types, "Couldn't create new RzType.sdb_types"); + RzTypeDB *typedb = rz_type_db_new(); + mu_assert_notnull(typedb, "Couldn't create new RzTypeDB"); + mu_assert_notnull(typedb->sdb_types, "Couldn't create new RzTypeDB.sdb_types"); - setup_sdb_for_atomic(types->sdb_types); + setup_sdb_for_atomic(typedb->sdb_types); - RzBaseType *base = rz_type_get_base_type(types, "char"); + RzBaseType *base = rz_type_db_get_base_type(typedb, "char"); mu_assert_notnull(base, "Couldn't create get base type of atomic type \"char\""); mu_assert_eq(RZ_BASE_TYPE_KIND_ATOMIC, base->kind, "Wrong base type"); @@ -303,175 +303,175 @@ static bool test_types_get_base_type_atomic(void) { mu_assert_eq(base->size, 8, "atomic type size"); rz_type_base_type_free(base); - rz_type_free(types); + rz_type_db_free(typedb); mu_end; } static bool test_types_save_base_type_atomic(void) { - RzType *types = rz_type_new(); - mu_assert_notnull(types, "Couldn't create new RzTypes"); - mu_assert_notnull(types->sdb_types, "Couldn't create new RzTypes.sdb_types"); + RzTypeDB *typedb = rz_type_db_new(); + mu_assert_notnull(typedb, "Couldn't create new RzTypes"); + mu_assert_notnull(typedb->sdb_types, "Couldn't create new RzTypes.sdb_types"); RzBaseType *base = rz_type_base_type_new(RZ_BASE_TYPE_KIND_ATOMIC); base->name = strdup("char"); base->type = strdup("c"); base->size = 8; - rz_type_save_base_type(types, base); + rz_type_db_save_base_type(typedb, base); rz_type_base_type_free(base); Sdb *reg = sdb_new0(); setup_sdb_for_atomic(reg); - assert_sdb_eq(types->sdb_types, reg, "save atomic type"); + assert_sdb_eq(typedb->sdb_types, reg, "save atomic type"); sdb_free(reg); - rz_type_free(types); + rz_type_db_free(typedb); mu_end; } static bool test_types_get_base_type_not_found(void) { - RzType *types = rz_type_new(); - setup_sdb_for_not_found(types->sdb_types); + RzTypeDB *typedb = rz_type_db_new(); + setup_sdb_for_not_found(typedb->sdb_types); - mu_assert_notnull(types, "Couldn't create new RzType"); - mu_assert_notnull(types->sdb_types, "Couldn't create new RzType.sdb_types"); + mu_assert_notnull(typedb, "Couldn't create new RzTypeDB"); + mu_assert_notnull(typedb->sdb_types, "Couldn't create new RzTypeDB.sdb_types"); - RzBaseType *base = rz_type_get_base_type(types, "non_existant23321312___"); + RzBaseType *base = rz_type_db_get_base_type(typedb, "non_existant23321312___"); mu_assert_null(base, "Should find nothing"); - base = rz_type_get_base_type(types, "foo"); + base = rz_type_db_get_base_type(typedb, "foo"); mu_assert_null(base, "Should find nothing"); - base = rz_type_get_base_type(types, "bar"); + base = rz_type_db_get_base_type(typedb, "bar"); mu_assert_null(base, "Should find nothing"); - base = rz_type_get_base_type(types, "quax"); + base = rz_type_db_get_base_type(typedb, "quax"); mu_assert_null(base, "Should find nothing"); - base = rz_type_get_base_type(types, "omega"); + base = rz_type_db_get_base_type(typedb, "omega"); mu_assert_null(base, "Should find nothing"); - rz_type_free(types); + rz_type_db_free(typedb); mu_end; } bool test_dll_names(void) { - RzType *T = rz_type_new(); - T->sdb_types = setup_sdb_for_function(); + RzTypeDB *typedb = rz_type_db_new(); + typedb->sdb_types = setup_sdb_for_function(); char *s; - s = rz_type_func_guess(T, "sub.KERNEL32.dll_ExitProcess"); + s = rz_type_func_guess(typedb, "sub.KERNEL32.dll_ExitProcess"); mu_assert_notnull(s, "dll_ should be ignored"); mu_assert_streq(s, "ExitProcess", "dll_ should be ignored"); free(s); - s = rz_type_func_guess(T, "sub.dll_ExitProcess_32"); + s = rz_type_func_guess(typedb, "sub.dll_ExitProcess_32"); mu_assert_notnull(s, "number should be ignored"); mu_assert_streq(s, "ExitProcess", "number should be ignored"); free(s); - s = rz_type_func_guess(T, "sym.imp.KERNEL32.dll_ReadFile"); + s = rz_type_func_guess(typedb, "sym.imp.KERNEL32.dll_ReadFile"); mu_assert_notnull(s, "dll_ and number should be ignored case 1"); mu_assert_streq(s, "ReadFile", "dll_ and number should be ignored case 1"); free(s); - s = rz_type_func_guess(T, "sub.VCRUNTIME14.dll_memcpy"); + s = rz_type_func_guess(typedb, "sub.VCRUNTIME14.dll_memcpy"); mu_assert_notnull(s, "dll_ and number should be ignored case 2"); mu_assert_streq(s, "memcpy", "dll_ and number should be ignored case 2"); free(s); - s = rz_type_func_guess(T, "sub.KERNEL32.dll_ExitProcess_32"); + s = rz_type_func_guess(typedb, "sub.KERNEL32.dll_ExitProcess_32"); mu_assert_notnull(s, "dll_ and number should be ignored case 3"); mu_assert_streq(s, "ExitProcess", "dll_ and number should be ignored case 3"); free(s); - s = rz_type_func_guess(T, "WS2_32.dll_WSAStartup"); + s = rz_type_func_guess(typedb, "WS2_32.dll_WSAStartup"); mu_assert_notnull(s, "dll_ and number should be ignored case 4"); mu_assert_streq(s, "WSAStartup", "dll_ and number should be ignored case 4"); free(s); - sdb_free(T->sdb_types); - rz_type_free(T); + sdb_free(typedb->sdb_types); + rz_type_db_free(typedb); mu_end; } bool test_ignore_prefixes(void) { - RzType *T = rz_type_new(); - T->sdb_types = setup_sdb_for_function(); + RzTypeDB *typedb = rz_type_db_new(); + typedb->sdb_types = setup_sdb_for_function(); char *s; - s = rz_type_func_guess(T, "fcn.KERNEL32.dll_ExitProcess_32"); + s = rz_type_func_guess(typedb, "fcn.KERNEL32.dll_ExitProcess_32"); mu_assert_null(s, "fcn. names should be ignored"); free(s); - s = rz_type_func_guess(T, "loc.KERNEL32.dll_ExitProcess_32"); + s = rz_type_func_guess(typedb, "loc.KERNEL32.dll_ExitProcess_32"); mu_assert_null(s, "loc. names should be ignored"); free(s); - sdb_free(T->sdb_types); - rz_type_free(T); + sdb_free(typedb->sdb_types); + rz_type_db_free(typedb); mu_end; } bool test_remove_rz_prefixes(void) { - RzType *T = rz_type_new(); - T->sdb_types = setup_sdb_for_function(); + RzTypeDB *typedb = rz_type_db_new(); + typedb->sdb_types = setup_sdb_for_function(); char *s; - s = rz_type_func_guess(T, "sym.imp.ExitProcess"); + s = rz_type_func_guess(typedb, "sym.imp.ExitProcess"); mu_assert_notnull(s, "sym.imp should be ignored"); mu_assert_streq(s, "ExitProcess", "sym.imp should be ignored"); free(s); - s = rz_type_func_guess(T, "sym.imp.fcn.ExitProcess"); + s = rz_type_func_guess(typedb, "sym.imp.fcn.ExitProcess"); mu_assert_notnull(s, "sym.imp.fcn should be ignored"); mu_assert_streq(s, "ExitProcess", "sym.imp.fcn should be ignored"); free(s); - s = rz_type_func_guess(T, "longprefix.ExitProcess"); + s = rz_type_func_guess(typedb, "longprefix.ExitProcess"); mu_assert_null(s, "prefixes longer than 3 should not be ignored"); free(s); - sdb_free(T->sdb_types); - rz_type_free(T); + sdb_free(typedb->sdb_types); + rz_type_db_free(typedb); mu_end; } bool test_autonames(void) { - RzType *T = rz_type_new(); - T->sdb_types = setup_sdb_for_function(); + RzTypeDB *typedb = rz_type_db_new(); + typedb->sdb_types = setup_sdb_for_function(); char *s; - s = rz_type_func_guess(T, "sub.strchr_123"); + s = rz_type_func_guess(typedb, "sub.strchr_123"); mu_assert_null(s, "function that calls common fcns shouldn't be identified as such"); free(s); - s = rz_type_func_guess(T, "sub.__strchr_123"); + s = rz_type_func_guess(typedb, "sub.__strchr_123"); mu_assert_null(s, "initial _ should not confuse the api"); free(s); - s = rz_type_func_guess(T, "sub.__stack_chk_fail_740"); + s = rz_type_func_guess(typedb, "sub.__stack_chk_fail_740"); mu_assert_null(s, "initial _ should not confuse the api"); free(s); - s = rz_type_func_guess(T, "sym.imp.strchr"); + s = rz_type_func_guess(typedb, "sym.imp.strchr"); mu_assert_notnull(s, "sym.imp. should be ignored"); mu_assert_streq(s, "strchr", "strchr should be identified"); free(s); - sdb_free(T->sdb_types); - rz_type_free(T); + sdb_free(typedb->sdb_types); + rz_type_db_free(typedb); mu_end; } bool test_initial_underscore(void) { - RzType *T = rz_type_new(); - T->sdb_types = setup_sdb_for_function(); + RzTypeDB *typedb = rz_type_db_new(); + typedb->sdb_types = setup_sdb_for_function(); char *s; - s = rz_type_func_guess(T, "sym._strchr"); + s = rz_type_func_guess(typedb, "sym._strchr"); mu_assert_notnull(s, "sym._ should be ignored"); mu_assert_streq(s, "strchr", "strchr should be identified"); free(s); - sdb_free(T->sdb_types); - rz_type_free(T); + sdb_free(typedb->sdb_types); + rz_type_db_free(typedb); mu_end; } From 4c8f5de172426fceb0542a5f5fcf24a1d2aa8ab4 Mon Sep 17 00:00:00 2001 From: Anton Kochkov Date: Mon, 29 Mar 2021 17:54:40 +0800 Subject: [PATCH 05/25] Join RzType and RzAnalysis noreturn functions --- librz/analysis/analysis.c | 40 +++++++++++++++++++++++++++++++++++++ librz/core/canalysis.c | 2 +- librz/core/core.c | 2 ++ librz/include/rz_analysis.h | 3 ++- 4 files changed, 45 insertions(+), 2 deletions(-) diff --git a/librz/analysis/analysis.c b/librz/analysis/analysis.c index 62fef6eb682..33975c446e8 100644 --- a/librz/analysis/analysis.c +++ b/librz/analysis/analysis.c @@ -116,6 +116,7 @@ RZ_API RzAnalysis *rz_analysis_new(void) { analysis->sdb_zigns = sdb_ns(analysis->sdb, "zigns", 1); analysis->sdb_classes = sdb_ns(analysis->sdb, "classes", 1); analysis->sdb_classes_attrs = sdb_ns(analysis->sdb_classes, "attrs", 1); + analysis->sdb_noret = sdb_ns(analysis->sdb, "noreturn", 1); analysis->zign_path = strdup(""); analysis->cb_printf = (PrintfCallback)printf; (void)rz_analysis_pin_init(analysis); @@ -413,6 +414,7 @@ RZ_API void rz_analysis_purge(RzAnalysis *analysis) { rz_analysis_pin_fini(analysis); rz_analysis_pin_init(analysis); sdb_reset(analysis->sdb_cc); + sdb_reset(analysis->sdb_noret); rz_list_free(analysis->fcns); analysis->fcns = rz_list_newf(rz_analysis_function_free); rz_analysis_purge_imports(analysis); @@ -600,6 +602,44 @@ RZ_API bool rz_analysis_noreturn_at(RzAnalysis *analysis, ut64 addr) { return false; } +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_functions(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) { + 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); + } + 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); + } + } + ls_free(l); + return noretl; +} + RZ_API void rz_analysis_bind(RzAnalysis *analysis, RzAnalysisBind *b) { if (b) { b->analysis = analysis; diff --git a/librz/core/canalysis.c b/librz/core/canalysis.c index 0ce49cccbb6..075a9f475a5 100644 --- a/librz/core/canalysis.c +++ b/librz/core/canalysis.c @@ -6813,7 +6813,7 @@ RZ_API void rz_core_analysis_propagate_noreturn_relocs(RzCore *core, ut64 addr) int bits1 = core->analysis->bits; int bits2 = core->rasm->bits; // find known noreturn functions to propagate - RzList *noretl = rz_type_noreturn_functions(core->analysis->typedb); + RzList *noretl = rz_analysis_noreturn_functions(core->analysis); // List of the potentially noreturn functions SetU *todo = set_u_new(); struct core_noretl u = { core, noretl, todo }; diff --git a/librz/core/core.c b/librz/core/core.c index 55ed1a380e9..49aea1c3471 100644 --- a/librz/core/core.c +++ b/librz/core/core.c @@ -1148,6 +1148,7 @@ static void autocompleteFilename(RzLineCompletion *completion, RzLineBuffer *buf free(input); } +/* //TODO: make it recursive to handle nested struct static int autocomplete_pfele(RzCore *core, RzLineCompletion *completion, char *key, char *pfx, int idx, char *ptr) { int i, ret = 0; @@ -1175,6 +1176,7 @@ static int autocomplete_pfele(RzCore *core, RzLineCompletion *completion, char * } return ret; } +*/ #define ADDARG(x) \ if (!strncmp(buf->data + chr, x, strlen(buf->data + chr))) { \ diff --git a/librz/include/rz_analysis.h b/librz/include/rz_analysis.h index 688bc289c8d..18cee816984 100644 --- a/librz/include/rz_analysis.h +++ b/librz/include/rz_analysis.h @@ -1685,7 +1685,6 @@ RZ_API const char *rz_analysis_syscc_default(RzAnalysis *analysis); RZ_API void rz_analysis_set_syscc_default(RzAnalysis *analysis, const char *convention); RZ_API const char *rz_analysis_cc_func(RzAnalysis *analysis, const char *func_name); RZ_API RzList *rz_analysis_calling_conventions(RzAnalysis *analysis); -RZ_API bool rz_analysis_noreturn_at(RzAnalysis *analysis, ut64 addr); typedef struct rz_analysis_data_t { ut64 addr; @@ -1862,6 +1861,8 @@ RZ_API void rz_analysis_unset_limits(RzAnalysis *analysis); RZ_API bool rz_analysis_noreturn_add(RzAnalysis *analysis, const char *name, ut64 addr); RZ_API bool rz_analysis_noreturn_drop(RzAnalysis *analysis, const char *expr); RZ_API bool rz_analysis_noreturn_at_addr(RzAnalysis *analysis, ut64 addr); +RZ_API bool rz_analysis_noreturn_at(RzAnalysis *analysis, ut64 addr); +RZ_API RzList *rz_analysis_noreturn_functions(RzAnalysis *analysis); /* zign spaces */ RZ_API int rz_sign_space_count_for(RzAnalysis *a, const RzSpace *space); From 8382a356906c7dd36a03b94a5857e5ff93c5c531 Mon Sep 17 00:00:00 2001 From: Anton Kochkov Date: Mon, 29 Mar 2021 19:55:35 +0800 Subject: [PATCH 06/25] Add noreturn column in `aflt` output --- librz/core/canalysis.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/librz/core/canalysis.c b/librz/core/canalysis.c index 075a9f475a5..96289f2123f 100644 --- a/librz/core/canalysis.c +++ b/librz/core/canalysis.c @@ -3830,6 +3830,7 @@ static int fcn_list_table(RzCore *core, const char *q, int fmt) { rz_table_add_column(t, typeNumber, "xref", 0); rz_table_add_column(t, typeNumber, "calls", 0); rz_table_add_column(t, typeNumber, "cc", 0); + rz_table_add_column(t, typeNumber, "noreturn", 0); rz_list_foreach (core->analysis->fcns, iter, fcn) { const char *fcnAddr = sdb_fmt("0x%08" PFMT64x, fcn->addr); const char *fcnSize = sdb_fmt("%" PFMT64u, rz_analysis_function_linear_size(fcn)); @@ -3845,8 +3846,8 @@ static int fcn_list_table(RzCore *core, const char *q, int fmt) { const char *callstr = sdb_fmt("%d", rz_list_length(calls)); rz_list_free(calls); snprintf(ccstr, sizeof(ccstr), "%d", rz_analysis_function_complexity(fcn)); - - rz_table_add_row(t, fcnAddr, fcnSize, fcn->name, nbbs, xref, callstr, ccstr, NULL); + const char *noret = fcn->is_noreturn ? "yes" : ""; + rz_table_add_row(t, fcnAddr, fcnSize, fcn->name, nbbs, xref, callstr, ccstr, noret, NULL); } if (rz_table_query(t, q)) { char *s = (fmt == 'j') From e39db08ee1418f7b70c20a5b872a022426d35ca0 Mon Sep 17 00:00:00 2001 From: Anton Kochkov Date: Wed, 31 Mar 2021 13:45:29 +0800 Subject: [PATCH 07/25] Fix build warning --- librz/analysis/dwarf_process.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/librz/analysis/dwarf_process.c b/librz/analysis/dwarf_process.c index 43ab8466e64..d949b7f3424 100644 --- a/librz/analysis/dwarf_process.c +++ b/librz/analysis/dwarf_process.c @@ -1,9 +1,9 @@ // SPDX-FileCopyrightText: 2012-2020 houndthe // SPDX-License-Identifier: LGPL-3.0-only -#include #include #include +#include #include #include #include From 560dea1332628bde1969c9fc7b176692a2d20c09 Mon Sep 17 00:00:00 2001 From: Anton Kochkov Date: Wed, 31 Mar 2021 14:08:07 +0800 Subject: [PATCH 08/25] Fix type signatures --- librz/analysis/sign.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/librz/analysis/sign.c b/librz/analysis/sign.c index 7c9563f61bb..a7df5acbec6 100644 --- a/librz/analysis/sign.c +++ b/librz/analysis/sign.c @@ -93,8 +93,9 @@ RZ_API RzList *rz_sign_fcn_types(RzAnalysis *a, RzAnalysisFunction *fcn) { rz_list_append(ret, rz_str_newf("func.%s.args=%d", fcn->name, fcnargs)); int i; for (i = 0; i < fcnargs; i++) { - const char *arg = rz_type_func_args_name(a->typedb, fcn->name, i); - rz_list_append(ret, rz_str_newf("func.%s.arg.%d=\"%s\"", fcn->name, i, arg)); + const char *arg_name = rz_type_func_args_name(a->typedb, fcn->name, i); + const char *arg_type = rz_type_func_args_type(a->typedb, fcn->name, i); + rz_list_append(ret, rz_str_newf("func.%s.arg.%d=\"%s,%s\"", fcn->name, i, arg_type, arg_name)); } } From 0607c4a7b4e1b8b86271c906daf12d6c3bd843bb Mon Sep 17 00:00:00 2001 From: Anton Kochkov Date: Wed, 31 Mar 2021 14:22:04 +0800 Subject: [PATCH 09/25] Fix formats --- librz/type/format.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/librz/type/format.c b/librz/type/format.c index 2bbaf29e7c8..71f86ecccd2 100644 --- a/librz/type/format.c +++ b/librz/type/format.c @@ -1885,6 +1885,9 @@ RZ_API int rz_type_format_struct_size(RzTypeDB *typedb, const char *f, int mode, return (mode & RZ_PRINT_UNIONMODE) ? biggest : size; } +static int rz_type_format_data_internal(RzTypeDB *typedb, RzPrint *p, RzStrBuf *outbuf, ut64 seek, const ut8 *b, const int len, + const char *formatname, int mode, const char *setval, char *ofield); + static int rz_type_format_struct(RzTypeDB *typedb, RzPrint *p, RzStrBuf *outbuf, ut64 seek, const ut8 *b, int len, const char *name, int slide, int mode, const char *setval, char *field, int anon) { const char *fmt; @@ -1915,7 +1918,7 @@ static int rz_type_format_struct(RzTypeDB *typedb, RzPrint *p, RzStrBuf *outbuf, } rz_strbuf_appendf(outbuf, "<%s>\n", name); } - rz_type_format_data(typedb, p, seek, b, len, fmt, mode, setval, field); + rz_type_format_data_internal(typedb, p, outbuf, seek, b, len, fmt, mode, setval, field); return rz_type_format_struct_size(typedb, fmt, mode, 0); } @@ -2033,7 +2036,7 @@ RZ_API void rz_type_db_format_purge(RzTypeDB *typedb) { typedb->formats = sdb_new0(); } -RZ_API char *rz_type_format_data(RzTypeDB *typedb, RzPrint *p, ut64 seek, const ut8 *b, const int len, +static int rz_type_format_data_internal(RzTypeDB *typedb, RzPrint *p, RzStrBuf *outbuf, ut64 seek, const ut8 *b, const int len, const char *formatname, int mode, const char *setval, char *ofield) { int nargs, i, invalid, nexti, idx, times, otimes, endian, isptr = 0; const int old_bits = typedb->target->bits; @@ -2070,7 +2073,6 @@ RZ_API char *rz_type_format_data(RzTypeDB *typedb, RzPrint *p, ut64 seek, const free(internal_format); return 0; } - RzStrBuf *outbuf = rz_strbuf_new(""); // len+2 to save space for the null termination in wide strings ut8 *buf = calloc(1, len + 2); @@ -2842,7 +2844,13 @@ RZ_API char *rz_type_format_data(RzTypeDB *typedb, RzPrint *p, ut64 seek, const free(buf); free(field); free(args); - //return i; + return i; +} + +RZ_API char *rz_type_format_data(RzTypeDB *typedb, RzPrint *p, ut64 seek, const ut8 *b, const int len, + const char *formatname, int mode, const char *setval, char *ofield) { + RzStrBuf *outbuf = rz_strbuf_new(""); + rz_type_format_data_internal(typedb, p, outbuf, seek, b, len, formatname, mode, setval, ofield); char *outstr = rz_strbuf_drain(outbuf); return outstr; } From e2f49cf2e59fbb4365eb109f2978fcfbd48a4906 Mon Sep 17 00:00:00 2001 From: Anton Kochkov Date: Wed, 31 Mar 2021 14:43:42 +0800 Subject: [PATCH 10/25] Fix function signature --- librz/analysis/fcn.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/librz/analysis/fcn.c b/librz/analysis/fcn.c index 1cdb12291fe..410480540ed 100644 --- a/librz/analysis/fcn.c +++ b/librz/analysis/fcn.c @@ -1758,9 +1758,13 @@ RZ_API char *rz_analysis_function_get_signature(RzAnalysisFunction *function) { for (i = 0; i < argc; i++) { const char *arg_name = rz_type_func_args_name(a->typedb, function->name, i); const char *arg_type = rz_type_func_args_type(a->typedb, function->name, i); + // Here we check if the type is a pointer, in this case we don't put + // the space between type and name for the style reasons + // "char *var" looks much better than "char * var" + const char *maybe_space = rz_str_endswith(arg_type, "*") ? "" : " "; char *new_args = (i + 1 == argc) - ? rz_str_newf("%s%s %s", args, arg_type, arg_name) - : rz_str_newf("%s%s %s, ", args, arg_type, arg_name); + ? rz_str_newf("%s%s%s%s", args, arg_type, maybe_space, arg_name) + : rz_str_newf("%s%s%s%s, ", args, arg_type, maybe_space, arg_name); free(args); args = new_args; } From 3a71ee5f117d8bdbe1d0a3761f0b2198722e82b8 Mon Sep 17 00:00:00 2001 From: Anton Kochkov Date: Wed, 31 Mar 2021 15:53:36 +0800 Subject: [PATCH 11/25] Noreturn function fixes --- librz/analysis/analysis.c | 9 +++++++-- librz/core/cmd_type.c | 12 ++++++------ librz/include/rz_type.h | 4 ++++ librz/type/function.c | 16 ++++++++++++++++ 4 files changed, 33 insertions(+), 8 deletions(-) diff --git a/librz/analysis/analysis.c b/librz/analysis/analysis.c index 33975c446e8..1cea1b75ea2 100644 --- a/librz/analysis/analysis.c +++ b/librz/analysis/analysis.c @@ -518,13 +518,18 @@ RZ_API bool rz_analysis_noreturn_drop(RzAnalysis *analysis, const char *expr) { return false; } +static bool rz_analysis_is_noreturn(RzAnalysis *analysis, const char *name) { + return rz_type_func_is_noreturn(analysis->typedb, name) || + sdb_bool_get(analysis->sdb_noret, K_NORET_FUNC(name), NULL); +} + static bool rz_analysis_noreturn_at_name(RzAnalysis *analysis, const char *name) { - if (sdb_bool_get(analysis->sdb_noret, K_NORET_FUNC(name), NULL)) { + if (rz_analysis_is_noreturn(analysis, name)) { return true; } char *tmp = rz_type_func_guess(analysis->typedb, (char *)name); if (tmp) { - if (sdb_bool_get(analysis->sdb_noret, K_NORET_FUNC(tmp), NULL)) { + if (rz_analysis_is_noreturn(analysis, tmp)) { free(tmp); return true; } diff --git a/librz/core/cmd_type.c b/librz/core/cmd_type.c index 31342376ca3..8ac7d584f0a 100644 --- a/librz/core/cmd_type.c +++ b/librz/core/cmd_type.c @@ -458,7 +458,7 @@ static void noreturn_del(RzCore *core, const char *s) { char *k; RzList *list = rz_str_split_duplist(s, " ", false); rz_list_foreach (list, iter, k) { - rz_analysis_noreturn_drop(core->analysis, k); + rz_type_func_noreturn_drop(core->analysis->typedb, k); } rz_list_free(list); } @@ -471,7 +471,7 @@ static void cmd_type_noreturn(RzCore *core, const char *input) { RzListIter *iter; char *name; rz_list_foreach (noretl, iter, name) { - rz_analysis_noreturn_drop(core->analysis, name); + rz_type_func_noreturn_drop(core->analysis->typedb, name); } } else { char *s = strdup(rz_str_trim_head_ro(input + 1)); @@ -486,7 +486,7 @@ static void cmd_type_noreturn(RzCore *core, const char *input) { if (n) { rz_analysis_noreturn_add(core->analysis, arg, n); } else { - rz_analysis_noreturn_add(core->analysis, arg, UT64_MAX); + rz_type_func_noreturn_add(core->analysis->typedb, arg); } } break; case 'a': // "tna" @@ -1173,7 +1173,7 @@ RZ_IPI RzCmdStatus rz_type_list_noreturn_handler(RzCore *core, int argc, const c if (n) { rz_analysis_noreturn_add(core->analysis, name, n); } else { - rz_analysis_noreturn_add(core->analysis, name, UT64_MAX); + rz_type_func_noreturn_add(core->analysis->typedb, name); } } else { rz_core_types_function_noreturn_print(core, mode); @@ -1183,7 +1183,7 @@ RZ_IPI RzCmdStatus rz_type_list_noreturn_handler(RzCore *core, int argc, const c RZ_IPI RzCmdStatus rz_type_noreturn_del_handler(RzCore *core, int argc, const char **argv) { for (int i = 1; i < argc; i++) { - rz_analysis_noreturn_drop(core->analysis, argv[i]); + rz_type_func_noreturn_drop(core->analysis->typedb, argv[i]); } return RZ_CMD_STATUS_OK; } @@ -1193,7 +1193,7 @@ RZ_IPI RzCmdStatus rz_type_noreturn_del_all_handler(RzCore *core, int argc, cons RzListIter *iter; char *name; rz_list_foreach (noretl, iter, name) { - rz_analysis_noreturn_drop(core->analysis, name); + rz_type_func_noreturn_drop(core->analysis->typedb, name); } return RZ_CMD_STATUS_OK; } diff --git a/librz/include/rz_type.h b/librz/include/rz_type.h index 22e0c360ed2..b92b9f09cf8 100644 --- a/librz/include/rz_type.h +++ b/librz/include/rz_type.h @@ -210,7 +210,11 @@ RZ_API bool rz_type_func_arg_count_set(RzTypeDB *typedb, RZ_NONNULL const char * RZ_API bool rz_type_func_arg_set(RzTypeDB *typedb, RZ_NONNULL const char *func_name, int i, RZ_NONNULL const char *arg_name, RZ_NONNULL const char *arg_type); RZ_API bool rz_type_func_ret_set(RzTypeDB *typedb, const char *func_name, const char *type); RZ_API RZ_OWN char *rz_type_func_guess(RzTypeDB *typedb, RZ_NONNULL char *func_name); + RZ_API RzList *rz_type_noreturn_functions(RzTypeDB *typedb); +RZ_API bool rz_type_func_is_noreturn(RzTypeDB *typedb, RZ_NONNULL const char *name); +RZ_API bool rz_type_func_noreturn_add(RzTypeDB *typedb, RZ_NONNULL const char *name); +RZ_API bool rz_type_func_noreturn_drop(RzTypeDB *typedb, RZ_NONNULL const char *name); // Listing API RZ_API RzList *rz_type_db_enums(RzTypeDB *typedb); diff --git a/librz/type/function.c b/librz/type/function.c index ef275b61b9e..1148fad7d49 100644 --- a/librz/type/function.c +++ b/librz/type/function.c @@ -260,3 +260,19 @@ RZ_API RzList *rz_type_noreturn_functions(RzTypeDB *typedb) { ls_free(l); return noretl; } + +RZ_API bool rz_type_func_is_noreturn(RzTypeDB *typedb, RZ_NONNULL const char *name) { + rz_return_val_if_fail(typedb && name, false); + return sdb_bool_get(typedb->sdb_types, sdb_fmt("func.%s.noreturn", name), NULL); +} + +RZ_API bool rz_type_func_noreturn_add(RzTypeDB *typedb, RZ_NONNULL const char *name) { + rz_return_val_if_fail(typedb && name, false); + return sdb_bool_set(typedb->sdb_types, sdb_fmt("func.%s.noreturn", name), true, 0); +} + +RZ_API bool rz_type_func_noreturn_drop(RzTypeDB *typedb, RZ_NONNULL const char *name) { + rz_return_val_if_fail(typedb && name, false); + sdb_unset(typedb->sdb_types, sdb_fmt("func.%s.noreturn", name), 0); + return true; +} From 49c21adbbe34fbaa73d0685a325ca21dac46a04b Mon Sep 17 00:00:00 2001 From: Anton Kochkov Date: Wed, 31 Mar 2021 16:26:50 +0800 Subject: [PATCH 12/25] Fix wrongly written tests --- test/db/analysis/noreturn | 3 - test/db/cmd/cmd_k | 2602 +------------------------------------ 2 files changed, 2 insertions(+), 2603 deletions(-) diff --git a/test/db/analysis/noreturn b/test/db/analysis/noreturn index eb379f9467d..1b1e037a76e 100644 --- a/test/db/analysis/noreturn +++ b/test/db/analysis/noreturn @@ -2,13 +2,10 @@ NAME=noreturn 0 FILE=bins/mach0/ls-osx-x86_64 CMDS=< Date: Wed, 31 Mar 2021 16:45:11 +0800 Subject: [PATCH 13/25] Fix unit tests for RzType --- test/unit/test_type.c | 41 ++++++++++++++++++++++++++--------------- 1 file changed, 26 insertions(+), 15 deletions(-) diff --git a/test/unit/test_type.c b/test/unit/test_type.c index 53f8f369284..64391da6e27 100644 --- a/test/unit/test_type.c +++ b/test/unit/test_type.c @@ -8,15 +8,13 @@ #include "minunit.h" #include "test_sdb.h" -static Sdb *setup_sdb_for_function(void) { - Sdb *res = sdb_new0(); +static void setup_sdb_for_function(Sdb *res) { sdb_set(res, "ExitProcess", "func", 0); sdb_set(res, "ReadFile", "func", 0); sdb_set(res, "memcpy", "func", 0); sdb_set(res, "strchr", "func", 0); sdb_set(res, "__stack_chk_fail", "func", 0); sdb_set(res, "WSAStartup", "func", 0); - return res; } static void setup_sdb_for_struct(Sdb *res) { @@ -74,7 +72,7 @@ static void setup_sdb_for_not_found(Sdb *res) { static bool test_types_get_base_type_struct(void) { RzTypeDB *typedb = rz_type_db_new(); - mu_assert_notnull(typedb, "Couldn't create new RzTypeDb"); + mu_assert_notnull(typedb, "Couldn't create new RzTypeDB"); mu_assert_notnull(typedb->sdb_types, "Couldn't create new RzTypeDB.sdb_types"); setup_sdb_for_struct(typedb->sdb_types); @@ -197,6 +195,7 @@ static bool test_types_save_base_type_union(void) { static bool test_types_get_base_type_enum(void) { RzTypeDB *typedb = rz_type_db_new(); mu_assert_notnull(typedb, "Couldn't create new RzTypeDB"); + mu_assert_notnull(typedb->sdb_types, "Couldn't create new RzTypeDB.sdb_types"); setup_sdb_for_enum(typedb->sdb_types); @@ -221,7 +220,8 @@ static bool test_types_get_base_type_enum(void) { static bool test_types_save_base_type_enum(void) { RzTypeDB *typedb = rz_type_db_new(); - mu_assert_notnull(typedb, "Couldn't create new RzTypeDb"); + mu_assert_notnull(typedb, "Couldn't create new RzTypeDB"); + mu_assert_notnull(typedb->sdb_types, "Couldn't create new RzTypeDB.sdb_types"); RzBaseType *base = rz_type_base_type_new(RZ_BASE_TYPE_KIND_ENUM); base->name = strdup("foo"); @@ -251,6 +251,7 @@ static bool test_types_save_base_type_enum(void) { static bool test_types_get_base_type_typedef(void) { RzTypeDB *typedb = rz_type_db_new(); mu_assert_notnull(typedb, "Couldn't create new RzTypeDB"); + mu_assert_notnull(typedb->sdb_types, "Couldn't create new RzTypeDB.sdb_types"); setup_sdb_for_typedef(typedb->sdb_types); @@ -353,7 +354,10 @@ static bool test_types_get_base_type_not_found(void) { bool test_dll_names(void) { RzTypeDB *typedb = rz_type_db_new(); - typedb->sdb_types = setup_sdb_for_function(); + setup_sdb_for_function(typedb->sdb_types); + mu_assert_notnull(typedb, "Couldn't create new RzTypeDB"); + mu_assert_notnull(typedb->sdb_types, "Couldn't create new RzTypeDB.sdb_types"); + char *s; s = rz_type_func_guess(typedb, "sub.KERNEL32.dll_ExitProcess"); @@ -386,14 +390,16 @@ bool test_dll_names(void) { mu_assert_streq(s, "WSAStartup", "dll_ and number should be ignored case 4"); free(s); - sdb_free(typedb->sdb_types); rz_type_db_free(typedb); mu_end; } bool test_ignore_prefixes(void) { RzTypeDB *typedb = rz_type_db_new(); - typedb->sdb_types = setup_sdb_for_function(); + setup_sdb_for_function(typedb->sdb_types); + mu_assert_notnull(typedb, "Couldn't create new RzTypeDB"); + mu_assert_notnull(typedb->sdb_types, "Couldn't create new RzTypeDB.sdb_types"); + char *s; s = rz_type_func_guess(typedb, "fcn.KERNEL32.dll_ExitProcess_32"); @@ -404,14 +410,16 @@ bool test_ignore_prefixes(void) { mu_assert_null(s, "loc. names should be ignored"); free(s); - sdb_free(typedb->sdb_types); rz_type_db_free(typedb); mu_end; } bool test_remove_rz_prefixes(void) { RzTypeDB *typedb = rz_type_db_new(); - typedb->sdb_types = setup_sdb_for_function(); + setup_sdb_for_function(typedb->sdb_types); + mu_assert_notnull(typedb, "Couldn't create new RzTypeDB"); + mu_assert_notnull(typedb->sdb_types, "Couldn't create new RzTypeDB.sdb_types"); + char *s; s = rz_type_func_guess(typedb, "sym.imp.ExitProcess"); @@ -428,14 +436,16 @@ bool test_remove_rz_prefixes(void) { mu_assert_null(s, "prefixes longer than 3 should not be ignored"); free(s); - sdb_free(typedb->sdb_types); rz_type_db_free(typedb); mu_end; } bool test_autonames(void) { RzTypeDB *typedb = rz_type_db_new(); - typedb->sdb_types = setup_sdb_for_function(); + setup_sdb_for_function(typedb->sdb_types); + mu_assert_notnull(typedb, "Couldn't create new RzTypeDB"); + mu_assert_notnull(typedb->sdb_types, "Couldn't create new RzTypeDB.sdb_types"); + char *s; s = rz_type_func_guess(typedb, "sub.strchr_123"); @@ -455,14 +465,16 @@ bool test_autonames(void) { mu_assert_streq(s, "strchr", "strchr should be identified"); free(s); - sdb_free(typedb->sdb_types); rz_type_db_free(typedb); mu_end; } bool test_initial_underscore(void) { RzTypeDB *typedb = rz_type_db_new(); - typedb->sdb_types = setup_sdb_for_function(); + setup_sdb_for_function(typedb->sdb_types); + mu_assert_notnull(typedb, "Couldn't create new RzTypeDB"); + mu_assert_notnull(typedb->sdb_types, "Couldn't create new RzTypeDB.sdb_types"); + char *s; s = rz_type_func_guess(typedb, "sym._strchr"); @@ -470,7 +482,6 @@ bool test_initial_underscore(void) { mu_assert_streq(s, "strchr", "strchr should be identified"); free(s); - sdb_free(typedb->sdb_types); rz_type_db_free(typedb); mu_end; } From 8db736f5817ad3253f08447a84e24adcc4016d4d Mon Sep 17 00:00:00 2001 From: Anton Kochkov Date: Wed, 31 Mar 2021 17:16:21 +0800 Subject: [PATCH 14/25] Fix endianess for RzTypes --- librz/analysis/analysis.c | 1 + librz/core/cconfig.c | 10 ++++++++-- librz/include/rz_type.h | 1 + librz/type/format.c | 6 +++--- librz/type/type.c | 4 ++++ 5 files changed, 17 insertions(+), 5 deletions(-) diff --git a/librz/analysis/analysis.c b/librz/analysis/analysis.c index 1cea1b75ea2..ba87ed171d7 100644 --- a/librz/analysis/analysis.c +++ b/librz/analysis/analysis.c @@ -304,6 +304,7 @@ RZ_API int rz_analysis_set_big_endian(RzAnalysis *analysis, int bigend) { if (analysis->reg) { analysis->reg->big_endian = bigend; } + rz_type_db_set_endian(analysis->typedb, bigend); return true; } diff --git a/librz/core/cconfig.c b/librz/core/cconfig.c index 023fc43dd6e..36c36019eb4 100644 --- a/librz/core/cconfig.c +++ b/librz/core/cconfig.c @@ -695,6 +695,8 @@ static bool cb_asmarch(void *user, void *data) { if (!core->analysis || !core->analysis->typedb) { rz_core_analysis_type_init(core); } + // set endian of RzAnalysis to match binary + rz_analysis_set_big_endian(core->analysis, bigbin); rz_core_analysis_cc_init(core); return true; @@ -1175,12 +1177,16 @@ static bool cb_bigendian(void *user, void *data) { bool isbig = rz_asm_set_big_endian(core->rasm, node->i_value); // Set analysis endianness the same as asm rz_analysis_set_big_endian(core->analysis, isbig); + // While analysis sets endianess for TypesDB there might + // be cases when it isn't availble for the chosen analysis + // plugin but types and printing commands still need the + // corresponding endianness. Thus we set these explicitly: + rz_type_db_set_endian(core->analysis->typedb, node->i_value); + core->print->big_endian = node->i_value; // the big endian should also be assigned to dbg->bp->endian if (core->dbg && core->dbg->bp) { core->dbg->bp->endian = isbig; } - // Set printing endian to user's choice - core->print->big_endian = node->i_value; return true; } diff --git a/librz/include/rz_type.h b/librz/include/rz_type.h index b92b9f09cf8..a06427fcde1 100644 --- a/librz/include/rz_type.h +++ b/librz/include/rz_type.h @@ -97,6 +97,7 @@ RZ_API void rz_type_db_purge(RzTypeDB *typedb); RZ_API void rz_type_db_set_bits(RzTypeDB *typedb, int bits); RZ_API void rz_type_db_set_os(RzTypeDB *typedb, const char *os); RZ_API void rz_type_db_set_cpu(RzTypeDB *typedb, const char *cpu); +RZ_API void rz_type_db_set_endian(RzTypeDB *typedb, bool big_endian); RZ_API char *rz_type_db_kuery(RzTypeDB *typedb, const char *query); RZ_API const char *rz_type_db_get(RzTypeDB *typedb, const char *name); diff --git a/librz/type/format.c b/librz/type/format.c index 71f86ecccd2..de01c3e485d 100644 --- a/librz/type/format.c +++ b/librz/type/format.c @@ -2538,7 +2538,7 @@ static int rz_type_format_data_internal(RzTypeDB *typedb, RzPrint *p, RzStrBuf * /* case 'D': if (isptr) { - if (p->bits == 64) { + if (typedb->target->bits == 64) { i += rz_print_format_disasm(p, addr64, size); } else { i += rz_print_format_disasm(p, addr, size); @@ -2684,7 +2684,7 @@ static int rz_type_format_data_internal(RzTypeDB *typedb, RzPrint *p, RzStrBuf * s = rz_type_format_struct(typedb, p, outbuf, seeki, buf + i, len - i, fmtname, slide, mode, setval, nxtfield, anon); - i += (isptr) ? (p->bits / 8) : s; + i += (isptr) ? (typedb->target->bits / 8) : s; if (MUSTSEEJSON) { if (!isptr && (!arg[1] || arg[1] == ' ')) { rz_strbuf_append(outbuf, "]}"); @@ -2717,7 +2717,7 @@ static int rz_type_format_data_internal(RzTypeDB *typedb, RzPrint *p, RzStrBuf * if (elem > -1) { elem--; } - i += (isptr) ? (p->bits / 8) : s; + i += (isptr) ? (typedb->target->bits / 8) : s; } if (mode & RZ_PRINT_ISFIELD) { if (!SEEVALUE) { diff --git a/librz/type/type.c b/librz/type/type.c index 6a6e0f5b762..a1e14393246 100644 --- a/librz/type/type.c +++ b/librz/type/type.c @@ -63,6 +63,10 @@ RZ_API void rz_type_db_set_cpu(RzTypeDB *typedb, const char *cpu) { typedb->target->cpu = cpu; } +RZ_API void rz_type_db_set_endian(RzTypeDB *typedb, bool big_endian) { + typedb->target->big_endian = big_endian; +} + RZ_API char *rz_type_db_kuery(RzTypeDB *typedb, const char *query) { char *output = NULL; if (query) { From b3ef8611e1aa514959d2573ad12805a5ee1ee6e0 Mon Sep 17 00:00:00 2001 From: Anton Kochkov Date: Wed, 31 Mar 2021 18:15:03 +0800 Subject: [PATCH 15/25] Remove D (disassembly) pf tests --- test/db/cmd/cmd_pf2 | 32 -------------------------------- 1 file changed, 32 deletions(-) diff --git a/test/db/cmd/cmd_pf2 b/test/db/cmd/cmd_pf2 index 2a5a59b942e..c4a32258d94 100644 --- a/test/db/cmd/cmd_pf2 +++ b/test/db/cmd/cmd_pf2 @@ -205,38 +205,6 @@ EXPECT=< Date: Wed, 31 Mar 2021 20:16:52 +0800 Subject: [PATCH 16/25] Fix `tn` test --- test/db/cmd/types | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/test/db/cmd/types b/test/db/cmd/types index 2f7cf430dcf..65bbbde18bb 100644 --- a/test/db/cmd/types +++ b/test/db/cmd/types @@ -1789,15 +1789,13 @@ RUN NAME=tn common FILE=bins/pe/pe.exe CMDS=< Date: Tue, 6 Apr 2021 12:22:50 +0800 Subject: [PATCH 17/25] Address review feedback --- librz/core/core.c | 59 ----------------------------------------- librz/core/meson.build | 2 +- librz/include/rz_type.h | 3 ++- librz/meson.build | 1 + 4 files changed, 4 insertions(+), 61 deletions(-) diff --git a/librz/core/core.c b/librz/core/core.c index 49aea1c3471..a76e526d1de 100644 --- a/librz/core/core.c +++ b/librz/core/core.c @@ -1148,36 +1148,6 @@ static void autocompleteFilename(RzLineCompletion *completion, RzLineBuffer *buf free(input); } -/* -//TODO: make it recursive to handle nested struct -static int autocomplete_pfele(RzCore *core, RzLineCompletion *completion, char *key, char *pfx, int idx, char *ptr) { - int i, ret = 0; - int len = strlen(ptr); - const char *fmt = rz_type_db_format_get(core->analysis->typedb, key); - if (fmt) { - int nargs = rz_str_word_set0_stack(fmt); - if (nargs > 1) { - for (i = 1; i < nargs; i++) { - const char *arg = rz_str_word_get0(fmt, i); - char *p = strchr(arg, '('); - char *p2 = strchr(arg, ')'); - // remove '(' and ')' from fmt - if (p && p2) { - arg = p + 1; - *p2 = '\0'; - } - if (!len || !strncmp(ptr, arg, len)) { - char *s = rz_str_newf("pf%s.%s.%s", pfx, key, arg); - rz_line_completion_push(completion, s); - free(s); - } - } - } - } - return ret; -} -*/ - #define ADDARG(x) \ if (!strncmp(buf->data + chr, x, strlen(buf->data + chr))) { \ rz_line_completion_push(completion, x); \ @@ -1667,35 +1637,6 @@ RZ_API void rz_core_autocomplete(RZ_NULLABLE RzCore *core, RzLineCompletion *com ADDARG("gui.alt_background") ADDARG("gui.border") } - /* - } else if (!strncmp(buf->data, "pf.", 3) || !strncmp(buf->data, "pf*.", 4) || !strncmp(buf->data, "pfd.", 4) || !strncmp(buf->data, "pfv.", 4) || !strncmp(buf->data, "pfj.", 4)) { - char pfx[2]; - int chr = (buf->data[2] == '.') ? 3 : 4; - if (chr == 4) { - pfx[0] = buf->data[2]; - pfx[1] = 0; - } else { - *pfx = 0; - } - // FIXME: FORMATS - RzListIter *iter; - RzList *fmtl = rz_type_db_format_all(core->analysis->typedb); - rz_list_foreach (fmtl, iter, kv) { - int len = strlen(buf->data + chr); - int minlen = RZ_MIN(len, strlen(sdbkv_key(kv))); - if (!len || !strncmp(buf->data + chr, sdbkv_key(kv), minlen)) { - char *p = strchr(buf->data + chr, '.'); - if (p) { - autocomplete_pfele(core, completion, sdbkv_key(kv), pfx, 0, p + 1); - break; - } else { - char *s = rz_str_newf("pf%s.%s", pfx, sdbkv_key(kv)); - rz_line_completion_push(completion, s); - free(s); - } - } - } - */ } else if ((!strncmp(buf->data, "afvn ", 5)) || (!strncmp(buf->data, "afan ", 5))) { RzAnalysisFunction *fcn = rz_analysis_get_fcn_in(core->analysis, core->offset, 0); RzList *vars; diff --git a/librz/core/meson.build b/librz/core/meson.build index 74a332142c1..55cf04d992d 100644 --- a/librz/core/meson.build +++ b/librz/core/meson.build @@ -139,7 +139,7 @@ pkgconfig_mod.generate( 'rz_cons', 'rz_analysis', 'rz_socket', - 'rz_type', + 'rz_type', 'rz_io', 'rz_lang', 'rz_hash', diff --git a/librz/include/rz_type.h b/librz/include/rz_type.h index a06427fcde1..2601f71f518 100644 --- a/librz/include/rz_type.h +++ b/librz/include/rz_type.h @@ -9,6 +9,7 @@ #include #include #include +#include #ifdef __cplusplus extern "C" { @@ -68,7 +69,7 @@ typedef struct rz_base_type_union_t { } RzBaseTypeUnion; typedef struct rz_base_type_enum_t { - RzVector /* Date: Tue, 6 Apr 2021 13:03:39 +0800 Subject: [PATCH 18/25] Add function noreturn serialization --- librz/analysis/serialize_analysis.c | 12 ++++++ librz/include/rz_analysis.h | 2 + test/unit/meson.build | 4 +- test/unit/test_serialize_analysis.c | 61 +++++++++++++++++++++++++++++ 4 files changed, 77 insertions(+), 2 deletions(-) diff --git a/librz/analysis/serialize_analysis.c b/librz/analysis/serialize_analysis.c index 61f052b101b..d790a0a6745 100644 --- a/librz/analysis/serialize_analysis.c +++ b/librz/analysis/serialize_analysis.c @@ -1228,6 +1228,16 @@ RZ_API bool rz_serialize_analysis_functions_load(RZ_NONNULL Sdb *db, RZ_NONNULL return ret; } +RZ_API void rz_serialize_analysis_function_noreturn_save(RZ_NONNULL Sdb *db, RZ_NONNULL RzAnalysis *analysis) { + sdb_copy(analysis->sdb_noret, db); +} + +RZ_API bool rz_serialize_analysis_function_noreturn_load(RZ_NONNULL Sdb *db, RZ_NONNULL RzAnalysis *analysis, RZ_NULLABLE RzSerializeResultInfo *res) { + sdb_reset(analysis->sdb_noret); + sdb_copy(db, analysis->sdb_noret); + return true; +} + static bool store_xref_cb(void *j, const ut64 k, const void *v) { const RzAnalysisXRef *xref = v; pj_o(j); @@ -1996,6 +2006,7 @@ RZ_API void rz_serialize_analysis_save(RZ_NONNULL Sdb *db, RZ_NONNULL RzAnalysis rz_serialize_analysis_xrefs_save(sdb_ns(db, "xrefs", true), analysis); rz_serialize_analysis_blocks_save(sdb_ns(db, "blocks", true), analysis); rz_serialize_analysis_functions_save(sdb_ns(db, "functions", true), analysis); + rz_serialize_analysis_function_noreturn_save(sdb_ns(db, "noreturn", true), analysis); rz_serialize_analysis_meta_save(sdb_ns(db, "meta", true), analysis); rz_serialize_analysis_hints_save(sdb_ns(db, "hints", true), analysis); rz_serialize_analysis_classes_save(sdb_ns(db, "classes", true), analysis); @@ -2022,6 +2033,7 @@ RZ_API bool rz_serialize_analysis_load(RZ_NONNULL Sdb *db, RZ_NONNULL RzAnalysis SUB("blocks", rz_serialize_analysis_blocks_load(subdb, analysis, diff_parser, res)); // All bbs have ref=1 now SUB("functions", rz_serialize_analysis_functions_load(subdb, analysis, diff_parser, res)); + SUB("noreturn", rz_serialize_analysis_function_noreturn_load(subdb, analysis, res)); // BB's refs have increased if they are part of a function. // We must subtract from each to hold our invariant again. // If any block has ref=0 then, it should be deleted. But we can't do this while diff --git a/librz/include/rz_analysis.h b/librz/include/rz_analysis.h index 18cee816984..3bdd61556b4 100644 --- a/librz/include/rz_analysis.h +++ b/librz/include/rz_analysis.h @@ -2041,6 +2041,8 @@ RZ_API RZ_NULLABLE RzAnalysisVar *rz_serialize_analysis_var_load(RZ_NONNULL RzAn RZ_API void rz_serialize_analysis_functions_save(RZ_NONNULL Sdb *db, RZ_NONNULL RzAnalysis *analysis); RZ_API bool rz_serialize_analysis_functions_load(RZ_NONNULL Sdb *db, RZ_NONNULL RzAnalysis *analysis, RzSerializeAnalDiffParser diff_parser, RZ_NULLABLE RzSerializeResultInfo *res); +RZ_API void rz_serialize_analysis_function_noreturn_save(RZ_NONNULL Sdb *db, RZ_NONNULL RzAnalysis *analysis); +RZ_API bool rz_serialize_analysis_function_noreturn_load(RZ_NONNULL Sdb *db, RZ_NONNULL RzAnalysis *analysis, RZ_NULLABLE RzSerializeResultInfo *res); RZ_API void rz_serialize_analysis_xrefs_save(RZ_NONNULL Sdb *db, RZ_NONNULL RzAnalysis *analysis); RZ_API bool rz_serialize_analysis_xrefs_load(RZ_NONNULL Sdb *db, RZ_NONNULL RzAnalysis *analysis, RZ_NULLABLE RzSerializeResultInfo *res); RZ_API void rz_serialize_analysis_meta_save(RZ_NONNULL Sdb *db, RZ_NONNULL RzAnalysis *analysis); diff --git a/test/unit/meson.build b/test/unit/meson.build index 6343fd222b1..0ea0eb134e4 100644 --- a/test/unit/meson.build +++ b/test/unit/meson.build @@ -76,7 +76,7 @@ if get_option('enable_tests') 'table', 'task', 'tree', - 'type', + 'type', 'uleb128', 'unum', 'util', @@ -106,7 +106,7 @@ if get_option('enable_tests') rz_bp_dep, rz_reg_dep, rz_syscall_dep, - rz_type_dep, + rz_type_dep, rz_analysis_dep, rz_parse_dep, rz_egg_dep, diff --git a/test/unit/test_serialize_analysis.c b/test/unit/test_serialize_analysis.c index fb5ade8aafc..7b9fde9a618 100644 --- a/test/unit/test_serialize_analysis.c +++ b/test/unit/test_serialize_analysis.c @@ -479,6 +479,60 @@ bool test_analysis_function_load() { mu_end; } +static Sdb *noreturn_ref_db() { + Sdb *db = sdb_new0(); + sdb_bool_set(db, "addr.8000500.noreturn", true, 0); + sdb_bool_set(db, "addr.8000555.noreturn", true, 0); + sdb_bool_set(db, "addr.8000610.noreturn", true, 0); + sdb_bool_set(db, "addr.8000632.noreturn", true, 0); + return db; +} + +bool test_analysis_function_noreturn_save() { + RzAnalysis *analysis = rz_analysis_new(); + + rz_analysis_noreturn_add(analysis, NULL, 0x800800); + bool has = sdb_bool_get(analysis->sdb_noret, "addr.800800.noreturn", 0); + mu_assert_true(has, "noreturn add error"); + rz_analysis_noreturn_drop(analysis, "0x800800"); + bool hasnt = sdb_bool_get(analysis->sdb_noret, "addr.800800.noreturn", 0); + mu_assert_false(hasnt, "noreturn drop error"); + + rz_analysis_noreturn_add(analysis, NULL, 0x8000500); + rz_analysis_noreturn_add(analysis, NULL, 0x8000555); + rz_analysis_noreturn_add(analysis, NULL, 0x8000610); + rz_analysis_noreturn_add(analysis, NULL, 0x8000632); + Sdb *db = sdb_new0(); + rz_serialize_analysis_function_noreturn_save(db, analysis); + + Sdb *expected = noreturn_ref_db(); + assert_sdb_eq(db, expected, "function noreturn save"); + sdb_free(db); + sdb_free(expected); + rz_analysis_free(analysis); + mu_end; +} + +bool test_analysis_function_noreturn_load() { + RzAnalysis *analysis = rz_analysis_new(); + Sdb *db = noreturn_ref_db(); + bool succ = rz_serialize_analysis_function_noreturn_load(db, analysis, NULL); + sdb_free(db); + mu_assert("load success", succ); + + bool has = sdb_bool_get(analysis->sdb_noret, "addr.8000500.noreturn", 0); + has &= sdb_bool_get(analysis->sdb_noret, "addr.8000555.noreturn", 0); + has &= sdb_bool_get(analysis->sdb_noret, "addr.8000610.noreturn", 0); + has &= sdb_bool_get(analysis->sdb_noret, "addr.8000632.noreturn", 0); + mu_assert_true(has, "noreturn load error"); + + bool hasnt = sdb_bool_get(analysis->sdb_noret, "addr.800800.noreturn", 0); + mu_assert_false(hasnt, "noreturn should not exist"); + + rz_analysis_free(analysis); + mu_end; +} + Sdb *vars_ref_db() { Sdb *db = sdb_new0(); sdb_set(db, "0x539", "{\"name\":\"hirsch\",\"bits\":64,\"type\":0,\"stack\":0,\"maxstack\":0,\"ninstr\":0,\"bp_frame\":true,\"diff\":{},\"bbs\":[]," @@ -1441,6 +1495,9 @@ Sdb *analysis_ref_db() { sdb_set(functions, "0x4d2", "{\"name\":\"effekt\",\"bits\":32,\"type\":1,\"stack\":0,\"maxstack\":0,\"ninstr\":0,\"bp_frame\":true,\"diff\":{},\"bbs\":[1337]}", 0); sdb_set(functions, "0x539", "{\"name\":\"hirsch\",\"bits\":32,\"type\":0,\"stack\":0,\"maxstack\":0,\"ninstr\":0,\"bp_frame\":true,\"diff\":{},\"bbs\":[1337,1234]}", 0); + Sdb *noret = sdb_ns(db, "noreturn", true); + sdb_bool_set(noret, "addr.800800.noreturn", true, 0); + Sdb *xrefs = sdb_ns(db, "xrefs", true); sdb_set(xrefs, "0x42", "[{\"to\":1337,\"type\":\"C\"}]", 0); sdb_set(xrefs, "0x539", "[{\"to\":12648430,\"type\":\"d\"}]", 0); @@ -1510,6 +1567,8 @@ bool test_analysis_save() { rz_analysis_block_unref(ba); rz_analysis_block_unref(bb); + rz_analysis_noreturn_add(analysis, NULL, 0x800800); + rz_analysis_xrefs_set(analysis, 0x42, 1337, RZ_ANALYSIS_REF_TYPE_CALL); rz_analysis_xrefs_set(analysis, 1337, 0xc0ffee, RZ_ANALYSIS_REF_TYPE_DATA); @@ -1640,6 +1699,8 @@ int all_tests() { mu_run_test(test_analysis_block_load); mu_run_test(test_analysis_function_save); mu_run_test(test_analysis_function_load); + mu_run_test(test_analysis_function_noreturn_save); + mu_run_test(test_analysis_function_noreturn_load); mu_run_test(test_analysis_var_save); mu_run_test(test_analysis_var_load); mu_run_test(test_analysis_xrefs_save); From 0d291bef37ff59071647765f1a2e607f126c0549 Mon Sep 17 00:00:00 2001 From: Anton Kochkov Date: Tue, 6 Apr 2021 13:57:46 +0800 Subject: [PATCH 19/25] Fix broken tests --- librz/analysis/fcn.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/librz/analysis/fcn.c b/librz/analysis/fcn.c index 410480540ed..8c9248d7e3f 100644 --- a/librz/analysis/fcn.c +++ b/librz/analysis/fcn.c @@ -1751,13 +1751,13 @@ RZ_API char *rz_analysis_function_get_signature(RzAnalysisFunction *function) { } unsigned int i; - const char *ret_type = rz_type_func_ret(a->typedb, function->name); - int argc = rz_type_func_args_count(a->typedb, function->name); + const char *ret_type = rz_type_func_ret(a->typedb, realname); + int argc = rz_type_func_args_count(a->typedb, realname); char *args = strdup(""); for (i = 0; i < argc; i++) { - const char *arg_name = rz_type_func_args_name(a->typedb, function->name, i); - const char *arg_type = rz_type_func_args_type(a->typedb, function->name, i); + const char *arg_name = rz_type_func_args_name(a->typedb, realname, i); + const char *arg_type = rz_type_func_args_type(a->typedb, realname, i); // Here we check if the type is a pointer, in this case we don't put // the space between type and name for the style reasons // "char *var" looks much better than "char * var" From 6b864e24ffb52628d29cbeb37b1c7202357997f1 Mon Sep 17 00:00:00 2001 From: Anton Kochkov Date: Tue, 6 Apr 2021 14:17:11 +0800 Subject: [PATCH 20/25] Minor signature fix --- librz/analysis/sign.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/librz/analysis/sign.c b/librz/analysis/sign.c index a7df5acbec6..4d247ec5b2b 100644 --- a/librz/analysis/sign.c +++ b/librz/analysis/sign.c @@ -69,9 +69,8 @@ RZ_API RzList *rz_sign_fcn_vars(RzAnalysis *a, RzAnalysisFunction *fcn) { RZ_API RzList *rz_sign_fcn_types(RzAnalysis *a, RzAnalysisFunction *fcn) { - // From analysis/types/*: - // Get key-value types from sdb matching "func.%s", fcn->name - // Get func.%s.args (number of args) + // Get key-value types from types db fcn->name + // Get number of function args // Get type,name pairs // Put everything in RzList following the next format: // types: main.ret=%type%, main.args=%num%, main.arg.0="int,argc", ... @@ -86,10 +85,10 @@ RZ_API RzList *rz_sign_fcn_types(RzAnalysis *a, RzAnalysisFunction *fcn) { int fcnargs = rz_type_func_args_count(a->typedb, fcn->name); const char *ret_type = rz_type_func_ret(a->typedb, fcn->name); + if (ret_type) { + rz_list_append(ret, rz_str_newf("func.%s.ret=%s", fcn->name, ret_type)); + } if (fcnargs) { - if (ret_type) { - rz_list_append(ret, rz_str_newf("func.%s.ret=%s", fcn->name, ret_type)); - } rz_list_append(ret, rz_str_newf("func.%s.args=%d", fcn->name, fcnargs)); int i; for (i = 0; i < fcnargs; i++) { From 1edd4b2677d1e42ad44cf0ee0ff8a30c8a2d617c Mon Sep 17 00:00:00 2001 From: Anton Kochkov Date: Tue, 6 Apr 2021 14:29:08 +0800 Subject: [PATCH 21/25] Modify meaningless type test --- test/db/cmd/cmd_pd2 | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/test/db/cmd/cmd_pd2 b/test/db/cmd/cmd_pd2 index a390022c48a..d84a4f5c64e 100644 --- a/test/db/cmd/cmd_pd2 +++ b/test/db/cmd/cmd_pd2 @@ -335,7 +335,7 @@ CMDS=< 0x8d4890f4 ; likely ,===< 0x00005b06 eb00 jmp 0x5b08 ; rip=0x5b08 -> 0xc30a15ff `---> 0x00005b08 ff150ac30100 call qword [reloc.__libc_start_main] ; [0x21e18:8]=0 ; rsp=0xfffffffffffffff8 ; rip=0x0 - || ; int __libc_start_main(func: unk_size_format, -1, char **: unk_size_format, func: unk_size_format, func: unk_size_format, func: unk_size_format, -1) EOF RUN From 28522853c3ca1e000c04713dba80494aa2a06e03 Mon Sep 17 00:00:00 2001 From: Anton Kochkov Date: Tue, 6 Apr 2021 14:49:38 +0800 Subject: [PATCH 22/25] Fix wrongly written `Cf` test --- test/db/cmd/cmd_pf | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/test/db/cmd/cmd_pf b/test/db/cmd/cmd_pf index 11553e3de6c..6361868db82 100644 --- a/test/db/cmd/cmd_pf +++ b/test/db/cmd/cmd_pf @@ -62,17 +62,11 @@ EXPECT=< Date: Tue, 6 Apr 2021 16:21:57 +0800 Subject: [PATCH 23/25] Fix `za t` (zignature type) command --- librz/core/cmd_descs/cmd_descs.c | 4 +++- librz/core/cmd_descs/cmd_zign.yaml | 8 +++++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/librz/core/cmd_descs/cmd_descs.c b/librz/core/cmd_descs/cmd_descs.c index d248a0b8967..4a3fce6141f 100644 --- a/librz/core/cmd_descs/cmd_descs.c +++ b/librz/core/cmd_descs/cmd_descs.c @@ -3376,6 +3376,7 @@ static const RzCmdDescDetailEntry zign_add_Zignature_space_types_detail_entries[ { .text = "g", .arg_str = NULL, .comment = "graph metrics" }, { .text = "o", .arg_str = NULL, .comment = "original offset" }, { .text = "r", .arg_str = NULL, .comment = "references" }, + { .text = "t", .arg_str = NULL, .comment = "types" }, { .text = "x", .arg_str = NULL, .comment = "cross references" }, { .text = "h", .arg_str = NULL, .comment = "bbhash (hashing of function basic blocks)" }, { .text = "v", .arg_str = NULL, .comment = "vars (and args)" }, @@ -3404,6 +3405,7 @@ static const RzCmdDescDetailEntry zign_add_Examples_detail_entries[] = { { .text = "za", .arg_str = " foo o 0x08048123", .comment = "" }, { .text = "za", .arg_str = " foo c this is a comment (base64?)", .comment = "" }, { .text = "za", .arg_str = " foo r sym.imp.strcpy sym.imp.sprintf sym.imp.strlen", .comment = "" }, + { .text = "za", .arg_str = " foo t func.sym.imp.strlen.ret=int", .comment = "" }, { .text = "za", .arg_str = " foo h 2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae", .comment = "" }, { 0 }, }; @@ -3414,7 +3416,7 @@ static const RzCmdDescDetail zign_add_details[] = { { .name = "Examples", .entries = zign_add_Examples_detail_entries }, { 0 }, }; -static const char *zign_add_type_choices[] = { "a", "b", "c", "n", "g", "o", "r", "x", "h", "v", NULL }; +static const char *zign_add_type_choices[] = { "a", "b", "c", "n", "g", "o", "r", "t", "x", "h", "v", NULL }; static const RzCmdDescArg zign_add_args[] = { { .name = "zigname", diff --git a/librz/core/cmd_descs/cmd_zign.yaml b/librz/core/cmd_descs/cmd_zign.yaml index 2b2d522ea69..99e00dd9c63 100644 --- a/librz/core/cmd_descs/cmd_zign.yaml +++ b/librz/core/cmd_descs/cmd_zign.yaml @@ -65,6 +65,7 @@ commands: - g - o - r + - t - x - h - v @@ -88,6 +89,8 @@ commands: comment: "original offset" - text: "r" comment: "references" + - text: "t" + comment: "types" - text: "x" comment: "cross references" - text: "h" @@ -134,6 +137,9 @@ commands: - text: "za" arg_str: " foo r sym.imp.strcpy sym.imp.sprintf sym.imp.strlen" comment: "" + - text: "za" + arg_str: " foo t func.sym.imp.strlen.ret=int" + comment: "" - text: "za" arg_str: " foo h 2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae" comment: "" @@ -288,4 +294,4 @@ commands: - name: from type: RZ_CMD_ARG_TYPE_NUM - name: to - type: RZ_CMD_ARG_TYPE_NUM \ No newline at end of file + type: RZ_CMD_ARG_TYPE_NUM From 96ad08bb6ee5b0b43e775539a10f29bf4c33e956 Mon Sep 17 00:00:00 2001 From: Anton Kochkov Date: Tue, 6 Apr 2021 15:24:14 +0800 Subject: [PATCH 24/25] Fix signature type test --- test/db/cmd/cmd_zignature | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/db/cmd/cmd_zignature b/test/db/cmd/cmd_zignature index 1749d5384ce..974af63e72f 100644 --- a/test/db/cmd/cmd_zignature +++ b/test/db/cmd/cmd_zignature @@ -1770,7 +1770,7 @@ FILE=bins/elf/ls CMDS=< Date: Tue, 6 Apr 2021 17:29:20 +0800 Subject: [PATCH 25/25] Remove dead declarations --- librz/include/rz_analysis.h | 4 ---- 1 file changed, 4 deletions(-) diff --git a/librz/include/rz_analysis.h b/librz/include/rz_analysis.h index 3bdd61556b4..106c30e46c1 100644 --- a/librz/include/rz_analysis.h +++ b/librz/include/rz_analysis.h @@ -1552,10 +1552,6 @@ RZ_API bool rz_analysis_xref_del(RzAnalysis *analysis, ut64 from, ut64 to); RZ_API RzList *rz_analysis_get_fcns(RzAnalysis *analysis); -/* type.c */ -RZ_API void rz_analysis_remove_parsed_type(RzAnalysis *analysis, const char *name); -RZ_API void rz_analysis_save_parsed_type(RzAnalysis *analysis, const char *parsed); - /* var.c */ RZ_API RZ_OWN char *rz_analysis_function_autoname_var(RzAnalysisFunction *fcn, char kind, const char *pfx, int ptr); RZ_API RZ_BORROW RzAnalysisVar *rz_analysis_function_set_var(RzAnalysisFunction *fcn, int delta, char kind, RZ_NULLABLE const char *type, int size, bool isarg, RZ_NONNULL const char *name);