laziness FTW
authorEli Bendersky <eliben@gmail.com>
Fri, 2 Dec 2011 08:12:45 +0000 (10:12 +0200)
committerEli Bendersky <eliben@gmail.com>
Fri, 2 Dec 2011 08:12:45 +0000 (10:12 +0200)
.hgignore
elftools/dwarf/dwarfinfo.py
z.py

index f1dca2eae9821c4518262a820af6f76aee532ad3..ba42721965a39db5228cd077d942735652432f67 100644 (file)
--- a/.hgignore
+++ b/.hgignore
@@ -3,4 +3,5 @@ syntax: glob
 *.pyc
 .coverage
 htmlcov
+tags
 
index 8bda113eb1a16326caad82442225bc3a5c524dfc..64bf12364b12f3c518d0cbe1dada23a8dafea64d 100644 (file)
@@ -63,22 +63,30 @@ class DWARFInfo(object):
             dwarf_format=32,
             address_size=4)
         
-        # Populate the list with CUs found in debug_info. For each CU only its
-        # header is parsed immediately (the abbrev table isn't loaded before
-        # it's being referenced by one of the CU's DIEs). 
-        # Since there usually aren't many CUs in a single object, this
-        # shouldn't present a performance problem.
-        #
-        self._CU = self._parse_CUs()
+        # A list of CUs. Populated lazily when they're actually requested.
+        self._CUs = None
         
         # Cache for abbrev tables: a dict keyed by offset
         self._abbrevtable_cache = {}
+
+        # A list of parsed line programs. Populated lazily when the line
+        # programs are actually requested
+        self._lineprograms = None
     
     def iter_CUs(self):
         """ Yield all the compile units (CompileUnit objects) in the debug info
         """
-        return iter(self._CU)
-    
+        if self._CUs is None:
+            self._CUs = self._parse_CUs()
+        return iter(self._CUs)
+
+    def iter_line_programs(self):
+        """ Yield all the line programs (LineProgram ojects) in the debug info
+        """
+        if self._lineprograms is None:
+            self._lineprograms = self._parse_line_programs()
+        return iter(self._lineprograms)
+
     def get_abbrev_table(self, offset):
         """ Get an AbbrevTable from the given offset in the debug_abbrev
             section.
@@ -178,7 +186,9 @@ class DWARFInfo(object):
             # 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)
+                self.structs.Dwarf_uint32(''),
+                self.debug_line_sec.stream,
+                offset)
             dwarf_format = 64 if initial_length == 0xFFFFFFFF else 32
 
             # Prepare the structs for this line program, based on its format
diff --git a/z.py b/z.py
index 865d75b0e9cf416bc2558df2729b35f800d8cd72..4bf370970f5490757a51ea411a1b93256c471192 100644 (file)
--- a/z.py
+++ b/z.py
@@ -12,7 +12,7 @@ from elftools.elf.relocation import *
 # read a little-endian, 64-bit file
 es = ELFStructs(True, 64)
 
-stream = open('tests/testfiles/penalty_64.o.elf', 'rb')
+stream = open('tests/testfiles/exe_simple64.elf', 'rb')
 #stream = open('binfiles/z32.elf', 'rb')
 
 efile = ELFFile(stream)
@@ -22,13 +22,8 @@ print '===> %s sections!' % efile.num_sections()
 #~ print efile.has_dwarf_info()
 
 dwarfinfo = efile.get_dwarf_info()
-print dwarfinfo.get_string_from_table(0x4bc0)
-cu = dwarfinfo.get_CU(0)
 
-print cu.structs.Dwarf_dw_form['DW_FORM_strp'].parse('\x01\x00\x00\x00\x01\x00\x00\x00')
-print 'CU header', cu.header
-topdie = cu.get_top_DIE()
-
-print topdie
-dinfo_sec = efile.get_section_by_name('.debug_info')
+for lp in dwarfinfo.iter_line_programs():
+    print lp
+    print lp.header