about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorTheofilos Augoustis <theofilos.augoustis@gmail.com>2025-10-06 12:02:40 +0000
committerTheofilos Augoustis <theofilos.augoustis@gmail.com>2025-10-07 11:11:59 +0000
commit852744bb2e83dce906d40ef8cd28abc5346242bd (patch)
tree622b423000748573c6e7e47761f99aefe5d8ac61 /src
parentb75e57d22f11615cca76ade019306f224bbb91fa (diff)
downloadfocaccia-852744bb2e83dce906d40ef8cd28abc5346242bd.tar.gz
focaccia-852744bb2e83dce906d40ef8cd28abc5346242bd.zip
Add support for reading DCZID host-side
Diffstat (limited to 'src')
-rw-r--r--src/focaccia/arch/aarch64.py9
-rw-r--r--src/focaccia/arch/aarch64_dczid.py19
-rw-r--r--src/focaccia/arch/arch.py4
-rw-r--r--src/focaccia/lldb_target.py3
-rw-r--r--src/focaccia/symbolic.py4
5 files changed, 36 insertions, 3 deletions
diff --git a/src/focaccia/arch/aarch64.py b/src/focaccia/arch/aarch64.py
index 1067495..6c1163e 100644
--- a/src/focaccia/arch/aarch64.py
+++ b/src/focaccia/arch/aarch64.py
@@ -1,5 +1,7 @@
 """Description of 64-bit ARM."""
 
+from collections.abc import Callable
+
 from .arch import Arch, RegisterDescription as _Reg
 
 archname = 'aarch64'
@@ -131,6 +133,7 @@ regname_aliases = {
     'Q30': 'V30',
     'Q31': 'V31',
     'TPIDR_EL0': 'TPIDR',
+    'DCZID_EL0': 'DCZID',
 }
 
 def decompose_cpsr(cpsr: int) -> dict[str, int]:
@@ -167,3 +170,9 @@ class ArchAArch64(Arch):
 
         return regname_aliases.get(name.upper(), None)
 
+    def get_reg_reader(self, regname: str) -> Callable[[], int] | None:
+        if regname == 'DCZID':
+            from . import aarch64_dczid as dczid
+            return dczid.read
+        return None
+
diff --git a/src/focaccia/arch/aarch64_dczid.py b/src/focaccia/arch/aarch64_dczid.py
new file mode 100644
index 0000000..ddaa114
--- /dev/null
+++ b/src/focaccia/arch/aarch64_dczid.py
@@ -0,0 +1,19 @@
+from cffi import FFI
+
+ffi = FFI()
+ffi.cdef("int read_dczid();")
+
+code = r"""
+int read_dczid() {
+    int v;
+    __asm__ __volatile__ (
+        "mrs %0, dczid_el0" : "=r"(v)
+    );
+    return v;
+}
+"""
+lib = ffi.verify(code)
+
+def read():
+    return lib.read_dczid()
+
diff --git a/src/focaccia/arch/arch.py b/src/focaccia/arch/arch.py
index ce5e532..a7ab13b 100644
--- a/src/focaccia/arch/arch.py
+++ b/src/focaccia/arch/arch.py
@@ -1,4 +1,5 @@
 from typing import Literal
+from collections.abc import Callable
 
 class RegisterAccessor:
     def __init__(self, regname: str, start_bit: int, end_bit: int):
@@ -77,6 +78,9 @@ class Arch():
         _regname = self.to_regname(regname)
         return self._accessors.get(_regname, None)
 
+    def get_reg_reader(self, regname: str) -> Callable[[], int] | None:
+        return None
+
     def __eq__(self, other):
         return self.archname == other.archname
 
diff --git a/src/focaccia/lldb_target.py b/src/focaccia/lldb_target.py
index 1f31337..5a43b57 100644
--- a/src/focaccia/lldb_target.py
+++ b/src/focaccia/lldb_target.py
@@ -201,6 +201,9 @@ class LLDBConcreteTarget:
             flags = self.read_flags()
             if regname in flags:
                 return flags[regname]
+            reader = self.arch.get_reg_reader(regname)
+            if reader:
+                return reader()
             raise ConcreteRegisterError(
                 f'[In LLDBConcreteTarget.read_register]: Unable to read'
                 f' register {regname}: {err}')
diff --git a/src/focaccia/symbolic.py b/src/focaccia/symbolic.py
index 6510de5..cf3ef08 100644
--- a/src/focaccia/symbolic.py
+++ b/src/focaccia/symbolic.py
@@ -594,12 +594,10 @@ class _LLDBConcreteState(ReadableProgramState):
 
     def read_register(self, reg: str) -> int:
         regname = self.arch.to_regname(reg)
-        if regname is None and reg != "DCZID_EL0":
+        if regname is None:
             raise RegisterAccessError(reg, f'Not a register name: {reg}')
 
         try:
-            if reg == "DCZID_EL0":
-                return 4
             return self._target.read_register(regname)
         except ConcreteRegisterError:
             raise RegisterAccessError(regname, '')