about summary refs log tree commit diff stats
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
parentb75e57d22f11615cca76ade019306f224bbb91fa (diff)
downloadfocaccia-852744bb2e83dce906d40ef8cd28abc5346242bd.tar.gz
focaccia-852744bb2e83dce906d40ef8cd28abc5346242bd.zip
Add support for reading DCZID host-side
-rw-r--r--pyproject.toml1
-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
-rw-r--r--uv.lock28
7 files changed, 65 insertions, 3 deletions
diff --git a/pyproject.toml b/pyproject.toml
index 9a80ed2..9e52dfb 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -12,6 +12,7 @@ authors = [
 	{name = "Alp Berkman", email="alpberkman@gmail.com"}
 ]
 dependencies = [
+	"cffi",
 	"miasm",
 	"setuptools",
 	"cpuid @ git+https://github.com/taugoust/cpuid.py.git@master",
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, '')
diff --git a/uv.lock b/uv.lock
index e518c51..7f4d904 100644
--- a/uv.lock
+++ b/uv.lock
@@ -28,6 +28,23 @@ wheels = [
 ]
 
 [[package]]
+name = "cffi"
+version = "2.0.0"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+    { name = "pycparser", marker = "(implementation_name != 'PyPy' and platform_machine == 'aarch64' and sys_platform == 'linux') or (implementation_name != 'PyPy' and platform_machine == 'x86_64' and sys_platform == 'linux')" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/eb/56/b1ba7935a17738ae8453301356628e8147c79dbb825bcbc73dc7401f9846/cffi-2.0.0.tar.gz", hash = "sha256:44d1b5909021139fe36001ae048dbdde8214afa20200eda0f64c068cac5d5529", size = 523588, upload-time = "2025-09-08T23:24:04.541Z" }
+wheels = [
+    { url = "https://files.pythonhosted.org/packages/d5/72/12b5f8d3865bf0f87cf1404d8c374e7487dcf097a1c91c436e72e6badd83/cffi-2.0.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:b21e08af67b8a103c71a250401c78d5e0893beff75e28c53c98f4de42f774062", size = 220097, upload-time = "2025-09-08T23:22:48.677Z" },
+    { url = "https://files.pythonhosted.org/packages/c2/95/7a135d52a50dfa7c882ab0ac17e8dc11cec9d55d2c18dda414c051c5e69e/cffi-2.0.0-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:1e3a615586f05fc4065a8b22b8152f0c1b00cdbc60596d187c2a74f9e3036e4e", size = 207983, upload-time = "2025-09-08T23:22:50.06Z" },
+    { url = "https://files.pythonhosted.org/packages/3a/c8/15cb9ada8895957ea171c62dc78ff3e99159ee7adb13c0123c001a2546c1/cffi-2.0.0-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:81afed14892743bbe14dacb9e36d9e0e504cd204e0b165062c488942b9718037", size = 206519, upload-time = "2025-09-08T23:22:51.364Z" },
+    { url = "https://files.pythonhosted.org/packages/78/2d/7fa73dfa841b5ac06c7b8855cfc18622132e365f5b81d02230333ff26e9e/cffi-2.0.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:3e17ed538242334bf70832644a32a7aae3d83b57567f9fd60a26257e992b79ba", size = 219572, upload-time = "2025-09-08T23:22:52.902Z" },
+    { url = "https://files.pythonhosted.org/packages/07/e0/267e57e387b4ca276b90f0434ff88b2c2241ad72b16d31836adddfd6031b/cffi-2.0.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:3925dd22fa2b7699ed2617149842d2e6adde22b262fcbfada50e3d195e4b3a94", size = 222963, upload-time = "2025-09-08T23:22:54.518Z" },
+    { url = "https://files.pythonhosted.org/packages/b6/75/1f2747525e06f53efbd878f4d03bac5b859cbc11c633d0fb81432d98a795/cffi-2.0.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:2c8f814d84194c9ea681642fd164267891702542f028a15fc97d4674b6206187", size = 221361, upload-time = "2025-09-08T23:22:55.867Z" },
+]
+
+[[package]]
 name = "click"
 version = "8.2.1"
 source = { registry = "https://pypi.org/simple" }
@@ -49,6 +66,7 @@ name = "focaccia"
 version = "0.1.0"
 source = { editable = "." }
 dependencies = [
+    { name = "cffi", marker = "(platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux')" },
     { name = "cpuid", marker = "(platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux')" },
     { name = "miasm", marker = "(platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux')" },
     { name = "setuptools", marker = "(platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux')" },
@@ -65,6 +83,7 @@ dev = [
 [package.metadata]
 requires-dist = [
     { name = "black", marker = "extra == 'dev'" },
+    { name = "cffi" },
     { name = "cpuid", git = "https://github.com/taugoust/cpuid.py.git?rev=master" },
     { name = "miasm", directory = "miasm" },
     { name = "pyright", marker = "extra == 'dev'" },
@@ -164,6 +183,15 @@ wheels = [
 ]
 
 [[package]]
+name = "pycparser"
+version = "2.23"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/fe/cf/d2d3b9f5699fb1e4615c8e32ff220203e43b248e1dfcc6736ad9057731ca/pycparser-2.23.tar.gz", hash = "sha256:78816d4f24add8f10a06d6f05b4d424ad9e96cfebf68a4ddc99c65c0720d00c2", size = 173734, upload-time = "2025-09-09T13:23:47.91Z" }
+wheels = [
+    { url = "https://files.pythonhosted.org/packages/a0/e3/59cd50310fc9b59512193629e1984c1f95e5c8ae6e5d8c69532ccc65a7fe/pycparser-2.23-py3-none-any.whl", hash = "sha256:e5c6e8d3fbad53479cab09ac03729e0a9faf2bee3db8208a550daf5af81a5934", size = 118140, upload-time = "2025-09-09T13:23:46.651Z" },
+]
+
+[[package]]
 name = "pygments"
 version = "2.19.2"
 source = { registry = "https://pypi.org/simple" }