more preparations for full DIE parsing:
[pyelftools.git] / elftools / dwarf / die.py
1 #-------------------------------------------------------------------------------
2 # elftools: dwarf/die.py
3 #
4 # DWARF Debugging Information Entry
5 #
6 # Eli Bendersky (eliben@gmail.com)
7 # This code is in the public domain
8 #-------------------------------------------------------------------------------
9 from collections import namedtuple
10
11 from ..common.ordereddict import OrderedDict
12 from ..common.utils import struct_parse, preserve_stream_pos
13
14
15 # Describes an attribute value in the DIE:
16 #
17 # form:
18 # The DW_FORM_* name of this attribute
19 #
20 # value:
21 # The value parsed from the section and translated accordingly to the form
22 # (e.g. for a DW_FORM_strp it's the actual string taken from the string table)
23 #
24 # raw_value:
25 # Raw value as parsed from the section - used for debugging and presentation
26 # (e.g. for a DW_FORM_strp it's the raw string offset into the table)
27 #
28 AttributeValue = namedtuple('AttributeValue', 'form value raw_value')
29
30
31 class DIE(object):
32 """ A DWARF debugging information entry. On creation, parses itself from
33 the stream. Each DIE is held by a CU.
34
35 Accessible attributes:
36
37 tag:
38 The DIE tag
39
40 length:
41 The size this DIE occupies in the section
42
43 attributes:
44 An ordered dictionary mapping attribute names to values. It's
45 ordered to enable both efficient name->value mapping and
46 preserve the order of attributes in the section
47 """
48 def __init__(self, cu, stream, offset):
49 """ cu:
50 CompileUnit object this DIE belongs to. Used to obtain context
51 information (structs, abbrev table, etc.)
52
53 stream, offset:
54 The stream and offset into it where this DIE's data is located
55 """
56 self.cu = cu
57 self.dwarfinfo = self.cu.dwarfinfo # get DWARFInfo context
58 self.stream = stream
59 self.offset = offset
60 self.attributes = OrderedDict()
61 self._parse_DIE()
62
63 def _parse_DIE(self):
64 """ Parses the DIE info from the section, based on the abbreviation
65 table of the CU
66 """
67 print self.offset, self.cu.structs.dwarf_format
68 structs = self.cu.structs
69
70 # A DIE begins with the abbreviation code. Read it and use it to
71 # obtain the abbrev declaration for this DIE.
72 # Note: here and elsewhere, preserve_stream_pos is used on operations
73 # that manipulate the stream by reading data from it.
74 #
75 abbrev_code = struct_parse(
76 structs.Dwarf_uleb128(''), self.stream, self.offset)
77 with preserve_stream_pos(self.stream):
78 abbrev = self.cu.get_abbrev_table().get_abbrev(abbrev_code)
79
80 print '**', abbrev_code, abbrev, abbrev.decl
81
82 # Guided by the attributes listed in the abbreviation declaration, parse
83 # values from the stream.
84 #
85 for name, form in abbrev.iter_attr_specs():
86 print '** parsing at stream + ', self.stream.tell()
87 raw_value = struct_parse(structs.Dwarf_dw_form[form], self.stream)
88 print '**', name, form, raw_value
89 #~ print structs.Dwarf_dw_form[form]
90
91