mirror of
https://github.com/JakeHillion/drgn.git
synced 2024-12-22 17:23:06 +00:00
libdrgn: embed type and object finders in drgn_debug_info
This is preparation for embedding drgn_debug_info in drgn_program and initializing it earlier. Signed-off-by: Omar Sandoval <osandov@osandov.com>
This commit is contained in:
parent
085b0bc9db
commit
f24805486f
@ -2105,6 +2105,11 @@ struct drgn_error *drgn_debug_info_create(struct drgn_program *prog,
|
||||
free(dbinfo);
|
||||
return drgn_error_libdwfl();
|
||||
}
|
||||
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,
|
||||
drgn_debug_info_find_object,
|
||||
dbinfo);
|
||||
drgn_module_table_init(&dbinfo->modules);
|
||||
c_string_set_init(&dbinfo->module_names);
|
||||
drgn_dwarf_info_init(dbinfo);
|
||||
|
@ -20,8 +20,10 @@
|
||||
#include "drgn.h"
|
||||
#include "dwarf_info.h"
|
||||
#include "hash_table.h"
|
||||
#include "object_index.h"
|
||||
#include "orc_info.h"
|
||||
#include "string_builder.h"
|
||||
#include "type.h"
|
||||
#include "vector.h"
|
||||
|
||||
struct drgn_elf_file;
|
||||
@ -133,6 +135,9 @@ struct drgn_debug_info {
|
||||
/** Program owning this cache. */
|
||||
struct drgn_program *prog;
|
||||
|
||||
struct drgn_type_finder type_finder;
|
||||
struct drgn_object_finder object_finder;
|
||||
|
||||
/** DWARF frontend library handle. */
|
||||
Dwfl *dwfl;
|
||||
/** Modules keyed by build ID and address range. */
|
||||
|
@ -13,12 +13,10 @@ void drgn_object_index_init(struct drgn_object_index *oindex)
|
||||
|
||||
void drgn_object_index_deinit(struct drgn_object_index *oindex)
|
||||
{
|
||||
struct drgn_object_finder *finder;
|
||||
|
||||
finder = oindex->finders;
|
||||
struct drgn_object_finder *finder = oindex->finders;
|
||||
while (finder) {
|
||||
struct drgn_object_finder *next = finder->next;
|
||||
|
||||
if (finder->free)
|
||||
free(finder);
|
||||
finder = next;
|
||||
}
|
||||
@ -26,13 +24,17 @@ void drgn_object_index_deinit(struct drgn_object_index *oindex)
|
||||
|
||||
struct drgn_error *
|
||||
drgn_object_index_add_finder(struct drgn_object_index *oindex,
|
||||
struct drgn_object_finder *finder,
|
||||
drgn_object_find_fn fn, void *arg)
|
||||
{
|
||||
struct drgn_object_finder *finder;
|
||||
|
||||
if (finder) {
|
||||
finder->free = false;
|
||||
} else {
|
||||
finder = malloc(sizeof(*finder));
|
||||
if (!finder)
|
||||
return &drgn_enomem;
|
||||
finder->free = true;
|
||||
}
|
||||
finder->fn = fn;
|
||||
finder->arg = arg;
|
||||
finder->next = oindex->finders;
|
||||
@ -40,13 +42,6 @@ drgn_object_index_add_finder(struct drgn_object_index *oindex,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void drgn_object_index_remove_finder(struct drgn_object_index *oindex)
|
||||
{
|
||||
struct drgn_object_finder *finder = oindex->finders->next;
|
||||
free(oindex->finders);
|
||||
oindex->finders = finder;
|
||||
}
|
||||
|
||||
struct drgn_error *drgn_object_index_find(struct drgn_object_index *oindex,
|
||||
const char *name,
|
||||
const char *filename,
|
||||
|
@ -35,6 +35,8 @@ struct drgn_object_finder {
|
||||
void *arg;
|
||||
/** Next callback to try. */
|
||||
struct drgn_object_finder *next;
|
||||
/** Whether this structure needs to be freed. */
|
||||
bool free;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -56,14 +58,11 @@ void drgn_object_index_init(struct drgn_object_index *oindex);
|
||||
/** Deinitialize a @ref drgn_object_index. */
|
||||
void drgn_object_index_deinit(struct drgn_object_index *oindex);
|
||||
|
||||
/** @sa drgn_program_add_object_finder() */
|
||||
struct drgn_error *
|
||||
drgn_object_index_add_finder(struct drgn_object_index *oindex,
|
||||
struct drgn_object_finder *finder,
|
||||
drgn_object_find_fn fn, void *arg);
|
||||
|
||||
/** Remove the most recently added object finding callback. */
|
||||
void drgn_object_index_remove_finder(struct drgn_object_index *oindex);
|
||||
|
||||
/**
|
||||
* Find an object in a @ref drgn_object_index.
|
||||
*
|
||||
|
@ -189,11 +189,19 @@ drgn_program_add_memory_segment(struct drgn_program *prog, uint64_t address,
|
||||
physical);
|
||||
}
|
||||
|
||||
struct drgn_error *
|
||||
drgn_program_add_object_finder_impl(struct drgn_program *prog,
|
||||
struct drgn_object_finder *finder,
|
||||
drgn_object_find_fn fn, void *arg)
|
||||
{
|
||||
return drgn_object_index_add_finder(&prog->oindex, finder, fn, arg);
|
||||
}
|
||||
|
||||
LIBDRGN_PUBLIC struct drgn_error *
|
||||
drgn_program_add_object_finder(struct drgn_program *prog,
|
||||
drgn_object_find_fn fn, void *arg)
|
||||
{
|
||||
return drgn_object_index_add_finder(&prog->oindex, fn, arg);
|
||||
return drgn_program_add_object_finder_impl(prog, NULL, fn, arg);
|
||||
}
|
||||
|
||||
static struct drgn_error *
|
||||
@ -731,21 +739,6 @@ drgn_program_load_debug_info(struct drgn_program *prog, const char **paths,
|
||||
err = drgn_debug_info_create(prog, &dbinfo);
|
||||
if (err)
|
||||
return err;
|
||||
err = drgn_program_add_object_finder(prog,
|
||||
drgn_debug_info_find_object,
|
||||
dbinfo);
|
||||
if (err) {
|
||||
drgn_debug_info_destroy(dbinfo);
|
||||
return err;
|
||||
}
|
||||
err = drgn_program_add_type_finder(prog,
|
||||
drgn_debug_info_find_type,
|
||||
dbinfo);
|
||||
if (err) {
|
||||
drgn_object_index_remove_finder(&prog->oindex);
|
||||
drgn_debug_info_destroy(dbinfo);
|
||||
return err;
|
||||
}
|
||||
prog->dbinfo = dbinfo;
|
||||
}
|
||||
|
||||
|
@ -244,6 +244,11 @@ struct drgn_error *drgn_program_init_kernel(struct drgn_program *prog);
|
||||
*/
|
||||
struct drgn_error *drgn_program_init_pid(struct drgn_program *prog, pid_t pid);
|
||||
|
||||
struct drgn_error *
|
||||
drgn_program_add_object_finder_impl(struct drgn_program *prog,
|
||||
struct drgn_object_finder *finder,
|
||||
drgn_object_find_fn fn, void *arg);
|
||||
|
||||
static inline struct drgn_error *
|
||||
drgn_program_is_little_endian(struct drgn_program *prog, bool *ret)
|
||||
{
|
||||
|
@ -1307,23 +1307,37 @@ void drgn_program_deinit_types(struct drgn_program *prog)
|
||||
struct drgn_type_finder *finder = prog->type_finders;
|
||||
while (finder) {
|
||||
struct drgn_type_finder *next = finder->next;
|
||||
if (finder->free)
|
||||
free(finder);
|
||||
finder = next;
|
||||
}
|
||||
}
|
||||
|
||||
struct drgn_error *
|
||||
drgn_program_add_type_finder_impl(struct drgn_program *prog,
|
||||
struct drgn_type_finder *finder,
|
||||
drgn_type_find_fn fn, void *arg)
|
||||
{
|
||||
if (finder) {
|
||||
finder->free = false;
|
||||
} else {
|
||||
finder = malloc(sizeof(*finder));
|
||||
if (!finder)
|
||||
return &drgn_enomem;
|
||||
finder->free = true;
|
||||
}
|
||||
finder->fn = fn;
|
||||
finder->arg = arg;
|
||||
finder->next = prog->type_finders;
|
||||
prog->type_finders = finder;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
LIBDRGN_PUBLIC struct drgn_error *
|
||||
drgn_program_add_type_finder(struct drgn_program *prog, drgn_type_find_fn fn,
|
||||
void *arg)
|
||||
{
|
||||
struct drgn_type_finder *finder = malloc(sizeof(*finder));
|
||||
if (!finder)
|
||||
return &drgn_enomem;
|
||||
finder->fn = fn;
|
||||
finder->arg = arg;
|
||||
finder->next = prog->type_finders;
|
||||
prog->type_finders = finder;
|
||||
return NULL;
|
||||
return drgn_program_add_type_finder_impl(prog, NULL, fn, arg);
|
||||
}
|
||||
|
||||
struct drgn_error *drgn_program_find_type_impl(struct drgn_program *prog,
|
||||
|
@ -56,8 +56,15 @@ struct drgn_type_finder {
|
||||
void *arg;
|
||||
/** Next callback to try. */
|
||||
struct drgn_type_finder *next;
|
||||
/** Whether this structure needs to be freed. */
|
||||
bool free;
|
||||
};
|
||||
|
||||
struct drgn_error *
|
||||
drgn_program_add_type_finder_impl(struct drgn_program *prog,
|
||||
struct drgn_type_finder *finder,
|
||||
drgn_type_find_fn fn, void *arg);
|
||||
|
||||
DEFINE_HASH_SET_TYPE(drgn_dedupe_type_set, struct drgn_type *);
|
||||
|
||||
/** <tt>(type, member name)</tt> pair. */
|
||||
|
Loading…
Reference in New Issue
Block a user