Source code for angr.knowledge_plugins.key_definitions.definition

from typing import Set

from ...engines.light import SpOffset
from ...code_location import CodeLocation
from .atoms import Atom, MemoryLocation, Register
from .tag import Tag


[docs]class Definition: """ An atom definition. :ivar atom: The atom being defined. :ivar codeloc: Where this definition is created in the original binary code. :ivar data: A concrete value (or many concrete values) that the atom holds when the definition is created. :ivar dummy: Tell whether the definition should be considered dummy or not. During simplification by AILment, definitions marked as dummy will not be removed. :ivar tags: A set of tags containing information about the definition gathered during analyses. """ __slots__ = ( "atom", "codeloc", "data", "dummy", "tags", "_hash", ) def __init__(self, atom: Atom, codeloc: CodeLocation, dummy: bool = False, tags: Set[Tag] = None): self.atom: Atom = atom self.codeloc: CodeLocation = codeloc self.dummy: bool = dummy self.tags = tags or set() self._hash = None def __eq__(self, other): return self.atom == other.atom and self.codeloc == other.codeloc def __repr__(self): if not self.tags: return "<Definition {{Atom:{}, Codeloc:{}}}{}>".format( self.atom, self.codeloc, "" if not self.dummy else "dummy" ) else: return "<Definition {{Tags:{}, Atom:{}, Codeloc:{}}}{}>".format( repr(self.tags), self.atom, self.codeloc, "" if not self.dummy else " dummy" ) def __str__(self): pretty_tags = "\n".join([str(tag) for tag in self.tags]) return f"Definition:\n" f"Atom: {self.atom}\n" f"CodeLoc: {self.codeloc}\n" f"Tags: {pretty_tags}" def __hash__(self): if self._hash is None: self._hash = hash((self.atom, self.codeloc)) return self._hash @property def offset(self) -> int: if isinstance(self.atom, Register): return self.atom.reg_offset elif isinstance(self.atom, MemoryLocation): if isinstance(self.atom.addr, SpOffset): return self.atom.addr.offset else: return self.atom.addr else: raise ValueError("Unsupported operation offset on %s." % type(self.atom)) @property def size(self) -> int: if isinstance(self.atom, Register): return self.atom.size elif isinstance(self.atom, MemoryLocation): return self.atom.bits // 8 else: raise ValueError("Unsupported operation size on %s." % type(self.atom))