libbacktrace: use real .opd for debuginfo on ppc64 v1 ABI (592e9c8)

This commit is contained in:
Bartosz Taudul 2024-03-13 00:23:08 +01:00
parent a9feb75bdf
commit 1f90cd473b
No known key found for this signature in database
GPG Key ID: B7FE2008B7575DF3

View File

@ -6519,8 +6519,9 @@ backtrace_uncompress_lzma (struct backtrace_state *state,
static int static int
elf_add (struct backtrace_state *state, const char *filename, int descriptor, elf_add (struct backtrace_state *state, const char *filename, int descriptor,
const unsigned char *memory, size_t memory_size, const unsigned char *memory, size_t memory_size,
uintptr_t base_address, backtrace_error_callback error_callback, uintptr_t base_address, struct elf_ppc64_opd_data *caller_opd,
void *data, fileline *fileline_fn, int *found_sym, int *found_dwarf, backtrace_error_callback error_callback, void *data,
fileline *fileline_fn, int *found_sym, int *found_dwarf,
struct dwarf_data **fileline_entry, int exe, int debuginfo, struct dwarf_data **fileline_entry, int exe, int debuginfo,
const char *with_buildid_data, uint32_t with_buildid_size) const char *with_buildid_data, uint32_t with_buildid_size)
{ {
@ -6575,6 +6576,7 @@ elf_add (struct backtrace_state *state, const char *filename, int descriptor,
struct elf_view split_debug_view[DEBUG_MAX]; struct elf_view split_debug_view[DEBUG_MAX];
unsigned char split_debug_view_valid[DEBUG_MAX]; unsigned char split_debug_view_valid[DEBUG_MAX];
struct elf_ppc64_opd_data opd_data, *opd; struct elf_ppc64_opd_data opd_data, *opd;
int opd_view_valid;
struct dwarf_sections dwarf_sections; struct dwarf_sections dwarf_sections;
struct dwarf_data *fileline_altlink = NULL; struct dwarf_data *fileline_altlink = NULL;
@ -6603,6 +6605,7 @@ elf_add (struct backtrace_state *state, const char *filename, int descriptor,
debug_view_valid = 0; debug_view_valid = 0;
memset (&split_debug_view_valid[0], 0, sizeof split_debug_view_valid); memset (&split_debug_view_valid[0], 0, sizeof split_debug_view_valid);
opd = NULL; opd = NULL;
opd_view_valid = 0;
if (!elf_get_view (state, descriptor, memory, memory_size, 0, sizeof ehdr, if (!elf_get_view (state, descriptor, memory, memory_size, 0, sizeof ehdr,
error_callback, data, &ehdr_view)) error_callback, data, &ehdr_view))
@ -6886,9 +6889,15 @@ elf_add (struct backtrace_state *state, const char *filename, int descriptor,
opd->addr = shdr->sh_addr; opd->addr = shdr->sh_addr;
opd->data = (const char *) opd_data.view.view.data; opd->data = (const char *) opd_data.view.view.data;
opd->size = shdr->sh_size; opd->size = shdr->sh_size;
opd_view_valid = 1;
} }
} }
// A debuginfo file may not have a useful .opd section, but we can use the
// one from the original executable.
if (opd == NULL)
opd = caller_opd;
if (symtab_shndx == 0) if (symtab_shndx == 0)
symtab_shndx = dynsym_shndx; symtab_shndx = dynsym_shndx;
if (symtab_shndx != 0) if (symtab_shndx != 0)
@ -6967,9 +6976,9 @@ elf_add (struct backtrace_state *state, const char *filename, int descriptor,
elf_release_view (state, &debuglink_view, error_callback, data); elf_release_view (state, &debuglink_view, error_callback, data);
if (debugaltlink_view_valid) if (debugaltlink_view_valid)
elf_release_view (state, &debugaltlink_view, error_callback, data); elf_release_view (state, &debugaltlink_view, error_callback, data);
ret = elf_add (state, "", d, NULL, 0, base_address, error_callback, ret = elf_add (state, "", d, NULL, 0, base_address, opd,
data, fileline_fn, found_sym, found_dwarf, NULL, 0, error_callback, data, fileline_fn, found_sym,
1, NULL, 0); found_dwarf, NULL, 0, 1, NULL, 0);
if (ret < 0) if (ret < 0)
backtrace_close (d, error_callback, data); backtrace_close (d, error_callback, data);
else if (descriptor >= 0) else if (descriptor >= 0)
@ -6984,12 +6993,6 @@ elf_add (struct backtrace_state *state, const char *filename, int descriptor,
buildid_view_valid = 0; buildid_view_valid = 0;
} }
if (opd)
{
elf_release_view (state, &opd->view, error_callback, data);
opd = NULL;
}
if (debuglink_name != NULL) if (debuglink_name != NULL)
{ {
int d; int d;
@ -7004,9 +7007,9 @@ elf_add (struct backtrace_state *state, const char *filename, int descriptor,
elf_release_view (state, &debuglink_view, error_callback, data); elf_release_view (state, &debuglink_view, error_callback, data);
if (debugaltlink_view_valid) if (debugaltlink_view_valid)
elf_release_view (state, &debugaltlink_view, error_callback, data); elf_release_view (state, &debugaltlink_view, error_callback, data);
ret = elf_add (state, "", d, NULL, 0, base_address, error_callback, ret = elf_add (state, "", d, NULL, 0, base_address, opd,
data, fileline_fn, found_sym, found_dwarf, NULL, 0, error_callback, data, fileline_fn, found_sym,
1, NULL, 0); found_dwarf, NULL, 0, 1, NULL, 0);
if (ret < 0) if (ret < 0)
backtrace_close (d, error_callback, data); backtrace_close (d, error_callback, data);
else if (descriptor >= 0) else if (descriptor >= 0)
@ -7031,7 +7034,7 @@ elf_add (struct backtrace_state *state, const char *filename, int descriptor,
{ {
int ret; int ret;
ret = elf_add (state, filename, d, NULL, 0, base_address, ret = elf_add (state, filename, d, NULL, 0, base_address, opd,
error_callback, data, fileline_fn, found_sym, error_callback, data, fileline_fn, found_sym,
found_dwarf, &fileline_altlink, 0, 1, found_dwarf, &fileline_altlink, 0, 1,
debugaltlink_buildid_data, debugaltlink_buildid_size); debugaltlink_buildid_data, debugaltlink_buildid_size);
@ -7068,7 +7071,7 @@ elf_add (struct backtrace_state *state, const char *filename, int descriptor,
if (ret) if (ret)
{ {
ret = elf_add (state, filename, -1, gnu_debugdata_uncompressed, ret = elf_add (state, filename, -1, gnu_debugdata_uncompressed,
gnu_debugdata_uncompressed_size, base_address, gnu_debugdata_uncompressed_size, base_address, opd,
error_callback, data, fileline_fn, found_sym, error_callback, data, fileline_fn, found_sym,
found_dwarf, NULL, 0, 0, NULL, 0); found_dwarf, NULL, 0, 0, NULL, 0);
if (ret >= 0 && descriptor >= 0) if (ret >= 0 && descriptor >= 0)
@ -7077,6 +7080,13 @@ elf_add (struct backtrace_state *state, const char *filename, int descriptor,
} }
} }
if (opd_view_valid)
{
elf_release_view (state, &opd->view, error_callback, data);
opd_view_valid = 0;
opd = NULL;
}
/* Read all the debug sections in a single view, since they are /* Read all the debug sections in a single view, since they are
probably adjacent in the file. If any of sections are probably adjacent in the file. If any of sections are
uncompressed, we never release this view. */ uncompressed, we never release this view. */
@ -7323,7 +7333,7 @@ elf_add (struct backtrace_state *state, const char *filename, int descriptor,
if (split_debug_view_valid[i]) if (split_debug_view_valid[i])
elf_release_view (state, &split_debug_view[i], error_callback, data); elf_release_view (state, &split_debug_view[i], error_callback, data);
} }
if (opd) if (opd_view_valid)
elf_release_view (state, &opd->view, error_callback, data); elf_release_view (state, &opd->view, error_callback, data);
if (descriptor >= 0) if (descriptor >= 0)
backtrace_close (descriptor, error_callback, data); backtrace_close (descriptor, error_callback, data);
@ -7439,7 +7449,7 @@ phdr_callback (struct PhdrIterate *info, void *pdata)
return 0; return 0;
} }
if (elf_add (pd->state, filename, descriptor, NULL, 0, info->dlpi_addr, if (elf_add (pd->state, filename, descriptor, NULL, 0, info->dlpi_addr, NULL,
pd->error_callback, pd->data, &elf_fileline_fn, pd->found_sym, pd->error_callback, pd->data, &elf_fileline_fn, pd->found_sym,
&found_dwarf, NULL, 0, 0, NULL, 0)) &found_dwarf, NULL, 0, 0, NULL, 0))
{ {
@ -7528,9 +7538,9 @@ backtrace_initialize (struct backtrace_state *state, const char *filename,
fileline elf_fileline_fn = elf_nodebug; fileline elf_fileline_fn = elf_nodebug;
struct phdr_data pd; struct phdr_data pd;
ret = elf_add (state, filename, descriptor, NULL, 0, 0, error_callback, data, ret = elf_add (state, filename, descriptor, NULL, 0, 0, NULL, error_callback,
&elf_fileline_fn, &found_sym, &found_dwarf, NULL, 1, 0, NULL, data, &elf_fileline_fn, &found_sym, &found_dwarf, NULL, 1, 0,
0); NULL, 0);
if (!ret) if (!ret)
return 0; return 0;