From: Seva Alekseyev Date: Sat, 7 Mar 2020 14:05:01 +0000 (-0500) Subject: DW_AT_const_value is not a location, take 2 (#277) X-Git-Tag: v0.27~57 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=f0572414228eac3b3d6a22652b859bffd9308df9;p=pyelftools.git DW_AT_const_value is not a location, take 2 (#277) Fixes #274 --- diff --git a/elftools/dwarf/locationlists.py b/elftools/dwarf/locationlists.py index 5fba0c3..2f8c51e 100644 --- a/elftools/dwarf/locationlists.py +++ b/elftools/dwarf/locationlists.py @@ -104,13 +104,15 @@ class LocationParser(object): @staticmethod def _attribute_has_loc_expr(attr, dwarf_version): - return (dwarf_version < 4 and attr.form == 'DW_FORM_block1' or - attr.form == 'DW_FORM_exprloc') + return ((dwarf_version < 4 and attr.form == 'DW_FORM_block1' and + not attr.name == 'DW_AT_const_value') or + attr.form == 'DW_FORM_exprloc') @staticmethod def _attribute_has_loc_list(attr, dwarf_version): return ((dwarf_version < 4 and - attr.form in ('DW_FORM_data4', 'DW_FORM_data8')) or + attr.form in ('DW_FORM_data4', 'DW_FORM_data8') and + not attr.name == 'DW_AT_const_value') or attr.form == 'DW_FORM_sec_offset') @staticmethod @@ -120,4 +122,7 @@ class LocationParser(object): 'DW_AT_data_member_location', 'DW_AT_frame_base', 'DW_AT_segment', 'DW_AT_static_link', 'DW_AT_use_location', - 'DW_AT_vtable_elem_location')) + 'DW_AT_vtable_elem_location', + 'DW_AT_GNU_call_site_value', + 'DW_AT_GNU_call_site_target', + 'DW_AT_GNU_call_site_data_value')) diff --git a/test/test_dwarf_constisntloc.py b/test/test_dwarf_constisntloc.py new file mode 100644 index 0000000..b97ef39 --- /dev/null +++ b/test/test_dwarf_constisntloc.py @@ -0,0 +1,39 @@ +#------------------------------------------------------------------------------ +# elftools tests +# +# Seva Alekseyev (sevaa@sprynet.com) +# This code is in the public domain +#------------------------------------------------------------------------------ + +import unittest +import os, sys, io + +sys.path.insert(1, os.getcwd()) + +from elftools.elf.elffile import ELFFile +from elftools.dwarf.dwarfinfo import DWARFInfo, DebugSectionDescriptor, DwarfConfig +from elftools.dwarf.locationlists import LocationParser + +class TestConstWithData4IsntLocation(unittest.TestCase): + def _test_file(self, filename): + filepath = os.path.join('test', 'testfiles_for_unittests', filename) + print('Reading %s...' % (filename)) + with open(filepath, 'rb') as f: + elffile = ELFFile(f) + dwarfinfo = elffile.get_dwarf_info() + locparser = LocationParser(dwarfinfo.location_lists()) + for CU in dwarfinfo.iter_CUs(): + print("Compile unit %s..." % CU.get_top_DIE().attributes['DW_AT_name'].value.decode('utf-8')) + ver = CU['version'] + for DIE in CU.iter_DIEs(): + for key in DIE.attributes: + attr = DIE.attributes[key] + if LocationParser.attribute_has_location(attr, ver): + # This will crash on unpatched library on DIE at 0x9f + locparser.parse_from_attribute(attr, ver) + + def test_main(self): + self._test_file('pascalenum.o') + +if __name__ == '__main__': + unittest.main() diff --git a/test/test_dwarf_locexpr_on_gnucall.py b/test/test_dwarf_locexpr_on_gnucall.py new file mode 100644 index 0000000..ba24da5 --- /dev/null +++ b/test/test_dwarf_locexpr_on_gnucall.py @@ -0,0 +1,39 @@ +#------------------------------------------------------------------------------ +# elftools tests +# +# Seva Alekseyev (sevaa@sprynet.com) +# This code is in the public domain +#------------------------------------------------------------------------------ + +import unittest +import os, sys, io + +# sys.path.insert(1, os.getcwd()) + +from elftools.elf.elffile import ELFFile +from elftools.dwarf.dwarfinfo import DWARFInfo, DebugSectionDescriptor, DwarfConfig +from elftools.dwarf.locationlists import LocationParser + +class TestGNUCallAttributesHaveLocation(unittest.TestCase): + def _test_file(self, filename): + filepath = os.path.join('test', 'testfiles_for_unittests', filename) + print('Reading %s...' % (filename)) + with open(filepath, 'rb') as f: + elffile = ELFFile(f) + dwarfinfo = elffile.get_dwarf_info() + for CU in dwarfinfo.iter_CUs(): + ver = CU['version'] + print("Compile unit %s..." % CU.get_top_DIE().attributes['DW_AT_name'].value.decode('utf-8')) + + for DIE in CU.iter_DIEs(): + for key in DIE.attributes: + attr = DIE.attributes[key] + if attr.form == 'DW_FORM_exprloc': + self.assertTrue(LocationParser.attribute_has_location(attr, CU['version']), "Attribute %s not recognized as a location" % key) + + + def test_main(self): + self._test_file('dwarf_gnuops1.o') + +if __name__ == '__main__': + unittest.main() \ No newline at end of file diff --git a/test/testfiles_for_unittests/dwarf_gnuops1.o b/test/testfiles_for_unittests/dwarf_gnuops1.o new file mode 100644 index 0000000..d489f64 Binary files /dev/null and b/test/testfiles_for_unittests/dwarf_gnuops1.o differ diff --git a/test/testfiles_for_unittests/pascalenum.o b/test/testfiles_for_unittests/pascalenum.o new file mode 100644 index 0000000..a8520e8 Binary files /dev/null and b/test/testfiles_for_unittests/pascalenum.o differ