Skip to content

Commit

Permalink
Add bin.dbginfo.debug_file_directory
Browse files Browse the repository at this point in the history
  • Loading branch information
imbillow committed Oct 20, 2023
1 parent 2d02625 commit b09bbce
Show file tree
Hide file tree
Showing 4 changed files with 129 additions and 18 deletions.
109 changes: 100 additions & 9 deletions librz/bin/dwarf/dwarf.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ static inline RZ_OWN RzBinDWARF *dwarf_from_file(
return dw;
}

static inline char *read_debuglink(RzCore *core, RzBinFile *binfile) {
static inline char *read_debuglink(RzBinFile *binfile) {
RzBinSection *sect = rz_bin_dwarf_section_by_name(binfile, ".gnu_debuglink", false);
RET_NULL_IF_FAIL(sect);
RzBuffer *buffer = rz_bin_dwarf_section_buf(binfile, sect);
Expand All @@ -52,7 +52,7 @@ static inline char *read_debuglink(RzCore *core, RzBinFile *binfile) {
return name;
}

static inline char *read_build_id(RzCore *core, RzBinFile *binfile) {
static inline char *read_build_id(RzBinFile *binfile) {
RzBinSection *sect = rz_bin_dwarf_section_by_name(binfile, ".note.gnu.build-id", false);
RET_NULL_IF_FAIL(sect);
RzBuffer *buffer = rz_bin_dwarf_section_buf(binfile, sect);
Expand Down Expand Up @@ -84,17 +84,108 @@ static inline char *read_build_id(RzCore *core, RzBinFile *binfile) {
return build_id;
}

static inline RzBinDWARF *dwarf_from_debuglink(
const char *file_directory,
RzList /*<const char *>*/ *debug_file_directorys,
const char *debuglink_path) {
RzBinDWARF *dw = NULL;
char *dir = NULL;
char *path = NULL;
char *file_dir = NULL;

path = rz_file_path_join(file_directory, debuglink_path);
if (!rz_file_exists(path)) {
free(path);
}

dir = rz_file_path_join(file_directory, ".debug");
path = rz_file_path_join(dir, debuglink_path);
if (!rz_file_exists(path)) {
free(path);
free(dir);
}

if (RZ_STR_ISNOTEMPTY(file_directory) && strlen(file_directory) >= 2 && file_directory[1] == ':') {
file_dir = rz_str_newf("/%c%s", file_directory[0], file_directory + 2);
} else {
file_dir = rz_str_new(file_directory);
}
RzListIter *it = NULL;
const char *debug_file_directory = NULL;
rz_list_foreach (debug_file_directorys, it, debug_file_directory) {
dir = rz_file_path_join(debug_file_directory, file_dir);
path = rz_file_path_join(dir, debuglink_path);
if (!rz_file_exists(path)) {
free(path);
free(dir);
}
}

dw = rz_file_exists(path) ? rz_bin_dwarf_dwo_from_file(path) : NULL;
free(dir);
free(path);
free(file_dir);
return dw;
}

static inline RzBinDWARF *dwarf_from_build_id(
RzList /*<const char *>*/ *debug_file_directorys,
const char *build_id_path) {
RzListIter *it = NULL;
const char *debug_file_directory = NULL;
rz_list_foreach (debug_file_directorys, it, debug_file_directory) {
char *dir = rz_file_path_join(debug_file_directory, ".build-id");
char *path = rz_file_path_join(dir, build_id_path);
if (rz_file_exists(path)) {
RzBinDWARF *dw = rz_bin_dwarf_dwo_from_file(path);
free(dir);
free(path);
return dw;
}
free(dir);
free(path);
}
return NULL;
}

RZ_API RZ_OWN RzBinDWARF *rz_bin_dwarf_search_debug_file_directory(
RZ_BORROW RZ_NONNULL RzBinFile *bf,
RZ_BORROW RZ_NONNULL RzList /*<const char *>*/ *debug_file_directorys) {
rz_return_val_if_fail(bf && debug_file_directorys, NULL);

RzBinDWARF *dw = NULL;
char *build_id = read_build_id(bf);
if (build_id) {
char *build_id_path = rz_str_newf("%c%c/%s", build_id[0], build_id[1], build_id + 2);
dw = dwarf_from_build_id(debug_file_directorys, build_id_path);
free(build_id);
free(build_id_path);
if (dw) {
return dw;
}
}
char *debuglink = read_debuglink(bf);
if (debuglink) {
char *file_dir = rz_file_dirname(bf->file);
if (file_dir) {
dw = dwarf_from_debuglink(file_dir, debug_file_directorys, debuglink);
}
free(debuglink);
free(file_dir);
if (dw) {
return dw;
}
}
return NULL;
}

/**
* \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);
RZ_API RZ_OWN RzBinDWARF *rz_bin_dwarf_dwo_from_file(RZ_BORROW RZ_NONNULL const char *filepath) {
rz_return_val_if_fail(filepath, NULL);

RzBinDWARF *dwo = NULL;
RzIO *io_tmp = rz_io_new();
Expand Down Expand Up @@ -124,7 +215,7 @@ RZ_API void rz_bin_dwarf_free(RZ_OWN RZ_NULLABLE RzBinDWARF *dw) {
if (!dw) {
return;
}
rz_bin_dwarf_free(dw->dwo_parent);
rz_bin_dwarf_free(dw->parent);

DebugRngLists_free(dw->rnglists);
DebugAddr_free(dw->addr);
Expand Down
25 changes: 21 additions & 4 deletions librz/core/cbin.c
Original file line number Diff line number Diff line change
Expand Up @@ -626,14 +626,31 @@ RZ_API bool rz_core_bin_apply_main(RzCore *r, RzBinFile *binfile, bool va) {
return true;
}

static inline RzBinDWARF *rz_core_bin_dwarf(RzCore *core, RzBinFile *binfile) {
static inline RzBinDWARF *load_dwarf(RzCore *core, RzBinFile *binfile) {
RzBinDWARF *dw = rz_bin_dwarf_from_file(binfile);

const char *dwo_path = rz_config_get(core->config, "bin.dbginfo.dwo_path");
if (RZ_STR_ISNOTEMPTY(dwo_path)) {
RzBinDWARF *dwo = rz_bin_dwarf_dwo_from_file(core->bin, dwo_path);
dwo->dwo_parent = dw;
return dwo;
if (dwo) {
dwo->parent = dw;
return dwo;
}
}
const char *debug_file_directory = rz_config_get(
core->config, "bin.dbginfo.debug_file_directory");
if (RZ_STR_ISNOTEMPTY(debug_file_directory)) {
RzList *debug_file_directorys =
rz_str_split_duplist(debug_file_directory, ";", true);
if (debug_file_directorys) {
RzBinDWARF *sep_dw =
rz_bin_dwarf_search_debug_file_directory(binfile, debug_file_directorys);
rz_list_free(debug_file_directorys);
if (sep_dw) {
sep_dw->parent = dw;
return sep_dw;
}
}
}
return dw;
}
Expand All @@ -644,7 +661,7 @@ RZ_API bool rz_core_bin_apply_dwarf(RzCore *core, RzBinFile *binfile) {
return false;
}

RzBinDWARF *dw = rz_core_bin_dwarf(core, binfile);
RzBinDWARF *dw = load_dwarf(core, binfile);
if (!dw) {
return false;
}
Expand Down
4 changes: 3 additions & 1 deletion librz/core/cconfig.c
Original file line number Diff line number Diff line change
Expand Up @@ -3230,7 +3230,9 @@ 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.dwo_path", "", NULL, "Load split debug information (DWARF) file if available");
SETCB("bin.dbginfo.dwo_path", "", NULL, "Load separate debug information (DWARF) file if available");
SETCB("bin.dbginfo.debug_file_directory", "/usr/lib/debug", NULL,
"Set the directories which searches for separate debugging information files to directory");
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
9 changes: 5 additions & 4 deletions librz/include/rz_bin_dwarf.h
Original file line number Diff line number Diff line change
Expand Up @@ -1420,7 +1420,7 @@ typedef struct {
struct rz_core_bin_dwarf_t;

typedef struct rz_core_bin_dwarf_t {
struct rz_core_bin_dwarf_t *dwo_parent;
struct rz_core_bin_dwarf_t *parent;

RzBinDwarfARanges *aranges;
RzBinDwarfLine *line;
Expand Down Expand Up @@ -1510,9 +1510,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 RZ_OWN RzBinDWARF *rz_bin_dwarf_dwo_from_file(RZ_BORROW RZ_NONNULL const char *filepath);
RZ_API RZ_OWN RzBinDWARF *rz_bin_dwarf_search_debug_file_directory(
RZ_BORROW RZ_NONNULL RzBinFile *bf,
RZ_BORROW RZ_NONNULL RzList /*<const char *>*/ *debug_file_directorys);

RZ_API void rz_bin_dwarf_free(RZ_OWN RZ_NULLABLE RzBinDWARF *dw);

Expand Down

0 comments on commit b09bbce

Please sign in to comment.