From: Eli Bendersky Date: Thu, 15 Dec 2011 14:11:06 +0000 (+0200) Subject: started implementing debug-dump=frames-interp X-Git-Tag: v0.10~34 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=8670bb3ab522625714e04a9c7b5254c1144e779a;p=pyelftools.git started implementing debug-dump=frames-interp --- diff --git a/elftools/dwarf/callframe.py b/elftools/dwarf/callframe.py index f656ee2..9821572 100644 --- a/elftools/dwarf/callframe.py +++ b/elftools/dwarf/callframe.py @@ -240,7 +240,8 @@ class CFIEntry(object): 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 @@ -316,11 +317,10 @@ class CFIEntry(object): 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': diff --git a/scripts/readelf.py b/scripts/readelf.py index 454cba3..10b17ac 100755 --- a/scripts/readelf.py +++ b/scripts/readelf.py @@ -36,6 +36,7 @@ from elftools.elf.descriptions import ( ) 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) @@ -435,6 +436,8 @@ class ReadElf(object): 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) @@ -630,6 +633,46 @@ class ReadElf(object): 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 """ diff --git a/tests/test_callframe.py b/tests/test_callframe.py index 73e35d9..fa0ac80 100644 --- a/tests/test_callframe.py +++ b/tests/test_callframe.py @@ -118,6 +118,10 @@ class TestCallFrame(unittest.TestCase): 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