Skip to content

Commit

Permalink
DLPX-90130 update-package failed with a merge conflict in the drgn br…
Browse files Browse the repository at this point in the history
  • Loading branch information
manoj-joseph committed Mar 5, 2024
2 parents d809685 + ef4b364 commit d623c34
Show file tree
Hide file tree
Showing 13 changed files with 434 additions and 160 deletions.
2 changes: 1 addition & 1 deletion libdrgn/debug_info.c
Original file line number Diff line number Diff line change
Expand Up @@ -1862,7 +1862,7 @@ drgn_debug_info_read_module(struct drgn_debug_info_load_state *load,
continue;
}
module->state = DRGN_DEBUG_INFO_MODULE_INDEXING;
return drgn_dwarf_index_read_module(index, module);
return drgn_dwarf_index_read_file(index, module->debug_file);
}
/*
* We checked all of the files and didn't find debugging information.
Expand Down
152 changes: 86 additions & 66 deletions libdrgn/dwarf_info.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,18 @@
#include "type.h"
#include "util.h"

#if !_ELFUTILS_PREREQ(0, 191)
static inline int dwarf_cu_dwp_section_info(Dwarf_CU *cu, unsigned int section,
Dwarf_Off *offsetp,
Dwarf_Off *sizep)
{
*offsetp = 0;
if (sizep)
*sizep = 0;
return 0;
}
#endif

void drgn_module_dwarf_info_deinit(struct drgn_module *module)
{
free(module->dwarf.eh_frame.fdes);
Expand Down Expand Up @@ -389,8 +401,7 @@ drgn_dwarf_index_read_cus(struct drgn_dwarf_index_state *state,
struct drgn_dwarf_index_cu_vector *cus =
&state->cus[omp_get_thread_num()];

Dwarf_Off off = 0;
Dwarf_Off next_off;
Dwarf_Off off, next_off;
size_t header_size;
Dwarf_Half version;
Dwarf_Off abbrev_offset;
Expand All @@ -400,116 +411,112 @@ drgn_dwarf_index_read_cus(struct drgn_dwarf_index_state *state,
uint64_t *v4_type_signaturep =
scn == DRGN_SCN_DEBUG_TYPES ? &v4_type_signature : NULL;
int ret;
while ((ret = dwarf_next_unit(file->dwarf, off, &next_off, &header_size,
&version, &abbrev_offset, &address_size,
&offset_size, v4_type_signaturep,
NULL)) == 0) {
Dwarf_Die skeldie, cudie;
for (off = 0;
(ret = dwarf_next_unit(file->dwarf, off, &next_off, &header_size,
&version, &abbrev_offset, &address_size,
&offset_size, v4_type_signaturep,
NULL)) == 0;
off = next_off) {
Dwarf_Die cudie;
if (scn == DRGN_SCN_DEBUG_TYPES) {
if (!dwarf_offdie_types(file->dwarf, off + header_size,
&skeldie))
&cudie))
return drgn_error_libdw();
} else {
if (!dwarf_offdie(file->dwarf, off + header_size,
&skeldie))
&cudie))
return drgn_error_libdw();
}
struct drgn_elf_file *cu_file = file;
Dwarf_Off cu_start_off = off, cu_end_off = next_off;
uint8_t unit_type;
#if _ELFUTILS_PREREQ(0, 171)
if (dwarf_cu_info(skeldie.cu, NULL, &unit_type, &skeldie,
&cudie, NULL, NULL, NULL))
Dwarf_Die subdie;
if (dwarf_cu_info(cudie.cu, NULL, &unit_type, &cudie, &subdie,
NULL, NULL, NULL))
return drgn_error_libdw();

if (unit_type == DW_UT_skeleton && cudie.cu) {
Dwarf *split_dwarf = dwarf_cu_getdwarf(cudie.cu);
cu_file = drgn_module_find_dwarf_file(file->module,
split_dwarf);
if (!cu_file) {
if (unit_type == DW_UT_skeleton && subdie.cu) {
Dwarf *split_dwarf = dwarf_cu_getdwarf(subdie.cu);
struct drgn_elf_file *split_file =
drgn_module_find_dwarf_file(file->module,
split_dwarf);
if (!split_file) {
const char *dwo_name =
drgn_dwarf_dwo_name(&skeldie);
drgn_dwarf_dwo_name(&cudie);
if (!dwo_name)
dwo_name = "";
err = drgn_module_create_split_dwarf_file(file->module,
dwo_name,
split_dwarf,
&cu_file);
&split_file);
if (err)
return err;
err = drgn_dwarf_index_read_file(state,
split_file);
if (err)
return err;
}

cu_start_off = (dwarf_dieoffset(&cudie)
- dwarf_cuoffset(&cudie));
if (dwarf_next_unit(split_dwarf, cu_start_off,
&cu_end_off, NULL, &version,
&abbrev_offset, &address_size,
&offset_size, v4_type_signaturep,
NULL)
|| dwarf_cu_info(cudie.cu, NULL, &unit_type, NULL,
NULL, NULL, NULL, NULL))
return drgn_error_libdw();
} else {
if (unit_type == DW_UT_skeleton
&& drgn_log_is_enabled(state->dbinfo->prog,
DRGN_LOG_WARNING)) {
continue;
} else if (unit_type == DW_UT_skeleton) {
if (drgn_log_is_enabled(state->dbinfo->prog,
DRGN_LOG_WARNING)) {
const char *dwo_name =
drgn_dwarf_dwo_name(&skeldie);
drgn_dwarf_dwo_name(&cudie);
drgn_log_warning(state->dbinfo->prog,
"%s: split DWARF file%s%s not found",
file->path ?: "",
dwo_name ? " " : "",
dwo_name ? dwo_name : "");
}
cudie = skeldie;
continue;
} else {
Dwarf_Off dwp_offset;
if (dwarf_cu_dwp_section_info(cudie.cu, DW_SECT_ABBREV,
&dwp_offset, NULL))
return drgn_error_libdw();
abbrev_offset += dwp_offset;
}
#else
unit_type = (scn == DRGN_SCN_DEBUG_TYPES
? DW_UT_type : DW_UT_compile);
cudie = skeldie;
#endif

if (!elf_data_contains_ptr(cu_file->scn_data[scn],
if (!elf_data_contains_ptr(file->scn_data[scn],
cudie.addr)) {
return drgn_elf_file_section_error(cu_file, NULL, NULL,
return drgn_elf_file_section_error(file, NULL, NULL,
cudie.addr,
"unit DIE from unexpected section");
}
if (cu_end_off > cu_file->scn_data[scn]->d_size)
cu_end_off = cu_file->scn_data[scn]->d_size;
const char *cu_buf =
(char *)cu_file->scn_data[scn]->d_buf + cu_start_off;
const char *cu_buf = (char *)file->scn_data[scn]->d_buf + off;
if (version < 2 || version > 5) {
return drgn_elf_file_section_errorf(cu_file,
cu_file->scns[scn],
cu_file->scn_data[scn],
return drgn_elf_file_section_errorf(file,
file->scns[scn],
file->scn_data[scn],
cu_buf,
"unknown DWARF unit version %" PRIu16,
version);
}
if (address_size > 8) {
return drgn_elf_file_section_errorf(cu_file,
cu_file->scns[scn],
cu_file->scn_data[scn],
return drgn_elf_file_section_errorf(file,
file->scns[scn],
file->scn_data[scn],
cu_buf,
"unsupported DWARF unit address size %" PRIu8,
address_size);
}

Elf_Data *debug_abbrev =
cu_file->scn_data[DRGN_SCN_DEBUG_ABBREV];
Elf_Data *debug_abbrev = file->scn_data[DRGN_SCN_DEBUG_ABBREV];
if (abbrev_offset > debug_abbrev->d_size) {
return drgn_elf_file_section_error(cu_file,
cu_file->scns[scn],
cu_file->scn_data[scn],
return drgn_elf_file_section_error(file,
file->scns[scn],
file->scn_data[scn],
cu_buf,
"debug_abbrev_offset is out of bounds");
}
const char *pending_abbrev =
(char *)debug_abbrev->d_buf + abbrev_offset;

Elf_Data *debug_str_offsets =
cu_file->scn_data[DRGN_SCN_DEBUG_STR_OFFSETS];
file->scn_data[DRGN_SCN_DEBUG_STR_OFFSETS];
const char *str_offsets = NULL;
if (debug_str_offsets) {
Dwarf_Word str_offsets_base;
Expand All @@ -535,10 +542,16 @@ drgn_dwarf_index_read_cus(struct drgn_dwarf_index_state *state,
// DW_AT_str_offsets_base; the base is always 0.
str_offsets_base = 0;
}
Dwarf_Off dwp_offset;
if (dwarf_cu_dwp_section_info(cudie.cu,
DW_SECT_STR_OFFSETS,
&dwp_offset, NULL))
return drgn_error_libdw();
str_offsets_base += dwp_offset;
if (str_offsets_base > debug_str_offsets->d_size) {
return drgn_elf_file_section_error(cu_file,
cu_file->scns[scn],
cu_file->scn_data[scn],
return drgn_elf_file_section_error(file,
file->scns[scn],
file->scn_data[scn],
cudie.addr,
".debug_str_offsets base is out of bounds");
}
Expand All @@ -552,9 +565,9 @@ drgn_dwarf_index_read_cus(struct drgn_dwarf_index_state *state,
if (!cu)
return &drgn_enomem;
*cu = (struct drgn_dwarf_index_cu){
.file = cu_file,
.file = file,
.buf = cu_buf,
.len = cu_end_off - cu_start_off,
.len = min(next_off, (Dwarf_Off)file->scn_data[scn]->d_size) - off,
.version = version,
.unit_type = unit_type,
.address_size = address_size,
Expand All @@ -564,20 +577,17 @@ drgn_dwarf_index_read_cus(struct drgn_dwarf_index_state *state,
.str_offsets = str_offsets,
.libdw_cu = cudie.cu,
};

off = next_off;
}
if (ret < 0)
return drgn_error_libdw();
return NULL;
}

struct drgn_error *
drgn_dwarf_index_read_module(struct drgn_dwarf_index_state *state,
struct drgn_module *module)
drgn_dwarf_index_read_file(struct drgn_dwarf_index_state *state,
struct drgn_elf_file *file)
{
struct drgn_error *err;
struct drgn_elf_file *file = module->debug_file;
err = drgn_dwarf_index_read_cus(state, file, DRGN_SCN_DEBUG_INFO);
if (!err && file->scn_data[DRGN_SCN_DEBUG_TYPES]) {
err = drgn_dwarf_index_read_cus(state, file,
Expand Down Expand Up @@ -2813,6 +2823,11 @@ static struct drgn_error *drgn_dwarf_read_loclistx(struct drgn_elf_file *file,
// the first header.
base = offset_size == 8 ? 20 : 12;
}
Dwarf_Off dwp_offset;
if (dwarf_cu_dwp_section_info(cu_die->cu, DW_SECT_LOCLISTS, &dwp_offset,
NULL))
return drgn_error_libdw();
base += dwp_offset;

if (!file->scns[DRGN_SCN_DEBUG_LOCLISTS]) {
return drgn_error_create(DRGN_ERROR_OTHER,
Expand Down Expand Up @@ -3003,6 +3018,11 @@ drgn_dwarf4_split_location_list(struct drgn_elf_file *file, Dwarf_Word offset,
err = drgn_elf_file_cache_section(file, DRGN_SCN_DEBUG_LOC);
if (err)
return err;
Dwarf_Off dwp_offset;
if (dwarf_cu_dwp_section_info(cu_die->cu, DW_SECT_LOCLISTS, &dwp_offset,
NULL))
return drgn_error_libdw();
offset += dwp_offset;
struct drgn_elf_file_section_buffer buffer;
drgn_elf_file_section_buffer_init_index(&buffer, file,
DRGN_SCN_DEBUG_LOC);
Expand Down
10 changes: 5 additions & 5 deletions libdrgn/dwarf_info.h
Original file line number Diff line number Diff line change
Expand Up @@ -240,16 +240,16 @@ bool drgn_dwarf_index_state_init(struct drgn_dwarf_index_state *state,
/** Deinitialize state for indexing new DWARF information. */
void drgn_dwarf_index_state_deinit(struct drgn_dwarf_index_state *state);

/** Read a @ref drgn_module to index its DWARF information. */
/** Read a @ref drgn_elf_file to index its DWARF information. */
struct drgn_error *
drgn_dwarf_index_read_module(struct drgn_dwarf_index_state *state,
struct drgn_module *module);
drgn_dwarf_index_read_file(struct drgn_dwarf_index_state *state,
struct drgn_elf_file *file);

/**
* Index new DWARF information.
*
* This should be called once all modules have been read with @ref
* drgn_dwarf_index_read_module() to finish indexing those modules.
* This should be called once all files have been read with @ref
* drgn_dwarf_index_read_file() to finish indexing those files.
*/
struct drgn_error *
drgn_dwarf_info_update_index(struct drgn_dwarf_index_state *state);
Expand Down
2 changes: 1 addition & 1 deletion scripts/build_manylinux_in_docker.sh
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ fi

# Install a recent version of elfutils instead of whatever is in the manylinux
# image.
elfutils_version=0.190
elfutils_version=0.191
elfutils_url=https://sourceware.org/elfutils/ftp/$elfutils_version/elfutils-$elfutils_version.tar.bz2
mkdir /tmp/elfutils
cd /tmp/elfutils
Expand Down
4 changes: 2 additions & 2 deletions tests/linux_kernel/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -164,13 +164,13 @@ def proc_in_sigwait(pid):
# 3. Returns the PID from __enter__().
# 4. Kills the process in __exit__().
@contextlib.contextmanager
def fork_and_sigwait(fn=None):
def fork_and_sigwait(fn=None, *args, **kwds):
pid = os.fork()
try:
if pid == 0:
try:
if fn:
fn()
fn(*args, **kwds)
while True:
signal.sigwait(())
finally:
Expand Down
Loading

0 comments on commit d623c34

Please sign in to comment.