建立 MAG160C 逆向工程交接仓库

This commit is contained in:
ZXCLI
2026-08-11 19:08:44 +08:00
commit 8409b27ba3
3135 changed files with 534408 additions and 0 deletions
@@ -0,0 +1,192 @@
"""
Various containers.
"""
from __future__ import annotations
from collections.abc import MutableMapping
from functools import wraps
from pprint import pformat
from typing import IO, TYPE_CHECKING, Any, Literal, overload
if TYPE_CHECKING:
from collections.abc import Callable, Iterator
from typing import Concatenate, ParamSpec, TypeVar
from typing_extensions import Self # 3.11+
from ..core import Construct
from .hex import HexString
_P = ParamSpec('_P')
_R = TypeVar('_R')
_T = TypeVar('_T')
__all__ = [
"recursion_lock",
"Container", "FlagsContainer", "ListContainer", "LazyContainer",
]
def recursion_lock(
retval: _R,
lock_name: str = "__recursion_lock__",
) -> Callable[[Callable[Concatenate[Any, _P], _T]], Callable[Concatenate[Any, _P], _T | _R]]:
def decorator(
func: Callable[Concatenate[Any, _P], _T],
) -> Callable[Concatenate[Any, _P], _T | _R]:
@wraps(func)
def wrapper(self: Any, *args: _P.args, **kw: _P.kwargs) -> _T | _R:
if getattr(self, lock_name, False):
return retval
setattr(self, lock_name, True)
try:
return func(self, *args, **kw)
finally:
setattr(self, lock_name, False)
return wrapper
return decorator
class Container(MutableMapping[str, Any]):
"""
A generic container of attributes.
Containers are the common way to express parsed data.
"""
def __init__(self, **kw: Any) -> None:
self.__dict__ = kw
# The core dictionary interface.
@overload
def __getitem__(self, name: Literal[
"ch_addralign", "ch_size",
"length",
"n_descsz", "n_offset", "n_namesz",
"sh_addralign", "sh_flags", "sh_size",
"bloom_size", "nbuckets", "nchains",
]) -> int: ...
@overload
def __getitem__(self, name: Literal[
"ch_type",
"sh_type",
"n_name", "n_type",
"tag", "vendor_name",
]) -> str: ...
@overload
def __getitem__(self, name: Literal[
"buckets", "chains",
]) -> list[int]: ...
@overload
def __getitem__(self, name: str) -> Any: ...
def __getitem__(self, name: str) -> Any:
return self.__dict__[name]
def __delitem__(self, name: str) -> None:
del self.__dict__[name]
def __setitem__(self, name: str, value: Any) -> None:
self.__dict__[name] = value
def __iter__(self) -> Iterator[str]:
return iter(self.__dict__)
def __len__(self) -> int:
return len(self.__dict__.keys())
# Copy interface.
def copy(self) -> Self:
return self.__class__(**self.__dict__)
__copy__ = copy
def __repr__(self) -> str:
return "%s(%s)" % (self.__class__.__name__, repr(self.__dict__))
def __str__(self) -> str:
return "%s(%s)" % (self.__class__.__name__, str(self.__dict__))
if TYPE_CHECKING:
# elftools.construct.debug Probe.printout()
stream_position: int
following_stream_data: str | HexString
context: Container
stack: ListContainer
# allow arbitray attributes
def __setattr__(self, name: str, value: object) -> None: ...
def __getattr__(self, name: str) -> Any: ...
class FlagsContainer(Container):
"""
A container providing pretty-printing for flags.
Only set flags are displayed.
"""
@recursion_lock("<...>")
def __str__(self) -> str:
d = dict((k, self[k]) for k in self
if self[k] and not k.startswith("_"))
return "%s(%s)" % (self.__class__.__name__, pformat(d))
class ListContainer(list[Any]):
"""
A container for lists.
"""
__slots__ = ("__recursion_lock__",)
@recursion_lock("[...]")
def __str__(self) -> str:
return pformat(self)
class LazyContainer:
__slots__ = ("subcon", "stream", "pos", "context", "_value")
def __init__(self, subcon: Construct, stream: IO[bytes], pos: int, context: Container) -> None:
self.subcon = subcon
self.stream = stream
self.pos = pos
self.context = context
self._value = NotImplemented
def __eq__(self, other: object) -> bool:
return isinstance(other, LazyContainer) and self._value == other._value
def __ne__(self, other: object) -> bool:
return not (self == other)
def __str__(self) -> str:
return self.__pretty_str__()
def __pretty_str__(self, nesting: int = 1, indentation: str = " ") -> str:
if self._value is NotImplemented:
text = "<unread>"
elif hasattr(self._value, "__pretty_str__"):
text = self._value.__pretty_str__(nesting, indentation)
else:
text = str(self._value)
return "%s: %s" % (self.__class__.__name__, text)
def read(self) -> Any:
self.stream.seek(self.pos)
return self.subcon._parse(self.stream, self.context)
def dispose(self) -> None:
del self.subcon
del self.stream
del self.context
del self.pos
def _get_value(self) -> Any:
if self._value is NotImplemented:
self._value = self.read()
return self._value
value = property(_get_value)
has_value = property(lambda self: self._value is not NotImplemented)