Skip to content

Commit

Permalink
libdrgn: embed drgn_debug_info in drgn_program
Browse files Browse the repository at this point in the history
This will simplify the implementation of the module API (#332).

Signed-off-by: Omar Sandoval <osandov@osandov.com>
  • Loading branch information
osandov committed Oct 2, 2023
1 parent f248054 commit c85dd74
Show file tree
Hide file tree
Showing 7 changed files with 43 additions and 71 deletions.
22 changes: 7 additions & 15 deletions libdrgn/debug_info.c
Original file line number Diff line number Diff line change
Expand Up @@ -2086,12 +2086,9 @@ bool drgn_debug_info_is_indexed(struct drgn_debug_info *dbinfo,
return c_string_set_search(&dbinfo->module_names, &name).entry != NULL;
}

struct drgn_error *drgn_debug_info_create(struct drgn_program *prog,
struct drgn_debug_info **ret)
void drgn_debug_info_init(struct drgn_debug_info *dbinfo,
struct drgn_program *prog)
{
struct drgn_debug_info *dbinfo = malloc(sizeof(*dbinfo));
if (!dbinfo)
return &drgn_enomem;
dbinfo->prog = prog;
const Dwfl_Callbacks *dwfl_callbacks;
if (prog->flags & DRGN_PROGRAM_IS_LINUX_KERNEL)
Expand All @@ -2101,10 +2098,10 @@ struct drgn_error *drgn_debug_info_create(struct drgn_program *prog,
else
dwfl_callbacks = &drgn_userspace_core_dump_dwfl_callbacks;
dbinfo->dwfl = dwfl_begin(dwfl_callbacks);
if (!dbinfo->dwfl) {
free(dbinfo);
return drgn_error_libdwfl();
}
// This is temporary until we stop using libdwfl, and is extremely
// unlikely to fail anwyays, so don't bother propagating an error up.
if (!dbinfo->dwfl)
abort();
drgn_program_add_type_finder_impl(prog, &dbinfo->type_finder,
drgn_debug_info_find_type, dbinfo);
drgn_program_add_object_finder_impl(prog, &dbinfo->object_finder,
Expand All @@ -2113,21 +2110,16 @@ struct drgn_error *drgn_debug_info_create(struct drgn_program *prog,
drgn_module_table_init(&dbinfo->modules);
c_string_set_init(&dbinfo->module_names);
drgn_dwarf_info_init(dbinfo);
*ret = dbinfo;
return NULL;
}

void drgn_debug_info_destroy(struct drgn_debug_info *dbinfo)
void drgn_debug_info_deinit(struct drgn_debug_info *dbinfo)
{
if (!dbinfo)
return;
drgn_dwarf_info_deinit(dbinfo);
c_string_set_deinit(&dbinfo->module_names);
drgn_debug_info_free_modules(dbinfo, false, true);
assert(drgn_module_table_empty(&dbinfo->modules));
drgn_module_table_deinit(&dbinfo->modules);
dwfl_end(dbinfo->dwfl);
free(dbinfo);
}

struct drgn_elf_file *drgn_module_find_dwarf_file(struct drgn_module *module,
Expand Down
10 changes: 5 additions & 5 deletions libdrgn/debug_info.h
Original file line number Diff line number Diff line change
Expand Up @@ -153,12 +153,12 @@ struct drgn_debug_info {
struct drgn_dwarf_info dwarf;
};

/** Create a @ref drgn_debug_info. */
struct drgn_error *drgn_debug_info_create(struct drgn_program *prog,
struct drgn_debug_info **ret);
/** Initialize a @ref drgn_debug_info. */
void drgn_debug_info_init(struct drgn_debug_info *dbinfo,
struct drgn_program *prog);

/** Destroy a @ref drgn_debug_info. */
void drgn_debug_info_destroy(struct drgn_debug_info *dbinfo);
/** Deinitialize a @ref drgn_debug_info. */
void drgn_debug_info_deinit(struct drgn_debug_info *dbinfo);

DEFINE_VECTOR_TYPE(drgn_module_vector, struct drgn_module *);

Expand Down
8 changes: 4 additions & 4 deletions libdrgn/dwarf_info.c
Original file line number Diff line number Diff line change
Expand Up @@ -4917,7 +4917,7 @@ drgn_dwarf_member_thunk_fn(struct drgn_object *res, void *arg_)
struct drgn_dwarf_member_thunk_arg *arg = arg_;
if (res) {
struct drgn_qualified_type qualified_type;
err = drgn_type_from_dwarf_attr(drgn_object_program(res)->dbinfo,
err = drgn_type_from_dwarf_attr(&drgn_object_program(res)->dbinfo,
arg->file, &arg->die, NULL,
false,
arg->can_be_incomplete_array,
Expand Down Expand Up @@ -5200,7 +5200,7 @@ drgn_dwarf_template_type_parameter_thunk_fn(struct drgn_object *res, void *arg_)
struct drgn_dwarf_die_thunk_arg *arg = arg_;
if (res) {
struct drgn_qualified_type qualified_type;
err = drgn_type_from_dwarf_attr(drgn_object_program(res)->dbinfo,
err = drgn_type_from_dwarf_attr(&drgn_object_program(res)->dbinfo,
arg->file, &arg->die, NULL,
true, true, NULL,
&qualified_type);
Expand All @@ -5222,7 +5222,7 @@ drgn_dwarf_template_value_parameter_thunk_fn(struct drgn_object *res,
struct drgn_error *err;
struct drgn_dwarf_die_thunk_arg *arg = arg_;
if (res) {
err = drgn_object_from_dwarf(drgn_object_program(res)->dbinfo,
err = drgn_object_from_dwarf(&drgn_object_program(res)->dbinfo,
arg->file, &arg->die, NULL, NULL,
NULL, res);
if (err)
Expand Down Expand Up @@ -5790,7 +5790,7 @@ drgn_dwarf_formal_parameter_thunk_fn(struct drgn_object *res, void *arg_)
struct drgn_dwarf_die_thunk_arg *arg = arg_;
if (res) {
struct drgn_qualified_type qualified_type;
err = drgn_type_from_dwarf_attr(drgn_object_program(res)->dbinfo,
err = drgn_type_from_dwarf_attr(&drgn_object_program(res)->dbinfo,
arg->file, &arg->die, NULL,
false, true, NULL,
&qualified_type);
Expand Down
53 changes: 17 additions & 36 deletions libdrgn/program.c
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ void drgn_program_init(struct drgn_program *prog,
drgn_memory_reader_init(&prog->reader);
drgn_program_init_types(prog);
drgn_object_index_init(&prog->oindex);
drgn_debug_info_init(&prog->dbinfo, prog);
prog->core_fd = -1;
if (platform)
drgn_program_set_platform(prog, platform);
Expand Down Expand Up @@ -147,7 +148,7 @@ void drgn_program_deinit(struct drgn_program *prog)
if (prog->core_fd != -1)
close(prog->core_fd);

drgn_debug_info_destroy(prog->dbinfo);
drgn_debug_info_deinit(&prog->dbinfo);
}

LIBDRGN_PUBLIC struct drgn_error *
Expand Down Expand Up @@ -695,7 +696,7 @@ static void drgn_program_set_language_from_main(struct drgn_program *prog)
if (prog->flags & DRGN_PROGRAM_IS_LINUX_KERNEL)
return;
const struct drgn_language *lang;
err = drgn_debug_info_main_language(prog->dbinfo, &lang);
err = drgn_debug_info_main_language(&prog->dbinfo, &lang);
if (err) {
drgn_error_destroy(err);
return;
Expand Down Expand Up @@ -734,20 +735,12 @@ drgn_program_load_debug_info(struct drgn_program *prog, const char **paths,
return NULL;

drgn_blocking_guard(prog);
struct drgn_debug_info *dbinfo = prog->dbinfo;
if (!dbinfo) {
err = drgn_debug_info_create(prog, &dbinfo);
if (err)
return err;
prog->dbinfo = dbinfo;
}

err = drgn_debug_info_load(dbinfo, paths, n, load_default, load_main);
err = drgn_debug_info_load(&prog->dbinfo, paths, n, load_default, load_main);
if ((!err || err->code == DRGN_ERROR_MISSING_DEBUG_INFO)) {
if (!prog->lang)
drgn_program_set_language_from_main(prog);
if (!prog->has_platform) {
dwfl_getdwarf(dbinfo->dwfl,
dwfl_getdwarf(prog->dbinfo.dwfl,
drgn_set_platform_from_dwarf, prog, 0);
}
}
Expand Down Expand Up @@ -1784,13 +1777,9 @@ bool drgn_program_find_symbol_by_address_internal(struct drgn_program *prog,
struct drgn_symbol *ret)
{
if (!module) {
if (prog->dbinfo) {
module = dwfl_addrmodule(prog->dbinfo->dwfl, address);
if (!module)
return false;
} else {
module = dwfl_addrmodule(prog->dbinfo.dwfl, address);
if (!module)
return false;
}
}

GElf_Off offset;
Expand Down Expand Up @@ -1894,11 +1883,6 @@ symbols_search(struct drgn_program *prog, struct symbols_search_arg *arg,
{
struct drgn_error *err;

if (!prog->dbinfo) {
return drgn_error_create(DRGN_ERROR_MISSING_DEBUG_INFO,
"could not find matching symbols");
}

symbolp_vector_init(&arg->results);

/*
Expand All @@ -1907,12 +1891,12 @@ symbols_search(struct drgn_program *prog, struct symbols_search_arg *arg,
*/
err = NULL;
if (arg->flags & SYMBOLS_SEARCH_ADDRESS) {
Dwfl_Module *module = dwfl_addrmodule(prog->dbinfo->dwfl,
Dwfl_Module *module = dwfl_addrmodule(prog->dbinfo.dwfl,
arg->address);
if (module && symbols_search_cb(module, NULL, NULL, 0, arg))
err = &drgn_enomem;
} else {
if (dwfl_getmodules(prog->dbinfo->dwfl, symbols_search_cb, arg,
if (dwfl_getmodules(prog->dbinfo.dwfl, symbols_search_cb, arg,
0))
err = &drgn_enomem;
}
Expand Down Expand Up @@ -2015,17 +1999,14 @@ drgn_program_find_symbol_by_name(struct drgn_program *prog,
struct find_symbol_by_name_arg arg = {
.name = name,
};
if (prog->dbinfo) {
dwfl_getmodules(prog->dbinfo->dwfl, find_symbol_by_name_cb,
&arg, 0);
if (arg.found) {
struct drgn_symbol *sym = malloc(sizeof(*sym));
if (!sym)
return &drgn_enomem;
drgn_symbol_from_elf(name, arg.addr, &arg.sym, sym);
*ret = sym;
return NULL;
}
dwfl_getmodules(prog->dbinfo.dwfl, find_symbol_by_name_cb, &arg, 0);
if (arg.found) {
struct drgn_symbol *sym = malloc(sizeof(*sym));
if (!sym)
return &drgn_enomem;
drgn_symbol_from_elf(name, arg.addr, &arg.sym, sym);
*ret = sym;
return NULL;
}
return drgn_error_format(DRGN_ERROR_LOOKUP,
"could not find symbol with name '%s'%s", name,
Expand Down
3 changes: 2 additions & 1 deletion libdrgn/program.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include <libkdumpfile/kdumpfile.h>
#endif

#include "debug_info.h"
#include "drgn.h"
#include "hash_table.h"
#include "language.h"
Expand Down Expand Up @@ -107,7 +108,7 @@ struct drgn_program {
* Debugging information.
*/
struct drgn_object_index oindex;
struct drgn_debug_info *dbinfo;
struct drgn_debug_info dbinfo;

/*
* Program information.
Expand Down
16 changes: 7 additions & 9 deletions libdrgn/register_state.c
Original file line number Diff line number Diff line change
Expand Up @@ -105,15 +105,13 @@ void drgn_register_state_set_pc(struct drgn_program *prog,
pc &= drgn_platform_address_mask(&prog->platform);
regs->_pc = pc;
drgn_register_state_set_known(regs, 0);
if (prog->dbinfo) {
Dwfl_Module *dwfl_module = dwfl_addrmodule(prog->dbinfo->dwfl,
pc - !regs->interrupted);
if (dwfl_module) {
void **userdatap;
dwfl_module_info(dwfl_module, &userdatap, NULL, NULL,
NULL, NULL, NULL, NULL);
regs->module = *userdatap;
}
Dwfl_Module *dwfl_module = dwfl_addrmodule(prog->dbinfo.dwfl,
pc - !regs->interrupted);
if (dwfl_module) {
void **userdatap;
dwfl_module_info(dwfl_module, &userdatap, NULL, NULL,
NULL, NULL, NULL, NULL);
regs->module = *userdatap;
}
}

Expand Down
2 changes: 1 addition & 1 deletion libdrgn/stack_trace.c
Original file line number Diff line number Diff line change
Expand Up @@ -495,7 +495,7 @@ not_found:;
if (!drgn_platforms_equal(&file->platform, &trace->prog->platform))
regs = NULL;
Dwarf_Die function_die = frame->scopes[frame->function_scope];
return drgn_object_from_dwarf(trace->prog->dbinfo, file, &die,
return drgn_object_from_dwarf(&trace->prog->dbinfo, file, &die,
dwarf_tag(&die) == DW_TAG_enumerator ?
&type_die : NULL,
&function_die, regs, ret);
Expand Down

0 comments on commit c85dd74

Please sign in to comment.