Skip to content

Commit

Permalink
[skip ci] Try load split DWARF file
Browse files Browse the repository at this point in the history
- Try process DW_UT_skeleton
- Fix dwo_id
- Check buffer size
  • Loading branch information
imbillow committed Oct 13, 2023
1 parent 6df64db commit ef67d5e
Show file tree
Hide file tree
Showing 7 changed files with 75 additions and 7 deletions.
3 changes: 3 additions & 0 deletions librz/bin/dwarf/abbrev.c
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,9 @@ RZ_API size_t rz_bin_dwarf_abbrev_count(RZ_BORROW RZ_NONNULL const RzBinDwarfAbb
*/
RZ_API RZ_BORROW RzBinDwarfAbbrevDecl *rz_bin_dwarf_abbrev_get(RZ_BORROW RZ_NONNULL const RzBinDwarfAbbrevTable *tbl, size_t idx) {
rz_return_val_if_fail(tbl, NULL);
if (idx > rz_vector_len(&tbl->abbrevs)) {
return NULL;
}
return rz_vector_index_ptr(&tbl->abbrevs, idx - 1);
}

Expand Down
21 changes: 21 additions & 0 deletions librz/bin/dwarf/dwarf.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,27 @@ RZ_IPI bool RzBinDwarfEncoding_from_file(RzBinDwarfEncoding *encoding, RzBinFile
return true;
}

/**
* \brief Load DWARF from split DWARF file
* \param bin The RzBin instance
* \param opt The RzBinDWARFOption reference
* \param filepath The file path
* \return RzBinDWARF pointer or NULL if failed
*/
RZ_API RZ_OWN RzBinDWARF *rz_bin_dwarf_dwo_from_file(
RZ_BORROW RZ_NONNULL RzBin *bin,
RZ_BORROW RZ_NONNULL const char *filepath) {
rz_return_val_if_fail(bin && filepath, NULL);
RzBinOptions bopt = { 0 };
rz_bin_options_init(&bopt, 0, 0, 0, false);
RzBinFile *prev = rz_bin_cur(bin);
RzBinFile *bf = rz_bin_open(bin, filepath, &bopt);
RET_NULL_IF_FAIL(bf);
RzBinDWARF *dwo = rz_bin_dwarf_from_file(bf);
AND_DO(prev, rz_bin_file_set_cur_binfile(bin, prev));
return dwo;
}

RZ_API RZ_OWN RzBinDWARF *rz_bin_dwarf_from_file(
RZ_BORROW RZ_NONNULL RzBinFile *bf) {
rz_return_val_if_fail(bf, NULL);
Expand Down
20 changes: 20 additions & 0 deletions librz/bin/dwarf/unit.c
Original file line number Diff line number Diff line change
Expand Up @@ -349,6 +349,26 @@ RZ_API RZ_OWN RzBinDwarfInfo *rz_bin_dwarf_info_from_buf(
RzBinDwarfCompUnit *unit = NULL;
rz_vector_foreach(&info->units, unit) {
ht_up_insert(info->unit_by_offset, unit->offset, unit);
switch (unit->hdr.ut) {
case DW_UT_skeleton: {
RzBinDwarfDie *die = rz_vector_head(&unit->dies);
if (!die) {
RZ_LOG_ERROR("Invalid DW_UT_skeleton [0x%" PFMT64x "]\n", unit->offset);
break;
}

break;
}
case DW_UT_compile:
case DW_UT_type:
case DW_UT_partial:
case DW_UT_split_compile:
case DW_UT_split_type:
case DW_UT_lo_user:
case DW_UT_hi_user:
default: break;
}

RzBinDwarfDie *die = NULL;
rz_vector_foreach(&unit->dies, die) {
ht_up_insert(info->die_by_offset, die->offset, die); // optimization for further processing
Expand Down
20 changes: 17 additions & 3 deletions librz/core/cbin.c
Original file line number Diff line number Diff line change
Expand Up @@ -626,13 +626,26 @@ RZ_API bool rz_core_bin_apply_main(RzCore *r, RzBinFile *binfile, bool va) {
return true;
}

RZ_API RzBinDWARF *rz_core_bin_dwarf(RzCore *core, RzBinFile *binfile) {
RzBinDWARF *dw = rz_bin_dwarf_from_file(binfile);
if (!dw) {
const char *filepath = rz_config_get(core->config, "bin.dbginfo.filepath");
if (!filepath) {
return NULL;
}
dw = rz_bin_dwarf_dwo_from_file(core->bin, filepath);
}

return dw;
}

RZ_API bool rz_core_bin_apply_dwarf(RzCore *core, RzBinFile *binfile) {
rz_return_val_if_fail(core && binfile, false);
if (!rz_config_get_i(core->config, "bin.dbginfo") || !binfile->o) {
return false;
}

RzBinDWARF *dw = rz_bin_dwarf_from_file(binfile);
RzBinDWARF *dw = rz_core_bin_dwarf(core, binfile);
if (!dw) {
return false;
}
Expand Down Expand Up @@ -1702,8 +1715,9 @@ static bool bin_dwarf(RzCore *core, RzBinFile *binfile, RzCmdStateOutput *state)
return false;
}

RzBinDWARF *dw = core->analysis->debug_info->dw;
dw = dw ? dw : rz_bin_dwarf_from_file(binfile);
RzBinDWARF *dw = core->analysis && core->analysis->debug_info
? core->analysis->debug_info->dw
: rz_bin_dwarf_from_file(binfile);
if (!dw) {
return false;
}
Expand Down
1 change: 1 addition & 0 deletions librz/core/cconfig.c
Original file line number Diff line number Diff line change
Expand Up @@ -3230,6 +3230,7 @@ RZ_API int rz_core_config_init(RzCore *core) {
SETI("bin.baddr", -1, "Base address of the binary");
SETI("bin.laddr", 0, "Base address for loading library ('*.so')");
SETCB("bin.dbginfo", "true", &cb_bindbginfo, "Load debug information at startup if available");
SETCB("bin.dbginfo.filepath", "", NULL, "Load split debug information (DWARF) file if available");
SETBPREF("bin.relocs", "true", "Load relocs information at startup if available");
SETICB("bin.minstr", 0, &cb_binminstr, "Minimum string length for strings in bin plugins");
SETICB("bin.maxstr", 0, &cb_binmaxstr, "Maximum string length for strings in bin plugins");
Expand Down
3 changes: 2 additions & 1 deletion librz/core/cdwarf.c
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,8 @@ RZ_API RZ_OWN char *rz_core_bin_dwarf_debug_info_to_string(

RzBinDwarfDie *die = NULL;
rz_vector_foreach(&unit->dies, die) {
rz_strbuf_appendf(sb, "<0x%" PFMT64x ">: Abbrev Number: %-4" PFMT64u " ", die->offset, die->abbrev_code);
rz_strbuf_appendf(sb, "<0x%" PFMT64x ">: Abbrev Number: %-4" PFMT64u " ",
die->offset, die->abbrev_code);

const char *tag_name = rz_bin_dwarf_tag(die->tag);
if (tag_name) {
Expand Down
14 changes: 11 additions & 3 deletions librz/include/rz_bin_dwarf.h
Original file line number Diff line number Diff line change
Expand Up @@ -1042,9 +1042,13 @@ typedef struct {
// A 4-byte unsigned offset into the .debug_abbrev section.
ut64 abbrev_offset;
DW_UT ut; // DWARF 5 addition
ut8 dwo_id; // DWARF 5 addition
ut64 type_sig; // DWARF 5 addition
ut64 type_offset; // DWARF 5 addition
union {
ut64 dwo_id; // DWARF 5 addition
struct {
ut64 type_sig; // DWARF 5 addition
ut64 type_offset; // DWARF 5 addition
};
};
ut64 header_size; // excluding length field
RzBinDwarfEncoding encoding;
} RzBinDwarfCompUnitHdr;
Expand Down Expand Up @@ -1498,6 +1502,10 @@ RZ_API void rz_bin_dwarf_line_op_fini(RZ_OWN RZ_NULLABLE RzBinDwarfLineOp *op);
RZ_API void rz_bin_dwarf_line_free(RZ_OWN RZ_NULLABLE RzBinDwarfLine *li);

RZ_API RZ_OWN RzBinDWARF *rz_bin_dwarf_from_file(RZ_BORROW RZ_NONNULL RzBinFile *bf);
RZ_API RZ_OWN RzBinDWARF *rz_bin_dwarf_dwo_from_file(
RZ_BORROW RZ_NONNULL RzBin *bin,
RZ_BORROW RZ_NONNULL const char *filepath);

RZ_API void rz_bin_dwarf_free(RZ_OWN RZ_NULLABLE RzBinDWARF *dw);

// Assuming ValueType is an enum defined elsewhere
Expand Down

0 comments on commit ef67d5e

Please sign in to comment.