From 8eb8e7f6544e6f198a04598558451cac82b64189 Mon Sep 17 00:00:00 2001 From: eliben Date: Thu, 22 Sep 2011 13:17:07 +0300 Subject: [PATCH] some refactoring. parsing a single DIE now appears to be working --- elftools/dwarf/die.py | 43 ++++++++++++++++++++++++++++++++----------- z.py | 7 ++++--- 2 files changed, 36 insertions(+), 14 deletions(-) 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.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 4f2d848..b41b70c 100644 --- 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') -- 2.30.2