diff --git a/librz/bin/dwarf/unit.c b/librz/bin/dwarf/unit.c index cb916a947d8..3fb8dbdf78f 100644 --- a/librz/bin/dwarf/unit.c +++ b/librz/bin/dwarf/unit.c @@ -107,6 +107,16 @@ static bool CU_attrs_parse( case DW_AT_sibling: die->sibling = rz_bin_dwarf_attr_udata(&attr); break; + case DW_AT_location: { + if (attr.value.kind == RzBinDwarfAttr_LoclistPtr || + attr.value.kind == RzBinDwarfAttr_Reference || + attr.value.kind == RzBinDwarfAttr_UConstant || + attr.value.kind == RzBinDwarfAttr_SecOffset) { + ut64 offset = rz_bin_dwarf_attr_udata(&attr); + ht_up_insert(ctx->info->location_encoding, + offset, &cu->hdr.encoding); + } + } default: break; } @@ -309,6 +319,7 @@ 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, NULL); + info->location_encoding = ht_up_new0(); if (!info->offset_comp_dir) { goto beach; } @@ -327,6 +338,7 @@ static inline void info_free(RzBinDwarfInfo *info) { ht_up_free(info->offset_comp_dir); ht_up_free(info->die_by_offset); ht_up_free(info->unit_by_offset); + ht_up_free(info->location_encoding); free(info); } diff --git a/librz/core/cbin.c b/librz/core/cbin.c index 9490d437348..39cbc63f39d 100644 --- a/librz/core/cbin.c +++ b/librz/core/cbin.c @@ -1789,6 +1789,9 @@ static bool bin_dwarf(RzCore *core, RzBinFile *binfile, RzCmdStateOutput *state) if (dw->info) { print_free(rz_core_bin_dwarf_debug_info_to_string(dw->info, dw)); } + if (dw->loclists) { + print_free(rz_core_bin_dwarf_loc_to_string(dw->loclists, dw)); + } if (dw->aranges) { print_free(rz_core_bin_dwarf_aranges_to_string(dw->aranges)); } diff --git a/librz/core/cdwarf.c b/librz/core/cdwarf.c index 980cab67bfb..c55d94d021c 100644 --- a/librz/core/cdwarf.c +++ b/librz/core/cdwarf.c @@ -226,6 +226,60 @@ RZ_API RZ_OWN char *rz_core_bin_dwarf_debug_info_to_string( return rz_strbuf_drain(sb); } +typedef struct { + RzBinDWARF *dw; + RzStrBuf *sb; +} DumpContext; + +static bool htup_loclists_cb(void *u, ut64 k, const void *v) { + const RzBinDwarfLocList *loclist = v; + DumpContext *ctx = u; + if (!(loclist && ctx && ctx->sb && ctx->dw)) { + return false; + } + RzStrBuf *sb = ctx->sb; + rz_strbuf_appendf(sb, "0x%" PFMT64x "\n", loclist->offset); + void **it; + rz_pvector_foreach (&loclist->entries, it) { + RzBinDwarfLocListEntry *entry = *it; + rz_strbuf_appendf(sb, "\t(0x%" PFMT64x ", 0x%" PFMT64x ")\t", entry->range->begin, entry->range->end); + if (entry->expression) { + const RzBinDwarfEncoding *enc = ht_up_find( + ctx->dw->info->location_encoding, k, NULL); + if (!enc) { + continue; + } + RzBinDWARFDumpOption dump_opt = { + .loclist_sep = ",\t", + .loclist_indent = "", + .expr_sep = ", " + }; + rz_bin_dwarf_expression_dump( + enc, entry->expression, ctx->sb, &dump_opt); + } + rz_strbuf_append(sb, "\n"); + } + return true; +} + +RZ_API RZ_OWN char *rz_core_bin_dwarf_loc_to_string( + RZ_NONNULL RZ_BORROW RzBinDwarfLocLists *loclists, + RZ_NONNULL RZ_BORROW RzBinDWARF *dw) { + rz_return_val_if_fail(dw && loclists && loclists->loclist_by_offset, NULL); + RzStrBuf *sb = rz_strbuf_new(NULL); + if (!sb) { + return NULL; + } + rz_strbuf_appendf(sb, "\nContents of the .debug_loc|.debug_loclists section:\n"); + DumpContext ctx = { + .dw = dw, + .sb = sb, + }; + ht_up_foreach(loclists->loclist_by_offset, htup_loclists_cb, &ctx); + rz_strbuf_append(sb, "\n"); + return rz_strbuf_drain(sb); +} + RZ_API RZ_OWN char *rz_core_bin_dwarf_aranges_to_string(RZ_NONNULL RZ_BORROW RzBinDwarfARanges *aranges) { rz_return_val_if_fail(aranges, NULL); RzStrBuf *sb = rz_strbuf_new(NULL); diff --git a/librz/include/rz_bin_dwarf.h b/librz/include/rz_bin_dwarf.h index 7f78e7c4c94..a26940b7a86 100644 --- a/librz/include/rz_bin_dwarf.h +++ b/librz/include/rz_bin_dwarf.h @@ -1097,6 +1097,7 @@ typedef struct { * that references this particular line information. */ HtUP /**/ *offset_comp_dir; + HtUP /**/ *location_encoding; } RzBinDwarfInfo; typedef struct { diff --git a/librz/include/rz_core.h b/librz/include/rz_core.h index 79735048dcd..893ac01d290 100644 --- a/librz/include/rz_core.h +++ b/librz/include/rz_core.h @@ -908,6 +908,9 @@ RZ_API RZ_OWN char *rz_core_bin_dwarf_attr_to_string( RZ_API RZ_OWN char *rz_core_bin_dwarf_debug_info_to_string( RZ_NONNULL RZ_BORROW const RzBinDwarfInfo *info, const RzBinDWARF *dw); +RZ_API RZ_OWN char *rz_core_bin_dwarf_loc_to_string( + RZ_NONNULL RZ_BORROW RzBinDwarfLocLists *loclists, + RZ_NONNULL RZ_BORROW RzBinDWARF *dw); RZ_API RZ_OWN char *rz_core_bin_dwarf_aranges_to_string(RZ_NONNULL RZ_BORROW RzBinDwarfARanges *aranges); RZ_API RZ_OWN char *rz_core_bin_dwarf_line_unit_to_string(RZ_NONNULL RZ_BORROW RzBinDwarfLineUnit *unit); RZ_API RZ_OWN char *rz_core_bin_dwarf_line_units_to_string(RZ_NONNULL RZ_BORROW RzBinDwarfLine *line);