建立 MAG160C 逆向工程交接仓库
This commit is contained in:
@@ -0,0 +1,90 @@
|
||||
#-------------------------------------------------------------------------------
|
||||
# elftools: dwarf/abbrevtable.py
|
||||
#
|
||||
# DWARF abbreviation table
|
||||
#
|
||||
# Eli Bendersky (eliben@gmail.com)
|
||||
# This code is in the public domain
|
||||
#-------------------------------------------------------------------------------
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import IO, TYPE_CHECKING, Any
|
||||
|
||||
from ..common.utils import struct_parse
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from collections.abc import Iterator
|
||||
|
||||
from ..construct.lib.container import Container
|
||||
from .structs import DWARFStructs
|
||||
|
||||
|
||||
class AbbrevTable:
|
||||
""" Represents a DWARF abbreviation table.
|
||||
"""
|
||||
__slots__ = ('structs', 'stream', 'offset', '_abbrev_map')
|
||||
def __init__(self, structs: DWARFStructs, stream: IO[bytes], offset: int) -> None:
|
||||
""" 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: int) -> AbbrevDecl:
|
||||
""" Get the AbbrevDecl for a given code. Raise KeyError if no
|
||||
declaration for this code exists.
|
||||
"""
|
||||
return self._abbrev_map[code]
|
||||
|
||||
def _parse_abbrev_table(self) -> dict[int, AbbrevDecl]:
|
||||
""" Parse the abbrev table from the stream
|
||||
"""
|
||||
map: dict[int, AbbrevDecl] = {}
|
||||
self.stream.seek(self.offset)
|
||||
while True:
|
||||
decl_code: int = struct_parse(
|
||||
struct=self.structs.the_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] = AbbrevDecl(decl_code, declaration)
|
||||
return map
|
||||
|
||||
|
||||
class AbbrevDecl:
|
||||
""" 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.
|
||||
"""
|
||||
__slots__ = ('code', 'decl', '_has_children')
|
||||
def __init__(self, code: int, decl: Container) -> None:
|
||||
self.code = code
|
||||
self.decl = decl
|
||||
self._has_children = decl['children_flag'] == 'DW_CHILDREN_yes'
|
||||
|
||||
def has_children(self) -> bool:
|
||||
return self._has_children
|
||||
|
||||
def iter_attr_specs(self) -> Iterator[tuple[str, str]]:
|
||||
""" 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: str) -> Any:
|
||||
return self.decl[entry]
|
||||
Reference in New Issue
Block a user