From 033b44fe666acf25f8a403d75e77b22da494c833 Mon Sep 17 00:00:00 2001 From: eliben Date: Mon, 19 Sep 2011 15:48:39 +0300 Subject: [PATCH] * take DWARF stuff from ELFFile * Currently DWARF format (32 or 64-bit) isn't handled correctly. see TODO --- elftools/common/utils.py | 5 +++-- elftools/dwarf/compileunit.py | 5 +++-- elftools/dwarf/dwarfinfo.py | 10 +++++++--- elftools/elf/elffile.py | 34 ++++++++++++++++++++++++++++++++++ z.py | 17 +++++++++++------ 5 files changed, 58 insertions(+), 13 deletions(-) diff --git a/elftools/common/utils.py b/elftools/common/utils.py index c099013..a36b3ec 100644 --- a/elftools/common/utils.py +++ b/elftools/common/utils.py @@ -6,7 +6,7 @@ # 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 @@ -39,4 +39,5 @@ def dwarf_assert(cond, msg=''): 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) + diff --git a/elftools/dwarf/compileunit.py b/elftools/dwarf/compileunit.py index 7791b86..5e133b0 100644 --- a/elftools/dwarf/compileunit.py +++ b/elftools/dwarf/compileunit.py @@ -9,9 +9,10 @@ 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 diff --git a/elftools/dwarf/dwarfinfo.py b/elftools/dwarf/dwarfinfo.py index 651c5da..5216bac 100644 --- a/elftools/dwarf/dwarfinfo.py +++ b/elftools/dwarf/dwarfinfo.py @@ -58,18 +58,22 @@ class DWARFInfo(object): 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 diff --git a/elftools/elf/elffile.py b/elftools/elf/elffile.py index 8704249..b1c2d81 100644 --- a/elftools/elf/elffile.py +++ b/elftools/elf/elffile.py @@ -14,6 +14,7 @@ from .sections import ( Section, StringTableSection, SymbolTableSection, NullSection, RelocationSection) from .segments import Segment, InterpSegment +from ..dwarf.dwarfinfo import DWARFInfo, DebugSectionLocator class ELFFile(object): @@ -97,6 +98,39 @@ 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): diff --git a/z.py b/z.py index 8ef75d2..6fc8ff6 100644 --- a/z.py +++ b/z.py @@ -14,17 +14,22 @@ stream = open('tests/testfiles/z.elf', 'rb') #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'] -- 2.30.2