diff options
author | Tom de Vries <tdevries@suse.de> | 2019-02-08 05:55:44 +0000 |
---|---|---|
committer | Tom de Vries <vries@gcc.gnu.org> | 2019-02-08 05:55:44 +0000 |
commit | 2bd0a246c60fb6cf52f38e82d1750e175d258596 (patch) | |
tree | 5cb2d29e5baf28d9a9fa68dbca448c0a1677c1e5 /libbacktrace | |
parent | 0dc1a7f1dda2eb42b07e5519f758aa4ba2596b4c (diff) | |
download | gcc-2bd0a246c60fb6cf52f38e82d1750e175d258596.tar.gz |
[libbacktrace] Handle DW_FORM_ref_addr
Add handling of the DW_FORM_ref_addr encoding to libbacktrace.
2019-02-08 Tom de Vries <tdevries@suse.de>
PR libbacktrace/78063
* dwarf.c (build_address_map): Keep all parsed units.
(read_referenced_name_from_attr): Handle DW_FORM_ref_addr.
From-SVN: r268663
Diffstat (limited to 'libbacktrace')
-rw-r--r-- | libbacktrace/ChangeLog | 6 | ||||
-rw-r--r-- | libbacktrace/dwarf.c | 32 |
2 files changed, 18 insertions, 20 deletions
diff --git a/libbacktrace/ChangeLog b/libbacktrace/ChangeLog index 7d0c582d91f..06fa109a675 100644 --- a/libbacktrace/ChangeLog +++ b/libbacktrace/ChangeLog @@ -1,3 +1,9 @@ +2019-02-08 Tom de Vries <tdevries@suse.de> + + PR libbacktrace/78063 + * dwarf.c (build_address_map): Keep all parsed units. + (read_referenced_name_from_attr): Handle DW_FORM_ref_addr. + 2019-01-31 Tom de Vries <tdevries@suse.de> PR libbacktrace/89136 diff --git a/libbacktrace/dwarf.c b/libbacktrace/dwarf.c index e78d36b0b43..d7dacf3ef32 100644 --- a/libbacktrace/dwarf.c +++ b/libbacktrace/dwarf.c @@ -1513,14 +1513,12 @@ build_address_map (struct backtrace_state *state, uintptr_t base_address, size_t units_count; size_t i; struct unit **pu; - size_t prev_addrs_count; size_t unit_offset = 0; memset (&addrs->vec, 0, sizeof addrs->vec); memset (&unit_vec->vec, 0, sizeof unit_vec->vec); addrs->count = 0; unit_vec->count = 0; - prev_addrs_count = 0; /* Read through the .debug_info section. FIXME: Should we use the .debug_aranges section? gdb and addr2line don't use it, but I'm @@ -1620,18 +1618,6 @@ build_address_map (struct backtrace_state *state, uintptr_t base_address, if (unit_buf.reported_underflow) goto fail; - - if (addrs->count > prev_addrs_count || unit_tag == DW_TAG_partial_unit) - prev_addrs_count = addrs->count; - else - { - /* Unit was not used; remove it from the vector. */ - --units_count; - units.size -= sizeof (u); - units.alc += sizeof (u); - free_abbrevs (state, &u->abbrevs, error_callback, data); - backtrace_free (state, u, sizeof *u, error_callback, data); - } } if (info.reported_underflow) goto fail; @@ -2189,13 +2175,19 @@ read_referenced_name_from_attr (struct dwarf_data *ddata, struct unit *u, return NULL; } - if (attr->form == DW_FORM_ref_addr - || attr->form == DW_FORM_ref_sig8) + if (attr->form == DW_FORM_ref_sig8) + return NULL; + + if (val->encoding == ATTR_VAL_REF_INFO) { - /* This refers to an abstract origin defined in - some other compilation unit. We can handle - this case if we must, but it's harder. */ - return NULL; + struct unit *unit + = find_unit (ddata->units, ddata->units_count, + val->u.uint); + if (unit == NULL) + return NULL; + + uint64_t offset = val->u.uint - unit->low_offset; + return read_referenced_name (ddata, unit, offset, error_callback, data); } if (val->encoding == ATTR_VAL_UINT |