mirror of
https://github.com/JakeHillion/drgn.git
synced 2024-12-22 09:13:06 +00:00
libdrgn: bypass libdwfl with struct drgn_elf_file
Now that we track the debug file ourselves, we can avoid calling libdwfl in a bunch of places. By tracking the bias ourselves, we can avoid a bunch more. Signed-off-by: Omar Sandoval <osandov@osandov.com>
This commit is contained in:
parent
34f122144a
commit
bcb53d712b
@ -1780,12 +1780,14 @@ drgn_module_find_files(struct drgn_module *module)
|
||||
dwfl_module_info(module->dwfl_module, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, &debug_file_path);
|
||||
|
||||
module->debug_file_bias = debug_file_bias;
|
||||
err = drgn_elf_file_create(module, debug_file_path, dwarf_getelf(dwarf),
|
||||
&module->debug_file);
|
||||
if (err) {
|
||||
module->debug_file = NULL;
|
||||
return err;
|
||||
}
|
||||
module->debug_file->dwarf = dwarf;
|
||||
if (!module->debug_file->scns[DRGN_SCN_DEBUG_INFO] ||
|
||||
!module->debug_file->scns[DRGN_SCN_DEBUG_ABBREV]) {
|
||||
return drgn_error_create(DRGN_ERROR_OTHER,
|
||||
@ -2074,11 +2076,7 @@ drgn_module_find_cfi(struct drgn_program *prog, struct drgn_module *module,
|
||||
&prog->platform))
|
||||
return &drgn_not_found;
|
||||
|
||||
Dwarf_Addr bias;
|
||||
dwfl_module_info(module->dwfl_module, NULL, NULL, NULL, &bias, NULL,
|
||||
NULL, NULL);
|
||||
uint64_t unbiased_pc = pc - bias;
|
||||
|
||||
uint64_t unbiased_pc = pc - module->debug_file_bias;
|
||||
if (prog->prefer_orc_unwinder) {
|
||||
err = drgn_debug_info_find_orc_cfi(module, unbiased_pc, row_ret,
|
||||
interrupted_ret,
|
||||
|
@ -71,6 +71,11 @@ struct drgn_module {
|
||||
Dwfl_Module *dwfl_module;
|
||||
/** File containing debugging information. */
|
||||
struct drgn_elf_file *debug_file;
|
||||
/**
|
||||
* Difference between addresses in program and addresses in @ref
|
||||
* drgn_module::debug_file.
|
||||
*/
|
||||
uint64_t debug_file_bias;
|
||||
|
||||
/** DWARF debugging information. */
|
||||
struct drgn_module_dwarf_info dwarf;
|
||||
|
@ -3070,20 +3070,16 @@ drgn_dwarf_index_iterator_next(struct drgn_dwarf_index_iterator *it)
|
||||
static struct drgn_error *
|
||||
drgn_dwarf_index_get_die(struct drgn_dwarf_index_die *die, Dwarf_Die *die_ret)
|
||||
{
|
||||
Dwarf_Addr bias;
|
||||
Dwarf *dwarf = dwfl_module_getdwarf(die->file->module->dwfl_module,
|
||||
&bias);
|
||||
if (!dwarf)
|
||||
return drgn_error_libdwfl();
|
||||
uintptr_t start =
|
||||
(uintptr_t)die->file->scn_data[DRGN_SCN_DEBUG_INFO]->d_buf;
|
||||
size_t size = die->file->scn_data[DRGN_SCN_DEBUG_INFO]->d_size;
|
||||
if (die->addr >= start && die->addr < start + size) {
|
||||
if (!dwarf_offdie(dwarf, die->addr - start, die_ret))
|
||||
if (!dwarf_offdie(die->file->dwarf, die->addr - start, die_ret))
|
||||
return drgn_error_libdw();
|
||||
} else {
|
||||
start = (uintptr_t)die->file->scn_data[DRGN_SCN_DEBUG_TYPES]->d_buf;
|
||||
if (!dwarf_offdie_types(dwarf, die->addr - start, die_ret))
|
||||
if (!dwarf_offdie_types(die->file->dwarf, die->addr - start,
|
||||
die_ret))
|
||||
return drgn_error_libdw();
|
||||
}
|
||||
return NULL;
|
||||
@ -3345,12 +3341,15 @@ struct drgn_error *drgn_module_find_dwarf_scopes(struct drgn_module *module,
|
||||
{
|
||||
struct drgn_error *err;
|
||||
|
||||
Dwarf_Addr bias;
|
||||
Dwarf *dwarf = dwfl_module_getdwarf(module->dwfl_module, &bias);
|
||||
if (!dwarf)
|
||||
return drgn_error_libdw();
|
||||
*bias_ret = bias;
|
||||
pc -= bias;
|
||||
if (!module->debug_file) {
|
||||
*bias_ret = 0;
|
||||
*dies_ret = NULL;
|
||||
*length_ret = 0;
|
||||
return NULL;
|
||||
}
|
||||
Dwarf *dwarf = module->debug_file->dwarf;
|
||||
*bias_ret = module->debug_file_bias;
|
||||
pc -= module->debug_file_bias;
|
||||
|
||||
/* First, try to get the CU containing the PC. */
|
||||
Dwarf_Aranges *aranges;
|
||||
@ -3927,10 +3926,7 @@ drgn_dwarf_location(struct drgn_elf_file *file, Dwarf_Attribute *attr,
|
||||
*expr_size_ret = 0;
|
||||
return NULL;
|
||||
}
|
||||
Dwarf_Addr bias;
|
||||
dwfl_module_info(file->module->dwfl_module, NULL, NULL, NULL,
|
||||
&bias, NULL, NULL, NULL);
|
||||
pc.value = pc.value - !regs->interrupted - bias;
|
||||
pc.value -= !regs->interrupted + file->module->debug_file_bias;
|
||||
|
||||
if (cu_version >= 5) {
|
||||
return drgn_dwarf5_location_list(file, offset, &cu_die,
|
||||
@ -4824,11 +4820,9 @@ drgn_object_from_dwarf_subprogram(struct drgn_debug_info *dbinfo,
|
||||
Dwarf_Addr low_pc;
|
||||
if (dwarf_lowpc(die, &low_pc) == -1)
|
||||
return drgn_object_set_absent(ret, qualified_type, 0);
|
||||
Dwarf_Addr bias;
|
||||
dwfl_module_info(file->module->dwfl_module, NULL, NULL, NULL, &bias,
|
||||
NULL, NULL, NULL);
|
||||
return drgn_object_set_reference(ret, qualified_type, low_pc + bias, 0,
|
||||
0);
|
||||
return drgn_object_set_reference(ret, qualified_type,
|
||||
low_pc + file->module->debug_file_bias,
|
||||
0, 0);
|
||||
}
|
||||
|
||||
static struct drgn_error *read_bits(struct drgn_program *prog, void *dst,
|
||||
@ -6640,23 +6634,19 @@ drgn_type_from_dwarf_internal(struct drgn_debug_info *dbinfo,
|
||||
uintptr_t die_addr;
|
||||
if (drgn_dwarf_find_definition(dbinfo, (uintptr_t)die->addr,
|
||||
&file, &die_addr)) {
|
||||
Dwarf_Addr bias;
|
||||
Dwarf *dwarf = dwfl_module_getdwarf(file->module->dwfl_module,
|
||||
&bias);
|
||||
if (!dwarf)
|
||||
return drgn_error_libdwfl();
|
||||
uintptr_t start =
|
||||
(uintptr_t)file->scn_data[DRGN_SCN_DEBUG_INFO]->d_buf;
|
||||
size_t size =
|
||||
file->scn_data[DRGN_SCN_DEBUG_INFO]->d_size;
|
||||
if (die_addr >= start && die_addr < start + size) {
|
||||
if (!dwarf_offdie(dwarf, die_addr - start,
|
||||
if (!dwarf_offdie(file->dwarf, die_addr - start,
|
||||
&definition_die))
|
||||
return drgn_error_libdw();
|
||||
} else {
|
||||
start = (uintptr_t)file->scn_data[DRGN_SCN_DEBUG_TYPES]->d_buf;
|
||||
/* Assume .debug_types */
|
||||
if (!dwarf_offdie_types(dwarf, die_addr - start,
|
||||
if (!dwarf_offdie_types(file->dwarf,
|
||||
die_addr - start,
|
||||
&definition_die))
|
||||
return drgn_error_libdw();
|
||||
}
|
||||
|
@ -12,6 +12,7 @@
|
||||
#ifndef DRGN_ELF_FILE_H
|
||||
#define DRGN_ELF_FILE_H
|
||||
|
||||
#include <elfutils/libdw.h>
|
||||
#include <libelf.h>
|
||||
|
||||
#include "binary_buffer.h"
|
||||
@ -80,6 +81,8 @@ struct drgn_elf_file {
|
||||
const char *path;
|
||||
/** libelf handle. */
|
||||
Elf *elf;
|
||||
/** libdw handle if we're using DWARF information from this file. */
|
||||
Dwarf *dwarf;
|
||||
/**
|
||||
* Platform of this file.
|
||||
*
|
||||
|
@ -302,18 +302,13 @@ drgn_stack_frame_source(struct drgn_stack_trace *trace, size_t frame,
|
||||
return filename;
|
||||
} else if (trace->frames[frame].num_scopes > 0) {
|
||||
struct drgn_register_state *regs = trace->frames[frame].regs;
|
||||
Dwfl_Module *dwfl_module =
|
||||
regs->module ? regs->module->dwfl_module : NULL;
|
||||
if (!dwfl_module)
|
||||
if (!regs->module)
|
||||
return NULL;
|
||||
|
||||
struct optional_uint64 pc = drgn_register_state_get_pc(regs);
|
||||
if (!pc.has_value)
|
||||
return NULL;
|
||||
Dwarf_Addr bias;
|
||||
if (!dwfl_module_getdwarf(dwfl_module, &bias))
|
||||
return NULL;
|
||||
pc.value = pc.value - bias - !regs->interrupted;
|
||||
pc.value -= !regs->interrupted + regs->module->debug_file_bias;
|
||||
|
||||
Dwarf_Die *scopes = trace->frames[frame].scopes;
|
||||
size_t num_scopes = trace->frames[frame].num_scopes;
|
||||
|
Loading…
Reference in New Issue
Block a user