False positive on LocationParser.attribute_has_location() (#501)
[pyelftools.git] / elftools / dwarf / locationlists.py
index 9a349779baa02eecf260f846392a2edcd50aa65b..6397738293e9fa636f3bcbb91182ef0c5d715907 100644 (file)
@@ -325,10 +325,19 @@ class LocationParser(object):
 
     @staticmethod
     def _attribute_has_loc_list(attr, dwarf_version):
-        return ((dwarf_version < 4 and
+        return (((dwarf_version < 4 and
                  attr.form in ('DW_FORM_data1', 'DW_FORM_data2', 'DW_FORM_data4', 'DW_FORM_data8') and
                  not attr.name == 'DW_AT_const_value') or
-                attr.form in ('DW_FORM_sec_offset', 'DW_FORM_loclistx'))
+                attr.form in ('DW_FORM_sec_offset', 'DW_FORM_loclistx')) and
+                not LocationParser._attribute_is_member_offset(attr, dwarf_version))
+    
+    # Starting with DWARF3, DW_AT_data_member_location may contain an integer offset
+    # instead of a location expression. Need to prevent false positives on attribute_has_location().
+    @staticmethod
+    def _attribute_is_member_offset(attr, dwarf_version):
+        return (dwarf_version >= 3 and
+            attr.name == 'DW_AT_data_member_location' and
+            attr.form in ('DW_FORM_data1', 'DW_FORM_data2', 'DW_FORM_data4', 'DW_FORM_data8', 'DW_FORM_sdata', 'DW_FORM_udata'))
 
     @staticmethod
     def _attribute_is_loclistptr_class(attr):
@@ -341,4 +350,8 @@ class LocationParser(object):
                                'DW_AT_call_value',
                                'DW_AT_GNU_call_site_value',
                                'DW_AT_GNU_call_site_target',
-                               'DW_AT_GNU_call_site_data_value'))
+                               'DW_AT_GNU_call_site_data_value',
+                               'DW_AT_call_target',
+                               'DW_AT_call_target_clobbered',
+                               'DW_AT_call_data_location',
+                               'DW_AT_call_data_value'))