renamed 'location expression' to the more general 'dwarf expression'
[pyelftools.git] / elftools / dwarf / abbrevtable.py
1 #-------------------------------------------------------------------------------
2 # elftools: dwarf/abbrevtable.py
3 #
4 # DWARF abbreviation table
5 #
6 # Eli Bendersky (eliben@gmail.com)
7 # This code is in the public domain
8 #-------------------------------------------------------------------------------
9 from ..common.utils import struct_parse, dwarf_assert
10
11
12 class AbbrevTable(object):
13 """ Represents a DWARF abbreviation table.
14 """
15 def __init__(self, structs, stream, offset):
16 """ Create new abbreviation table. Parses the actual table from the
17 stream and stores it internally.
18
19 structs:
20 A DWARFStructs instance for parsing the data
21
22 stream, offset:
23 The stream and offset into the stream where this abbreviation
24 table lives.
25 """
26 self.structs = structs
27 self.stream = stream
28 self.offset = offset
29
30 self._abbrev_map = self._parse_abbrev_table()
31
32 def get_abbrev(self, code):
33 """ Get the AbbrevDecl for a given code. Raise KeyError if no
34 declaration for this code exists.
35 """
36 return AbbrevDecl(code, self._abbrev_map[code])
37
38 def _parse_abbrev_table(self):
39 """ Parse the abbrev table from the stream
40 """
41 map = {}
42 self.stream.seek(self.offset)
43 while True:
44 decl_code = struct_parse(
45 struct=self.structs.Dwarf_uleb128(''),
46 stream=self.stream)
47 if decl_code == 0:
48 break
49 declaration = struct_parse(
50 struct=self.structs.Dwarf_abbrev_declaration,
51 stream=self.stream)
52 map[decl_code] = declaration
53 return map
54
55
56 class AbbrevDecl(object):
57 """ Wraps a parsed abbreviation declaration, exposing its fields with
58 dict-like access, and adding some convenience methods.
59
60 The abbreviation declaration represents an "entry" that points to it.
61 """
62 def __init__(self, code, decl):
63 self.code = code
64 self.decl = decl
65
66 def has_children(self):
67 """ Does the entry have children?
68 """
69 return self['children_flag'] == 'DW_CHILDREN_yes'
70
71 def iter_attr_specs(self):
72 """ Iterate over the attribute specifications for the entry. Yield
73 (name, form) pairs.
74 """
75 for attr_spec in self['attr_spec']:
76 yield attr_spec.name, attr_spec.form
77
78 def __getitem__(self, entry):
79 return self.decl[entry]
80