From: Seth LaForge Date: Thu, 3 Dec 2015 04:43:36 +0000 (-0800) Subject: Improved DWARFv4 support. X-Git-Tag: v0.24~11^2 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=5db298d75abbd76d1f3bd0101660af6d8960fa6e;p=pyelftools.git Improved DWARFv4 support. Handle DW_AT_data_member_location attributes with type DW_FORM_data*, which store a simple integer offset rather than dwarf expression. This seems to come up with struct members, at least on ARM. Handle DW_AT_location attributes with type DW_FORM_sec_offset as not having dwarf expressions, as allowed by the DWARFv4 standard. This seems to come up with some local variables, at least on ARM. Test DW_FORM_sec_offset support in location lists and DW_AT_data_member_location formatting support. Test code, compiled with gcc (Ubuntu 4.8.4-2ubuntu1~14.04) 4.8.4 on x86-64: struct Foo { char bim : 8; char bar : 3; char baz : 5; }; int get_bar(struct Foo foo) { return foo.bar; } int f1(int a, char b) { return a+b; } --- diff --git a/elftools/dwarf/descriptions.py b/elftools/dwarf/descriptions.py index abe9252..a894ceb 100644 --- a/elftools/dwarf/descriptions.py +++ b/elftools/dwarf/descriptions.py @@ -420,13 +420,24 @@ _DWARF_EXPR_DUMPER_CACHE = {} def _location_list_extra(attr, die, section_offset): # According to section 2.6 of the DWARF spec v3, class loclistptr means # a location list, and class block means a location expression. - # - if attr.form in ('DW_FORM_data4', 'DW_FORM_data8'): + # DW_FORM_sec_offset is new in DWARFv4 as a section offset. + if attr.form in ('DW_FORM_data4', 'DW_FORM_data8', 'DW_FORM_sec_offset'): return '(location list)' else: return describe_DWARF_expr(attr.value, die.cu.structs) +def _data_member_location_extra(attr, die, section_offset): + # According to section 5.5.6 of the DWARF spec v4, a data member location + # can be an integer offset, or a location description. + # + if attr.form in ('DW_FORM_data1', 'DW_FORM_data2', + 'DW_FORM_data4', 'DW_FORM_data8'): + return '' # No extra description needed + else: + return describe_DWARF_expr(attr.value, die.cu.structs) + + def _import_extra(attr, die, section_offset): # For DW_AT_import the value points to a DIE (that can be either in the # current DIE's CU or in another CU, depending on the FORM). The extra @@ -479,7 +490,7 @@ _EXTRA_INFO_DESCRIPTION_MAP = defaultdict( DW_AT_location=_location_list_extra, DW_AT_string_length=_location_list_extra, DW_AT_return_addr=_location_list_extra, - DW_AT_data_member_location=_location_list_extra, + DW_AT_data_member_location=_data_member_location_extra, DW_AT_vtable_elem_location=_location_list_extra, DW_AT_segment=_location_list_extra, DW_AT_static_link=_location_list_extra, diff --git a/test/testfiles_for_readelf/improved-dwarfv4.o.elf b/test/testfiles_for_readelf/improved-dwarfv4.o.elf new file mode 100644 index 0000000..f8fda66 Binary files /dev/null and b/test/testfiles_for_readelf/improved-dwarfv4.o.elf differ