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')) and
- not LocationParser._attribute_is_member_offset(attr, dwarf_version))
+ not LocationParser._attribute_is_constant(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().
+ # As for DW_AT_upper_bound/DW_AT_count, we've seen it in form DW_FORM_locexpr in a V5 binary. usually it's a constant,
+ # but the constant sholdn't be misinterpreted as a loclist pointer.
@staticmethod
- def _attribute_is_member_offset(attr, dwarf_version):
- return (dwarf_version >= 3 and
- attr.name == 'DW_AT_data_member_location' and
+ def _attribute_is_constant(attr, dwarf_version):
+ return (((dwarf_version >= 3 and attr.name == 'DW_AT_data_member_location') or
+ (attr.name in ('DW_AT_upper_bound', 'DW_AT_count'))) and
attr.form in ('DW_FORM_data1', 'DW_FORM_data2', 'DW_FORM_data4', 'DW_FORM_data8', 'DW_FORM_sdata', 'DW_FORM_udata'))
@staticmethod
'DW_AT_call_target',
'DW_AT_call_target_clobbered',
'DW_AT_call_data_location',
- 'DW_AT_call_data_value'))
+ 'DW_AT_call_data_value',
+ 'DW_AT_upper_bound',
+ 'DW_AT_count'))
attr = AttributeValue(name='DW_AT_call_target', form='DW_FORM_exprloc', value=[80], raw_value=[80], offset=8509, indirection_length=0)
self.assertTrue(LocationParser.attribute_has_location(attr, 5))
+ # This attribute came from the binary in issue #508
+ # DW_TAG_subrange_type at 0x45DEA
+ attr = AttributeValue(name='DW_AT_upper_bound', form='DW_FORM_exprloc', value=[163, 1, 94, 49, 28], raw_value=[163, 1, 94, 49, 28], offset=286191, indirection_length=0)
+ self.assertTrue(LocationParser.attribute_has_location(attr, 5))
+
+
if __name__ == '__main__':
unittest.main()
\ No newline at end of file