Source code for angr.analyses.decompiler.structured_codegen.base

from typing import Dict, Optional, Set, Union
from sortedcontainers import SortedDict

from ....sim_variable import SimVariable

#
#   Position Mapping Classes
#


[docs]class PositionMappingElement: __slots__ = ("start", "length", "obj")
[docs] def __init__(self, start, length, obj): self.start: int = start self.length: int = length self.obj = obj
def __contains__(self, offset): return self.start <= offset < self.start + self.length def __repr__(self): return "<%d-%d: %s>" % (self.start, self.start + self.length, self.obj)
[docs]class PositionMapping: __slots__ = ("_posmap",) DUPLICATION_CHECK = True
[docs] def __init__(self): self._posmap: Union[SortedDict, Dict[int, PositionMappingElement]] = SortedDict()
[docs] def items(self): return self._posmap.items()
# # Public methods #
[docs] def add_mapping(self, start_pos, length, obj): # duplication check if self.DUPLICATION_CHECK: try: pre = next(self._posmap.irange(maximum=start_pos, reverse=True)) if start_pos in self._posmap[pre]: raise ValueError("New mapping is overlapping with an existing element.") except StopIteration: pass self._posmap[start_pos] = PositionMappingElement(start_pos, length, obj)
[docs] def get_node(self, pos: int): element = self.get_element(pos) if element is None: return None return element.obj
[docs] def get_element(self, pos: int) -> Optional[PositionMappingElement]: try: pre = next(self._posmap.irange(maximum=pos, reverse=True)) except StopIteration: return None element = self._posmap[pre] if pos in element: return element return None
[docs]class InstructionMappingElement: __slots__ = ("ins_addr", "posmap_pos")
[docs] def __init__(self, ins_addr, posmap_pos): self.ins_addr: int = ins_addr self.posmap_pos: int = posmap_pos
def __contains__(self, offset: int): return self.ins_addr == offset def __repr__(self): return "<%d: %d>" % (self.ins_addr, self.posmap_pos)
[docs]class InstructionMapping: __slots__ = ("_insmap",)
[docs] def __init__(self): self._insmap: Union[SortedDict, Dict[int, InstructionMappingElement]] = SortedDict()
[docs] def items(self): return self._insmap.items()
[docs] def add_mapping(self, ins_addr, posmap_pos): if ins_addr in self._insmap: if posmap_pos <= self._insmap[ins_addr].posmap_pos: self._insmap[ins_addr] = InstructionMappingElement(ins_addr, posmap_pos) else: self._insmap[ins_addr] = InstructionMappingElement(ins_addr, posmap_pos)
[docs] def get_nearest_pos(self, ins_addr: int) -> Optional[int]: try: pre_max = next(self._insmap.irange(maximum=ins_addr, reverse=True)) pre_min = next(self._insmap.irange(minimum=ins_addr, reverse=True)) except StopIteration: return None e1: InstructionMappingElement = self._insmap[pre_max] e2: InstructionMappingElement = self._insmap[pre_min] if abs(ins_addr - e1.ins_addr) <= abs(ins_addr - e2.ins_addr): return e1.posmap_pos else: return e2.posmap_pos
[docs]class BaseStructuredCodeGenerator:
[docs] def __init__(self, flavor=None): self.flavor = flavor self.text = None self.map_pos_to_node = None self.map_pos_to_addr = None self.map_addr_to_pos = None self.map_ast_to_pos: Optional[Dict[SimVariable, Set[PositionMappingElement]]] = None
[docs] def reapply_options(self, options): pass
[docs] def regenerate_text(self) -> None: pass
[docs] def reload_variable_types(self) -> None: pass