* take DWARF stuff from ELFFile
authoreliben <devnull@localhost>
Mon, 19 Sep 2011 12:48:39 +0000 (15:48 +0300)
committereliben <devnull@localhost>
Mon, 19 Sep 2011 12:48:39 +0000 (15:48 +0300)
* Currently DWARF format (32 or 64-bit) isn't handled correctly. see TODO

elftools/common/utils.py
elftools/dwarf/compileunit.py
elftools/dwarf/dwarfinfo.py
elftools/elf/elffile.py
z.py

index c0990137bda3b9b43288b9f5f16b01952dead43f..a36b3ec3e6a014ce83e051273837563525965097 100644 (file)
@@ -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)
+
index 7791b8633170aefe49b5e7b88ed99e442c061b85..5e133b0a507a526ca40fb04262a25e363ae390c1 100644 (file)
@@ -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
index 651c5da31a79f5f506436ce0f66b2708584c195f..5216bac2c4327feddaa1a1f847ea8467656ffd18 100644 (file)
@@ -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
         
index 8704249088f4a28cc8f49c67957c463cabb030e8..b1c2d81e7aaed9c4e65258a14cdd0f551ea74e6f 100644 (file)
@@ -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 8ef75d212c163d3bccbd339ffaa084714b223852..6fc8ff6d739a1ad3c3db6d82bd98389f93b27868 100644 (file)
--- 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']