aboutsummaryrefslogtreecommitdiff
path: root/libbacktrace
diff options
context:
space:
mode:
authorTom de Vries <tdevries@suse.de>2019-02-08 05:55:44 +0000
committerTom de Vries <tdevries@suse.de>2019-02-08 05:55:44 +0000
commitbdbd898b8680153da4950e31c1d7d1c1fd2391d6 (patch)
tree5cb2d29e5baf28d9a9fa68dbca448c0a1677c1e5 /libbacktrace
parentc027b0599f7164244134765853877ff56501ed31 (diff)
[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. git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@268663 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libbacktrace')
-rw-r--r--libbacktrace/ChangeLog6
-rw-r--r--libbacktrace/dwarf.c32
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