else: # FDE
cie = self.cie
cie_decoded_table = cie.get_decoded()
- cur_line = cie_decoded_table.table[-1]
+ last_line_in_CIE = cie_decoded_table.table[-1]
+ cur_line = last_line_in_CIE
cur_line['pc'] = self['initial_location']
reg_order = cie_decoded_table.reg_order
dwarf_assert(
isinstance(self, FDE),
'%s instruction must be in a FDE' % name)
- last_line_in_CIE = self.cie.get_decoded().table[-1]
dwarf_assert(
instr.args[0] in last_line_in_CIE,
'%s: can not find register in CIE')
- cur_line[instr.args[0]] = last_line_in_CIE
+ cur_line[instr.args[0]] = last_line_in_CIE[instr.args[0]]
elif name == 'DW_CFA_remember_state':
line_stack.append(cur_line)
elif name == 'DW_CFA_restore_state':
)
from elftools.dwarf.dwarfinfo import DWARFInfo
from elftools.dwarf.descriptions import (
+ describe_reg_name,
describe_attr_value, set_global_machine_arch, describe_CFI_instructions)
from elftools.dwarf.constants import (
DW_LNS_copy, DW_LNS_set_file, DW_LNE_define_file)
self._dump_debug_line_programs()
elif dump_what == 'frames':
self._dump_debug_frames()
+ elif dump_what == 'frames-interp':
+ self._dump_debug_frames_interp()
else:
self._emitline('debug dump not yet supported for "%s"' % dump_what)
self._emit(describe_CFI_instructions(entry))
self._emitline()
+ def _dump_debug_frames_interp(self):
+ """ Dump the interpreted (decoded) frame information from .debug_frame
+ """
+ if not self._dwarfinfo.has_CFI():
+ return
+
+ self._emitline('Contents of the .debug_frame section:')
+
+ for entry in self._dwarfinfo.CFI_entries():
+ if isinstance(entry, CIE):
+ self._emitline('\n%08x %08x %08x CIE "%s" cf=%d df=%d ra=%d' % (
+ entry.offset,
+ entry['length'],
+ entry['CIE_id'],
+ entry['augmentation'],
+ entry['code_alignment_factor'],
+ entry['data_alignment_factor'],
+ entry['return_address_register']))
+ else: # FDE
+ self._emitline('\n%08x %08x %08x FDE cie=%08x pc=%08x..%08x' % (
+ entry.offset,
+ entry['length'],
+ entry['CIE_pointer'],
+ entry.cie.offset,
+ entry['initial_location'],
+ entry['initial_location'] + entry['address_range']))
+
+ # Print the heading row for the decoded table
+ self._emit(' LOC')
+ self._emit(' ' if entry.structs.address_size == 4 else ' ')
+ self._emit('CFA ')
+
+ decoded_table = entry.get_decoded()
+ for regnum in decoded_table.reg_order:
+ self._emit('%-6s' % describe_reg_name(regnum))
+ self._emitline('ra ')
+
+
+
+
def _emit(self, s=''):
""" Emit an object to output
"""
self.assertEqual(decoded_FDE.table[5]['pc'], 0x11223344 + 20)
self.assertEqual(decoded_FDE.table[5][4].type, RegisterRule.OFFSET)
self.assertEqual(decoded_FDE.table[5][4].arg, -12)
+ self.assertEqual(decoded_FDE.table[6]['pc'], 0x11223344 + 64)
+ self.assertEqual(decoded_FDE.table[9]['pc'], 0x11223344 + 76)
+ self.assertEqual(decoded_FDE.table[9][6].type, RegisterRule.SAME_VALUE)
+ self.assertEqual(decoded_FDE.table[10]['pc'], 0x11223344 + 80)
def test_describe_CFI_instructions(self):
# The data here represents a single CIE