From a13438b23243ad8462b40e3dacba696bb7109499 Mon Sep 17 00:00:00 2001 From: billow Date: Mon, 16 Sep 2024 03:26:09 +0800 Subject: [PATCH] analysis/dwarf: load sourceline information for global variables (#4635) * refactor `rz_analysis_var_global_list_show` * Adding source line information to global variables (DWARF only) * Add test `global variables list` --- librz/arch/dwarf_process.c | 64 +++++++--- librz/arch/var_global.c | 30 ++++- librz/bin/dwarf/line.c | 52 +++++--- librz/bin/dwarf/unit.c | 10 +- librz/core/canalysis.c | 131 +++++++++++--------- librz/include/rz_analysis.h | 18 ++- librz/include/rz_bin_dwarf.h | 7 +- test/db/analysis/vars | 17 +++ test/integration/test_analysis_global_var.c | 2 +- test/integration/test_dwarf.c | 18 +-- 10 files changed, 237 insertions(+), 112 deletions(-) diff --git a/librz/arch/dwarf_process.c b/librz/arch/dwarf_process.c index ca2aa6a3753..8b638418dc1 100644 --- a/librz/arch/dwarf_process.c +++ b/librz/arch/dwarf_process.c @@ -1399,6 +1399,7 @@ static bool function_var_parse( const RzBinDwarfDie *var_die, bool *has_unspecified_parameters) { v->offset = var_die->offset; + v->cu_index = ctx->unit->index; switch (var_die->tag) { case DW_TAG_formal_parameter: v->kind = RZ_ANALYSIS_VAR_KIND_FORMAL_PARAMETER; @@ -1656,6 +1657,41 @@ static bool variable_exist_global(RzAnalysis *a, RzAnalysisDwarfVariable *v) { return false; } +static bool try_create_var_global( + RZ_BORROW RZ_IN RZ_NONNULL DwContext *ctx, + RZ_BORROW RZ_IN RZ_NONNULL const RzBinDwarfDie *die, + RzAnalysisDwarfVariable *v) { + + bool result = false; + if (!(v->type && v->location->kind == RzBinDwarfLocationKind_ADDRESS)) { + goto beach; + } + if (variable_exist_global(ctx->analysis, v)) { + goto beach; + } + + RzBinDwarfAttr *attr = NULL; + attr = rz_bin_dwarf_die_get_attr(die, DW_AT_decl_file); + RzBinDwarfLineUnit *lu = ctx->unit ? rz_pvector_at(ctx->dw->line->units, ctx->unit->index) : NULL; + ut64 file_index = attr ? rz_bin_dwarf_attr_udata(attr) : UT64_MAX; + const char *file = file_index != 0 && lu ? rz_bin_dwarf_file_path(ctx->dw, lu, file_index) : NULL; + + attr = rz_bin_dwarf_die_get_attr(die, DW_AT_decl_line); + ut32 line = attr ? rz_bin_dwarf_attr_udata(attr) : UT32_MAX; + + attr = rz_bin_dwarf_die_get_attr(die, DW_AT_decl_column); + ut32 column = attr ? rz_bin_dwarf_attr_udata(attr) : UT32_MAX; + + result = rz_analysis_var_global_create_with_sourceline( + ctx->analysis, v->prefer_name, v->type, v->location->address, + file, line, column); + + v->type = NULL; +beach: + variable_fini(v); + return result; +} + static bool variable_from_die( RZ_BORROW RZ_IN RZ_NONNULL DwContext *ctx, RZ_BORROW RZ_IN RZ_NONNULL const RzBinDwarfDie *die) { @@ -1664,22 +1700,8 @@ static bool variable_from_die( variable_fini(&v); return false; } - if (!(v.type && v.location->kind == RzBinDwarfLocationKind_ADDRESS)) { - variable_fini(&v); - return false; - } - if (variable_exist_global(ctx->analysis, &v)) { - variable_fini(&v); - return false; - } - - bool result = rz_analysis_var_global_create( - ctx->analysis, v.prefer_name, v.type, v.location->address); - - v.type = NULL; - variable_fini(&v); - return result; + return try_create_var_global(ctx, die, &v); } static void die_parse(DwContext *ctx, RzBinDwarfDie *die) { @@ -1943,11 +1965,17 @@ static bool RzBinDwarfLocation_as_RzAnalysisVarStorage( break; } case RzBinDwarfLocationKind_ADDRESS: { - if (variable_exist_global(a, dw_var)) { + RzBinDwarfDie *die = ht_up_find(a->debug_info->dw->info->die_by_offset, dw_var->offset, NULL); + if (!die) { return false; } - rz_analysis_var_global_create(a, dw_var->prefer_name, - rz_type_clone(dw_var->type), loc->address); + DwContext context = { + .analysis = a, + .dw = a->debug_info->dw, + .unit = rz_vector_index_ptr(&a->debug_info->dw->info->units, dw_var->cu_index), + .str_escaped = NULL + }; + try_create_var_global(&context, die, dw_var); rz_analysis_var_fini(var); return false; } diff --git a/librz/arch/var_global.c b/librz/arch/var_global.c index 13c487b6f55..28a352b80bf 100644 --- a/librz/arch/var_global.c +++ b/librz/arch/var_global.c @@ -20,6 +20,9 @@ RZ_API RZ_OWN RzAnalysisVarGlobal *rz_analysis_var_global_new(RZ_NONNULL const c glob->name = rz_str_dup(name); glob->addr = addr; glob->analysis = NULL; + glob->coord.decl_file = NULL; + glob->coord.decl_line = UT32_MAX; + glob->coord.decl_col = UT32_MAX; return glob; } @@ -85,9 +88,14 @@ RZ_API bool rz_analysis_var_global_add(RzAnalysis *analysis, RZ_NONNULL RzAnalys * \param name Global variable name * \param type Global variable type * \param addr Global variable address + * \param file File containing source declaration + * \param line Line number of source declaration + * \param colum Column position of source declaration * \return true if succeed */ -RZ_API bool rz_analysis_var_global_create(RzAnalysis *analysis, RZ_NONNULL const char *name, RZ_NONNULL RZ_BORROW RzType *type, ut64 addr) { +RZ_API bool rz_analysis_var_global_create_with_sourceline(RzAnalysis *analysis, + RZ_NONNULL const char *name, RZ_NONNULL RZ_BORROW RzType *type, ut64 addr, + RZ_NULLABLE const char *file, ut32 line, ut32 colum) { rz_return_val_if_fail(analysis && name && type, false); RzAnalysisVarGlobal *glob = rz_analysis_var_global_new(name, addr); @@ -102,9 +110,29 @@ RZ_API bool rz_analysis_var_global_create(RzAnalysis *analysis, RZ_NONNULL const return false; } + glob->coord.decl_file = rz_str_constpool_get(&analysis->constpool, file); + glob->coord.decl_line = line; + glob->coord.decl_col = colum; + return true; } +/** + * \brief Create the global variable and add into hashtable + * + * \param analysis RzAnalysis + * \param name Global variable name + * \param type Global variable type + * \param addr Global variable address + * \return true if succeed + */ +RZ_API bool rz_analysis_var_global_create(RzAnalysis *analysis, + RZ_NONNULL const char *name, RZ_NONNULL RZ_BORROW RzType *type, ut64 addr) { + rz_return_val_if_fail(analysis && name && type, false); + return rz_analysis_var_global_create_with_sourceline( + analysis, name, type, addr, NULL, UT32_MAX, UT32_MAX); +} + /** * \brief Free the global variable instance * diff --git a/librz/bin/dwarf/line.c b/librz/bin/dwarf/line.c index 9b535594af5..c4f9c2abeb0 100644 --- a/librz/bin/dwarf/line.c +++ b/librz/bin/dwarf/line.c @@ -205,18 +205,20 @@ static bool LineHdr_parse_v4(DWLineContext *ctx) { /** * \brief Get the full path from a file index, it will join the directory find in \p info with the filename - * \param ctx the context + * \param dw the DWARF instance + * \param hdr the RzBinDwarfLineUnitHdr instance * \param index the index of the file * \return the full path or NULL if the file index is invalid */ static char *full_file_path( - DWLineContext *ctx, + RzBinDWARF *dw, + RzBinDwarfLineUnitHdr *hdr, ut64 index) { - rz_return_val_if_fail(ctx && ctx->hdr, NULL); - if (index >= rz_vector_len(&ctx->hdr->file_names)) { + rz_return_val_if_fail(hdr, NULL); + if (index >= rz_vector_len(&hdr->file_names)) { return NULL; } - RzBinDwarfFileEntry *file = rz_vector_index_ptr(&ctx->hdr->file_names, index); + RzBinDwarfFileEntry *file = rz_vector_index_ptr(&hdr->file_names, index); if (!file->path_name) { return NULL; } @@ -230,12 +232,12 @@ static char *full_file_path( * or backslashes anyway, we will simply use slashes always here. */ - const char *comp_dir = ctx->dw && ctx->dw->info - ? ht_up_find(ctx->dw->info->offset_comp_dir, ctx->hdr->offset, NULL) + const char *comp_dir = dw && dw->info + ? ht_up_find(dw->info->comp_dir_by_offset, hdr->offset, NULL) : NULL; - const ut64 dir_index = ctx->hdr->encoding.version < 5 ? file->directory_index - 1 : file->directory_index; - const char *dir = (dir_index >= 0 && dir_index < rz_pvector_len(&ctx->hdr->directories)) - ? rz_pvector_at(&ctx->hdr->directories, dir_index) + const ut64 dir_index = hdr->encoding.version < 5 ? file->directory_index - 1 : file->directory_index; + const char *dir = (dir_index >= 0 && dir_index < rz_pvector_len(&hdr->directories)) + ? rz_pvector_at(&hdr->directories, dir_index) : NULL; char *file_path_abs = NULL; if (comp_dir && dir) { @@ -254,6 +256,19 @@ static char *full_file_path( return file_path_abs; } +/** + * \brief Get the full path from a file index, it will join the directory find in \p info with the filename + * \param dw the DWARF instance + * \param lu the RzBinDwarfLineUnit instance + * \param index the index of the file + * \return the full path or NULL if the file index is invalid + */ +RZ_API char *rz_bin_dwarf_file_path(RZ_NONNULL RZ_BORROW RzBinDWARF *dw, + RZ_NONNULL RZ_BORROW RzBinDwarfLineUnit *lu, ut64 index) { + rz_return_val_if_fail(dw && lu, NULL); + return full_file_path(dw, &lu->hdr, index); +} + static const char *full_file_path_cached(DWLineContext *ctx, ut64 file_index) { if (ctx->hdr->encoding.version <= 4) { file_index -= 1; @@ -267,7 +282,7 @@ static const char *full_file_path_cached(DWLineContext *ctx, ut64 file_index) { } char *path = rz_pvector_at(ctx->file_path_cache, file_index); if (!path) { - path = full_file_path(ctx, file_index); + path = full_file_path(ctx->dw, ctx->hdr, file_index); rz_pvector_set(ctx->file_path_cache, file_index, path); } return path; @@ -636,7 +651,7 @@ static RzBinDwarfLine *Line_parse( return NULL; } li->R = R; - li->units = rz_list_newf((RzListFree)LineUnit_free); + li->units = rz_pvector_new((RzPVectorFree)LineUnit_free); if (!li->units) { free(li); return NULL; @@ -678,7 +693,7 @@ static RzBinDwarfLine *Line_parse( } rz_pvector_free(ctx.file_path_cache); - rz_list_push(li->units, unit); + rz_pvector_push(li->units, unit); } li->lines = rz_bin_source_line_info_builder_build_and_fini(&source_line_info_builder); return li; @@ -689,7 +704,7 @@ RZ_API void rz_bin_dwarf_line_free(RZ_OWN RZ_NULLABLE RzBinDwarfLine *li) { return; } R_free(li->R); - rz_list_free(li->units); + rz_pvector_free(li->units); rz_bin_source_line_info_free(li->lines); free(li); } @@ -854,16 +869,17 @@ RZ_API void rz_bin_dwarf_line_units_dump( RZ_NONNULL RZ_BORROW RzBinDwarfLine *line, RZ_NONNULL RZ_BORROW RzStrBuf *sb) { rz_return_if_fail(line && line->R && sb); - if (!(rz_list_empty(line->units))) { + if (!(rz_pvector_empty(line->units))) { rz_strbuf_append(sb, ".debug_line content:\n"); } - RzListIter *it; + void **it; RzBinDwarfLineUnit *unit; bool first = true; - rz_list_foreach (line->units, it, unit) { - if (!unit) { + rz_pvector_foreach (line->units, it) { + if (!it) { continue; } + unit = *it; if (first) { first = false; } else { diff --git a/librz/bin/dwarf/unit.c b/librz/bin/dwarf/unit.c index d6bdc0c42da..32ec2c93e44 100644 --- a/librz/bin/dwarf/unit.c +++ b/librz/bin/dwarf/unit.c @@ -66,7 +66,7 @@ static void CU_attr_apply(DebugInfoContext *ctx, RzBinDwarfCompUnit *cu, RzBinDw return; offset_comp_dir: if (cu->stmt_list < UT64_MAX && cu->comp_dir) { - ht_up_insert(ctx->info->offset_comp_dir, cu->stmt_list, (void *)cu->comp_dir); + ht_up_insert(ctx->info->comp_dir_by_offset, cu->stmt_list, (void *)cu->comp_dir); } } @@ -264,6 +264,7 @@ static bool CU_Hdr_parse(DebugInfoContext *ctx, RzBinDwarfCompUnitHdr *hdr) { */ static bool CU_parse_all(DebugInfoContext *ctx) { RzBinEndianReader *buffer = ctx->info->R; + ut64 index = 0; while (true) { ut64 offset = R_tell(buffer); if (offset >= R_size(buffer)) { @@ -293,6 +294,7 @@ static bool CU_parse_all(DebugInfoContext *ctx) { unit.offset, unit.hdr.length, unit.hdr.abbrev_offset); CU_dies_parse(ctx, &unit, tbl); ctx->info->die_count += rz_vector_len(&unit.dies); + unit.index = index++; rz_vector_push(&ctx->info->units, &unit); } return true; @@ -314,9 +316,9 @@ RZ_API RZ_BORROW RzBinDwarfAttr *rz_bin_dwarf_die_get_attr( static bool info_init(RzBinDwarfInfo *info) { rz_vector_init(&info->units, sizeof(RzBinDwarfCompUnit), (RzVectorFree)CU_fini, NULL); - info->offset_comp_dir = ht_up_new(NULL, NULL); + info->comp_dir_by_offset = ht_up_new(NULL, NULL); info->location_encoding = ht_up_new(NULL, NULL); - if (!info->offset_comp_dir) { + if (!info->comp_dir_by_offset) { goto beach; } return true; @@ -331,7 +333,7 @@ static inline void info_free(RzBinDwarfInfo *info) { } R_free(info->R); rz_vector_fini(&info->units); - ht_up_free(info->offset_comp_dir); + ht_up_free(info->comp_dir_by_offset); ht_up_free(info->die_by_offset); ht_up_free(info->unit_by_offset); ht_up_free(info->location_encoding); diff --git a/librz/core/canalysis.c b/librz/core/canalysis.c index e147cf55b92..f64a73c1604 100644 --- a/librz/core/canalysis.c +++ b/librz/core/canalysis.c @@ -4457,74 +4457,89 @@ RZ_IPI char *rz_core_analysis_all_vars_display(RzCore *core, RzAnalysisFunction return rz_strbuf_drain(sb); } +static void var_global_show(RzAnalysis *analysis, RzAnalysisVarGlobal *glob, RzCmdStateOutput *state) { + char *var_type = rz_type_as_string(analysis->typedb, glob->type); + if (!var_type) { + return; + } + ut64 var_size = rz_type_db_get_bitsize(analysis->typedb, glob->type) / 8; + switch (state->mode) { + case RZ_OUTPUT_MODE_QUIET: + rz_cons_println(glob->name); + break; + case RZ_OUTPUT_MODE_STANDARD: + rz_cons_printf("global %s %s @ 0x%" PFMT64x, var_type, glob->name, glob->addr); + if (RZ_STR_ISNOTEMPTY(glob->coord.decl_file)) { + rz_cons_printf(" %s:%" PFMT32d "%" PFMT32d "\n", + glob->coord.decl_file, glob->coord.decl_line, glob->coord.decl_col); + } else { + rz_cons_print("\n"); + } + break; + case RZ_OUTPUT_MODE_JSON: { + PJ *pj = state->d.pj; + pj_o(pj); + pj_ks(pj, "name", glob->name); + pj_ks(pj, "type", var_type); + pj_kn(pj, "size", var_size); + char addr[32]; + rz_strf(addr, "0x%" PFMT64x, glob->addr); + pj_ks(pj, "addr", addr); + if (RZ_STR_ISNOTEMPTY(glob->coord.decl_file)) + pj_ks(pj, "decl_file", glob->coord.decl_file); + if (glob->coord.decl_line != UT32_MAX) + pj_kn(pj, "decl_line", glob->coord.decl_line); + if (glob->coord.decl_col != UT32_MAX) + pj_kn(pj, "decl_col", glob->coord.decl_col); + pj_end(pj); + break; + } + case RZ_OUTPUT_MODE_TABLE: { + rz_table_add_rowf(state->d.t, "ssxxsdd", glob->name, var_type, var_size, glob->addr, + RZ_STR_ISNOTEMPTY(glob->coord.decl_file) ? glob->coord.decl_file : "-", + glob->coord.decl_line, glob->coord.decl_col); + break; + } + default: + break; + } + free(var_type); +} + +typedef struct { + RzAnalysis *analysis; + RzCmdStateOutput *state; +} VarGlobalShowContext; + +static bool var_global_show_cb(void *user, RZ_UNUSED const char *k, const void *v) { + VarGlobalShowContext *ctx = user; + RzAnalysisVarGlobal *glob = (RzAnalysisVarGlobal *)v; + var_global_show(ctx->analysis, glob, ctx->state); + return true; +} + RZ_IPI bool rz_analysis_var_global_list_show(RzAnalysis *analysis, RzCmdStateOutput *state, RZ_NULLABLE const char *name) { rz_return_val_if_fail(analysis && state, false); - RzList *global_vars = NULL; - RzAnalysisVarGlobal *glob = NULL; + rz_cmd_state_output_array_start(state); + rz_cmd_state_output_set_columnsf(state, "ssxxsnn", + "name", "type", "size", "address", "decl_file", "decl_line", "decl_col"); if (name) { - global_vars = rz_list_new(); - if (!global_vars) { - return false; - } - glob = rz_analysis_var_global_get_byname(analysis, name); + RzAnalysisVarGlobal *glob = rz_analysis_var_global_get_byname(analysis, name); if (!glob) { RZ_LOG_ERROR("Global variable '%s' does not exist!\n", name); - rz_list_free(global_vars); - return false; + goto beach; } - rz_list_append(global_vars, glob); + var_global_show(analysis, glob, state); } else { - global_vars = rz_analysis_var_global_get_all(analysis); + VarGlobalShowContext context = { + .analysis = analysis, + .state = state + }; + ht_sp_foreach(analysis->ht_global_var, var_global_show_cb, &context); } - RzListIter *it = NULL; - char *var_type = NULL; - bool json = state->mode == RZ_OUTPUT_MODE_JSON; - PJ *pj = json ? state->d.pj : NULL; - RzTable *table = state->mode == RZ_OUTPUT_MODE_TABLE ? state->d.t : NULL; - - rz_cmd_state_output_array_start(state); - rz_cmd_state_output_set_columnsf(state, "ssxx", "name", "type", - "size", "address"); - if (!global_vars) { - rz_cmd_state_output_array_end(state); - return false; - } - rz_list_foreach (global_vars, it, glob) { - var_type = rz_type_as_string(analysis->typedb, glob->type); - if (!var_type) { - continue; - } - ut64 var_size = rz_type_db_get_bitsize(analysis->typedb, glob->type) / 8; - switch (state->mode) { - case RZ_OUTPUT_MODE_QUIET: - rz_cons_println(glob->name); - break; - case RZ_OUTPUT_MODE_STANDARD: - rz_cons_printf("global %s %s @ 0x%" PFMT64x "\n", - var_type, glob->name, glob->addr); - break; - case RZ_OUTPUT_MODE_JSON: - pj_o(pj); - pj_ks(pj, "name", glob->name); - pj_ks(pj, "type", var_type); - pj_ki(pj, "size", var_size); - char addr[32]; - rz_strf(addr, "0x%" PFMT64x, glob->addr); - pj_ks(pj, "addr", addr); - pj_end(pj); - break; - case RZ_OUTPUT_MODE_TABLE: { - rz_table_add_rowf(table, "ssxx", glob->name, var_type, var_size, glob->addr); - break; - } - default: - break; - } - free(var_type); - } +beach: rz_cmd_state_output_array_end(state); - rz_list_free(global_vars); return true; } diff --git a/librz/include/rz_analysis.h b/librz/include/rz_analysis.h index 503b9dd9d76..b4915444984 100644 --- a/librz/include/rz_analysis.h +++ b/librz/include/rz_analysis.h @@ -738,6 +738,7 @@ typedef struct dwarf_variable_t { const char *prefer_name; ///< prefer name of the variable, reference to name or link_name depends on language RzType *type; ///< type of the variable RzAnalysisVarKind kind; ///< kind of the variable + ut32 cu_index; ///< compile unit index } RzAnalysisDwarfVariable; typedef enum { @@ -800,6 +801,16 @@ typedef struct rz_analysis_var_t { }; } origin; ///< Origin of the variable, i.e. DWARF, PDB, OMF } RzAnalysisVar; + +/** + * A declaration with its occurrence in the program source. + */ +typedef struct { + ut32 decl_line; ///< File containing source declaration + ut32 decl_col; ///< Line number of source declaration + const char *decl_file; ///< Column position of source declaration +} RzAnalysisDeclCoord; + /** * \brief Global variables */ @@ -810,6 +821,7 @@ typedef struct rz_analysis_var_global_t { RzType *type; ///< type of the variable RzVector /**/ constraints; RZ_BORROW RzAnalysis *analysis; ///< analysis pertaining to this global variable + RzAnalysisDeclCoord coord; ///< a declaration of the variable } RzAnalysisVarGlobal; typedef struct dwarf_function_t { @@ -1889,7 +1901,11 @@ RZ_API void rz_analysis_fcn_vars_add_types(RzAnalysis *analysis, RZ_NONNULL RzAn // Global vars RZ_API RZ_OWN RzAnalysisVarGlobal *rz_analysis_var_global_new(RZ_NONNULL const char *name, ut64 addr); RZ_API bool rz_analysis_var_global_add(RzAnalysis *analysis, RZ_NONNULL RzAnalysisVarGlobal *global_var); -RZ_API bool rz_analysis_var_global_create(RzAnalysis *analysis, RZ_NONNULL const char *name, RZ_NONNULL RZ_BORROW RzType *type, ut64 addr); +RZ_API bool rz_analysis_var_global_create_with_sourceline(RzAnalysis *analysis, + RZ_NONNULL const char *name, RZ_NONNULL RZ_BORROW RzType *type, ut64 addr, + RZ_NULLABLE const char *file, ut32 line, ut32 colum); +RZ_API bool rz_analysis_var_global_create(RzAnalysis *analysis, + RZ_NONNULL const char *name, RZ_NONNULL RZ_BORROW RzType *type, ut64 addr); RZ_API void rz_analysis_var_global_free(RzAnalysisVarGlobal *glob); RZ_API RZ_NULLABLE RzFlagItem *rz_analysis_var_global_get_flag_item(RzAnalysisVarGlobal *glob); diff --git a/librz/include/rz_bin_dwarf.h b/librz/include/rz_bin_dwarf.h index b497ac2688f..95a79e7c804 100644 --- a/librz/include/rz_bin_dwarf.h +++ b/librz/include/rz_bin_dwarf.h @@ -1076,6 +1076,7 @@ typedef struct { typedef struct rz_bin_dwarf_comp_unit_t { ut64 offset; + ut64 index; RzBinDwarfCompUnitHdr hdr; RzVector /**/ dies; const char *name; @@ -1103,7 +1104,7 @@ typedef struct { * representing the DW_AT_comp_dir attribute of the compilation unit * that references this particular line information. */ - HtUP /**/ *offset_comp_dir; + HtUP /**/ *comp_dir_by_offset; HtUP /**/ *location_encoding; } RzBinDwarfInfo; @@ -1210,7 +1211,7 @@ typedef struct { */ typedef struct { RzBinEndianReader *R; - RzList /**/ *units; + RzPVector /**/ *units; RzBinSourceLineInfo *lines; } RzBinDwarfLine; @@ -1529,6 +1530,8 @@ RZ_API void rz_bin_dwarf_line_free(RZ_OWN RZ_NULLABLE RzBinDwarfLine *li); RZ_API void rz_bin_dwarf_line_units_dump( RZ_NONNULL RZ_BORROW RzBinDwarfLine *line, RZ_NONNULL RZ_BORROW RzStrBuf *sb); +RZ_API char *rz_bin_dwarf_file_path(RZ_NONNULL RZ_BORROW RzBinDWARF *dw, + RZ_NONNULL RZ_BORROW RzBinDwarfLineUnit *lu, ut64 index); /// dwarf RZ_API RZ_OWN RzBinDWARF *rz_bin_dwarf_from_file(RZ_BORROW RZ_NONNULL RzBinFile *bf); diff --git a/test/db/analysis/vars b/test/db/analysis/vars index 80b6f7618cc..b578ac9da7e 100644 --- a/test/db/analysis/vars +++ b/test/db/analysis/vars @@ -1,3 +1,20 @@ +NAME=global variables list +FILE=bins/elf/float_ex1/float_ex1_globals +CMDS=<cur, NULL, false); mu_assert_notnull(li, "line info"); - mu_assert_eq(rz_list_length(li->units), 1, "line units count"); + mu_assert_eq(rz_pvector_len(li->units), 1, "line units count"); mu_assert_notnull(li->lines, "line info"); const RzBinSourceLineSample test_line_samples[] = { { 0x1129, 3, 1, "main.c" }, @@ -208,7 +208,7 @@ bool test_dwarf3_cpp_basic(void) { // this should work for dwarf2 aswell RzBinDwarfLine *li = rz_bin_dwarf_line_from_file( bin->cur, NULL, false); mu_assert_notnull(li, "line info"); - mu_assert_eq(rz_list_length(li->units), 1, "line units count"); + mu_assert_eq(rz_pvector_len(li->units), 1, "line units count"); mu_assert_notnull(li->lines, "line info"); const RzBinSourceLineSample test_line_samples[] = { { 0x1169, 19, 12, "main.cpp" }, @@ -324,7 +324,7 @@ bool test_dwarf3_cpp_many_comp_units(void) { RzBinDwarfLine *li = rz_bin_dwarf_line_from_file( bin->cur, NULL, false); mu_assert_notnull(li, "line info"); - mu_assert_eq(rz_list_length(li->units), 2, "line units count"); + mu_assert_eq(rz_pvector_len(li->units), 2, "line units count"); mu_assert_notnull(li->lines, "line info"); const RzBinSourceLineSample test_line_samples[] = { { 0x118a, 3, 3, "mammal.cpp" }, @@ -442,8 +442,8 @@ bool test_dwarf_cpp_empty_line_info(void) { // this should work for dwarf2 aswel RzBinDwarfLine *li = rz_bin_dwarf_line_from_file( bin->cur, NULL, false); mu_assert_notnull(li, "line info"); - mu_assert_eq(rz_list_length(li->units), 25, "line units count"); - RzBinDwarfLineUnit *lunit = rz_list_last(li->units); + mu_assert_eq(rz_pvector_len(li->units), 25, "line units count"); + RzBinDwarfLineUnit *lunit = rz_pvector_tail(li->units); mu_assert_notnull(lunit, "line unit"); RzBinDwarfLineUnitHdr *hdr = &lunit->hdr; @@ -570,7 +570,7 @@ bool test_dwarf2_cpp_many_comp_units(void) { RzBinDwarfLine *li = rz_bin_dwarf_line_from_file( bin->cur, NULL, false); mu_assert_notnull(li, "line info"); - mu_assert_eq(rz_list_length(li->units), 2, "line units count"); + mu_assert_eq(rz_pvector_len(li->units), 2, "line units count"); mu_assert_notnull(li->lines, "line info"); const RzBinSourceLineSample test_line_samples[] = { { 0x118a, 3, 3, "mammal.cpp" }, @@ -662,7 +662,7 @@ bool test_dwarf4_cpp_many_comp_units(void) { RzBinDwarfLine *li = rz_bin_dwarf_line_from_file( bin->cur, NULL, false); mu_assert_notnull(li, "line info"); - mu_assert_eq(rz_list_length(li->units), 2, "line units count"); + mu_assert_eq(rz_pvector_len(li->units), 2, "line units count"); mu_assert_notnull(li->lines, "line info"); const RzBinSourceLineSample test_line_samples[] = { { 0x401160, 15, 0, "../main.cpp" }, @@ -771,7 +771,7 @@ bool test_dwarf4_multidir_comp_units(void) { RzBinDwarfLine *li = dw->line; mu_assert_notnull(li, "line info"); - mu_assert_eq(rz_list_length(li->units), 2, "line units count"); + mu_assert_eq(rz_pvector_len(li->units), 2, "line units count"); mu_assert_notnull(li->lines, "line info"); const RzBinSourceLineSample test_line_samples[] = { { 0x1139, 6, 12, "/home/florian/dev/dwarf-comp-units/main.c" }, @@ -807,7 +807,7 @@ bool test_big_endian_dwarf2(void) { RzBinDwarfLine *li = rz_bin_dwarf_line_from_file(bin->cur, NULL, false); mu_assert_notnull(li, "line info"); - mu_assert_eq(rz_list_length(li->units), 1, "line units count"); + mu_assert_eq(rz_pvector_len(li->units), 1, "line units count"); mu_assert_notnull(li->lines, "line info"); const RzBinSourceLineSample test_line_samples[] = { { 0x10000ec4, 30, 1, "/home/hound/Projects/r2test/dwarf/cpp/sudoku_cpp/grid.cpp" },