diff options
author | Mark Wielaard <mjw@redhat.com> | 2012-01-31 19:22:03 +0100 |
---|---|---|
committer | Mark Wielaard <mjw@redhat.com> | 2012-01-31 23:28:32 +0100 |
commit | cb643d6731f3b0131e34e055272c694bd0bf97ed (patch) | |
tree | 4ad31e359c93deb5191d63fa9efd9fa201e6651d | |
parent | a77881a2b8a3202dd3b5d1c61236118d6601bb5c (diff) |
Handle DW_FORM_sec_offset in dwarf_formudata.
-rw-r--r-- | libdw/ChangeLog | 4 | ||||
-rw-r--r-- | libdw/dwarf_formudata.c | 84 | ||||
-rw-r--r-- | src/ChangeLog | 4 | ||||
-rw-r--r-- | src/readelf.c | 3 |
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: |