- Retrieve symbols by name - get_symbol_by_name (#58).
- Symbol/section names are strings internally now, not bytestrings (this may
affect API usage in Python 3) (#76).
+ - Added DT_MIPS_* constants to ENUM_D_TAG (#79)
+ - Made dwarf_decode_address example a bit more useful for command-line
+ invocation.
+ - More DWARF v4 support w.r.t decoding function ranges; DW_AT_high_pc value
+ is now either absolute or relative to DW_AT_low_pc, depending on the class
+ of the form encoded in the file.
+ Version 0.23 (08.11.2014)
else:
return None
+def describe_form_class(form):
+ """For a given form name, determine its value class.
+
+ For example, given 'DW_FORM_data1' returns 'constant'.
+
+ For some forms, like DW_FORM_indirect and DW_FORM_sec_offset, the class is
+ not hard-coded and extra information is required. For these, None is
+ returned.
+ """
+ return _FORM_CLASS[form]
+
+
#-------------------------------------------------------------------------------
# The machine architecture. Set globally via set_global_machine_arch
DW_FORM_ref_sig8=_describe_attr_ref,
)
+_FORM_CLASS = dict(
+ DW_FORM_addr='address',
+ DW_FORM_block2='block',
+ DW_FORM_block4='block',
+ DW_FORM_data2='constant',
+ DW_FORM_data4='constant',
+ DW_FORM_data8='constant',
+ DW_FORM_string='string',
+ DW_FORM_block='block',
+ DW_FORM_block1='block',
+ DW_FORM_data1='constant',
+ DW_FORM_flag='flag',
+ DW_FORM_sdata='constant',
+ DW_FORM_strp='string',
+ DW_FORM_udata='constant',
+ DW_FORM_ref_addr='reference',
+ DW_FORM_ref1='reference',
+ DW_FORM_ref2='reference',
+ DW_FORM_ref4='reference',
+ DW_FORM_ref8='reference',
+ DW_FORM_ref_udata='reference',
+ DW_FORM_indirect=None,
+ DW_FORM_sec_offset=None,
+ DW_FORM_exprloc='exprloc',
+ DW_FORM_flag_present='flag',
+ DW_FORM_ref_sig8='reference',
+)
_DESCR_DW_INL = {
DW_INL_not_inlined: '(not inlined)',
sys.path[0:0] = ['.', '..']
from elftools.common.py3compat import maxint, bytes2str
+from elftools.dwarf.descriptions import describe_form_class
from elftools.elf.elffile import ELFFile
try:
if DIE.tag == 'DW_TAG_subprogram':
lowpc = DIE.attributes['DW_AT_low_pc'].value
- highpc = DIE.attributes['DW_AT_high_pc'].value
+
+ # DWARF v4 in section 2.17 describes how to interpret the
+ # DW_AT_high_pc attribute based on the class of its form.
+ # For class 'address' it's taken as an absolute address
+ # (similarly to DW_AT_low_pc); for class 'constant', it's
+ # an offset from DW_AT_low_pc.
+ highpc_attr = DIE.attributes['DW_AT_high_pc']
+ highpc_attr_class = describe_form_class(highpc_attr.form)
+ if highpc_attr_class == 'address':
+ highpc = highpc_attr.value
+ elif highpc_attr_class == 'constant':
+ highpc = lowpc + highpc_attr.value
+ else:
+ print('Error: invalid DW_AT_high_pc class:',
+ highpc_attr_class)
+ continue
+
if lowpc <= address <= highpc:
return DIE.attributes['DW_AT_name'].value
except KeyError: