some API cleanups + added lineprogram
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 @@
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 @@
# 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 @@
""" 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 @@
"""
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 @@
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'))