1 #-------------------------------------------------------------------------------
2 # elftools: dwarf/die.py
4 # DWARF Debugging Information Entry
6 # Eli Bendersky (eliben@gmail.com)
7 # This code is in the public domain
8 #-------------------------------------------------------------------------------
9 from collections
import namedtuple
11 from ..common
.ordereddict
import OrderedDict
12 from ..common
.utils
import struct_parse
, preserve_stream_pos
15 # Describes an attribute value in the DIE:
18 # The DW_FORM_* name of this attribute
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)
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)
28 AttributeValue
= namedtuple('AttributeValue', 'form value raw_value')
32 """ A DWARF debugging information entry. On creation, parses itself from
33 the stream. Each DIE is held by a CU.
35 Accessible attributes:
41 The size this DIE occupies in the section
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
48 def __init__(self
, cu
, stream
, offset
):
50 CompileUnit object this DIE belongs to. Used to obtain context
51 information (structs, abbrev table, etc.)
54 The stream and offset into it where this DIE's data is located
57 self
.dwarfinfo
= self
.cu
.dwarfinfo
# get DWARFInfo context
60 self
.attributes
= OrderedDict()
64 """ Parses the DIE info from the section, based on the abbreviation
67 print self
.offset
, self
.cu
.structs
.dwarf_format
68 structs
= self
.cu
.structs
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.
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
)
80 print '**', abbrev_code
, abbrev
, abbrev
.decl
82 # Guided by the attributes listed in the abbreviation declaration, parse
83 # values from the stream.
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]