From 80638fb97cc933ea06761f5bbcd5af41803a76d8 Mon Sep 17 00:00:00 2001 From: Eli Bendersky Date: Fri, 2 Dec 2011 10:12:45 +0200 Subject: [PATCH] laziness FTW --- .hgignore | 1 + elftools/dwarf/dwarfinfo.py | 30 ++++++++++++++++++++---------- z.py | 13 ++++--------- 3 files changed, 25 insertions(+), 19 deletions(-) diff --git a/.hgignore b/.hgignore index f1dca2e..ba42721 100644 --- a/.hgignore +++ b/.hgignore @@ -3,4 +3,5 @@ syntax: glob *.pyc .coverage htmlcov +tags diff --git a/elftools/dwarf/dwarfinfo.py b/elftools/dwarf/dwarfinfo.py index 8bda113..64bf123 100644 --- a/elftools/dwarf/dwarfinfo.py +++ b/elftools/dwarf/dwarfinfo.py @@ -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 865d75b..4bf3709 100644 --- 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 -- 2.30.2