about summary refs log tree commit diff stats
path: root/snapshot.py
diff options
context:
space:
mode:
Diffstat (limited to 'snapshot.py')
-rw-r--r--snapshot.py135
1 files changed, 0 insertions, 135 deletions
diff --git a/snapshot.py b/snapshot.py
deleted file mode 100644
index 9c9e4b3..0000000
--- a/snapshot.py
+++ /dev/null
@@ -1,135 +0,0 @@
-from arch.arch import Arch
-
-class MemoryAccessError(Exception):
-    def __init__(self, addr: int, size: int, msg: str):
-        super().__init__(msg)
-        self.mem_addr = addr
-        self.mem_size = size
-
-class SparseMemory:
-    """Sparse memory.
-
-    Note that out-of-bound reads are possible when performed on unwritten
-    sections of existing pages and that there is no safeguard check for them.
-    """
-    def __init__(self, page_size=4096):
-        self.page_size = page_size
-        self._pages: dict[int, bytes] = {}
-
-    def _to_page_addr_and_offset(self, addr: int) -> tuple[int, int]:
-        off = addr % self.page_size
-        return addr - off, off
-
-    def read(self, addr: int, size: int) -> bytes:
-        """Read a number of bytes from memory.
-        :param addr: The offset from where to read.
-        :param size: The number of bytes to read, starting at at `addr`.
-
-        :return: `size` bytes of data.
-        :raise MemoryAccessError: If `[addr, addr + size)` is not entirely
-                                  contained in the set of stored bytes.
-        :raise ValueError: If `size < 0`.
-        """
-        if size < 0:
-            raise ValueError(f'A negative size is not allowed!')
-
-        res = bytes()
-        while size > 0:
-            page_addr, off = self._to_page_addr_and_offset(addr)
-            if page_addr not in self._pages:
-                raise MemoryAccessError(addr, size,
-                                        f'Address {addr} is not contained in'
-                                        f' the sparse memory.')
-            data = self._pages[page_addr]
-            assert(len(data) == self.page_size)
-            read_size = min(size, self.page_size - off)
-            res += data[off:off+read_size]
-
-            size -= read_size
-            addr += read_size
-        return res
-
-    def write(self, addr: int, data: bytes):
-        """Store bytes in the memory.
-        :param addr: The address at which to store the data.
-        :param data: The data to store at `addr`.
-        """
-        offset = 0  # Current offset into `data`
-        while offset < len(data):
-            page_addr, off = self._to_page_addr_and_offset(addr)
-            if page_addr not in self._pages:
-                self._pages[page_addr] = bytes(self.page_size)
-            page = self._pages[page_addr]
-            assert(len(page) == self.page_size)
-
-            write_size = min(len(data) - offset, self.page_size - off)
-            new_page = page[:off] + data[offset:offset + write_size] + page[off+write_size:]
-            assert(len(new_page) == self.page_size)
-            self._pages[page_addr] = new_page
-
-            offset += write_size
-            addr += write_size
-
-        assert(len(data) == offset)  # Exactly all data was written
-
-class ProgramState:
-    """A snapshot of the program's state."""
-    def __init__(self, arch: Arch):
-        self.arch = arch
-
-        dict_t = dict[str, int | None]
-        self.regs: dict_t = { reg: None for reg in arch.regnames }
-        self.mem = SparseMemory()
-
-    def read(self, reg: str) -> int:
-        """Read a register's value.
-
-        :raise KeyError:   If `reg` is not a register name.
-        :raise ValueError: If the register has no value.
-        """
-        regname = self.arch.to_regname(reg)
-        if regname is None:
-            raise KeyError(f'Not a register name: {reg}')
-
-        assert(regname in self.regs)
-        regval = self.regs[regname]
-        if regval is None:
-            raise ValueError(f'Unable to read value of register {reg} (aka.'
-                             f' {regname}): The register contains no value.')
-        return regval
-
-    def set(self, reg: str, value: int):
-        """Assign a value to a register.
-
-        :raise KeyError: If `reg` is not a register name.
-        """
-        regname = self.arch.to_regname(reg)
-        if regname is None:
-            raise KeyError(f'Not a register name: {reg}')
-
-        self.regs[regname] = value
-
-    def read_memory(self, addr: int, size: int) -> bytes:
-        """Read a number of bytes from memory.
-
-        :param addr: The address from which to read data.
-        :param data: Number of bytes to read, starting at `addr`. Must be
-                     at least zero.
-
-        :raise MemoryAccessError: If `[addr, addr + size)` is not entirely
-                                  contained in the set of stored bytes.
-        :raise ValueError: If `size < 0`.
-        """
-        return self.mem.read(addr, size)
-
-    def write_memory(self, addr: int, data: bytes):
-        """Write a number of bytes to memory.
-
-        :param addr: The address at which to store the data.
-        :param data: The data to store at `addr`.
-        """
-        self.mem.write(addr, data)
-
-    def __repr__(self):
-        return f'Snapshot ({self.arch.archname}): ' \
-               + repr({r: hex(v) for r, v in self.regs.items() if v is not None})