Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DLPX-90130 update-package failed with a merge conflict in the drgn branch #60

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
Loading