from ..common.utils import struct_parse, preserve_stream_pos
-# AttributeValue - describes an attribute value in the DIE:
+# AttributeValue - describes an attribute value in the DIE:
#
# name:
# The name (DW_AT_*) of this attribute
-#
-# form:
+#
+# form:
# The DW_FORM_* name of this attribute
#
# value:
class DIE(object):
""" A DWARF debugging information entry. On creation, parses itself from
the stream. Each DIE is held by a CU.
-
+
Accessible attributes:
-
+
tag:
The DIE tag
-
+
size:
The size this DIE occupies in the section
-
+
offset:
The offset of this DIE in the stream
-
+
attributes:
- An ordered dictionary mapping attribute names to values. It's
+ An ordered dictionary mapping attribute names to values. It's
ordered to preserve the order of attributes in the section
-
+
has_children:
Specifies whether this DIE has children
-
+
abbrev_code:
The abbreviation code pointing to an abbreviation entry (not
- that this is for informational pusposes only - this object
+ that this is for informational pusposes only - this object
interacts with its abbreviation table transparently).
-
+
See also the public methods.
"""
def __init__(self, cu, stream, offset):
""" cu:
CompileUnit object this DIE belongs to. Used to obtain context
information (structs, abbrev table, etc.)
-
+
stream, offset:
The stream and offset into it where this DIE's data is located
"""
self.dwarfinfo = self.cu.dwarfinfo # get DWARFInfo context
self.stream = stream
self.offset = offset
-
+
self.attributes = OrderedDict()
self.tag = None
self.has_children = None
self.size = 0
self._children = []
self._parent = None
-
- self._parse_DIE()
-
+
+ self._parse_DIE()
+
def is_null(self):
""" Is this a null entry?
"""
return self.tag is None
-
+
def get_parent(self):
- """ The parent DIE of this DIE. None if the DIE has no parent (i.e. a
+ """ The parent DIE of this DIE. None if the DIE has no parent (i.e. a
top-level DIE).
"""
return self._parent
-
+
def iter_children(self):
""" Yield all children of this DIE
"""
return iter(self._children)
-
+
def iter_siblings(self):
""" Yield all siblings of this DIE
"""
#
def add_child(self, die):
self._children.append(die)
-
+
def set_parent(self, die):
self._parent = die
#------ PRIVATE ------#
-
+
def __repr__(self):
s = 'DIE %s, size=%s, has_chidren=%s\n' % (
self.tag, self.size, self.has_children)
for attrname, attrval in self.attributes.iteritems():
s += ' |%-18s: %s\n' % (attrname, attrval)
return s
-
+
def __str__(self):
return self.__repr__()
-
+
def _parse_DIE(self):
""" Parses the DIE info from the section, based on the abbreviation
table of the CU
"""
structs = self.cu.structs
-
- # A DIE begins with the abbreviation code. Read it and use it to
+
+ # A DIE begins with the abbreviation code. Read it and use it to
# obtain the abbrev declaration for this DIE.
# Note: here and elsewhere, preserve_stream_pos is used on operations
# that manipulate the stream by reading data from it.
#
self.abbrev_code = struct_parse(
structs.Dwarf_uleb128(''), self.stream, self.offset)
-
+
# This may be a null entry
if self.abbrev_code == 0:
self.size = self.stream.tell() - self.offset
return
-
+
with preserve_stream_pos(self.stream):
abbrev_decl = self.cu.get_abbrev_table().get_abbrev(
self.abbrev_code)
attr_offset = self.stream.tell()
raw_value = struct_parse(structs.Dwarf_dw_form[form], self.stream)
- value = self._translate_attr_value(form, raw_value)
+ value = self._translate_attr_value(form, raw_value)
self.attributes[name] = AttributeValue(
name=name,
form=form,
value=value,
raw_value=raw_value,
offset=attr_offset)
-
+
self.size = self.stream.tell() - self.offset
def _translate_attr_value(self, form, raw_value):
else:
value = raw_value
return value
-
+