started implementing debug-dump=frames-interp
authorEli Bendersky <eliben@gmail.com>
Thu, 15 Dec 2011 14:11:06 +0000 (16:11 +0200)
committerEli Bendersky <eliben@gmail.com>
Thu, 15 Dec 2011 14:11:06 +0000 (16:11 +0200)
elftools/dwarf/callframe.py
scripts/readelf.py
tests/test_callframe.py

index f656ee26d07aaaf7d43a81ba2fb02cc29e87332d..982157293e1cdc2d8d69e5392aa85f97b872cc71 100644 (file)
@@ -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':
index 454cba374fefbd91f8f26d0099e0e317f3d445a9..10b17acc6d85d193830a81626177d2b3e44dd479 100755 (executable)
@@ -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
         """
index 73e35d940d8582d574fd8233431aaa8f5657f4be..fa0ac8005f5dee6780ed52f2856b78ff8ada7626 100644 (file)
@@ -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