From f4a11d093375ccedce84b33eb998a6db9eec6d10 Mon Sep 17 00:00:00 2001 From: Eli Bendersky Date: Fri, 2 Dec 2011 09:58:47 +0200 Subject: [PATCH] some API cleanups + added lineprogram --- elftools/dwarf/descriptions.py | 1 - elftools/dwarf/dwarfinfo.py | 53 ++++++++++++++++++++++++---------- elftools/dwarf/lineprogram.py | 23 +++++++++++++++ elftools/elf/elffile.py | 2 ++ 4 files changed, 63 insertions(+), 16 deletions(-) create mode 100644 elftools/dwarf/lineprogram.py diff --git a/elftools/dwarf/descriptions.py b/elftools/dwarf/descriptions.py index ddb8f6b..57df8a4 100644 --- a/elftools/dwarf/descriptions.py +++ b/elftools/dwarf/descriptions.py @@ -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 diff --git a/elftools/dwarf/dwarfinfo.py b/elftools/dwarf/dwarfinfo.py index db42017..8bda113 100644 --- a/elftools/dwarf/dwarfinfo.py +++ b/elftools/dwarf/dwarfinfo.py @@ -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 index 0000000..d865141 --- /dev/null +++ b/elftools/dwarf/lineprogram.py @@ -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] + diff --git a/elftools/elf/elffile.py b/elftools/elf/elffile.py index a9ca631..065c06d 100644 --- a/elftools/elf/elffile.py +++ b/elftools/elf/elffile.py @@ -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')) -- 2.30.2