some API cleanups + added lineprogram
authorEli Bendersky <eliben@gmail.com>
Fri, 2 Dec 2011 07:58:47 +0000 (09:58 +0200)
committerEli Bendersky <eliben@gmail.com>
Fri, 2 Dec 2011 07:58:47 +0000 (09:58 +0200)
elftools/dwarf/descriptions.py
elftools/dwarf/dwarfinfo.py
elftools/dwarf/lineprogram.py [new file with mode: 0644]
elftools/elf/elffile.py

index ddb8f6bd1bc765c1f5c3b01ebb34679a221d8a33..57df8a4a323686ae49aff27d70eb2c3e790a07bc 100644 (file)
@@ -247,7 +247,6 @@ def _import_extra(attr, die, section_offset):
     else:
         # Relative offset to the current DIE's CU
         ref_die_offset = attr.value + die.cu.cu_offset
-    #print '&&&', attr.form, attr.value, ref_die_offset, ref_die_offset - section_offset
 
     # Now find the CU this DIE belongs to (since we have to find its abbrev
     # table). This is done by linearly scanning through all CUs, looking for
index db42017f3a929fb61b71e0431fabda58993e9955..8bda113eb1a16326caad82442225bc3a5c524dfc 100644 (file)
@@ -8,13 +8,13 @@
 #-------------------------------------------------------------------------------
 from collections import namedtuple
 
-from ..construct import CString
 from ..common.exceptions import DWARFError
 from ..common.utils import (struct_parse, dwarf_assert,
                             parse_cstring_from_stream)
 from .structs import DWARFStructs
 from .compileunit import CompileUnit
 from .abbrevtable import AbbrevTable
+from .lineprogram import LineProgram
 
 
 # Describes a debug section
@@ -74,21 +74,10 @@ class DWARFInfo(object):
         # Cache for abbrev tables: a dict keyed by offset
         self._abbrevtable_cache = {}
     
-    def num_CUs(self):
-        """ Number of compile units in the debug info
-        """
-        return len(self._CU)
-    
-    def get_CU(self, n):
-        """ Get the compile unit (CompileUnit object) at index #n
-        """
-        return self._CU[n]
-    
     def iter_CUs(self):
         """ Yield all the compile units (CompileUnit objects) in the debug info
         """
-        for i in range(self.num_CUs()):
-            yield self.get_CU(i)
+        return iter(self._CU)
     
     def get_abbrev_table(self, offset):
         """ Get an AbbrevTable from the given offset in the debug_abbrev
@@ -124,9 +113,8 @@ class DWARFInfo(object):
         """ Parse CU entries from debug_info.
         """
         offset = 0
-        section_boundary = self.debug_info_sec.size
         CUlist = []
-        while offset < section_boundary:
+        while offset < self.debug_info_sec.size:
             # Section 7.4 (32-bit and 64-bit DWARF Formats) of the DWARF spec v3
             # states that the first 32-bit word of the CU header determines 
             # whether the CU is represented with 32-bit or 64-bit DWARF format.
@@ -181,3 +169,38 @@ class DWARFInfo(object):
         """
         return 2 <= version <= 3
 
+    def _parse_line_programs(self):
+        """ Parse line programs from debug_line
+        """
+        offset = 0
+        lineprograms = []
+        while offset < self.debug_line_sec.size:
+            # Similarly to CU parsing, peek at the initial_length field of the
+            # header to figure out the DWARF format for it.
+            initial_length = struct_parse(
+                self.structs.Dwarf_uint32(''), self.debug_line_sec, offset)
+            dwarf_format = 64 if initial_length == 0xFFFFFFFF else 32
+
+            # Prepare the structs for this line program, based on its format
+            # and the default endianness. The address_size plays no role for
+            # line programs so we just give it a default value.
+            lineprog_structs = DWARFStructs(
+                little_endian=self.little_endian,
+                dwarf_format=dwarf_format,
+                address_size=4)
+
+            lineprog_header = struct_parse(
+                lineprog_structs.Dwarf_lineprog_header,
+                self.debug_line_sec.stream,
+                offset)
+
+            lineprograms.append(LineProgram(
+                header=lineprog_header,
+                dwarfinfo=self,
+                structs=lineprog_structs))
+
+            # Calculate the offset to the next line program (see DWARF 6.2.4)
+            offset += ( lineprog_header['unit_length'] +
+                        lineprog_structs.initial_length_field_size())
+        return lineprograms
+
diff --git a/elftools/dwarf/lineprogram.py b/elftools/dwarf/lineprogram.py
new file mode 100644 (file)
index 0000000..d865141
--- /dev/null
@@ -0,0 +1,23 @@
+#-------------------------------------------------------------------------------
+# elftools: dwarf/lineprogram.py
+#
+# DWARF line number program
+#
+# Eli Bendersky (eliben@gmail.com)
+# This code is in the public domain
+#-------------------------------------------------------------------------------
+
+
+class LineProgram(object):
+    def __init__(self, header, dwarfinfo, structs):
+        self.dwarfinfo = dwarfinfo
+        self.header = header
+        pass
+
+    #------ PRIVATE ------#
+    
+    def __getitem__(self, name):
+        """ Implement dict-like access to header entries
+        """
+        return self.header[name]
+
index a9ca631b92b7cb718040130f23528fff4b321a8e..065c06d35abdc24d07aa84526bf85a75121bb3a5 100644 (file)
@@ -105,6 +105,8 @@ class ELFFile(object):
     
     def has_dwarf_info(self):
         """ Check whether this file appears to have debugging information. 
+            We assume that if it has the debug_info section, it has all theother
+            required sections as well.
         """
         return bool(self.get_section_by_name('.debug_info'))