# Eli Bendersky (eliben@gmail.com)
# This code is in the public domain
#-------------------------------------------------------------------------------
-from .exceptions import ELFParseError, ELFError
+from .exceptions import ELFParseError, ELFError, DWARFError
from ..construct import ConstructError
def _assert_with_exception(cond, msg, exception_type):
if not cond:
- raise exception_type(msg)
\ No newline at end of file
+ raise exception_type(msg)
+
class CompileUnit(object):
- def __init__(self, header, cu_die):
+ def __init__(self, header, format_bits, cu_die):
self.header = header
- self.cu_die
+ self.format_bits = format_bits
+ self.cu_die = cu_die
def __getitem__(self, name):
""" Implement dict-like access to header entries
containers.
"""
offset = self.debug_info_loc.offset
- section_boundary = self.debug_info_loc.offset + self.debug_info_loc.length
+ print 'loc', self.debug_info_loc
+ section_boundary = self.debug_info_loc.offset + self.debug_info_loc.size
CUlist = []
while offset < section_boundary:
cu_header = struct_parse(
self.structs.Dwarf_CU_header, self.stream, offset)
- dwarf_assert(self._is_supported_version(cu_header['version']))
+ print offset, cu_header
+ dwarf_assert(
+ self._is_supported_version(cu_header['version']),
+ "Expected supported DWARF version. Got '%s'" % cu_header['version'])
CUlist.append(CompileUnit(cu_header, None))
# Compute the offset of the next CU in the section. The unit_length
# field of the CU header contains its size not including the length
# field itself.
offset = ( offset +
- cu['unit_length'] +
+ cu_header['unit_length'] +
self.initial_lenght_field_size())
return CUlist
Section, StringTableSection, SymbolTableSection, NullSection,
RelocationSection)
from .segments import Segment, InterpSegment
+from ..dwarf.dwarfinfo import DWARFInfo, DebugSectionLocator
class ELFFile(object):
for i in range(self.num_segments()):
yield self.get_segment(i)
+ def has_dwarf_info(self):
+ """ Check whether this file appears to have debugging information.
+ """
+ return bool(self.get_section_by_name('.debug_info'))
+
+ def get_dwarf_info(self):
+ """ Return a DWARFInfo object representing the debugging information in
+ this file.
+ """
+ # Expect has_dwarf_info that was called, so at least .debug_info is
+ # present. Check also the presence of other must-have debug sections.
+ #
+ debug_sections = {}
+ for secname in ('.debug_info', '.debug_abbrev', '.debug_str',
+ '.debug_line'):
+ section = self.get_section_by_name(secname)
+ elf_assert(
+ section is not None,
+ "Expected to find DWARF section '%s' in the file" % (
+ secname))
+ debug_sections[secname] = DebugSectionLocator(
+ offset=section['sh_offset'],
+ size=section['sh_size'])
+
+ return DWARFInfo(
+ stream=self.stream,
+ little_endian=self.little_endian,
+ dwarfclass=self.elfclass,
+ debug_info_loc=debug_sections['.debug_info'],
+ debug_abbrev_loc=debug_sections['.debug_abbrev'],
+ debug_str_loc=debug_sections['.debug_str'],
+ debug_line_loc=debug_sections['.debug_line'])
+
#-------------------------------- PRIVATE --------------------------------#
def __getitem__(self, name):
#stream = open('binfiles/z32.elf', 'rb')
efile = ELFFile(stream)
-
+print efile.elfclass, efile.little_endian
print '===> %s sections!' % efile.num_sections()
-print efile.get_section_by_name('.debug_info').name
+print efile.has_dwarf_info()
+
+print efile.get_dwarf_info()
+
+
+#~ print efile.get_section_by_name('.debug_info').name
#~ print '===> %s segments!' % efile.num_segments()
-for sec in efile.iter_sections():
- print type(sec), sec.name
- if isinstance(sec, SymbolTableSection):
- print ' linked string table:', sec.stringtable.name
+#~ for sec in efile.iter_sections():
+ #~ print type(sec), sec.name
+ #~ if isinstance(sec, SymbolTableSection):
+ #~ print ' linked string table:', sec.stringtable.name
#~ for seg in efile.iter_segments():
#~ print type(seg), seg['p_type'], seg['p_offset']