some refactoring. parsing a single DIE now appears to be working
authoreliben <devnull@localhost>
Thu, 22 Sep 2011 10:17:07 +0000 (13:17 +0300)
committereliben <devnull@localhost>
Thu, 22 Sep 2011 10:17:07 +0000 (13:17 +0300)
elftools/dwarf/die.py
z.py

index fa1e5b84bd76e9df3817f70ac718a12ff7dfcaa7..f4fc2cb01d862268531ec64f0e96e7ba4a1cfd3f 100644 (file)
@@ -12,7 +12,7 @@ from ..common.ordereddict import OrderedDict
 from ..common.utils import struct_parse, preserve_stream_pos
 
 
-# Describes an attribute value in the DIE: 
+# AttributeValue - describes an attribute value in the DIE: 
 #
 # form: 
 #   The DW_FORM_* name of this attribute
@@ -37,13 +37,16 @@ class DIE(object):
             tag:
                 The DIE tag
         
-            length:
+            size:
                 The size this DIE occupies in the section
             
             attributes:
                 An ordered dictionary mapping attribute names to values. It's 
                 ordered to enable both efficient name->value mapping and
                 preserve the order of attributes in the section
+            
+            has_children:
+                Specifies whether this DIE has children
     """
     def __init__(self, cu, stream, offset):
         """ cu:
@@ -64,7 +67,6 @@ class DIE(object):
         """ Parses the DIE info from the section, based on the abbreviation
             table of the CU
         """
-        print self.offset, self.cu.structs.dwarf_format
         structs = self.cu.structs
         
         # A DIE begins with the abbreviation code. Read it and use it to 
@@ -75,17 +77,36 @@ class DIE(object):
         abbrev_code = struct_parse(
             structs.Dwarf_uleb128(''), self.stream, self.offset)
         with preserve_stream_pos(self.stream):
-            abbrev = self.cu.get_abbrev_table().get_abbrev(abbrev_code)
-        
-        print '**', abbrev_code, abbrev, abbrev.decl
+            abbrev_decl = self.cu.get_abbrev_table().get_abbrev(abbrev_code)
+        self.has_children = abbrev_decl.has_children()
         
         # Guided by the attributes listed in the abbreviation declaration, parse
         # values from the stream.
         #
-        for name, form in abbrev.iter_attr_specs():
-            print '** parsing at stream + ', self.stream.tell()
+        for name, form in abbrev_decl.iter_attr_specs():
             raw_value = struct_parse(structs.Dwarf_dw_form[form], self.stream)
-            print '**', name, form, raw_value
-            #~ print structs.Dwarf_dw_form[form]
-
+            value = self._translate_attr_value(form, raw_value)            
+            self.attributes[name] = AttributeValue(form, value, raw_value)
+        
+        self.size = self.stream.tell() - self.offset
 
+    def _translate_attr_value(self, form, raw_value):
+        """ Translate a raw attr value according to the form
+        """
+        value = None
+        if form == 'DW_FORM_strp':
+            with preserve_stream_pos(self.stream):
+                value = self.dwarfinfo.get_string_from_table(raw_value)
+        elif form == 'DW_FORM_flag':
+            value = not raw_value == 0
+        elif form == 'DW_FORM_indirect':
+            form = raw_value
+            raw_value = struct_parse(
+                structs.Dwarf_dw_form[form], self.stream)
+            # Let's hope this doesn't get too deep :-)
+            return self._translate_attr_value(form, raw_value)
+        else:
+            value = raw_value
+        return value
+        
+         
\ No newline at end of file
diff --git a/z.py b/z.py
index 4f2d848079c690bbe3d3b5e1a4ae5d8e954c95c0..b41b70c51b22ca21c0bf7db8e460e9627c917995 100644 (file)
--- a/z.py
+++ b/z.py
@@ -20,12 +20,13 @@ print '===> %s sections!' % efile.num_sections()
 print efile.has_dwarf_info()
 
 dwarfinfo = efile.get_dwarf_info()
-
-print dwarfinfo.get_string_from_table(126)
+tt = dwarfinfo.structs.Dwarf_dw_form['DW_FORM_block1'].parse('\x03\x12\x34\x46')
 
 cu = dwarfinfo.get_CU(1)
 print 'CU header', cu.header
-print cu.get_top_DIE()
+topdie = cu.get_top_DIE()
+
+print topdie.size, topdie.attributes
 
 #~ print dwarfinfo.structs.Dwarf_abbrev_entry.parse('\x13\x01\x01\x03\x50\x04\x00\x00')