summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Wielaard <mjw@redhat.com>2012-01-31 19:22:03 +0100
committerMark Wielaard <mjw@redhat.com>2012-01-31 23:28:32 +0100
commitcb643d6731f3b0131e34e055272c694bd0bf97ed (patch)
tree4ad31e359c93deb5191d63fa9efd9fa201e6651d
parenta77881a2b8a3202dd3b5d1c61236118d6601bb5c (diff)
Handle DW_FORM_sec_offset in dwarf_formudata.
-rw-r--r--libdw/ChangeLog4
-rw-r--r--libdw/dwarf_formudata.c84
-rw-r--r--src/ChangeLog4
-rw-r--r--src/readelf.c3
4 files changed, 86 insertions, 9 deletions
diff --git a/libdw/ChangeLog b/libdw/ChangeLog
index cfc5c894..98b67f4a 100644
--- a/libdw/ChangeLog
+++ b/libdw/ChangeLog
@@ -1,3 +1,7 @@
+2012-01-31 Mark Wielaard <mjw@redhat.com>
+
+ * dwarf_formudata.c (dwarf_formudata): Handle DW_FORM_sec_offset.
+
2011-11-31 Mark Wielaard <mjw@redhat.com>
* Makefile.am (known-dwarf.h): Run gawk on config/known-dwarf.awk.
diff --git a/libdw/dwarf_formudata.c b/libdw/dwarf_formudata.c
index 573a5783..07efbe0b 100644
--- a/libdw/dwarf_formudata.c
+++ b/libdw/dwarf_formudata.c
@@ -1,5 +1,5 @@
/* Return unsigned constant represented by attribute.
- Copyright (C) 2003-2010 Red Hat, Inc.
+ Copyright (C) 2003-2012 Red Hat, Inc.
This file is part of Red Hat elfutils.
Written by Ulrich Drepper <drepper@redhat.com>, 2003.
@@ -134,11 +134,83 @@ dwarf_formudata (attr, return_uval)
case DW_FORM_data4:
case DW_FORM_data8:
- if (__libdw_read_address (attr->cu->dbg, cu_sec_idx (attr->cu),
- attr->valp,
- attr->form == DW_FORM_data4 ? 4 : 8,
- return_uval))
- return -1;
+ case DW_FORM_sec_offset:
+ /* Before DWARF4 data4 and data8 are pure constants unless the
+ attribute also allows offsets (*ptr classes), since DWARF4
+ they are always just constants (start_scope is special though,
+ since it only could express a rangelist since DWARF4). */
+ if (attr->form == DW_FORM_sec_offset
+ || (attr->cu->version < 4 && attr->code != DW_AT_start_scope))
+ {
+ switch (attr->code)
+ {
+ case DW_AT_data_member_location:
+ case DW_AT_frame_base:
+ case DW_AT_location:
+ case DW_AT_return_addr:
+ case DW_AT_segment:
+ case DW_AT_static_link:
+ case DW_AT_string_length:
+ case DW_AT_use_location:
+ case DW_AT_vtable_elem_location:
+ /* loclistptr */
+ if (__libdw_formptr (attr, IDX_debug_loc,
+ DWARF_E_NO_LOCLIST, NULL,
+ return_uval) == NULL)
+ return -1;
+ break;
+
+ case DW_AT_macro_info:
+ /* macptr */
+ if (__libdw_formptr (attr, IDX_debug_macinfo,
+ DWARF_E_NO_ENTRY, NULL,
+ return_uval) == NULL)
+ return -1;
+ break;
+
+ case DW_AT_ranges:
+ case DW_AT_start_scope:
+ /* rangelistptr */
+ if (__libdw_formptr (attr, IDX_debug_ranges,
+ DWARF_E_NO_DEBUG_RANGES, NULL,
+ return_uval) == NULL)
+ return -1;
+ break;
+
+ case DW_AT_stmt_list:
+ /* lineptr */
+ if (__libdw_formptr (attr, IDX_debug_line,
+ DWARF_E_NO_DEBUG_LINE, NULL,
+ return_uval) == NULL)
+ return -1;
+ break;
+
+ default:
+ /* sec_offset can only be used by one of the above attrs. */
+ if (attr->form == DW_FORM_sec_offset)
+ {
+ __libdw_seterrno (DWARF_E_INVALID_DWARF);
+ return -1;
+ }
+
+ /* Not one of the special attributes, just a constant. */
+ if (__libdw_read_address (attr->cu->dbg, cu_sec_idx (attr->cu),
+ attr->valp,
+ attr->form == DW_FORM_data4 ? 4 : 8,
+ return_uval))
+ return -1;
+ break;
+ }
+ }
+ else
+ {
+ /* We are dealing with a constant data4 or data8. */
+ if (__libdw_read_address (attr->cu->dbg, cu_sec_idx (attr->cu),
+ attr->valp,
+ attr->form == DW_FORM_data4 ? 4 : 8,
+ return_uval))
+ return -1;
+ }
break;
case DW_FORM_sdata:
diff --git a/src/ChangeLog b/src/ChangeLog
index de6031f1..ff19b484 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,7 @@
+2012-01-31 Mark Wielaard <mjw@redhat.com>
+
+ * readelf.c (attr_callback): Don't special case DW_FORM_sec_offset.
+
2012-01-21 Ulrich Drepper <drepper@gmail.com>
* addr2line.c: Update copyright year.
diff --git a/src/readelf.c b/src/readelf.c
index 10e25e3a..88766889 100644
--- a/src/readelf.c
+++ b/src/readelf.c
@@ -5612,9 +5612,6 @@ attr_callback (Dwarf_Attribute *attrp, void *arg)
break;
case DW_FORM_sec_offset:
- attrp->form = cbargs->offset_size == 8 ? DW_FORM_data8 : DW_FORM_data4;
- /* Fall through. */
-
case DW_FORM_udata:
case DW_FORM_sdata:
case DW_FORM_data8: