some refactoring. parsing a single DIE now appears to be working
diff --git a/elftools/dwarf/die.py b/elftools/dwarf/die.py
index fa1e5b8..f4fc2cb 100644
--- a/elftools/dwarf/die.py
+++ b/elftools/dwarf/die.py
@@ -12,7 +12,7 @@
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 @@
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 @@
""" 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 @@
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 4f2d848..b41b70c 100644
--- a/z.py
+++ b/z.py
@@ -20,12 +20,13 @@
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')