blob: 44ccdd5e5a277c43dda1df75ac8eb5324463b6d1 [file] [log] [blame]
#-------------------------------------------------------------------------------
# elftools: dwarf/abbrevtable.py
#
# DWARF abbreviation table
#
# Eli Bendersky (eliben@gmail.com)
# This code is in the public domain
#-------------------------------------------------------------------------------
from ..common.utils import struct_parse, dwarf_assert
class AbbrevTable(object):
""" Represents a DWARF abbreviation table.
"""
def __init__(self, structs, stream, offset):
""" Create new abbreviation table. Parses the actual table from the
stream and stores it internally.
structs:
A DWARFStructs instance for parsing the data
stream, offset:
The stream and offset into the stream where this abbreviation
table lives.
"""
self.structs = structs
self.stream = stream
self.offset = offset
self._abbrev_map = self._parse_abbrev_table()
def get_abbrev(self, code):
""" Get the AbbrevDecl for a given code. Raise KeyError if no
declaration for this code exists.
"""
return AbbrevDecl(code, self._abbrev_map[code])
def _parse_abbrev_table(self):
""" Parse the abbrev table from the stream
"""
map = {}
self.stream.seek(self.offset)
while True:
decl_code = struct_parse(
struct=self.structs.Dwarf_uleb128(''),
stream=self.stream)
if decl_code == 0:
break
declaration = struct_parse(
struct=self.structs.Dwarf_abbrev_declaration,
stream=self.stream)
map[decl_code] = declaration
return map
class AbbrevDecl(object):
""" Wraps a parsed abbreviation declaration, exposing its fields with
dict-like access, and adding some convenience methods.
The abbreviation declaration represents an "entry" that points to it.
"""
def __init__(self, code, decl):
self.code = code
self.decl = decl
def has_children(self):
""" Does the entry have children?
"""
return self['children_flag'] == 'DW_CHILDREN_yes'
def iter_attr_specs(self):
""" Iterate over the attribute specifications for the entry. Yield
(name, form) pairs.
"""
for attr_spec in self['attr_spec']:
yield attr_spec.name, attr_spec.form
def __getitem__(self, entry):
return self.decl[entry]