about summary refs log tree commit diff stats
path: root/tools/_qemu_tool.py
diff options
context:
space:
mode:
authorTheofilos Augoustis <theofilos.augoustis@gmail.com>2024-02-08 16:45:22 +0100
committerTheofilos Augoustis <theofilos.augoustis@gmail.com>2024-02-08 16:45:22 +0100
commitf66f6edbd7d8918b497ccc17b78d4a77425fcb66 (patch)
treefe3f7f2ce9828b9f7374709b7b05acaf28ad85c9 /tools/_qemu_tool.py
parenta24c5f12d6d909898472f7208cbe16b086a001c9 (diff)
downloadfocaccia-f66f6edbd7d8918b497ccc17b78d4a77425fcb66.tar.gz
focaccia-f66f6edbd7d8918b497ccc17b78d4a77425fcb66.zip
Store instructions in SymbolicTransformation
Diffstat (limited to '')
-rw-r--r--tools/_qemu_tool.py23
1 files changed, 18 insertions, 5 deletions
diff --git a/tools/_qemu_tool.py b/tools/_qemu_tool.py
index ff7dc38..9659f0e 100644
--- a/tools/_qemu_tool.py
+++ b/tools/_qemu_tool.py
@@ -7,11 +7,10 @@ work to do.
 """
 
 import gdb
-import platform
 from typing import Iterable
 
 import focaccia.parser as parser
-from focaccia.arch import supported_architectures, Arch
+from focaccia.arch import supported_architectures
 from focaccia.compare import compare_symbolic
 from focaccia.snapshot import ProgramState, ReadableProgramState, \
                               RegisterAccessError, MemoryAccessError
@@ -28,7 +27,21 @@ class GDBProgramState(ReadableProgramState):
     def read_register(self, reg: str) -> int:
         try:
             val = self._frame.read_register(reg.lower())
-            return int(val) & 0xffffffffffffffff  # force int to be unsigned
+            size = val.type.sizeof * 8
+
+            # For vector registers, we have to assemble Python's
+            # arbitrary-length integers from GDB's fixed-size integers
+            # ourselves:
+            if size > 64:  # Value is a vector
+                num_longs = size // 64
+                vals = val[f'v{num_longs}_int64']
+                res = 0
+                for i in range(num_longs):
+                    val = int(vals[i].cast(gdb.lookup_type('unsigned long')))
+                    res += val << i * 64
+                return res
+            # For non-vector values, just return the 64-bit value
+            return int(val.cast(gdb.lookup_type('unsigned long')))
         except ValueError as err:
             from focaccia.arch import x86
             rflags = int(self._frame.read_register('eflags'))
@@ -186,10 +199,11 @@ def collect_conc_trace(gdb: GDBServerStateIterator, \
     state_iter = iter(gdb)
     cur_state = next(state_iter)
     symb_i = 0
+
+    # An online trace matching algorithm.
     while True:
         try:
             pc = cur_state.read_register('pc')
-            assert(pc is not None)
 
             while pc != strace[symb_i].addr:
                 next_i = find_index(strace[symb_i+1:], pc, lambda t: t.addr)
@@ -202,7 +216,6 @@ def collect_conc_trace(gdb: GDBServerStateIterator, \
                           f' reference trace.')
                     cur_state = next(state_iter)
                     pc = cur_state.read_register('pc')
-                    assert(pc is not None)
                     continue
 
                 # Otherwise, jump to the next matching symbolic state