Source code for angr.storage.memory_mixins.name_resolution_mixin

import claripy
from archinfo.arch_arm import is_arm_arch
from . import MemoryMixin

stn_map = {"st%d" % n: n for n in range(8)}
tag_map = {"tag%d" % n: n for n in range(8)}


[docs]class NameResolutionMixin(MemoryMixin): """ This mixin allows you to provide register names as load addresses, and will automatically translate this to an offset and size. """ def _resolve_location_name(self, name, is_write=False): # Delayed load so SimMemory does not rely on SimEngines from ...engines.vex.claripy.ccall import _get_flags if self.category == "reg": if self.state.arch.name in ("X86", "AMD64"): if name in stn_map: return (((stn_map[name] + self.load("ftop")) & 7) << 3) + self.state.arch.registers["fpu_regs"][ 0 ], 8 elif name in tag_map: return ((tag_map[name] + self.load("ftop")) & 7) + self.state.arch.registers["fpu_tags"][0], 1 elif name in ("flags", "eflags", "rflags"): # we tweak the state to convert the vex condition registers into the flags register if not is_write: # this work doesn't need to be done if we're just gonna overwrite it self.store("cc_dep1", _get_flags(self.state)) # constraints cannot be added by this self.store("cc_op", 0) # OP_COPY return self.state.arch.registers["cc_dep1"] if is_arm_arch(self.state.arch): if name == "flags": if not is_write: self.store("cc_dep1", _get_flags(self.state)) self.store("cc_op", 0) return self.state.arch.registers["cc_dep1"] if name == "sp" and "sp" not in self.state.arch.registers: sp_reg_name = self.state.arch.register_names[self.state.arch.sp_offset] return self.state.arch.registers[sp_reg_name] if name == "lr" and "lr" not in self.state.arch.registers: lr_reg_name = self.state.arch.register_names[self.state.arch.lr_offset] return self.state.arch.registers[lr_reg_name] return self.state.arch.registers[name] elif name[0] == "*": return self.state.registers.load(name[1:]), None else: raise SimMemoryError("Trying to address memory with a register name.")
[docs] def store(self, addr, data, size=None, **kwargs): if isinstance(addr, str): named_addr, named_size = self._resolve_location_name(addr, is_write=True) if isinstance(data, claripy.ast.BV) and len(data) < named_size * self.state.arch.byte_width: data = data.zero_extend(named_size * self.state.arch.byte_width - len(data)) return super().store(named_addr, data, size=named_size if size is None else size, **kwargs) else: return super().store(addr, data, size=size, **kwargs)
[docs] def load(self, addr, size=None, **kwargs): if isinstance(addr, str): named_addr, named_size = self._resolve_location_name(addr, is_write=False) return super().load(named_addr, size=named_size if size is None else size, **kwargs) else: return super().load(addr, size=size, **kwargs)
from ...errors import SimMemoryError