after cleanup and fixing, it actually shows signs of life
authorEli Bendersky <eliben@gmail.com>
Sat, 3 Dec 2011 14:33:54 +0000 (16:33 +0200)
committerEli Bendersky <eliben@gmail.com>
Sat, 3 Dec 2011 14:33:54 +0000 (16:33 +0200)
elftools/dwarf/dwarfinfo.py
elftools/dwarf/lineprogram.py
z.py

index 8ebb47df6ab6a136f51002214efb97b29a3b8a6b..bb073e0d48c9cdfafe945fe39d36fa4c5674a926 100644 (file)
@@ -114,7 +114,7 @@ class DWARFInfo(object):
         top_DIE = CU.get_top_DIE()
         if 'DW_AT_stmt_list' in top_DIE.attributes:
             return self._parse_line_program_at_offset(
-                    top_DIE.attributes['DW_AT_stmt_list'], CU.structs)
+                    top_DIE.attributes['DW_AT_stmt_list'].value, CU.structs)
         else:
             return None
         
@@ -188,16 +188,16 @@ class DWARFInfo(object):
         lineprog_header = struct_parse(
             structs.Dwarf_lineprog_header,
             self.debug_line_sec.stream,
-            offset)
+            debug_line_offset)
 
         # Calculate the offset to the next line program (see DWARF 6.2.4)
-        end_offset = (  offset + lineprog_header['unit_length'] +
-                        lineprog_structs.initial_length_field_size())
+        end_offset = (  debug_line_offset + lineprog_header['unit_length'] +
+                        structs.initial_length_field_size())
 
         return LineProgram(
             header=lineprog_header,
             dwarfinfo=self,
-            structs=lineprog_structs,
+            structs=structs,
             program_start_offset=self.debug_line_sec.stream.tell(),
             program_end_offset=end_offset)
 
index 43d8f90304fec7953d60592544990defaefc7817..11cd57f30a5c1287ef0f23013f09e4b8a51a3db2 100644 (file)
@@ -6,6 +6,8 @@
 # Eli Bendersky (eliben@gmail.com)
 # This code is in the public domain
 #-------------------------------------------------------------------------------
+import copy
+
 from ..common.utils import struct_parse
 from .constants import *
 
@@ -28,6 +30,13 @@ class LineState(object):
         self.epilogue_begin = False
         self.isa = 0
 
+    def __repr__(self):
+        a = ['<LineState %x:' % id(self)]
+        a.append('  address = 0x%x' % self.address)
+        for attr in ('file', 'line', 'column', 'is_stmt', 'basic_block',
+                     'end_sequence', 'prologue_end', 'epilogue_begin', 'isa'):
+            a.append('  %s = %s' % (attr, getattr(self, attr)))
+        return '\n'.join(a) + '>\n'
 
 class LineProgram(object):
     """ Builds a "line table", which is essentially the matrix described
@@ -85,7 +94,7 @@ class LineProgram(object):
             # Used by instructions that have to add the current state to the
             # line table. After adding, some state registers have to be
             # cleared.
-            linetable.append(state)
+            linetable.append(copy.copy(state))
             state.basic_block = False
             state.prologue_end = False
             state.epilogue_begin = False
@@ -93,7 +102,7 @@ class LineProgram(object):
         offset = self.program_start_offset
         while offset < self.program_end_offset:
             opcode = struct_parse(
-                self.structs.Dwarf_uint8, 
+                self.structs.Dwarf_uint8('')
                 self.stream,
                 offset)
 
@@ -107,42 +116,50 @@ class LineProgram(object):
                 adjusted_opcode = opcode - self['opcode_base']
                 state.address += ((adjusted_opcode / self['line_range']) *
                                   self['minimum_instruction_length'])
-                self.line += (self['line_base'] + 
+                state.line += (self['line_base'] + 
                               adjusted_opcode % self['line_range'])
                 add_state_to_table()
             elif opcode == 0:
                 # Extended opcode: start with a zero byte, followed by
                 # instruction size and the instruction itself.
-                inst_len = struct_parse(self.Dwarf_uleb128, self.stream)
-                ex_opcode = struct_parse(self.Dwarf_uint8, self.stream)
+                inst_len = struct_parse(self.structs.Dwarf_uleb128(''),
+                                        self.stream)
+                ex_opcode = struct_parse(self.structs.Dwarf_uint8(''),
+                                         self.stream)
 
                 if ex_opcode == DW_LNE_end_sequence:
                     state.end_sequence = True
-                    add_state_to_table(state)
-                    state = LineState() # reset state
+                    add_state_to_table()
+                    # reset state
+                    state = LineState(self.header['default_is_stmt']) 
                 elif ex_opcode == DW_LNE_set_address:
-                    operand = struct_parse(self.Dwarf_target_addr, self.stream)
+                    operand = struct_parse(self.structs.Dwarf_target_addr(''),
+                                           self.stream)
                     state.address = operand
                 elif ex_opcode == DW_LNE_define_file:
-                    operand = struct_parse(self.Dwarf_lineprog_file_entry,
-                                           self.stream)
+                    operand = struct_parse(
+                        self.structs.Dwarf_lineprog_file_entry, self.stream)
                     self['file_entry'].append(operand)
             else: # 0 < opcode < opcode_base
                 # Standard opcode
                 if opcode == DW_LNS_copy:
                     add_state_to_table()
                 elif opcode == DW_LNS_advance_pc:
-                    operand = struct_parse(self.Dwarf_uleb128, self.stream)
+                    operand = struct_parse(self.structs.Dwarf_uleb128(''),
+                                           self.stream)
                     state.address += (
                         operand * self.header['minimum_instruction_length'])
                 elif opcode == DW_LNS_advance_line:
-                    operand = struct_parse(self.Dwarf_sleb128, self.stream)
+                    operand = struct_parse(self.structs.Dwarf_sleb128(''),
+                                           self.stream)
                     state.line += operand
                 elif opcode == DW_LNS_set_file:
-                    operand = struct_parse(self.Dwarf_sleb128, self.stream)
+                    operand = struct_parse(self.structs.Dwarf_sleb128(''),
+                                           self.stream)
                     state.file = operand
                 elif opcode == DW_LNS_set_column:
-                    operand = struct_parse(self.Dwarf_uleb128, self.stream)
+                    operand = struct_parse(self.structs.Dwarf_uleb128(''),
+                                           self.stream)
                     state.column = operand
                 elif opcode == DW_LNS_negate_stmt:
                     state.is_stmt = not state.is_stmt
@@ -153,16 +170,20 @@ class LineProgram(object):
                     state.address += ((adjusted_opcode / self['line_range']) *
                                       self['minimum_instruction_length'])
                 elif opcode == DW_LNS_fixed_advance_pc:
-                    operand = struct_parse(self.Dwarf_uint16, self.stream)
+                    operand = struct_parse(self.structs.Dwarf_uint16,
+                                           self.stream)
                     state.address += operand
                 elif opcode == DW_LNS_set_prologue_end:
                     state.prologue_end = True
                 elif opcode == DW_LNS_set_epilogue_begin:
                     state.epilogue_begin = True
                 elif opcode == DW_LNS_set_isa:
-                    operand = struct_parse(self.Dwarf_uleb128, self.stream)
+                    operand = struct_parse(self.structs.Dwarf_uleb128(''),
+                                           self.stream)
                     state.isa = operand
                 else:
                     dwarf_assert(False, 'Invalid standard line program opcode: %s' % (
                         opcode,))
+            offset = self.stream.tell()
+        return linetable
 
diff --git a/z.py b/z.py
index f60394881669285a4782eb4c0a44a26784d7979e..fed0ab7b933e681ec7a87a81b8c01ba4ebe45769 100644 (file)
--- a/z.py
+++ b/z.py
@@ -22,7 +22,13 @@ print '===> %s sections!' % efile.num_sections()
 #~ print efile.has_dwarf_info()
 
 dwarfinfo = efile.get_dwarf_info()
+CUs = list(dwarfinfo.iter_CUs())
+print 'num CUs:', len(CUs)
+print 'first CU:', CUs[0]
 
+lp = dwarfinfo.line_program_for_CU(CUs[0])
+print 'lp:', lp, lp.header
+print 'linetable:', lp.get_line_table()
 #for lp in dwarfinfo.iter_line_programs():
     #print lp
     #print lp.header