summaryrefslogtreecommitdiffstats
path: root/debug
diff options
context:
space:
mode:
authorArthur Hanson Rasmusson <arthur@vgpu.io>2026-10-02 11:44:31 -0400
committerArthur Hanson Rasmusson <arthur@vgpu.io>2026-10-02 11:44:31 -0400
commit05797fd8cf884bb680540dfc188f36836a215c9f (patch)
treed64966acd9d47037bc8dae1ab9e2e1c66c9d526d /debug
parent4467eb66a4c8a776e35e9644960eba699dc85e6f (diff)
downloadopen-iov-05797fd8cf884bb680540dfc188f36836a215c9f.tar.gz
open-iov-05797fd8cf884bb680540dfc188f36836a215c9f.zip
rename (cosmetic): green-eye -> risc-v-gsp-rm-debugger in user-facing names, docs, CLI, launcher and CI workflow; internal greeneye package/module identifiers unchanged (includes in-flight greeneye module edits present in the tree)
Diffstat (limited to 'debug')
-rw-r--r--debug/risc-v-gsp-rm-vm/Makefile8
-rw-r--r--debug/risc-v-gsp-rm-vm/README.md32
-rw-r--r--debug/risc-v-gsp-rm-vm/RISC-V-GSP-RM-DEBUGGER-ROADMAP.md (renamed from debug/risc-v-gsp-rm-vm/GREEN-EYE-ROADMAP.md)20
-rw-r--r--debug/risc-v-gsp-rm-vm/docs/00-OVERVIEW.md30
-rw-r--r--debug/risc-v-gsp-rm-vm/docs/01-DESIGN.md6
-rw-r--r--debug/risc-v-gsp-rm-vm/docs/02-USAGE.md46
-rw-r--r--debug/risc-v-gsp-rm-vm/docs/03-SCRIPTING.md8
-rw-r--r--debug/risc-v-gsp-rm-vm/docs/04-PLUGINS.md12
-rw-r--r--debug/risc-v-gsp-rm-vm/docs/05-GHIDRA-BRIDGE.md18
-rw-r--r--debug/risc-v-gsp-rm-vm/docs/06-ACCURACY.md16
-rw-r--r--debug/risc-v-gsp-rm-vm/docs/07-PORTABILITY-PLAYBOOKS.md16
-rw-r--r--debug/risc-v-gsp-rm-vm/docs/08-ROADMAP.md16
-rw-r--r--debug/risc-v-gsp-rm-vm/docs/09-GSP-FIRMWARE-NOTES.md12
-rw-r--r--debug/risc-v-gsp-rm-vm/docs/10-RELATED-WORK.md18
-rw-r--r--debug/risc-v-gsp-rm-vm/docs/11-GSP-RM-SERVICE-DEVELOPER-GUIDE.md15
-rw-r--r--debug/risc-v-gsp-rm-vm/docs/12-INJECTION-SDK.md2
-rw-r--r--debug/risc-v-gsp-rm-vm/docs/13-GHIDRA-CONTROL.md8
-rw-r--r--debug/risc-v-gsp-rm-vm/docs/14-ADVERSARIAL-INTEROP-GUIDE.md46
-rw-r--r--debug/risc-v-gsp-rm-vm/docs/15-AGENTIC-GSP-IDE.md46
-rw-r--r--debug/risc-v-gsp-rm-vm/docs/16-CUSTOM-SIMULATOR.md20
-rw-r--r--debug/risc-v-gsp-rm-vm/docs/17-RM-HARNESS.md8
-rw-r--r--debug/risc-v-gsp-rm-vm/docs/18-HARNESS-AUTOMATION.md2
-rw-r--r--debug/risc-v-gsp-rm-vm/docs/19-CONTROL-DISCOVERY.md6
-rw-r--r--debug/risc-v-gsp-rm-vm/docs/20-MCP-SERVER.md26
-rw-r--r--debug/risc-v-gsp-rm-vm/docs/21-CI-RELEASE-PIPELINE.md8
-rw-r--r--debug/risc-v-gsp-rm-vm/docs/22-PORTING-CUDA-AND-DEVICES.md32
-rw-r--r--debug/risc-v-gsp-rm-vm/docs/23-RM610-READINESS.md24
-rw-r--r--debug/risc-v-gsp-rm-vm/docs/24-DEVICE-MAP.md2
-rw-r--r--debug/risc-v-gsp-rm-vm/docs/25-VALUE-VALIDATION.md14
-rw-r--r--debug/risc-v-gsp-rm-vm/docs/26-ARCHITECTURE.md18
-rw-r--r--debug/risc-v-gsp-rm-vm/docs/27-TOOL-AUDIT.md28
-rw-r--r--debug/risc-v-gsp-rm-vm/docs/28-PORTING-AUTOMATION.md4
-rw-r--r--debug/risc-v-gsp-rm-vm/docs/29-PACKAGING-AND-TRIALING.md6
-rw-r--r--debug/risc-v-gsp-rm-vm/examples/scripts/dump_diff.py2
-rw-r--r--debug/risc-v-gsp-rm-vm/examples/scripts/trace_rpc.py2
-rw-r--r--debug/risc-v-gsp-rm-vm/firmware/uproc_demo/Makefile2
-rw-r--r--debug/risc-v-gsp-rm-vm/firmware/uproc_demo/linker.ld4
-rw-r--r--debug/risc-v-gsp-rm-vm/firmware/uproc_demo/main.c10
-rw-r--r--debug/risc-v-gsp-rm-vm/firmware/uproc_demo/start.S2
-rw-r--r--debug/risc-v-gsp-rm-vm/ghidra/ExportForGreenEye.java8
-rw-r--r--debug/risc-v-gsp-rm-vm/ghidra/GreenEyeControl.java16
-rw-r--r--debug/risc-v-gsp-rm-vm/ghidra/MarkGreenEyeHits.java12
-rw-r--r--debug/risc-v-gsp-rm-vm/ghidra/README.md8
-rw-r--r--debug/risc-v-gsp-rm-vm/greeneye/__init__.py4
-rw-r--r--debug/risc-v-gsp-rm-vm/greeneye/analyze.py6
-rw-r--r--debug/risc-v-gsp-rm-vm/greeneye/cli.py38
-rw-r--r--debug/risc-v-gsp-rm-vm/greeneye/device_map.py2
-rw-r--r--debug/risc-v-gsp-rm-vm/greeneye/elf.py2
-rw-r--r--debug/risc-v-gsp-rm-vm/greeneye/errors.py4
-rw-r--r--debug/risc-v-gsp-rm-vm/greeneye/gdbridge.py22
-rw-r--r--debug/risc-v-gsp-rm-vm/greeneye/ghidra.py4
-rw-r--r--debug/risc-v-gsp-rm-vm/greeneye/inject.py4
-rw-r--r--debug/risc-v-gsp-rm-vm/greeneye/plugins.py4
-rw-r--r--debug/risc-v-gsp-rm-vm/greeneye/record.py2
-rw-r--r--debug/risc-v-gsp-rm-vm/greeneye/rsp.py2
-rw-r--r--debug/risc-v-gsp-rm-vm/greeneye/session.py20
-rw-r--r--debug/risc-v-gsp-rm-vm/greeneye/sim_backend.py2
-rw-r--r--debug/risc-v-gsp-rm-vm/greeneye/symbols.py6
-rw-r--r--debug/risc-v-gsp-rm-vm/greeneye/target.py35
-rw-r--r--debug/risc-v-gsp-rm-vm/harness/__init__.py2
-rw-r--r--debug/risc-v-gsp-rm-vm/harness/ci_release.py8
-rw-r--r--debug/risc-v-gsp-rm-vm/harness/common.py2
-rw-r--r--debug/risc-v-gsp-rm-vm/harness/control_discovery.py2
-rw-r--r--debug/risc-v-gsp-rm-vm/harness/mutation_harness.py4
-rw-r--r--debug/risc-v-gsp-rm-vm/harness/package_sim.py22
-rw-r--r--debug/risc-v-gsp-rm-vm/harness/port_driver_versions.py6
-rw-r--r--debug/risc-v-gsp-rm-vm/harness/port_new_device.py8
-rw-r--r--debug/risc-v-gsp-rm-vm/harness/portability_matrix.py10
-rw-r--r--debug/risc-v-gsp-rm-vm/harness/reach.py6
-rw-r--r--debug/risc-v-gsp-rm-vm/harness/value_demos/README.md10
-rw-r--r--debug/risc-v-gsp-rm-vm/harness/value_demos/__init__.py2
-rw-r--r--debug/risc-v-gsp-rm-vm/harness/value_demos/_common.py4
-rw-r--r--debug/risc-v-gsp-rm-vm/harness/value_demos/s05_snapshot_diff.py2
-rw-r--r--debug/risc-v-gsp-rm-vm/harness/value_demos/s07_version_diff.py6
-rw-r--r--debug/risc-v-gsp-rm-vm/harness/value_demos/s08_mutation_triage.py2
-rw-r--r--debug/risc-v-gsp-rm-vm/harness/value_demos/s09_grabbing_a_ghidra_address.py2
-rw-r--r--debug/risc-v-gsp-rm-vm/harness/version_diff.py48
-rw-r--r--debug/risc-v-gsp-rm-vm/plugins/README.md4
-rw-r--r--debug/risc-v-gsp-rm-vm/plugins/example_plugin.py2
-rw-r--r--debug/risc-v-gsp-rm-vm/plugins/mcp_server.py20
-rw-r--r--debug/risc-v-gsp-rm-vm/plugins/rmharness_plugin.py10
-rw-r--r--debug/risc-v-gsp-rm-vm/qemu/README.md6
-rw-r--r--debug/risc-v-gsp-rm-vm/qemu/greeneye_trace.c10
-rwxr-xr-xdebug/risc-v-gsp-rm-vm/qemu/launch.sh4
-rwxr-xr-xdebug/risc-v-gsp-rm-vm/risc-v-gsp-rm-debugger.sh (renamed from debug/risc-v-gsp-rm-vm/greeneye.sh)2
-rw-r--r--debug/risc-v-gsp-rm-vm/rmharness/README.md16
-rwxr-xr-xdebug/risc-v-gsp-rm-vm/rmharness/harness.sh2
-rw-r--r--debug/risc-v-gsp-rm-vm/sdk/Makefile2
-rw-r--r--debug/risc-v-gsp-rm-vm/sdk/greeneye_service.h4
-rw-r--r--debug/risc-v-gsp-rm-vm/sdk/injected_demo.c2
-rw-r--r--debug/risc-v-gsp-rm-vm/sim/__init__.py2
-rw-r--r--debug/risc-v-gsp-rm-vm/tests/test_bridge.py31
-rw-r--r--debug/risc-v-gsp-rm-vm/tests/test_harness.py2
-rw-r--r--debug/risc-v-gsp-rm-vm/tests/test_mcp.py4
-rw-r--r--debug/risc-v-gsp-rm-vm/tests/test_session_call.py195
-rw-r--r--debug/risc-v-gsp-rm-vm/tests/test_sim_backend.py2
-rw-r--r--debug/risc-v-gsp-rm-vm/tests/test_smoke_qemu.py2
-rw-r--r--debug/risc-v-gsp-rm-vm/tests/test_value_demos.py2
-rw-r--r--debug/risc-v-gsp-rm-vm/tests/test_version_diff.py38
99 files changed, 818 insertions, 486 deletions
diff --git a/debug/risc-v-gsp-rm-vm/Makefile b/debug/risc-v-gsp-rm-vm/Makefile
index fc43b37..d75d8cc 100644
--- a/debug/risc-v-gsp-rm-vm/Makefile
+++ b/debug/risc-v-gsp-rm-vm/Makefile
@@ -1,4 +1,4 @@
-# green-eye convenience targets. The real work lives in the package.
+# risc-v-gsp-rm-debugger convenience targets. The real work lives in the package.
PYTHON ?= python3
.PHONY: all demo test demo-run plugin probe-real clean info
@@ -15,10 +15,10 @@ test: demo
$(PYTHON) -m unittest discover -s tests -t .
demo-run: demo
- ./greeneye.sh demo --no-build
+ ./risc-v-gsp-rm-debugger.sh demo --no-build
info:
- ./greeneye.sh info
+ ./risc-v-gsp-rm-debugger.sh info
# Optional TCG plugin (needs the QEMU plugin headers; see qemu/README.md).
plugin:
@@ -26,7 +26,7 @@ plugin:
# Run the real GSP fwimage for a bounded window and report first divergence.
probe-real:
- ./greeneye.sh probe
+ ./risc-v-gsp-rm-debugger.sh probe
clean:
$(MAKE) -C firmware/uproc_demo clean
diff --git a/debug/risc-v-gsp-rm-vm/README.md b/debug/risc-v-gsp-rm-vm/README.md
index 627e1d5..a1e4b9b 100644
--- a/debug/risc-v-gsp-rm-vm/README.md
+++ b/debug/risc-v-gsp-rm-vm/README.md
@@ -1,4 +1,4 @@
-# green-eye — GSP runtime analysis in a RISC-V QEMU VM
+# risc-v-gsp-rm-debugger — GSP runtime analysis in a RISC-V QEMU VM
> **# TOOL IN DEVELOPMENT - NOT READY YET!**
> Experimental tooling for simulating and inspecting the GSP firmware's
@@ -6,7 +6,7 @@
> reverse engineering. It is a development-only, out-of-tree tool: never a
> dependency of the shipped driver and never present in a guest.
-green-eye boots GSP/uproc firmware in `qemu-system-riscv64`, attaches over
+risc-v-gsp-rm-debugger boots GSP/uproc firmware in `qemu-system-riscv64`, attaches over
QEMU's gdbstub with a GDB-free Python client, and exposes Frida-like
instrumentation: hooks, breakpoints, watchpoints, memory dumping, structure
decoding, snapshot diffing, session recording, plugins and a Ghidra bridge.
@@ -23,27 +23,27 @@ Start with [`docs/00-OVERVIEW.md`](docs/00-OVERVIEW.md).
cd open-iov/debug/risc-v-gsp-rm-vm
make demo # build the bundled RV64 uproc demo (clang + lld)
-./greeneye.sh demo # boot it, hook handlers, watch counters, record + analyze
-./greeneye.sh demo --backend native # same run on the deterministic native sim
-./greeneye.sh record --backend native --trace --duration 0.5 # exec/access trace
-./greeneye.sh info # environment / tooling check
+./risc-v-gsp-rm-debugger.sh demo # boot it, hook handlers, watch counters, record + analyze
+./risc-v-gsp-rm-debugger.sh demo --backend native # same run on the deterministic native sim
+./risc-v-gsp-rm-debugger.sh record --backend native --trace --duration 0.5 # exec/access trace
+./risc-v-gsp-rm-debugger.sh info # environment / tooling check
```
Interactively instrument a session:
```bash
-./greeneye.sh attach --kernel firmware/uproc_demo/build/uproc_demo.elf
-greeneye> bp rpc_sum
-greeneye> watch gsp_ctrl+0x10 8 w
-greeneye> x 0x80000840 64
-greeneye> c 2
+./risc-v-gsp-rm-debugger.sh attach --kernel firmware/uproc_demo/build/uproc_demo.elf
+risc-v-gsp-rm-debugger> bp rpc_sum
+risc-v-gsp-rm-debugger> watch gsp_ctrl+0x10 8 w
+risc-v-gsp-rm-debugger> x 0x80000840 64
+risc-v-gsp-rm-debugger> c 2
```
Or launch a target separately and attach to it by port:
```bash
-./greeneye.sh launch --kernel <elf> # prints the gdbstub port, keeps QEMU alive
-./greeneye.sh attach --port <port> --kernel <elf>
+./risc-v-gsp-rm-debugger.sh launch --kernel <elf> # prints the gdbstub port, keeps QEMU alive
+./risc-v-gsp-rm-debugger.sh attach --port <port> --kernel <elf>
```
Requirements: QEMU (`qemu-system-misc` on Ubuntu gives
@@ -80,7 +80,7 @@ dumps/ recorded sessions (gitignored)
| [01-DESIGN](docs/01-DESIGN.md) | architecture and data model |
| [02-USAGE](docs/02-USAGE.md) | CLI and REPL recipes |
| [03-SCRIPTING](docs/03-SCRIPTING.md) | Python API + probe specs |
-| [04-PLUGINS](docs/04-PLUGINS.md) | writing green-eye plugins |
+| [04-PLUGINS](docs/04-PLUGINS.md) | writing risc-v-gsp-rm-debugger plugins |
| [05-GHIDRA-BRIDGE](docs/05-GHIDRA-BRIDGE.md) | static/dynamic address join |
| [06-ACCURACY](docs/06-ACCURACY.md) | simulation fidelity and measurement |
| [07-PORTABILITY-PLAYBOOKS](docs/07-PORTABILITY-PLAYBOOKS.md) | new GSP/device/arch runs |
@@ -89,7 +89,7 @@ dumps/ recorded sessions (gitignored)
| [10-RELATED-WORK](docs/10-RELATED-WORK.md) | Frida/GDB/QEMU-plugin comparison |
| [11-GSP-RM-SERVICE-DEVELOPER-GUIDE](docs/11-GSP-RM-SERVICE-DEVELOPER-GUIDE.md) | writing, injecting and debugging firmware services |
| [12-INJECTION-SDK](docs/12-INJECTION-SDK.md) | injection blob/ABI specification |
-| [13-GHIDRA-CONTROL](docs/13-GHIDRA-CONTROL.md) | driving green-eye from GhidraScripts |
+| [13-GHIDRA-CONTROL](docs/13-GHIDRA-CONTROL.md) | driving risc-v-gsp-rm-debugger from GhidraScripts |
| [14-ADVERSARIAL-INTEROP-GUIDE](docs/14-ADVERSARIAL-INTEROP-GUIDE.md) | navigating unpredictable/adversarial firmware change |
| [15-AGENTIC-GSP-IDE](docs/15-AGENTIC-GSP-IDE.md) | agentic workflows and runbooks |
| [16-CUSTOM-SIMULATOR](docs/16-CUSTOM-SIMULATOR.md) | non-QEMU simulator design; M1 native backend + M1.5 trace status/usage |
@@ -106,7 +106,7 @@ dumps/ recorded sessions (gitignored)
| [27-TOOL-AUDIT](docs/27-TOOL-AUDIT.md) | tool audit: purpose, tests, usage, status |
| [28-PORTING-AUTOMATION](docs/28-PORTING-AUTOMATION.md) | driver-version sweep and new-device scaffolds (pilot, dry-run default) |
| [29-PACKAGING-AND-TRIALING](docs/29-PACKAGING-AND-TRIALING.md) | trial simulation packages (pilot) |
-| [GREEN-EYE-ROADMAP](GREEN-EYE-ROADMAP.md) | the long-term program (H1–H7) |
+| [RISC-V-GSP-RM-DEBUGGER-ROADMAP](RISC-V-GSP-RM-DEBUGGER-ROADMAP.md) | the long-term program (H1–H7) |
<!-- change (2026-10-02): add docs 28/29 to the documentation map; scope: doc
map only; benefit: new tool-tree documents are linked from the tree front
diff --git a/debug/risc-v-gsp-rm-vm/GREEN-EYE-ROADMAP.md b/debug/risc-v-gsp-rm-vm/RISC-V-GSP-RM-DEBUGGER-ROADMAP.md
index 0e1b58e..26f586f 100644
--- a/debug/risc-v-gsp-rm-vm/GREEN-EYE-ROADMAP.md
+++ b/debug/risc-v-gsp-rm-vm/RISC-V-GSP-RM-DEBUGGER-ROADMAP.md
@@ -1,7 +1,7 @@
-# GREEN-EYE ROADMAP — long-term program
+# RISC-V GSP-RM DEBUGGER ROADMAP — long-term program
> **# TOOL IN DEVELOPMENT - NOT READY YET!**
-> This is the long-term plan for green-eye, the runtime analysis, injection and
+> This is the long-term plan for risc-v-gsp-rm-debugger, the runtime analysis, injection and
> measurement environment for the NVIDIA GPU System Processor (GSP) and its
> adjacent microcontrollers. Near-term, committed work lives in
> [`docs/08-ROADMAP.md`](docs/08-ROADMAP.md); this document is the program.
@@ -24,7 +24,7 @@ churn, the project needs a toolchain that can:
5. **Reimplement** — turn observed behaviour into reviewed code in
`open-iov-vfio` with evidence attached.
-green-eye is the vehicle for that program. It is explicitly a **development
+risc-v-gsp-rm-debugger is the vehicle for that program. It is explicitly a **development
environment**, never a shipped component.
## 1. Starting point (H0, done)
@@ -75,7 +75,7 @@ and `greeneye/inject.py`, verified by direct call and firmware dispatch.
### H1.3 GSP-RM service injection (needs H2 device model)
Once real GSP-RM runs in the simulator (H2), extend the SDK to:
-* build against RM headers or against a green-eye shim for
+* build against RM headers or against a risc-v-gsp-rm-debugger shim for
public work;
* register a service with the simulated RM core instead of a demo handler
table;
@@ -169,7 +169,7 @@ and can become the substrate for injection, fuzzing and adversarial work.
### H3.2 Design sketch
```
-+-------------------- green-eye Python control plane --------------------+
++-------------------- risc-v-gsp-rm-debugger Python control plane --------------------+
| Session API, hooks/watchpoints, recorder, plugins, Ghidra/agent bridge |
+---------------------------- Backend interface -------------------------+
| QEMU-RSP backend (today) | native simulator backend
@@ -189,7 +189,7 @@ and can become the substrate for injection, fuzzing and adversarial work.
* **Time-travel** is built from snapshot + deterministic event replay.
### H3.3 Implementation plan
-1. **M1**: RV64IMAC interpreter + RAM + UART; boots the demo uproc; green-eye
+1. **M1**: RV64IMAC interpreter + RAM + UART; boots the demo uproc; risc-v-gsp-rm-debugger
Session works against the native backend (parity with QEMU for the demo).
2. **M2**: memory map DSL + falcon/CSB/PTIMER devices; boots a re-hosted
uproc build; snapshots/restore.
@@ -214,7 +214,7 @@ state, deliberate anti-analysis, or shifted resources — navigate and
reimplement quickly.
### H4.1 Semantic diffing
-* Import each firmware's Ghidra corpus and green-eye symbol DB; diff RPC
+* Import each firmware's Ghidra corpus and risc-v-gsp-rm-debugger symbol DB; diff RPC
dispatch tables, handler inventory, control sets, message layouts.
* Run the same stimulus harness against each version and use
`greeneye compare` for hit/watch/write deltas; automatically flag functions
@@ -245,7 +245,7 @@ techniques in docs/09.
### H4.5 Reimplementation workflow (accuracy loop)
The canonical loop for any behaviour:
1. Observe on hardware/VFIO (reference capture).
-2. Observe in green-eye (simulator, replayable).
+2. Observe in risc-v-gsp-rm-debugger (simulator, replayable).
3. `compare` + metric table M1–M6 (docs/06-ACCURACY.md).
4. Implement in `open-iov-vfio` with the session directories attached as
evidence.
@@ -293,10 +293,10 @@ emulation.
memory, WPR2/FWSEC state (with an explicit, documented security posture:
the soft model is a study environment, never a confidentiality boundary).
* Run modes: pure RTL simulation (Verilator) for determinism and coverage;
- FPGA for speed; co-simulation with green-eye (JTAG/DPI/a bridge) so the
+ FPGA for speed; co-simulation with risc-v-gsp-rm-debugger (JTAG/DPI/a bridge) so the
same Python hooks, sessions and comparisons apply.
-### H6.2 Integration with green-eye
+### H6.2 Integration with risc-v-gsp-rm-debugger
* A `Backend` implementation talking to the RTL simulation clock/step and
memory API; breakpoints become simulation traps; watchpoints become
signal/page monitors.
diff --git a/debug/risc-v-gsp-rm-vm/docs/00-OVERVIEW.md b/debug/risc-v-gsp-rm-vm/docs/00-OVERVIEW.md
index e4906cc..f09d576 100644
--- a/debug/risc-v-gsp-rm-vm/docs/00-OVERVIEW.md
+++ b/debug/risc-v-gsp-rm-vm/docs/00-OVERVIEW.md
@@ -1,4 +1,4 @@
-# 00 — green-eye overview
+# 00 — risc-v-gsp-rm-debugger overview
> **# TOOL IN DEVELOPMENT - NOT READY YET!**
> Experimental tooling for simulating and inspecting the GSP firmware's
@@ -15,7 +15,7 @@ the firmware do things* — which handler runs, what it reads and writes, what
it returns, how its state machine evolves — without a physical GPU, without
WPR2/hazard exposure, and repeatably.
-green-eye runs uproc/GSP firmware in `qemu-system-riscv64` and gives the
+risc-v-gsp-rm-debugger runs uproc/GSP firmware in `qemu-system-riscv64` and gives the
developer Frida-like instrumentation over its memory and execution:
* breakpoints and enter/leave **hooks** (RV64 ABI aware),
@@ -60,16 +60,16 @@ whole stack scriptable, and QEMU is just the first execution backend.
```bash
cd open-iov/debug/risc-v-gsp-rm-vm
make demo # build the bundled RV64 uproc demo
-./greeneye.sh demo # canned instrumentation pass, records a session
-./greeneye.sh info # environment check
-./greeneye.sh probe # run the real GSP fwimage and report first divergence
+./risc-v-gsp-rm-debugger.sh demo # canned instrumentation pass, records a session
+./risc-v-gsp-rm-debugger.sh info # environment check
+./risc-v-gsp-rm-debugger.sh probe # run the real GSP fwimage and report first divergence
```
Interactively:
```bash
-./greeneye.sh demo --no-build --duration 0 # launches; prints the gdbstub port
-./greeneye.sh attach --port <port> --kernel firmware/uproc_demo/build/uproc_demo.elf
+./risc-v-gsp-rm-debugger.sh demo --no-build --duration 0 # launches; prints the gdbstub port
+./risc-v-gsp-rm-debugger.sh attach --port <port> --kernel firmware/uproc_demo/build/uproc_demo.elf
```
## Document map
@@ -79,7 +79,7 @@ Interactively:
| [01-DESIGN](01-DESIGN.md) | how the pieces fit, transport, data model, limits |
| [02-USAGE](02-USAGE.md) | CLI and REPL recipes |
| [03-SCRIPTING](03-SCRIPTING.md) | writing programs against the API |
-| [04-PLUGINS](04-PLUGINS.md) | extending green-eye |
+| [04-PLUGINS](04-PLUGINS.md) | extending risc-v-gsp-rm-debugger |
| [05-GHIDRA-BRIDGE](05-GHIDRA-BRIDGE.md) | static/dynamic address join |
| [06-ACCURACY](06-ACCURACY.md) | what the simulation does and does not prove |
| [07-PORTABILITY-PLAYBOOKS](07-PORTABILITY-PLAYBOOKS.md) | new GSP / device / architecture |
@@ -88,7 +88,7 @@ Interactively:
| [10-RELATED-WORK](10-RELATED-WORK.md) | Frida/GDB/QEMU-plugin comparison |
| [11-GSP-RM-SERVICE-DEVELOPER-GUIDE](11-GSP-RM-SERVICE-DEVELOPER-GUIDE.md) | writing/injecting/debugging RM services |
| [12-INJECTION-SDK](12-INJECTION-SDK.md) | injection blob/ABI specification |
-| [13-GHIDRA-CONTROL](13-GHIDRA-CONTROL.md) | driving green-eye from Ghidra |
+| [13-GHIDRA-CONTROL](13-GHIDRA-CONTROL.md) | driving risc-v-gsp-rm-debugger from Ghidra |
| [14-ADVERSARIAL-INTEROP-GUIDE](14-ADVERSARIAL-INTEROP-GUIDE.md) | adversarial firmware navigation |
| [15-AGENTIC-GSP-IDE](15-AGENTIC-GSP-IDE.md) | agentic workflows and runbooks |
| [16-CUSTOM-SIMULATOR](16-CUSTOM-SIMULATOR.md) | native simulator (M1/M1.5 implemented; M2+ design) |
@@ -105,23 +105,23 @@ Interactively:
| [27-TOOL-AUDIT](27-TOOL-AUDIT.md) | tool audit: purpose, tests, usage, status |
| [28-PORTING-AUTOMATION](28-PORTING-AUTOMATION.md) | driver-version sweep and new-device scaffolds (pilot) |
| [29-PACKAGING-AND-TRIALING](29-PACKAGING-AND-TRIALING.md) | trial simulation packages (pilot) |
-| [GREEN-EYE-ROADMAP](../GREEN-EYE-ROADMAP.md) | long-term program H1–H7 |
+| [RISC-V-GSP-RM-DEBUGGER-ROADMAP](../RISC-V-GSP-RM-DEBUGGER-ROADMAP.md) | long-term program H1–H7 |
## Where this fits in the Open-IOV workflow
-green-eye is a **development and research** tool, alongside the Ghidra corpus
+risc-v-gsp-rm-debugger is a **development and research** tool, alongside the Ghidra corpus
and the guest diagnostics. It does not replace either:
-* **Ghidra** answers *what is the code*; green-eye answers *what did it do*.
+* **Ghidra** answers *what is the code*; risc-v-gsp-rm-debugger answers *what did it do*.
* **Guest diagnostics** (`tools/guest-diag`) answer *what did the guest
- driver do*; green-eye answers *what did the firmware server do*.
+ driver do*; risc-v-gsp-rm-debugger answers *what did the firmware server do*.
* **The physical backend** (PLAN B) answers *what does real silicon do*;
- green-eye provides a safe place to repeat, mutate and single-step the same
+ risc-v-gsp-rm-debugger provides a safe place to repeat, mutate and single-step the same
firmware when the hardware path is hazardous or unavailable.
The intended accuracy loop is: run the same workload against the real
GSP-RM (hardware or mdev), record its RPC/state behaviour, then run the
-firmware in green-eye, record the same events, and compare with `compare`
+firmware in risc-v-gsp-rm-debugger, record the same events, and compare with `compare`
(see 06 and 07).
<!-- change (2026-10-02): add docs 28/29 to the status table and document map
diff --git a/debug/risc-v-gsp-rm-vm/docs/01-DESIGN.md b/debug/risc-v-gsp-rm-vm/docs/01-DESIGN.md
index c5de2da..034f87c 100644
--- a/debug/risc-v-gsp-rm-vm/docs/01-DESIGN.md
+++ b/debug/risc-v-gsp-rm-vm/docs/01-DESIGN.md
@@ -1,4 +1,4 @@
-# 01 — green-eye design
+# 01 — risc-v-gsp-rm-debugger design
> **# TOOL IN DEVELOPMENT - NOT READY YET!** See 00 for status.
@@ -73,7 +73,7 @@ the plugin layer, not the transport.
same return address are queued (LIFO). Tail calls and asynchronous
interrupts are not tracked — documented limitation.
* **Watchpoints**: `Z2/Z3/Z4` (write/read/access). QEMU stops *at* the
- accessing instruction, so green-eye temporarily clears the watch, steps one
+ accessing instruction, so risc-v-gsp-rm-debugger temporarily clears the watch, steps one
instruction, and re-arms it. Without this the target livelocks on the same
store.
* **Stop dispatch**: every stop reads the register file, resolves the PC to a
@@ -144,7 +144,7 @@ declarative so they can come from a Ghidra type export or a plugin later.
* The **kernel fast path** passes `-kernel <elf>`; QEMU loads segments and
sets PC.
* The **probe path** passes each PT_LOAD segment as a raw loader device and
- green-eye sets PC through the gdbstub — this lets a firmware linked for GPU
+ risc-v-gsp-rm-debugger sets PC through the gdbstub — this lets a firmware linked for GPU
physical addresses be relocated into RAM for observation.
* A **custom simulator** can be added as a session backend later (roadmap,
not v0.1) because `Session` only assumes the RSP-like operations.
diff --git a/debug/risc-v-gsp-rm-vm/docs/02-USAGE.md b/debug/risc-v-gsp-rm-vm/docs/02-USAGE.md
index 53cf19f..686d4c9 100644
--- a/debug/risc-v-gsp-rm-vm/docs/02-USAGE.md
+++ b/debug/risc-v-gsp-rm-vm/docs/02-USAGE.md
@@ -1,4 +1,4 @@
-# 02 — green-eye usage
+# 02 — risc-v-gsp-rm-debugger usage
> **# TOOL IN DEVELOPMENT - NOT READY YET!** See 00 for status.
@@ -14,7 +14,7 @@ All commands are run from `open-iov/debug/risc-v-gsp-rm-vm/`.
Check everything:
```bash
-./greeneye.sh info
+./risc-v-gsp-rm-debugger.sh info
make test # builds the demo then runs unit + QEMU smoke tests
```
@@ -22,7 +22,7 @@ make test # builds the demo then runs unit + QEMU smoke tests
```bash
make demo
-./greeneye.sh demo
+./risc-v-gsp-rm-debugger.sh demo
```
It boots `firmware/uproc_demo/build/uproc_demo.elf`, installs hooks on all
@@ -36,15 +36,15 @@ Options: `--no-build`, `--duration SECONDS`, `--kernel PATH`, `--record PATH`.
## 2. Interactive REPL
```bash
-./greeneye.sh attach --kernel firmware/uproc_demo/build/uproc_demo.elf
+./risc-v-gsp-rm-debugger.sh attach --kernel firmware/uproc_demo/build/uproc_demo.elf
```
`attach` launches the target itself when `--port` is omitted. To share a
target between terminals, launch it separately and attach by port:
```bash
-./greeneye.sh launch --kernel <elf> # prints: gdbstub: 127.0.0.1:<port>
-./greeneye.sh attach --port <port> --kernel <elf>
+./risc-v-gsp-rm-debugger.sh launch --kernel <elf> # prints: gdbstub: 127.0.0.1:<port>
+./risc-v-gsp-rm-debugger.sh attach --port <port> --kernel <elf>
```
REPL commands:
@@ -71,9 +71,9 @@ plugin when loaded with `--plugin plugins/example_plugin.py`).
## 3. Scripted sessions
```bash
-./greeneye.sh run examples/scripts/trace_rpc.py
-./greeneye.sh run examples/scripts/dump_diff.py
-./greeneye.sh run my_script.py --kernel <elf> --plugin plugins/example_plugin.py
+./risc-v-gsp-rm-debugger.sh run examples/scripts/trace_rpc.py
+./risc-v-gsp-rm-debugger.sh run examples/scripts/dump_diff.py
+./risc-v-gsp-rm-debugger.sh run my_script.py --kernel <elf> --plugin plugins/example_plugin.py
```
The script runs with `ge`, `s`/`session`, `memory`, `symbols`, `recorder` in
@@ -82,10 +82,10 @@ scope and is recorded by default. See [03-SCRIPTING](03-SCRIPTING.md).
## 4. Recording, analysis, comparison
```bash
-./greeneye.sh record --duration 2.0 --watch gsp_ctrl+0x10:8 --snapshot gsp_ctrl:392
-./greeneye.sh analyze dumps/20261002-082721-demo
-./greeneye.sh analyze dumps/<a> --symbols symbols.json > a.md
-./greeneye.sh compare dumps/<run-a> dumps/<run-b> --symbols
+./risc-v-gsp-rm-debugger.sh record --duration 2.0 --watch gsp_ctrl+0x10:8 --snapshot gsp_ctrl:392
+./risc-v-gsp-rm-debugger.sh analyze dumps/20261002-082721-demo
+./risc-v-gsp-rm-debugger.sh analyze dumps/<a> --symbols symbols.json > a.md
+./risc-v-gsp-rm-debugger.sh compare dumps/<run-a> dumps/<run-b> --symbols
```
`analyze` prints a markdown report: event counts, breakpoint hits by symbol,
@@ -97,9 +97,9 @@ vfio-mdev and old-firmware vs new-firmware runs.
## 5. Probing an arbitrary firmware image
```bash
-./greeneye.sh probe # the project's TU104 570.144 fwimage
-./greeneye.sh probe path/to/fw.elf --duration 0.5
-./greeneye.sh probe --instructions 2000 --no-relocate
+./risc-v-gsp-rm-debugger.sh probe # the project's TU104 570.144 fwimage
+./risc-v-gsp-rm-debugger.sh probe path/to/fw.elf --duration 0.5
+./risc-v-gsp-rm-debugger.sh probe --instructions 2000 --no-relocate
```
Segments are flattened into a raw kernel loaded at `0x80000000`; because QEMU
@@ -113,12 +113,12 @@ load-access fault on an unmodelled GPU register — that is the honest result
## 6. Symbol databases
```bash
-./greeneye.sh symbols export \
+./risc-v-gsp-rm-debugger.sh symbols export \
--names ../../userspace/cuda/570.144/annotations/names.tsv \
--index <run>/analysis/decompiled/decompiled_index.tsv \
--callgraph <run>/analysis/elf-index/callgraph.tsv \
--bias 0x100000 -o symbols-570.json
-./greeneye.sh symbols resolve --db symbols-570.json 0x453ef0
+./risc-v-gsp-rm-debugger.sh symbols resolve --db symbols-570.json 0x453ef0
```
`--bias` normalises file vaddrs to runtime addresses (`0x100000` is the
@@ -127,9 +127,9 @@ libcuda Ghidra image base; use 0 for firmware linked at its load address).
## 7. Plugins
```bash
-./greeneye.sh plugins
-./greeneye.sh run examples/scripts/trace_rpc.py --plugin plugins/example_plugin.py
-GREENEYE_PLUGINS=/path/to/plugins ./greeneye.sh demo
+./risc-v-gsp-rm-debugger.sh plugins
+./risc-v-gsp-rm-debugger.sh run examples/scripts/trace_rpc.py --plugin plugins/example_plugin.py
+GREENEYE_PLUGINS=/path/to/plugins ./risc-v-gsp-rm-debugger.sh demo
```
See [04-PLUGINS](04-PLUGINS.md).
@@ -150,7 +150,7 @@ See [04-PLUGINS](04-PLUGINS.md).
* **`qemu-system-riscv64 not found`** — install `qemu-system-misc` or set
`GREENEYE_QEMU`.
* **`gdbstub port not ready`** — QEMU exited early; the error includes its
- stderr. Check the ELF actually loads (`./greeneye.sh info`).
+ stderr. Check the ELF actually loads (`./risc-v-gsp-rm-debugger.sh info`).
* **A run seems stuck** — sessions never `pkill -f greeneye` (it matches the
invoking shell). Use `pkill -9 -f '[q]emu-system-riscv64'` to clean up
leftover emulators.
@@ -161,7 +161,7 @@ See [04-PLUGINS](04-PLUGINS.md).
## 10. Safety
-green-eye touches no GPU, no mdev, no kernel module and no host driver. It
+risc-v-gsp-rm-debugger touches no GPU, no mdev, no kernel module and no host driver. It
runs unprivileged QEMU instances on loopback gdbstub ports. The only host
side effects are temporary directories under `/tmp` and `dumps/` under the
tool tree. It is safe to run alongside the CUDA/PLAN-B work, but keep an eye
diff --git a/debug/risc-v-gsp-rm-vm/docs/03-SCRIPTING.md b/debug/risc-v-gsp-rm-vm/docs/03-SCRIPTING.md
index 89c61c4..93dfccf 100644
--- a/debug/risc-v-gsp-rm-vm/docs/03-SCRIPTING.md
+++ b/debug/risc-v-gsp-rm-vm/docs/03-SCRIPTING.md
@@ -1,9 +1,9 @@
-# 03 — green-eye scripting
+# 03 — risc-v-gsp-rm-debugger scripting
> **# TOOL IN DEVELOPMENT - NOT READY YET!** See 00 for status.
-green-eye scripts are ordinary Python programs run with
-`./greeneye.sh run <script.py>` (or `python3 -m greeneye run …`). The
+risc-v-gsp-rm-debugger scripts are ordinary Python programs run with
+`./risc-v-gsp-rm-debugger.sh run <script.py>` (or `python3 -m greeneye run …`). The
names `ge`, `session`/`s`, `memory`, `symbols`, `recorder` are preloaded, and
`__file__` points at the script path (use it to locate bundled assets).
@@ -214,7 +214,7 @@ finally:
## 13. Errors and timeouts
-All green-eye errors derive from `greeneye.GreenEyeError`:
+All risc-v-gsp-rm-debugger errors derive from `greeneye.GreenEyeError`:
`RspTimeout` (transport), `RspProtocolError`, `TargetError`,
`SymbolNotFound`, `StructError`. `RspClient.timeout` (default 10 s) bounds a
single packet read; `run`'s budget bounds the whole pass.
diff --git a/debug/risc-v-gsp-rm-vm/docs/04-PLUGINS.md b/debug/risc-v-gsp-rm-vm/docs/04-PLUGINS.md
index db9ee27..b0e6767 100644
--- a/debug/risc-v-gsp-rm-vm/docs/04-PLUGINS.md
+++ b/debug/risc-v-gsp-rm-vm/docs/04-PLUGINS.md
@@ -1,11 +1,11 @@
-# 04 — writing green-eye plugins
+# 04 — writing risc-v-gsp-rm-debugger plugins
> **# TOOL IN DEVELOPMENT - NOT READY YET!** See 00 for status.
A plugin is a Python module exposing `register(ge)`. It is loaded before the
session runs (CLI `--plugin PATH`, `GREENEYE_PLUGINS`, or the bundled
`plugins/` directory) and can add instrumentation, CLI commands and harness
-logic without touching green-eye itself.
+logic without touching risc-v-gsp-rm-debugger itself.
## 1. The API object
@@ -46,7 +46,7 @@ findings are replayable and comparable like any other event.
## 3. The four plugin classes
-**(a) Runtime RE tools** — add analysis that green-eye does not have:
+**(a) Runtime RE tools** — add analysis that risc-v-gsp-rm-debugger does not have:
```python
def register(ge):
@@ -103,15 +103,15 @@ def register(ge):
Run it with:
```bash
-./greeneye.sh run examples/scripts/trace_rpc.py --plugin plugins/example_plugin.py
+./risc-v-gsp-rm-debugger.sh run examples/scripts/trace_rpc.py --plugin plugins/example_plugin.py
```
## 5. Testing a plugin
-1. Load it against the demo firmware (`./greeneye.sh demo --plugin …`) — the
+1. Load it against the demo firmware (`./risc-v-gsp-rm-debugger.sh demo --plugin …`) — the
session must remain green and the plugin's events must appear in
`events.jsonl`.
-2. Unit-test pure logic outside green-eye; keep hooks small.
+2. Unit-test pure logic outside risc-v-gsp-rm-debugger; keep hooks small.
3. Never let a plugin assume a particular firmware: gate on
`ge.symbols.get(name)` and log a skip instead of failing.
diff --git a/debug/risc-v-gsp-rm-vm/docs/05-GHIDRA-BRIDGE.md b/debug/risc-v-gsp-rm-vm/docs/05-GHIDRA-BRIDGE.md
index f7f46c3..4f41d33 100644
--- a/debug/risc-v-gsp-rm-vm/docs/05-GHIDRA-BRIDGE.md
+++ b/debug/risc-v-gsp-rm-vm/docs/05-GHIDRA-BRIDGE.md
@@ -2,7 +2,7 @@
> **# TOOL IN DEVELOPMENT - NOT READY YET!** See 00 for status.
-Ghidra answers *what is the code*; green-eye answers *what did it do*. The
+Ghidra answers *what is the code*; risc-v-gsp-rm-debugger answers *what did it do*. The
bridge joins them in both directions: Ghidra symbols into the runtime session,
runtime hit addresses back into the Ghidra project.
@@ -19,13 +19,13 @@ runtime hit addresses back into the Ghidra project.
* CUDA `libcuda` in the host oracle: runtime base from `/proc/<pid>/maps`;
`--bias` normalises it if you want runtime addresses in the DB.
* The project's `decompiled_index.tsv`/bucket TSVs carry **both** program and
- file addresses; green-eye parses both and stores the program address in
+ file addresses; risc-v-gsp-rm-debugger parses both and stores the program address in
`symbol.extras["program_addr"]`.
## 2. Build a symbol DB from Ghidra exports
```bash
-./greeneye.sh symbols export \
+./risc-v-gsp-rm-debugger.sh symbols export \
--names ../../userspace/cuda/570.144/annotations/names.tsv \
--index ../../userspace/cuda/570.144/run/analysis/decompiled/decompiled_index.tsv \
--exports ../../userspace/cuda/570.144/run/analysis/elf-index/exports.tsv \
@@ -38,7 +38,7 @@ the existing export scripts (`ExportFunctionIndex.java`,
`DecompileFunctions.java`, …) to produce TSVs, then:
```bash
-./greeneye.sh symbols export --index <export.tsv> --bias 0 -o symbols-gsp.json
+./risc-v-gsp-rm-debugger.sh symbols export --index <export.tsv> --bias 0 -o symbols-gsp.json
```
`load_index_tsv` is column-aware: it accepts
@@ -62,7 +62,7 @@ live hit to the decompiled body.
## 4. Annotate hits back into Ghidra
```bash
-./greeneye.sh analyze dumps/<run> --symbols symbols-gsp.json --out run.md
+./risc-v-gsp-rm-debugger.sh analyze dumps/<run> --symbols symbols-gsp.json --out run.md
python3 - <<'PY'
from greeneye.ghidra import export_hits
from greeneye.symbols import SymbolDB
@@ -81,7 +81,7 @@ $GHIDRA/support/analyzeHeadless <proj_dir> <project> -process <program> -noanaly
```
`ExportForGreenEye.java` is the reverse helper: it walks the current program
-and writes a green-eye-compatible `addr<TAB>name<TAB>size` TSV.
+and writes a risc-v-gsp-rm-debugger-compatible `addr<TAB>name<TAB>size` TSV.
`greeneye.ghidra.render_ghidra_command(proj_dir, project, program, hits_tsv)`
renders the `analyzeHeadless … MarkGreenEyeHits.java` command line above for
@@ -92,11 +92,11 @@ scripts (the helper is not wired into the CLI).
Two practical routes today:
1. `greeneye decompose/decompile` → note the file vaddr → script
- `s.hook("0x…")` (green-eye translates to runtime via the bias you loaded).
+ `s.hook("0x…")` (risc-v-gsp-rm-debugger translates to runtime via the bias you loaded).
2. Use `symbols export` from the Ghidra index, then `s.hook("<name>")` by
name — the most robust route across recompilations.
-A future Ghidra-side green-eye console (roadmap item) can call
+A future Ghidra-side risc-v-gsp-rm-debugger console (roadmap item) can call
`greeneye` through its CLI to set breakpoints directly from the tool.
## 6. Limits
@@ -104,6 +104,6 @@ A future Ghidra-side green-eye console (roadmap item) can call
* Wrapper-generated functions are re-laid-out between driver patch versions;
transfer names, never raw wrapper addresses (the CUDA playbook's lesson).
* The decompiler does not recover struct types; structure schemas for
- green-eye decoding must be written or exported separately.
+ risc-v-gsp-rm-debugger decoding must be written or exported separately.
* `decompiled_index.tsv` buckets are large and gitignored; keep symbol JSONs
small (name/size/subsystem only) if they must be tracked.
diff --git a/debug/risc-v-gsp-rm-vm/docs/06-ACCURACY.md b/debug/risc-v-gsp-rm-vm/docs/06-ACCURACY.md
index 1a1ae82..47854d1 100644
--- a/debug/risc-v-gsp-rm-vm/docs/06-ACCURACY.md
+++ b/debug/risc-v-gsp-rm-vm/docs/06-ACCURACY.md
@@ -1,4 +1,4 @@
-# 06 — Accuracy: what the green-eye test bed does and does not prove
+# 06 — Accuracy: what the risc-v-gsp-rm-debugger test bed does and does not prove
> **# TOOL IN DEVELOPMENT - NOT READY YET!** See 00 for status.
> This document is deliberately conservative. Treat every claim without a
@@ -6,7 +6,7 @@
## 1. Purpose
-green-eye exists to measure how accurately Open-IOV's GSP emulation
+risc-v-gsp-rm-debugger exists to measure how accurately Open-IOV's GSP emulation
(`gsp-rm-vfio` and the in-kernel emulation) reproduces the behaviour of the
real GSP firmware, and to make the firmware itself analysable. That makes
accuracy a first-class deliverable, not an assumption. This document defines
@@ -15,14 +15,14 @@ conclusions.
## 2. Fidelity levels
-| Level | Property | green-eye today |
+| Level | Property | risc-v-gsp-rm-debugger today |
|---|---|---|
| **L0 — instruction semantics** | RV64IMAC executes as on the device core | high (QEMU TCG, same ISA family) |
| **L1 — memory behaviour** | reads/writes/ordering as firmware expects | high for RAM-resident code, *conditional* on mapping the same physical layout |
| **L2 — time/concurrency** | cycle counts, DMA latency, interrupt timing | **not modelled** (do not claim) |
| **L3 — device environment** | falcon windows, WPR2, CSB/TRANSCOM, PMU, timers, FB DMA, IRQ routing | **absent** (roadmap) |
-The practical reading: green-eye is an **execution and memory** microscope,
+The practical reading: risc-v-gsp-rm-debugger is an **execution and memory** microscope,
not a timing or silicon model. Conclusions of the form "the firmware writes X
before Y" are in scope; "the firmware takes N µs" is not.
@@ -79,7 +79,7 @@ Define these metrics once and use them everywhere:
| # | Metric | How it is measured |
|---|---|---|
-| M1 | **Inventory coverage** | set of controls/RPCs observed in a real run vs the emulation's handled set (and green-eye's observed set) |
+| M1 | **Inventory coverage** | set of controls/RPCs observed in a real run vs the emulation's handled set (and risc-v-gsp-rm-debugger's observed set) |
| M2 | **Reply agreement** | field-by-field diff of replies (real vs emulated); canonical-size and consumed-field checks included |
| M3 | **Ordering agreement** | sequence alignment of the control/event stream (edit distance / LCS) |
| M4 | **State agreement** | state-machine transitions observed in the firmware vs the emulation's internal state model |
@@ -90,7 +90,7 @@ Define these metrics once and use them everywhere:
Reference capture:
* real hardware/backend: the project's existing RPC logs (module trace,
`gsp-phys-log-dump`, status-queue drains) and the static-config oracle;
-* green-eye: `events.jsonl` + snapshots, symbol-annotated.
+* risc-v-gsp-rm-debugger: `events.jsonl` + snapshots, symbol-annotated.
Comparison: `greeneye compare dumps/real-<run> dumps/greeneye-<run>
--symbols`, then a short table of M1–M6 with counts. Never publish a single
@@ -98,7 +98,7 @@ Comparison: `greeneye compare dumps/real-<run> dumps/greeneye-<run>
## 6. Adversarial interoperability use
-green-eye is also a safe place to be adversarial: corrupt a reply, flip a
+risc-v-gsp-rm-debugger is also a safe place to be adversarial: corrupt a reply, flip a
capability bit, truncate a control payload, or inject a fault at a chosen
firmware PC, then observe whether the emulation and the firmware agree on the
failure path. The rules:
@@ -112,7 +112,7 @@ failure path. The rules:
## 7. Validating the tool itself
-Before trusting a green-eye session:
+Before trusting a risc-v-gsp-rm-debugger session:
* the demo firmware self-test must pass (`greeneye demo`, `make test`);
* the session must contain the expected `hook`/`watch` registrations and a
diff --git a/debug/risc-v-gsp-rm-vm/docs/07-PORTABILITY-PLAYBOOKS.md b/debug/risc-v-gsp-rm-vm/docs/07-PORTABILITY-PLAYBOOKS.md
index 5426bf1..b0c8c3f 100644
--- a/debug/risc-v-gsp-rm-vm/docs/07-PORTABILITY-PLAYBOOKS.md
+++ b/debug/risc-v-gsp-rm-vm/docs/07-PORTABILITY-PLAYBOOKS.md
@@ -5,7 +5,7 @@
These playbooks cover the three churn axes the project expects: a new GSP
firmware version, the same firmware on a new device, and a new GPU
architecture (e.g. GB10 / DGX Spark / Surface-class). They reuse the
-project's existing version discipline and add green-eye's runtime layer.
+project's existing version discipline and add risc-v-gsp-rm-debugger's runtime layer.
## 0. Common setup
@@ -16,7 +16,7 @@ project's existing version discipline and add green-eye's runtime layer.
3. Build a symbol DB for the new image:
* import the fwimage into the existing Ghidra project tooling
(`tools/ghidra/analyze_fwimage.py`, `DecompileFunctions.java`),
- * `./greeneye.sh symbols export --index <export.tsv> -o symbols-<ver>.json`.
+ * `./risc-v-gsp-rm-debugger.sh symbols export --index <export.tsv> -o symbols-<ver>.json`.
4. Record a baseline session of the previous version (see P1.4) so the
comparison has an anchor.
@@ -29,7 +29,7 @@ emulation is adjusted.
fwimage, diff the RPC dispatcher, subcommands, message layouts and version
strings against the previous version (`cudatool.py delta`-style discipline
for firmware; `diff_corpus.py` for the corpus).
-2. **Probe the new image** — `./greeneye.sh probe <new.fwimage>`: record the
+2. **Probe the new image** — `./risc-v-gsp-rm-debugger.sh probe <new.fwimage>`: record the
first divergence and the first MMIO/read/write addresses. Compare with the
previous version's probe; changed first-touch addresses are early
structure-change signals.
@@ -40,7 +40,7 @@ emulation is adjusted.
* `greeneye record --kernel <rehosted elf> --duration N --snapshot <regions>`
or the scripted harness (`run`),
* the real-backend reference traces for the same workload.
-5. **Compare** — `./greeneye.sh compare dumps/<old> dumps/<new> --symbols`:
+5. **Compare** — `./risc-v-gsp-rm-debugger.sh compare dumps/<old> dumps/<new> --symbols`:
hit-count deltas per function, watchpoint deltas, written-page deltas.
Investigate every function whose call-count changed before touching the
emulation.
@@ -60,7 +60,7 @@ emulation is adjusted.
2. Verify the firmware pairing: the image family (TU10x/GH100/LS10 …), FMC
partition manifests, and the version string; a mismatched pairing presents
as an emulation bug (the project learned this with 570.144 vs 570.211).
-3. `./greeneye.sh probe <device fwimage>` on the new device image; compare
+3. `./risc-v-gsp-rm-debugger.sh probe <device fwimage>` on the new device image; compare
first-divergence maps with the reference device. Differences here usually
point at profile data, not logic.
4. Re-run the P1.4/1.5 loop with the device profile applied; record probe +
@@ -77,7 +77,7 @@ newer PMU/SEC2 images and possibly RV64GC rather than RV64IMAC).
1. **Confirm the ISA and image shape** — `file`/`readelf` the new fwimage:
ISA string, segments, entry, compressed/float extensions. Update the
rehost build flags (`-march=…`) accordingly; note that QEMU supports
- RV64GC even if green-eye's demo uses IMAC.
+ RV64GC even if risc-v-gsp-rm-debugger's demo uses IMAC.
2. **Check the platform's boot variant** — newer platforms use FMC/manifest
partition models (`uproc/*_riscv/fmc`, `safety/PMU-*`, `conf_compute`
Init→ACR→RM flow). Record which partition model the image uses; the
@@ -89,7 +89,7 @@ newer PMU/SEC2 images and possibly RV64GC rather than RV64IMAC).
4. **Run the P1 loop** with the new architecture profile; expect the probe to
show *different* first-touch addresses (new register windows). Update the
device-model scope in `08-ROADMAP.md` with what the probe revealed.
-5. **Host portability** — green-eye itself is Python and QEMU; on aarch64
+5. **Host portability** — risc-v-gsp-rm-debugger itself is Python and QEMU; on aarch64
hosts install `qemu-system-misc` there and the same commands run. Keep
host-specific paths out of session metadata.
@@ -104,7 +104,7 @@ real firmware for a chosen workload.
* or the vfio-mdev path with the same workload.
Save the reference event stream in a session-compatible form (or the
vendor logs plus a conversion note).
-2. **green-eye capture:** run the same workload's firmware-side stimulus in
+2. **risc-v-gsp-rm-debugger capture:** run the same workload's firmware-side stimulus in
the rehosted simulator; record hooks, watchpoints, snapshots.
3. **Compare:** `greeneye compare` for hit/watch/write profiles; for RPC
payloads use M2 field agreement and M3 ordering (a small script or a
diff --git a/debug/risc-v-gsp-rm-vm/docs/08-ROADMAP.md b/debug/risc-v-gsp-rm-vm/docs/08-ROADMAP.md
index 5d8a9b1..3a518c4 100644
--- a/debug/risc-v-gsp-rm-vm/docs/08-ROADMAP.md
+++ b/debug/risc-v-gsp-rm-vm/docs/08-ROADMAP.md
@@ -1,16 +1,16 @@
-# 08 — green-eye roadmap
+# 08 — risc-v-gsp-rm-debugger roadmap
> **# TOOL IN DEVELOPMENT - NOT READY YET!** See 00 for status.
> This is the **near-term, committed** roadmap (rungs R0–R7 below). The
> **long-term program** — adversarial firmware navigation, adjacent
> microcontrollers, a non-QEMU custom simulator, a Verilog soft-processor
> environment and the agentic platform — lives in
-> [`../GREEN-EYE-ROADMAP.md`](../GREEN-EYE-ROADMAP.md).
+> [`../RISC-V-GSP-RM-DEBUGGER-ROADMAP.md`](../RISC-V-GSP-RM-DEBUGGER-ROADMAP.md).
> Items here are **not** v0.1. Do not start them ad hoc; each has a gate.
## R0. Product principles
-* green-eye stays a **development tool**: no shipped dependencies, no guest
+* risc-v-gsp-rm-debugger stays a **development tool**: no shipped dependencies, no guest
presence, no kernel-module coupling.
* Fidelity improvements must be *measurable* (metrics table in 06) and must
not slow the fast path (demo + probe) below usefulness.
@@ -72,7 +72,7 @@ only after the guest-bridge work (PLAN B) no longer depends on it.
[20-MCP-SERVER](20-MCP-SERVER.md) for the live tool list, transports and
capability flags. The text below is the original design sketch.
-**Why:** expose green-eye sessions to AI harnesses and other agents under the
+**Why:** expose risc-v-gsp-rm-debugger sessions to AI harnesses and other agents under the
plugin model the user requested.
**Shape:** a plugin (`plugins/mcp_server.py` when built) that wraps the
@@ -101,7 +101,7 @@ step traces already cover the common cases.
## R5. Fuzzing and mutation harness
Use AFL++ QEMU mode (or a custom mutator) against the rehosted firmware's
-RPC input surface, with green-eye recording crash/trap paths and symbol
+RPC input surface, with risc-v-gsp-rm-debugger recording crash/trap paths and symbol
annotation. Requires R1/R2 for stable input plumbing. Output: a corpus of
malformed controls and the firmware's error paths, feeding the emulation's
fail-closed rules (project security hygiene).
@@ -114,13 +114,13 @@ tables. This automates `07-PORTABILITY-PLAYBOOKS` P1–P3.
## R7. Ghidra two-way console
-A Ghidra script/plugin that talks to a live green-eye session (via the CLI or
+A Ghidra script/plugin that talks to a live risc-v-gsp-rm-debugger session (via the CLI or
a local socket) to toggle breakpoints/watchpoints from the decompiler and to
highlight hit addresses. Until then, the hit-TSV + `MarkGreenEyeHits.java`
flow is the supported path.
-## Not on the green-eye roadmap
+## Not on the risc-v-gsp-rm-debugger roadmap
* Graphics/display emulation, Windows guest internals, multi-tenant policy —
these belong to the main project roadmap, not to this analysis tool.
-* Replacing Ghidra: green-eye is the dynamic complement, never a decompiler.
+* Replacing Ghidra: risc-v-gsp-rm-debugger is the dynamic complement, never a decompiler.
diff --git a/debug/risc-v-gsp-rm-vm/docs/09-GSP-FIRMWARE-NOTES.md b/debug/risc-v-gsp-rm-vm/docs/09-GSP-FIRMWARE-NOTES.md
index 216bf93..b930cb9 100644
--- a/debug/risc-v-gsp-rm-vm/docs/09-GSP-FIRMWARE-NOTES.md
+++ b/debug/risc-v-gsp-rm-vm/docs/09-GSP-FIRMWARE-NOTES.md
@@ -1,4 +1,4 @@
-# 09 — GSP/uproc firmware notes used by green-eye
+# 09 — GSP/uproc firmware notes used by risc-v-gsp-rm-debugger
> **# TOOL IN DEVELOPMENT - NOT READY YET!** See 00 for status.
> Exact local-source provenance is recorded in the local task record; this
@@ -55,7 +55,7 @@ Two OS layers appear in the vendor snapshots:
paid for. This is the direction the GSP stack evolves toward.
**Implication for the simulator:** the scheduler is not the interesting part
-for RPC accuracy; the task/dispatcher semantics are. Green-eye's demo mirrors
+for RPC accuracy; the task/dispatcher semantics are. Risc-V GSP-RM debugger's demo mirrors
that shape (mailbox → dispatcher → handler → counters), and a rehost shim
should stub the scheduler while keeping task entry points and message
handling real.
@@ -73,7 +73,7 @@ handling real.
a live GSP with a debug command (`nvwatch …`) for bring-up.
These models matter for portability: a new architecture may change the
-partition layout or boot order, and green-eye's probe is the quickest way to
+partition layout or boot order, and risc-v-gsp-rm-debugger's probe is the quickest way to
see the new first-touch sequence before a device model exists.
## 5. Memory, DMA and registers
@@ -84,14 +84,14 @@ see the new first-touch sequence before a device model exists.
* The engines exchange data over **CSB/TRANSCOM windows and mailboxes** with
DMA into host/FB memory; the physical backend work in Open-IOV already
models the message-queue side (status/command queues, doorbells) — that is
- the layer green-eye can emulate first when R1 lands.
+ the layer risc-v-gsp-rm-debugger can emulate first when R1 lands.
* The GSP kernel's start path receives its memory permissions as boot args
from the bootloader rather than discovering them, which is why a
re-host should pass the same structure rather than re-derive it.
-## 6. How green-eye models this today (and honestly, does not)
+## 6. How risc-v-gsp-rm-debugger models this today (and honestly, does not)
-| Firmware aspect | green-eye v0.1 |
+| Firmware aspect | risc-v-gsp-rm-debugger v0.1 |
|---|---|
| Task/dispatcher/state-machine logic | modelled faithfully by the demo and by rehosted code |
| RPC handler input/output behaviour | observable and recordable; schemas decode structures |
diff --git a/debug/risc-v-gsp-rm-vm/docs/10-RELATED-WORK.md b/debug/risc-v-gsp-rm-vm/docs/10-RELATED-WORK.md
index a2a45db..90ca799 100644
--- a/debug/risc-v-gsp-rm-vm/docs/10-RELATED-WORK.md
+++ b/debug/risc-v-gsp-rm-vm/docs/10-RELATED-WORK.md
@@ -11,7 +11,7 @@ frida-agent requires a hosted OS process. The GSP image is bare-metal RV64
with its own libos; there is nothing to inject into, and even a hypothetical
RISC-V port would need an OS layer the firmware does not have.
-**Where the Frida *idea* lives in green-eye:** the scripting model. `Session`
+**Where the Frida *idea* lives in risc-v-gsp-rm-debugger:** the scripting model. `Session`
offers `hook`/`watch`/`memory`/`events` with Python callbacks, which is the
part of Frida that matters for this workflow. The difference is transport:
RSP to QEMU instead of an injected agent.
@@ -24,23 +24,23 @@ guest today.
## 2. GDB / gdbstub
QEMU's gdbstub is the transport both tools share. GDB itself is still useful
-for *debugging green-eye* (stub behaviour, protocol traces), and `gdb
+for *debugging risc-v-gsp-rm-debugger* (stub behaviour, protocol traces), and `gdb
-multiarch` can inspect the same target interactively. It is not the
instrumentation layer here because:
* every operation becomes a subprocess/parse problem instead of an API call;
* recording, symbol annotation, structure decoding and session diffing would
have to be rebuilt around GDB/MI anyway;
-* the project already uses GDB Python scripts for the CUDA corpus; green-eye
+* the project already uses GDB Python scripts for the CUDA corpus; risc-v-gsp-rm-debugger
is the equivalent for firmware, with a stronger data model.
## 3. QEMU TCG plugins
The correct complement, not a competitor: plugins execute inside QEMU and can
observe **every** instruction and memory access, which gdbstub breakpoints
-cannot. green-eye's `qemu/greeneye_trace.c` emits a JSONL access trace for
+cannot. risc-v-gsp-rm-debugger's `qemu/greeneye_trace.c` emits a JSONL access trace for
exactly this; integrating it into the session format is R4 on the roadmap.
-Rule of thumb: use green-eye hooks for semantics ("handler X ran with these
+Rule of thumb: use risc-v-gsp-rm-debugger hooks for semantics ("handler X ran with these
args") and TCG plugins for coverage/heatmaps ("every write to this window").
## 4. Unicorn / emulator libraries
@@ -55,17 +55,17 @@ reason the roadmap defers that work.
`rr` does not support RISC-V guests and records at the host-process level.
QEMU's own record/replay (`-icount`) can provide deterministic reruns later;
-green-eye's session recording occupies a different niche (semantic events,
+risc-v-gsp-rm-debugger's session recording occupies a different niche (semantic events,
not full replay) and can coexist.
## 6. Comparison table
-| Tool | Layer | RISC-V firmware | green-eye relationship |
+| Tool | Layer | RISC-V firmware | risc-v-gsp-rm-debugger relationship |
|---|---|---|---|
| Frida | userland process injection | no | conceptual model only |
-| GDB + gdbstub | execution control | yes (transport) | debugging green-eye; same stub |
+| GDB + gdbstub | execution control | yes (transport) | debugging risc-v-gsp-rm-debugger; same stub |
| QEMU TCG plugin | full instruction/memory trace | yes | complement (R4) |
-| green-eye | semantic instrumentation + recording + analysis | yes | this tool |
+| risc-v-gsp-rm-debugger | semantic instrumentation + recording + analysis | yes | this tool |
| Unicorn/rv8/etc. | CPU emulation library | yes | R2 candidate |
| Ghidra | static decompilation | yes | symbol/hit bridge (05) |
diff --git a/debug/risc-v-gsp-rm-vm/docs/11-GSP-RM-SERVICE-DEVELOPER-GUIDE.md b/debug/risc-v-gsp-rm-vm/docs/11-GSP-RM-SERVICE-DEVELOPER-GUIDE.md
index 6ba8d69..db5109c 100644
--- a/debug/risc-v-gsp-rm-vm/docs/11-GSP-RM-SERVICE-DEVELOPER-GUIDE.md
+++ b/debug/risc-v-gsp-rm-vm/docs/11-GSP-RM-SERVICE-DEVELOPER-GUIDE.md
@@ -9,13 +9,13 @@
The GSP runs a resource manager (RM) as **services**: message handlers, state
machines and engines that own objects (devices, address spaces, channels,
memory, notifiers) and answer controls. Open-IOV emulates those services; the
-long-term goal of green-eye is to let a developer **write, inject, run and
+long-term goal of risc-v-gsp-rm-debugger is to let a developer **write, inject, run and
debug their own versions of these services** before (or instead of) changing
the product emulation.
This guide teaches the loop on the demo uproc — which implements the same
shape as a GSP service — and maps each step to the future GSP-RM work in
-[`GREEN-EYE-ROADMAP.md`](../GREEN-EYE-ROADMAP.md) H1.3.
+[`RISC-V-GSP-RM-DEBUGGER-ROADMAP.md`](../RISC-V-GSP-RM-DEBUGGER-ROADMAP.md) H1.3.
## 2. Service anatomy
@@ -62,7 +62,7 @@ entry points, which is also the interception point).
## 4. Injecting and invoking
```bash
-./greeneye.sh inject --service sdk/build/injected_demo.elf \
+./risc-v-gsp-rm-debugger.sh inject --service sdk/build/injected_demo.elf \
--cmd 1 --arg0 0x41 --arg1 0x42
```
@@ -107,10 +107,9 @@ behaviour before the product emulation implements it.
## 6. Resource surfaces an engine can use
-Category map (details are RM-version-specific and tracked privately where
-provenance requires it):
+Category map (details are RM-version-specific):
-| Surface | Purpose | How green-eye helps today |
+| Surface | Purpose | How risc-v-gsp-rm-debugger helps today |
|---|---|---|
| Memory / descriptors | allocate, map, free, register host or vidmem ranges | watchpoints on allocation state; snapshot/diff; schema decode |
| Address spaces / page tables | GPU VA translation, mapping updates | hooks on map/unmap routines; memory diffs; TCG trace of accesses |
@@ -165,10 +164,10 @@ case 7:
```bash
make -C sdk
-./greeneye.sh inject --cmd 7 --arg0 0xab --arg1 0xcd
+./risc-v-gsp-rm-debugger.sh inject --cmd 7 --arg0 0xab --arg1 0xcd
# direct call -> 0xcdab
# firmware call -> 0xcdab
-./greeneye.sh analyze <printed session dir> # event/hit report
+./risc-v-gsp-rm-debugger.sh analyze <printed session dir> # event/hit report
```
## 10. What comes next (roadmap)
diff --git a/debug/risc-v-gsp-rm-vm/docs/12-INJECTION-SDK.md b/debug/risc-v-gsp-rm-vm/docs/12-INJECTION-SDK.md
index 26f1ffb..65ebb1d 100644
--- a/debug/risc-v-gsp-rm-vm/docs/12-INJECTION-SDK.md
+++ b/debug/risc-v-gsp-rm-vm/docs/12-INJECTION-SDK.md
@@ -1,7 +1,7 @@
# 12 — Injection SDK specification (v1, demo ABI)
> **# TOOL IN DEVELOPMENT - NOT READY YET!** See 00 for status and
-> [`GREEN-EYE-ROADMAP.md`](../GREEN-EYE-ROADMAP.md) §H1/H3 for the program.
+> [`RISC-V-GSP-RM-DEBUGGER-ROADMAP.md`](../RISC-V-GSP-RM-DEBUGGER-ROADMAP.md) §H1/H3 for the program.
## 1. Goals and non-goals
diff --git a/debug/risc-v-gsp-rm-vm/docs/13-GHIDRA-CONTROL.md b/debug/risc-v-gsp-rm-vm/docs/13-GHIDRA-CONTROL.md
index 26e534d..4d45160 100644
--- a/debug/risc-v-gsp-rm-vm/docs/13-GHIDRA-CONTROL.md
+++ b/debug/risc-v-gsp-rm-vm/docs/13-GHIDRA-CONTROL.md
@@ -2,7 +2,7 @@
> **# TOOL IN DEVELOPMENT - NOT READY YET!** See 00 for status.
-The bridge lets a GhidraScript drive a live green-eye session: execute the
+The bridge lets a GhidraScript drive a live risc-v-gsp-rm-debugger session: execute the
target until a point **chosen in the decompiler**, set/clear breakpoints, read
memory and registers, make remote calls, and export hit lists back into the
Ghidra project. Nothing about the firmware has to be rebuilt or re-hosted to
@@ -18,7 +18,7 @@ Ghidra (Java script) ── JSON lines over localhost ──► greeneye gdbridg
```bash
# Terminal 1: a live target + bridge (records by default)
-./greeneye.sh ghidra --kernel firmware/uproc_demo/build/uproc_demo.elf --bridge-port 7000
+./risc-v-gsp-rm-debugger.sh ghidra --kernel firmware/uproc_demo/build/uproc_demo.elf --bridge-port 7000
# prints: ghidra bridge on 127.0.0.1:7000
# Terminal 2: Ghidra headless, run until the decompiler's address
@@ -120,7 +120,7 @@ the decompiler (unit-test style), then inspect memory with
## 5. Address conventions
Ghidra shows **program addresses** (e.g. libcuda file vaddr + image base).
-green-eye resolves **runtime addresses**. For firmware linked at its load
+risc-v-gsp-rm-debugger resolves **runtime addresses**. For firmware linked at its load
address these coincide; otherwise export symbols with the right bias
(docs/05-GHIDRA-BRIDGE.md) and prefer `resolve(name)` over hardcoded numbers.
@@ -140,7 +140,7 @@ address these coincide; otherwise export symbols with the right bias
| Symptom | Cause / fix |
|---|---|
| `Connection refused` | bridge not started, wrong port, or it exited (`close`) |
-| `green-eye bridge closed the connection` | the server was stopped or the target session closed |
+| `risc-v-gsp-rm-debugger bridge closed the connection` | the server was stopped or the target session closed |
| timeout on `run_until` | address not executed; check symbol bias and that the target is not wedged |
| empty `hits` | the session was started without recording; use the CLI (records by default) |
| Java compile error on script load | Ghidra API drift; the script targets Ghidra 11/12 `GhidraScript` |
diff --git a/debug/risc-v-gsp-rm-vm/docs/14-ADVERSARIAL-INTEROP-GUIDE.md b/debug/risc-v-gsp-rm-vm/docs/14-ADVERSARIAL-INTEROP-GUIDE.md
index fb78265..f5b2568 100644
--- a/debug/risc-v-gsp-rm-vm/docs/14-ADVERSARIAL-INTEROP-GUIDE.md
+++ b/debug/risc-v-gsp-rm-vm/docs/14-ADVERSARIAL-INTEROP-GUIDE.md
@@ -1,4 +1,4 @@
-# 14 — Firmware adversarial interoperability research guide (green-eye + Ghidra)
+# 14 — Firmware adversarial interoperability research guide (risc-v-gsp-rm-debugger + Ghidra)
> **# TOOL IN DEVELOPMENT - NOT READY YET!** See 00 for status.
@@ -8,10 +8,10 @@ Open-IOV's hard problem is not writing the GSP emulation once; it is keeping
`open-iov-vfio` accurate while the firmware changes underneath it. New GSP
images, device pairings and architectures arrive stripped, signed and
hardware-coupled, and some actively resist analysis. This guide is the
-practical companion to `GREEN-EYE-ROADMAP.md` H4: how to move from "the new
+practical companion to `RISC-V-GSP-RM-DEBUGGER-ROADMAP.md` H4: how to move from "the new
image does something different" to a reviewed product change with evidence.
-Ghidra is the **static map**; green-eye is the **dynamic ground truth**;
+Ghidra is the **static map**; risc-v-gsp-rm-debugger is the **dynamic ground truth**;
recorded sessions are the **shared evidence**. Recipes use only the v0.1
surface, plus items explicitly labelled roadmap; see also docs/06-ACCURACY.md.
@@ -41,16 +41,16 @@ hardware coupling a simulator cannot yet exercise.
not proof of dead code.
4. Every claim carries its fidelity level (L0–L3, docs/06) and provenance.
-## 3. The joint workflow: Ghidra, green-eye, sessions
+## 3. The joint workflow: Ghidra, risc-v-gsp-rm-debugger, sessions
```
question > Ghidra (static): decompile, dispatcher tables, symbols
- > green-eye (dynamic): same stimulus, hooks, watchpoints, trace
+ > risc-v-gsp-rm-debugger (dynamic): same stimulus, hooks, watchpoints, trace
> sessions + hits TSV: greeneye compare -> triage -> evidence pack
> open-iov-vfio change (with evidence)
```
-| Question | Ghidra answers | green-eye answers | Shared artifact |
+| Question | Ghidra answers | risc-v-gsp-rm-debugger answers | Shared artifact |
|---|---|---|---|
| What is this code? | decompilation, call graph, xrefs | — | symbol DB (docs/05) |
| Did it execute here? | hypothesis from xrefs | `bp_hit`/`watch_hit` events | `greeneye_hits.tsv` |
@@ -73,22 +73,22 @@ emulation is touched.
`addr<TAB>name<TAB>size`, which `symbols export --index` accepts:
```bash
- ./greeneye.sh symbols export --index <new-export.tsv> --bias 0 -o symbols-new.json
- ./greeneye.sh symbols export --index <old-export.tsv> --bias 0 -o symbols-old.json
+ ./risc-v-gsp-rm-debugger.sh symbols export --index <new-export.tsv> --bias 0 -o symbols-new.json
+ ./risc-v-gsp-rm-debugger.sh symbols export --index <old-export.tsv> --bias 0 -o symbols-old.json
```
2. Probe each image for first-touch structure changes (docs/07 P1.2):
```bash
- ./greeneye.sh probe <old.fwimage> --symbols symbols-old.json --record
- ./greeneye.sh probe <new.fwimage> --symbols symbols-new.json --record
+ ./risc-v-gsp-rm-debugger.sh probe <old.fwimage> --symbols symbols-old.json --record
+ ./risc-v-gsp-rm-debugger.sh probe <new.fwimage> --symbols symbols-new.json --record
```
3. Run the **same stimulus** against the re-hosted build of each version. Put
it in a script so it is identical across runs:
```python
- # run_stimulus.py -- ./greeneye.sh run run_stimulus.py --kernel <rehosted.elf>
+ # run_stimulus.py -- ./risc-v-gsp-rm-debugger.sh run run_stimulus.py --kernel <rehosted.elf>
import greeneye as ge
s = ge.launch(kernel="<rehosted.elf>", record=True, name="stim")
ctrl = s.symbols.lookup("<control-symbol>") # demo: gsp_ctrl
@@ -109,7 +109,7 @@ emulation is touched.
delta and written-page delta:
```bash
- ./greeneye.sh compare dumps/<old-run> dumps/<new-run> --symbols
+ ./risc-v-gsp-rm-debugger.sh compare dumps/<old-run> dumps/<new-run> --symbols
```
5. Triage with a decision table rather than intuition:
@@ -134,7 +134,7 @@ with the capability model the emulation assumes.
1. Instrument the object ranges the service owns (kinds `w`, `r`, `a`):
```python
- # capability_probe.py -- ./greeneye.sh run capability_probe.py --kernel <elf>
+ # capability_probe.py -- ./risc-v-gsp-rm-debugger.sh run capability_probe.py --kernel <elf>
import greeneye as ge
s = ge.launch(kernel="<rehosted.elf>", record=True, name="caps")
base = s.symbols.lookup("<object-symbol>")
@@ -155,7 +155,7 @@ with the capability model the emulation assumes.
-serial file:/tmp/uart.log -bios none -kernel <rehosted.elf> -S \
-gdb tcp:127.0.0.1:4444 \
-plugin qemu/greeneye-trace.so,path=/tmp/ge-trace.jsonl,start=0x80000000,end=0x81000000,exec=on
- ./greeneye.sh attach --port 4444 --kernel <rehosted.elf> --plugin <capability-plugin.py>
+ ./risc-v-gsp-rm-debugger.sh attach --port 4444 --kernel <rehosted.elf> --plugin <capability-plugin.py>
```
`start=`/`end=` bound the trace, `exec=on` adds per-instruction records and
@@ -183,7 +183,7 @@ roadmap R5; until then, bounded mutation over existing primitives is honest.
1. Mutate single fields deterministically and record each attempt:
```python
- # mutate.py -- ./greeneye.sh run mutate.py --kernel <rehosted.elf>
+ # mutate.py -- ./risc-v-gsp-rm-debugger.sh run mutate.py --kernel <rehosted.elf>
import greeneye as ge
s = ge.launch(kernel="<rehosted.elf>", record=True, name="mutate")
ctrl = s.symbols.lookup("<control-symbol>")
@@ -205,12 +205,12 @@ roadmap R5; until then, bounded mutation over existing primitives is honest.
```
3. Capture error paths with hooks/watchpoints on the dispatcher, fault
- handlers and assert sites (symbol DB); `./greeneye.sh demo` records a trap.
+ handlers and assert sites (symbol DB); `./risc-v-gsp-rm-debugger.sh demo` records a trap.
4. Compare clean vs mutated sessions, keeping the mutation value in a `note`
so the pack is self-describing:
```bash
- ./greeneye.sh compare dumps/<clean-run> dumps/<mutated-run> --symbols
+ ./risc-v-gsp-rm-debugger.sh compare dumps/<clean-run> dumps/<mutated-run> --symbols
```
Every corpus entry needs the firmware hash; never run mutation against
@@ -225,7 +225,7 @@ timing or integrity state, or contains bogus code paths.
require the comparison to be empty:
```bash
- ./greeneye.sh compare dumps/<run1> dumps/<run2> --symbols
+ ./risc-v-gsp-rm-debugger.sh compare dumps/<run1> dumps/<run2> --symbols
```
Any delta is a non-determinism candidate (scheduler, uninitialised read, time); record it.
@@ -284,7 +284,7 @@ Goal: measure, not narrate. The contract is the M1–M6 table from docs/06:
Procedure: (1) capture the reference on hardware/VFIO (docs/07 P4); (2) capture
the simulator side with `record`/scripted `run`, hooks, watchpoints and
-snapshots; (3) `./greeneye.sh compare dumps/<reference-dir> dumps/<greeneye-dir>
+snapshots; (3) `./risc-v-gsp-rm-debugger.sh compare dumps/<reference-dir> dumps/<greeneye-dir>
--symbols`, with a script or plugin for per-control M2/M3 payload events;
(4) repeat with the injected-service path to test the service boundary;
(5) escalate — divergence that would change emulation behaviour must be
@@ -293,7 +293,7 @@ reproduced physically; simulator-only divergence becomes a fidelity gap.
### 4.6 From observation to reimplementation
The canonical accuracy loop (roadmap H4.5): (1) observe on hardware/VFIO;
-(2) observe in green-eye (replayable session); (3) `compare` + M1–M6;
+(2) observe in risc-v-gsp-rm-debugger (replayable session); (3) `compare` + M1–M6;
(4) implement in `open-iov-vfio` with the session directories attached as
evidence; (5) re-run the same stimulus and require the metric table to improve
or stay equal.
@@ -307,7 +307,7 @@ changed; decoy or low-fidelity observations never justify a product change.
Start the live bridge and drive it from the decompiler:
```bash
-./greeneye.sh ghidra --kernel <rehosted.elf> --bridge-port 7000
+./risc-v-gsp-rm-debugger.sh ghidra --kernel <rehosted.elf> --bridge-port 7000
$GHIDRA/support/analyzeHeadless <proj> <name> -process <program> -noanalysis \
-scriptPath debug/risc-v-gsp-rm-vm/ghidra \
-postScript GreenEyeControl.java 7000 0x<decompiler-address>
@@ -320,13 +320,13 @@ the bridge (`watch_set`) without a Java wrapper: `send("watch_set", {...})`.
Address conventions and bias pitfalls (docs/05 §1):
-* Ghidra shows **program addresses**; green-eye resolves **runtime addresses**.
+* Ghidra shows **program addresses**; risc-v-gsp-rm-debugger resolves **runtime addresses**.
For firmware linked at its load address they coincide; otherwise supply
`--bias` when building the symbol DB (`ExportForGreenEye.java` emits program
addresses).
* The classic mistake is passing a program address to `hook()` when the image
base is non-zero; prefer `s.hook("<name>")` and pass raw numbers through
- `resolve`. `decompiled_index.tsv` carries both spaces; green-eye keeps the
+ `resolve`. `decompiled_index.tsv` carries both spaces; risc-v-gsp-rm-debugger keeps the
program address in `symbol.extras["program_addr"]` for `bucket:line` mapping.
* Wrapper-generated functions are re-laid-out between versions: transfer
names, never raw wrapper addresses (docs/05 §6).
diff --git a/debug/risc-v-gsp-rm-vm/docs/15-AGENTIC-GSP-IDE.md b/debug/risc-v-gsp-rm-vm/docs/15-AGENTIC-GSP-IDE.md
index 79d17b8..1a4c62f 100644
--- a/debug/risc-v-gsp-rm-vm/docs/15-AGENTIC-GSP-IDE.md
+++ b/debug/risc-v-gsp-rm-vm/docs/15-AGENTIC-GSP-IDE.md
@@ -1,10 +1,10 @@
-# 15 — green-eye as an agentic integrated development, analysis and debugging environment for the GPU System Processor
+# 15 — risc-v-gsp-rm-debugger as an agentic integrated development, analysis and debugging environment for the GPU System Processor
> **# TOOL IN DEVELOPMENT - NOT READY YET!** See 00 for status.
## 1. Vision and what "agentic" means here
-green-eye already has the two properties that make an agent loop possible:
+risc-v-gsp-rm-debugger already has the two properties that make an agent loop possible:
a **deterministic, scriptable harness** (`ge.launch`/`ge.attach`, `Session`,
`record`, `compare`) and a **durable evidence format** (the session directory).
"Agentic" here means:
@@ -27,7 +27,7 @@ hooks that would make a full agent platform real.
```
+-------------------- agents (triage / hypothesis / RE / portability) ----+
| |
- | CLI: ./greeneye.sh info|demo|run|attach|launch|probe|record|analyze| |
+ | CLI: ./risc-v-gsp-rm-debugger.sh info|demo|run|attach|launch|probe|record|analyze| |
| compare|symbols|plugins|inject|ghidra |
| Python: ge.launch/attach, Session.*, memory.*, symbols.*, structs, |
| probes, plugins, ghidra.export_hits, inject.* |
@@ -55,11 +55,11 @@ primitive: it turns two sessions into hit/watch/write deltas. Format
### 2.2 Surfaces an agent may use
-* `./greeneye.sh …` — the stable CLI (all real subcommands listed above).
-* `./greeneye.sh run script.py` — the preloaded Python namespace (`ge`,
+* `./risc-v-gsp-rm-debugger.sh …` — the stable CLI (all real subcommands listed above).
+* `./risc-v-gsp-rm-debugger.sh run script.py` — the preloaded Python namespace (`ge`,
`session`/`s`, `memory`, `symbols`, `recorder`) makes a harness file the
unit of automation.
-* `./greeneye.sh ghidra` + `GreenEyeControl.java` — JSON-lines bridge for the
+* `./risc-v-gsp-rm-debugger.sh ghidra` + `GreenEyeControl.java` — JSON-lines bridge for the
decompiler loop (`run_until`, `bp_set`, `read_mem`, `call`, `hits`,
`export_hits`; protocol in docs/13 §3).
* Plugins — the extension point (docs/04). A plugin's `register(ge)` can add
@@ -103,17 +103,17 @@ Question template: "For control `<X>`, does the firmware set field `<Y>` of
the reply/object, and in what order relative to `<Z>`?"
1. Frame it as A/B: the emulation's reply (reference capture, docs/07 P4) and
- the firmware's reply in green-eye. One session alone cannot answer it.
+ the firmware's reply in risc-v-gsp-rm-debugger. One session alone cannot answer it.
2. Resolve the handler and object from the symbol DB; never hardcode:
```bash
- ./greeneye.sh symbols resolve --db symbols-<ver>.json <handler-or-addr>
+ ./risc-v-gsp-rm-debugger.sh symbols resolve --db symbols-<ver>.json <handler-or-addr>
```
3. Capture the firmware side with a hook + before/after snapshots:
```python
- # reply_q.py -- ./greeneye.sh run reply_q.py --kernel <rehosted.elf>
+ # reply_q.py -- ./risc-v-gsp-rm-debugger.sh run reply_q.py --kernel <rehosted.elf>
import greeneye as ge
from greeneye import Memory
@@ -144,7 +144,7 @@ the reply/object, and in what order relative to `<Z>`?"
```
5. Compare against the reference capture with
- `greeneye.analyze.compare_sessions(...)` / `./greeneye.sh compare …` for
+ `greeneye.analyze.compare_sessions(...)` / `./risc-v-gsp-rm-debugger.sh compare …` for
ordering (M3) and state the field diff in words (M2). If the reply is in a
different object, repeat step 3 on that object's address.
6. Report: question, session pair, `compare` output, M2/M3 rows, fidelity
@@ -158,14 +158,14 @@ the reply/object, and in what order relative to `<Z>`?"
$GHIDRA/support/analyzeHeadless <proj> <name> -process <program> -noanalysis \
-scriptPath debug/risc-v-gsp-rm-vm/ghidra \
-postScript ExportForGreenEye.java /tmp/symbols-<ver>.tsv
- ./greeneye.sh symbols export --index /tmp/symbols-<ver>.tsv --bias 0 -o symbols-<ver>.json
+ ./risc-v-gsp-rm-debugger.sh symbols export --index /tmp/symbols-<ver>.tsv --bias 0 -o symbols-<ver>.json
diff <(cut -f2 /tmp/symbols-old.tsv | sort) <(cut -f2 /tmp/symbols-new.tsv | sort)
```
2. Probe the new image for early structure changes:
```bash
- ./greeneye.sh probe <new.fwimage> --symbols symbols-<ver>.json --record
+ ./risc-v-gsp-rm-debugger.sh probe <new.fwimage> --symbols symbols-<ver>.json --record
```
3. Record the same stimulus against each version. Hook the old handler name;
@@ -175,8 +175,8 @@ the reply/object, and in what order relative to `<Z>`?"
4. Compare the sessions:
```bash
- ./greeneye.sh compare dumps/<old-run> dumps/<new-run> --symbols
- ./greeneye.sh analyze dumps/<new-run> --symbols symbols-<ver>.json --out new.md
+ ./risc-v-gsp-rm-debugger.sh compare dumps/<old-run> dumps/<new-run> --symbols
+ ./risc-v-gsp-rm-debugger.sh analyze dumps/<new-run> --symbols symbols-<ver>.json --out new.md
```
5. Classify the disappearance with the table below, then confirm in Ghidra:
@@ -188,7 +188,7 @@ the reply/object, and in what order relative to `<Z>`?"
| old function exists, zero hits under the standard stimulus | coverage gap or decoy | widen stimulus, check xrefs from the dispatch table |
| dispatch table entry changed but code identical | behaviour moved (state/input) | inspect the table with bridge `read_mem`/snapshot |
-6. With the bridge running (`./greeneye.sh ghidra --kernel <elf>`), execute
+6. With the bridge running (`./risc-v-gsp-rm-debugger.sh ghidra --kernel <elf>`), execute
until the dispatch site from the decompiler and set breakpoints:
```bash
@@ -200,7 +200,7 @@ the reply/object, and in what order relative to `<Z>`?"
7. Export hits and annotate the old function's fate:
```bash
- ./greeneye.sh analyze dumps/<new-run> --symbols symbols-<ver>.json --out new.md
+ ./risc-v-gsp-rm-debugger.sh analyze dumps/<new-run> --symbols symbols-<ver>.json --out new.md
python3 - <<'PY'
from greeneye.ghidra import export_hits
from greeneye.symbols import SymbolDB
@@ -225,7 +225,7 @@ the reply/object, and in what order relative to `<Z>`?"
mailbox dispatch):
```bash
- ./greeneye.sh inject --service sdk/build/injected_demo.elf \
+ ./risc-v-gsp-rm-debugger.sh inject --service sdk/build/injected_demo.elf \
--cmd 1 --arg0 0x41 --arg1 0x42
```
@@ -244,7 +244,7 @@ the reply/object, and in what order relative to `<Z>`?"
5. Compare two versions of the service to see the behavioural delta:
```bash
- ./greeneye.sh compare dumps/<svc-v1> dumps/<svc-v2> --symbols
+ ./risc-v-gsp-rm-debugger.sh compare dumps/<svc-v1> dumps/<svc-v2> --symbols
```
6. Stop condition: direct and firmware-dispatched results agree, the session
@@ -257,13 +257,13 @@ the reply/object, and in what order relative to `<Z>`?"
1. Follow the P1 loop in docs/07-PORTABILITY-PLAYBOOKS.md with real commands:
```bash
- ./greeneye.sh probe <old.fwimage> --symbols symbols-old.json --record
- ./greeneye.sh probe <new.fwimage> --symbols symbols-new.json --record
- ./greeneye.sh record --kernel <rehosted-old.elf> --duration 2.0 \
+ ./risc-v-gsp-rm-debugger.sh probe <old.fwimage> --symbols symbols-old.json --record
+ ./risc-v-gsp-rm-debugger.sh probe <new.fwimage> --symbols symbols-new.json --record
+ ./risc-v-gsp-rm-debugger.sh record --kernel <rehosted-old.elf> --duration 2.0 \
--watch gsp_ctrl+0x10:8 --snapshot gsp_ctrl:392
- ./greeneye.sh record --kernel <rehosted-new.elf> --duration 2.0 \
+ ./risc-v-gsp-rm-debugger.sh record --kernel <rehosted-new.elf> --duration 2.0 \
--watch gsp_ctrl+0x10:8 --snapshot gsp_ctrl:392
- ./greeneye.sh compare dumps/<old-run> dumps/<new-run> --symbols
+ ./risc-v-gsp-rm-debugger.sh compare dumps/<old-run> dumps/<new-run> --symbols
```
2. Keep the stimulus identical across versions: use one script/probe spec and
diff --git a/debug/risc-v-gsp-rm-vm/docs/16-CUSTOM-SIMULATOR.md b/debug/risc-v-gsp-rm-vm/docs/16-CUSTOM-SIMULATOR.md
index 2f99f7b..a842368 100644
--- a/debug/risc-v-gsp-rm-vm/docs/16-CUSTOM-SIMULATOR.md
+++ b/debug/risc-v-gsp-rm-vm/docs/16-CUSTOM-SIMULATOR.md
@@ -4,10 +4,10 @@
## 1. Purpose and status
-This document is the design and delivery plan for a green-eye-native execution
+This document is the design and delivery plan for a risc-v-gsp-rm-debugger-native execution
backend: a small deterministic RISC-V machine (`libgreenmachine`) implementing
the same `Session` contract as today's QEMU backend. It expands
-`GREEN-EYE-ROADMAP.md` §H3 (H3.1–H3.4) and the §H6 soft-processor annex.
+`RISC-V-GSP-RM-DEBUGGER-ROADMAP.md` §H3 (H3.1–H3.4) and the §H6 soft-processor annex.
**Beyond M1.5 (§1.1), nothing here exists yet.** The only production backend is
`QemuTarget` + `RspClient` (`greeneye/target.py`, `greeneye/rsp.py`); M2+ of
@@ -93,13 +93,13 @@ plugin and without leaving the process:
### 1.2 Usage
```bash
-./greeneye.sh demo --backend native # the canned demo, native backend
-./greeneye.sh run examples/scripts/trace_rpc.py --backend native
-printf 'bp rpc_sum\nc 0.2\nquit\n' | ./greeneye.sh attach --backend native
-./greeneye.sh record --backend native --trace --duration 0.5
-./greeneye.sh record --backend native --trace --trace-exec off \
+./risc-v-gsp-rm-debugger.sh demo --backend native # the canned demo, native backend
+./risc-v-gsp-rm-debugger.sh run examples/scripts/trace_rpc.py --backend native
+printf 'bp rpc_sum\nc 0.2\nquit\n' | ./risc-v-gsp-rm-debugger.sh attach --backend native
+./risc-v-gsp-rm-debugger.sh record --backend native --trace --duration 0.5
+./risc-v-gsp-rm-debugger.sh record --backend native --trace --trace-exec off \
--trace-start 0x80000000 --trace-end 0x80010000
-./greeneye.sh analyze dumps/<stamp>-record # renders the trace coverage section
+./risc-v-gsp-rm-debugger.sh analyze dumps/<stamp>-record # renders the trace coverage section
python3 examples/scripts/sim_bench.py --trace # throughput + trace overhead
python3 examples/scripts/sim_diff.py # QEMU/native profile diff
```
@@ -126,7 +126,7 @@ QEMU is an excellent execution engine and a poor *workflow* engine here. The
limits below are consequences of QEMU being a whole-board emulator with a GDB
stub as its scriptable surface; each maps to a §H3.1 requirement.
-| QEMU property | Consequence for green-eye | Requirement it forces |
+| QEMU property | Consequence for risc-v-gsp-rm-debugger | Requirement it forces |
|---|---|---|
| RSP serialises every access (hex frame, TCP round-trip, `PacketSize` chunking) | register/memory polling and watchpoint step-over are transport-bound; full-access tracing is impractical | in-process backend ABI with direct memory/register calls |
| No cheap machine snapshots; `savevm` is board-level and not exposed over the stub | region snapshots are copied over RSP; no instant checkpoint exists | copy-on-write full-machine snapshot/restore |
@@ -185,7 +185,7 @@ The control plane is unchanged: `Session`, hooks, watchpoints, `Memory`,
bridge sit above a backend interface. The §H3.2 sketch becomes:
```
-+-------------------- green-eye Python control plane --------------------+
++-------------------- risc-v-gsp-rm-debugger Python control plane --------------------+
| Session API, hooks/watchpoints, recorder, plugins, Ghidra/agent bridge |
+---------------------------- Backend interface -------------------------+
| QEMU-RSP backend (today) | native backend (planned)
diff --git a/debug/risc-v-gsp-rm-vm/docs/17-RM-HARNESS.md b/debug/risc-v-gsp-rm-vm/docs/17-RM-HARNESS.md
index 59db437..effacb0 100644
--- a/debug/risc-v-gsp-rm-vm/docs/17-RM-HARNESS.md
+++ b/debug/risc-v-gsp-rm-vm/docs/17-RM-HARNESS.md
@@ -14,7 +14,7 @@ metrics in [06-ACCURACY](06-ACCURACY.md) need the real host RM as a reference:
and engine inventory at a moment in time.
`rmharness` packages the host-side oracle tools and wires their output into
-green-eye sessions, so a simulator/emulation session and a host RM capture
+risc-v-gsp-rm-debugger sessions, so a simulator/emulation session and a host RM capture
can be recorded, diffed and cited together. It is the host half of the
accuracy loop (H4.5), not a boot path or a replacement for PLAN B traces.
@@ -67,7 +67,7 @@ access model as `nvidia-smi` and is safe alongside a running CUDA job.
maps to the RM `deviceId`; `--device PATH` overrides the `/dev/nvidiaN`
node.
-## 5. green-eye integration
+## 5. risc-v-gsp-rm-debugger integration
Wrappers `rmharness/rmtool.sh`, `rmharness/rmtop.sh`, `rmharness/rmq.sh`
locate and build the tools and pass arguments through. `rmharness/harness.sh`
@@ -137,12 +137,12 @@ migrations, MIG or a second GPU.
* **docs/06-ACCURACY** — recorded `rm_harness_run` blobs are the host
reference for M1/M6; keep the JSON captures in the session directories
cited by the metric table.
-* **GREEN-EYE-ROADMAP H3** — the custom simulator's device map and RM-core
+* **RISC-V-GSP-RM-DEBUGGER-ROADMAP H3** — the custom simulator's device map and RM-core
interception need real control semantics (IDs, sizes, status values) to
validate against; `rmtool` supplies that inventory before the H2.2 boot is
reached, and the shared `rm_api.c` can become the simulator's host-RM
client for differential tests.
-* **GREEN-EYE-ROADMAP H4.5** — the canonical observe -> compare -> implement
+* **RISC-V-GSP-RM-DEBUGGER-ROADMAP H4.5** — the canonical observe -> compare -> implement
loop can now include a host capture (`harness.sh --session`) beside the
simulator session, giving every emulation change an evidence pair.
* **R4 (full-memory trace)** — the session-event schema already carries
diff --git a/debug/risc-v-gsp-rm-vm/docs/18-HARNESS-AUTOMATION.md b/debug/risc-v-gsp-rm-vm/docs/18-HARNESS-AUTOMATION.md
index ecd0614..4fbe4d9 100644
--- a/debug/risc-v-gsp-rm-vm/docs/18-HARNESS-AUTOMATION.md
+++ b/debug/risc-v-gsp-rm-vm/docs/18-HARNESS-AUTOMATION.md
@@ -45,7 +45,7 @@ python3 harness/portability_matrix.py \
--out dumps/matrix-570
```
-Replacing the builtin scenario with a fixed green-eye script:
+Replacing the builtin scenario with a fixed risc-v-gsp-rm-debugger script:
```bash
python3 harness/portability_matrix.py --target <rehosted.elf> \
diff --git a/debug/risc-v-gsp-rm-vm/docs/19-CONTROL-DISCOVERY.md b/debug/risc-v-gsp-rm-vm/docs/19-CONTROL-DISCOVERY.md
index 0f9afbe..67ef556 100644
--- a/debug/risc-v-gsp-rm-vm/docs/19-CONTROL-DISCOVERY.md
+++ b/debug/risc-v-gsp-rm-vm/docs/19-CONTROL-DISCOVERY.md
@@ -1,7 +1,7 @@
# 19 — Control discovery and hot-path reachability
> **# TOOL IN DEVELOPMENT - NOT READY YET!** See 00 for status and
-> [`GREEN-EYE-ROADMAP.md`](../GREEN-EYE-ROADMAP.md) H4 for the program.
+> [`RISC-V-GSP-RM-DEBUGGER-ROADMAP.md`](../RISC-V-GSP-RM-DEBUGGER-ROADMAP.md) H4 for the program.
Two harness tools close the loop between "a new firmware image does something
we do not model" and "here is the code path, its trigger and its effects":
@@ -14,7 +14,7 @@ we do not model" and "here is the code path, its trigger and its effects":
Both are simulator-only, bounded, evidence-producing, and depend only on the
public `Session`/hook/watch primitives (stdlib-only Python). They are the
practical start of the "Sandsifter for RM" idea in
-[`GREEN-EYE-ROADMAP.md`](../GREEN-EYE-ROADMAP.md) H4 and reuse the contracts
+[`RISC-V-GSP-RM-DEBUGGER-ROADMAP.md`](../RISC-V-GSP-RM-DEBUGGER-ROADMAP.md) H4 and reuse the contracts
in [06-ACCURACY](06-ACCURACY.md) and [14-ADVERSARIAL-INTEROP-GUIDE](14-ADVERSARIAL-INTEROP-GUIDE.md).
---
@@ -235,7 +235,7 @@ Flags: `--method auto|stimulus|trigger|run|call`, `--all-methods`, `--args`,
`auto` tries methods in this order and stops at the first hit (use
`--all-methods` to compare routes):
-1. `stimulus` — run a green-eye script (or a probe spec's stimulus) with the
+1. `stimulus` — run a risc-v-gsp-rm-debugger script (or a probe spec's stimulus) with the
target hook and watchpoints armed. The script drives `session.run` itself.
2. `trigger` — read the surface's handler table, find the command ID(s) that
resolve to the target, settle the firmware, apply that command and run
diff --git a/debug/risc-v-gsp-rm-vm/docs/20-MCP-SERVER.md b/debug/risc-v-gsp-rm-vm/docs/20-MCP-SERVER.md
index a3b6111..dbfbb36 100644
--- a/debug/risc-v-gsp-rm-vm/docs/20-MCP-SERVER.md
+++ b/debug/risc-v-gsp-rm-vm/docs/20-MCP-SERVER.md
@@ -1,12 +1,12 @@
-# 20 — MCP server (green-eye agent interface)
+# 20 — MCP server (risc-v-gsp-rm-debugger agent interface)
> **# TOOL IN DEVELOPMENT - NOT READY YET!** See 00 for status.
## 1. What it is
-`plugins/mcp_server.py` is the green-eye **MCP (Model Context Protocol)
+`plugins/mcp_server.py` is the risc-v-gsp-rm-debugger **MCP (Model Context Protocol)
server** — roadmap [`R3`](08-ROADMAP.md#r3-mcp-server-plugin) and
-[`H7`](../GREEN-EYE-ROADMAP.md). It exposes the *active* `Session` as MCP
+[`H7`](../RISC-V-GSP-RM-DEBUGGER-ROADMAP.md). It exposes the *active* `Session` as MCP
tools so an AI agent (Claude Code, opencode, any MCP client) can inspect
symbols, set breakpoints/watchpoints, run the target, read memory, snapshot,
analyse/compare recordings, inject services, and drive the harnesses.
@@ -14,7 +14,7 @@ analyse/compare recordings, inject services, and drive the harnesses.
* **Stdlib-only**: JSON-RPC 2.0 over newline-delimited stdin/stdout, no MCP
library, no network listener unless explicitly asked.
* **Plugin first**: `register(ge)` adds an `mcp-serve` REPL/CLI command that
- serves the session already loaded by green-eye.
+ serves the session already loaded by risc-v-gsp-rm-debugger.
* **Standalone too**: the same file runs as a script that launches its own
session (`--kernel`, `--backend`, `--record`) and then serves MCP.
* **Read-only by default**: memory writes, remote calls and injection require
@@ -24,7 +24,7 @@ analyse/compare recordings, inject services, and drive the harnesses.
`not_available` tool error when the module/file is absent instead of
crashing. The tool list always advertises every capability.
-The core green-eye package is untouched; everything lives in the plugin.
+The core risc-v-gsp-rm-debugger package is untouched; everything lives in the plugin.
## 2. Running it
@@ -54,11 +54,11 @@ Logs go to stderr; **stdout carries protocol frames only**.
### 2.2 Plugin mode (serve a live session)
```bash
-./greeneye.sh attach --kernel firmware/uproc_demo/build/uproc_demo.elf \
+./risc-v-gsp-rm-debugger.sh attach --kernel firmware/uproc_demo/build/uproc_demo.elf \
--plugin plugins/mcp_server.py
-greeneye> mcp-serve # read/observe
-greeneye> mcp-serve --allow-write # + memory writes / remote calls
-greeneye> mcp-serve --allow-inject # + service injection
+risc-v-gsp-rm-debugger> mcp-serve # read/observe
+risc-v-gsp-rm-debugger> mcp-serve --allow-write # + memory writes / remote calls
+risc-v-gsp-rm-debugger> mcp-serve --allow-inject # + service injection
```
`mcp-serve` blocks until the MCP client disconnects or calls the `close`
@@ -80,7 +80,7 @@ client configs use standalone mode. Use absolute paths.
```json
{
"mcpServers": {
- "green-eye": {
+ "risc-v-gsp-rm-debugger": {
"command": "python3",
"args": [
"/home/rmcore/Git/integdev_gpu_drv/open-iov/debug/risc-v-gsp-rm-vm/plugins/mcp_server.py",
@@ -94,7 +94,7 @@ client configs use standalone mode. Use absolute paths.
}
```
-Or, one line: `claude mcp add green-eye -- python3
+Or, one line: `claude mcp add risc-v-gsp-rm-debugger -- python3
<tool-root>/plugins/mcp_server.py --stdio --record`.
### 3.2 opencode (`opencode.json`)
@@ -103,7 +103,7 @@ Or, one line: `claude mcp add green-eye -- python3
{
"$schema": "https://opencode.ai/config.json",
"mcp": {
- "green-eye": {
+ "risc-v-gsp-rm-debugger": {
"type": "local",
"command": [
"python3",
@@ -227,7 +227,7 @@ recorded, and the session can be compared like any other run.
2. **No guest, no hardware.** The server drives the simulator/QEMU session
only. It does not touch `/dev`, a kernel module, an mdev, a guest or a
physical GPU; the agent runs against the simulator by default
- ([H7](../GREEN-EYE-ROADMAP.md), [15-AGENTIC-GSP-IDE](15-AGENTIC-GSP-IDE.md) §5).
+ ([H7](../RISC-V-GSP-RM-DEBUGGER-ROADMAP.md), [15-AGENTIC-GSP-IDE](15-AGENTIC-GSP-IDE.md) §5).
3. **Read-only by default.** `--allow-write` enables `write_mem` and
`call_function`; `--allow-inject` enables `inject_service`. The agent's
client config decides which manifest class it gets; a read/observe agent is
diff --git a/debug/risc-v-gsp-rm-vm/docs/21-CI-RELEASE-PIPELINE.md b/debug/risc-v-gsp-rm-vm/docs/21-CI-RELEASE-PIPELINE.md
index aa71b54..d4d7680 100644
--- a/debug/risc-v-gsp-rm-vm/docs/21-CI-RELEASE-PIPELINE.md
+++ b/debug/risc-v-gsp-rm-vm/docs/21-CI-RELEASE-PIPELINE.md
@@ -13,7 +13,7 @@ playbook into one repeatable run and one attachable bundle:
| `harness/version_diff.py` | old vs new target, section by section: image/shape, symbol inventory, decompiled corpus hints, bounded QEMU probe, shared-scenario behavior, M1–M6 skeleton |
| `harness/ci_release.py` | runs version_diff → portability matrix → mutation smoke and hashes every artifact into `bundle-manifest.json` |
-`.github/workflows/greeneye.yml` runs the tool's test suite on pushes/PRs that
+`.github/workflows/risc-v-gsp-rm-debugger.yml` runs the tool's test suite on pushes/PRs that
touch `debug/risc-v-gsp-rm-vm/**` or `tools/rm*/**`. The repository-level
`.github/workflows/ci.yml` is independent and unchanged.
@@ -65,7 +65,7 @@ section then reports `skipped` with a reason unless Ghidra/JSON sources are
supplied.
Flags: `--old/--new` (required), `--out` (required), `--old-label/--new-label/
---release`, `--old-symbols/--new-symbols` (green-eye JSON), `--old-ghidra-names`,
+--release`, `--old-symbols/--new-symbols` (risc-v-gsp-rm-debugger JSON), `--old-ghidra-names`,
`--new-ghidra-names`, `--old-ghidra-index`, `--new-ghidra-index`,
`--old-ghidra-exports`, `--new-ghidra-exports` (`--old-ghidra-bias`/
`--new-ghidra-bias`), `--corpus-diff OLD NEW`, `--corpus-report FILE`,
@@ -84,7 +84,7 @@ never aborts the others. A failing QEMU probe or scenario is recorded as
2. **Symbol inventory.** ELF `.symtab` plus Ghidra `names.tsv`,
`decompiled_index.tsv`/bucket TSVs, 4-column `exports.tsv` and the
3-column `ExportForGreenEye` form (`addr<TAB>name<TAB>size`), plus
- green-eye `greeneye-symbols/1` JSON DBs. Matching follows
+ risc-v-gsp-rm-debugger `greeneye-symbols/1` JSON DBs. Matching follows
`userspace/cuda/tools/diff_corpus.py`: named functions match by name
(duplicates in address order), the address shift is the median of named
deltas, and `FUN_*` functions match at the shifted address. The report
@@ -240,7 +240,7 @@ the docs/14 §6 pack; the docs/23 §4 step 7 expected-artifact list maps 1:1.
## 5. CI workflow
-`.github/workflows/greeneye.yml` (new; `ci.yml` is untouched):
+`.github/workflows/risc-v-gsp-rm-debugger.yml` (new; `ci.yml` is untouched):
* triggers on push/PR paths `debug/risc-v-gsp-rm-vm/**` and `tools/rm*/**`;
* `ubuntu-latest`, no secrets, no hardware;
diff --git a/debug/risc-v-gsp-rm-vm/docs/22-PORTING-CUDA-AND-DEVICES.md b/debug/risc-v-gsp-rm-vm/docs/22-PORTING-CUDA-AND-DEVICES.md
index ad8a5e7..d92c0f0 100644
--- a/debug/risc-v-gsp-rm-vm/docs/22-PORTING-CUDA-AND-DEVICES.md
+++ b/debug/risc-v-gsp-rm-vm/docs/22-PORTING-CUDA-AND-DEVICES.md
@@ -1,8 +1,8 @@
-# 22 — Porting with green-eye: CUDA userspace, GSP firmware and new GPU devices
+# 22 — Porting with risc-v-gsp-rm-debugger: CUDA userspace, GSP firmware and new GPU devices
> **# TOOL IN DEVELOPMENT - NOT READY YET!** See 00-OVERVIEW for status.
> This is the combined porting guide for the three churn axes the project
-> faces. It joins the existing CUDA/GSP/firmware procedures with green-eye's
+> faces. It joins the existing CUDA/GSP/firmware procedures with risc-v-gsp-rm-debugger's
> runtime layer. Items marked "planned (docs/xx)" do not exist yet; do not
> invent commands for them.
@@ -68,19 +68,19 @@ tools/cudatool.py delta <old>/run/libcuda.so.<old> <new>/run/libcuda.so.<new>
### 2.2 Static analysis vs dynamic confirmation
-| Step | Existing project tooling | green-eye addition |
+| Step | Existing project tooling | risc-v-gsp-rm-debugger addition |
|---|---|---|
| Export/interface diff | `tools/cudatool.py delta` | — |
| Function matching / name-transfer measurement | `tools/cudatool.py fdematch <old-lib> <new-lib> --names <names.tsv>` | — |
| Corpus-level diff (added/removed/resized functions) | `tools/diff_corpus.py <old_index> <new_index>` | — |
-| Name transfer + corpus annotation | `ApplyNameMap.java` (`--dry-run` first), `tools/annotate_corpus.py` | `./greeneye.sh symbols export` builds a runtime-address symbol DB from the same index/names |
-| Driver-API smoke | `tools/test/cuda_drv_test.c` compiled as `/tmp/cdt` (prints `ALL OK`) | `./greeneye.sh symbols resolve --db ... <addr>` spot-checks transferred addresses per call path |
-| Runtime workload | `tools/cuda-ab/ab.sh all` (`vector_add.cu`; `RESULT`/`STATUS` must match host) | session-format evidence and `./greeneye.sh compare` when firmware-side sessions exist |
+| Name transfer + corpus annotation | `ApplyNameMap.java` (`--dry-run` first), `tools/annotate_corpus.py` | `./risc-v-gsp-rm-debugger.sh symbols export` builds a runtime-address symbol DB from the same index/names |
+| Driver-API smoke | `tools/test/cuda_drv_test.c` compiled as `/tmp/cdt` (prints `ALL OK`) | `./risc-v-gsp-rm-debugger.sh symbols resolve --db ... <addr>` spot-checks transferred addresses per call path |
+| Runtime workload | `tools/cuda-ab/ab.sh all` (`vector_add.cu`; `RESULT`/`STATUS` must match host) | session-format evidence and `./risc-v-gsp-rm-debugger.sh compare` when firmware-side sessions exist |
| Guest-side control observation | `tools/guest-diag/ioctl_trace.c`, host module trace (`gsp-resman-vfio:`) | annotation of the firmware-side RPC path with the per-version symbol DB |
-| Firmware-side confirmation | — | `./greeneye.sh probe` / `record` / `compare` against the paired firmware |
+| Firmware-side confirmation | — | `./risc-v-gsp-rm-debugger.sh probe` / `record` / `compare` against the paired firmware |
**Be honest about the execution boundary.** `cdt` and `vectorAdd` are x86_64
-guest binaries; the RISC-V simulator does not execute them. green-eye's
+guest binaries; the RISC-V simulator does not execute them. risc-v-gsp-rm-debugger's
contribution to a userspace port is the **symbol/evidence layer**: a
runtime-address DB per `libcuda` version, per-address resolution checks for
transferred names, and a recorded comparison format for the GSP-side behaviour
@@ -109,17 +109,17 @@ remains the dynamic oracle.
5. **Transfer names and knowledge.** Apply the map with `ApplyNameMap.java`
`--dry-run` first, then for real; translate the subsystem index; re-validate
entries the delta marked as moved.
-6. **Build the green-eye symbol DB** for the new version so runtime addresses
+6. **Build the risc-v-gsp-rm-debugger symbol DB** for the new version so runtime addresses
resolve:
```bash
cd debug/risc-v-gsp-rm-vm
- ./greeneye.sh symbols export \
+ ./risc-v-gsp-rm-debugger.sh symbols export \
--names ../../userspace/cuda/<new>/annotations/names.tsv \
--index ../../userspace/cuda/<new>/run/analysis/decompiled/decompiled_index.tsv \
--callgraph ../../userspace/cuda/<new>/run/analysis/elf-index/callgraph.tsv \
--bias 0x100000 -o symbols-<new>.json
- ./greeneye.sh symbols resolve --db symbols-<new>.json 0x<transferred-addr>
+ ./risc-v-gsp-rm-debugger.sh symbols resolve --db symbols-<new>.json 0x<transferred-addr>
```
`--bias 0x100000` is the Ghidra image base convention for `libcuda`
@@ -143,7 +143,7 @@ remains the dynamic oracle.
side is recorded, use the session compare primitive:
```bash
- ./greeneye.sh compare dumps/<old-fw-run> dumps/<new-fw-run> --symbols
+ ./risc-v-gsp-rm-debugger.sh compare dumps/<old-fw-run> dumps/<new-fw-run> --symbols
```
For multi-target orchestration use the portability matrix (docs/18); note
@@ -205,9 +205,9 @@ the top of the evidence pack.
### 3.3 Probe first-touch diff and symbol inventory
```bash
-./greeneye.sh symbols export --index <new-export.tsv> --bias 0 -o symbols-<new>.json
-./greeneye.sh probe <new-fwimage> --symbols symbols-<new>.json --record
-./greeneye.sh probe <reference-fwimage> --symbols symbols-<ref>.json --record
+./risc-v-gsp-rm-debugger.sh symbols export --index <new-export.tsv> --bias 0 -o symbols-<new>.json
+./risc-v-gsp-rm-debugger.sh probe <new-fwimage> --symbols symbols-<new>.json --record
+./risc-v-gsp-rm-debugger.sh probe <reference-fwimage> --symbols symbols-<ref>.json --record
```
The probe loads the segments, runs bounded and reports the first divergence
@@ -253,7 +253,7 @@ The project's support ladder is `docs/06-portability/hardware-software-matrix.md
### 3.6 aarch64 host / GB10-class design notes
-* **Host tooling** — green-eye is Python + QEMU; on aarch64 install
+* **Host tooling** — risc-v-gsp-rm-debugger is Python + QEMU; on aarch64 install
`qemu-system-misc` (provides `qemu-system-riscv64`) and the same commands
run. Keep host-specific paths out of session metadata (docs/07 P3.5).
`GREENEYE_QEMU` is the existing escape hatch if the binary lives elsewhere.
diff --git a/debug/risc-v-gsp-rm-vm/docs/23-RM610-READINESS.md b/debug/risc-v-gsp-rm-vm/docs/23-RM610-READINESS.md
index 72e0e62..7d18678 100644
--- a/debug/risc-v-gsp-rm-vm/docs/23-RM610-READINESS.md
+++ b/debug/risc-v-gsp-rm-vm/docs/23-RM610-READINESS.md
@@ -18,7 +18,7 @@ thing the approval message must acknowledge.
| No acquisition | No 610 runfile, GSP `.fwimage`, driver package or firmware blob is fetched, extracted, copied or mirrored before approval. |
| No analysis | No decompilation, symbol export, probe, corpus diff or pairing comparison against a 610 image before approval. |
| No emulation edits | No version-keyed handler, signature entry or profile edit justified by "610" before approval; changes require current-version evidence. |
-| No physical-GPU work | No unsupervised physical-GPU cycle, mdev claim or driver bind/unbind for 610; the project rule is no unattended physical-GPU cycles (GREEN-EYE-ROADMAP H7). |
+| No physical-GPU work | No unsupervised physical-GPU cycle, mdev claim or driver bind/unbind for 610; the project rule is no unattended physical-GPU cycles (RISC-V-GSP-RM-DEBUGGER-ROADMAP H7). |
| No support claims | 610 is not entered in the hardware/software matrix or the version matrix until it passes the docs/22 port checklists with evidence. |
Precision notes:
@@ -55,7 +55,7 @@ closed.
|---|---|---|---|---|
| C1 | All tools implemented and tested on the current driver/firmware | full test suites green (documents/demo/probe/inject/Ghidra/harness) | test logs attached to the request | tools implemented (docs/00); fresh full-suite run pending |
| C2 | Tests green | `make test` and the harness/rmharness suites pass | transcript with date and commit | green at v0.1; re-run pending (155 tests, docs/27) |
-| C3 | Demo, probe, inject, Ghidra work | `./greeneye.sh demo`, `probe`, `inject`, `ghidra` all demonstrated | session dirs + transcript | working per docs/00 |
+| C3 | Demo, probe, inject, Ghidra work | `./risc-v-gsp-rm-debugger.sh demo`, `probe`, `inject`, `ghidra` all demonstrated | session dirs + transcript | working per docs/00 |
| C4 | MCP monitoring works | MCP plugin implemented and exercised (roadmap R3, docs/08; docs/15) | tool list + a monitored run | implemented (docs/20); monitored run not yet attached |
| C5 | CI pipeline works | release/CI pipeline implemented and exercised (docs/21) | pipeline run with artifacts | implemented (docs/21); current-version run pending |
| C6 | Docs complete and accurate | doc review checklist (§3.2) signed | review record | to complete |
@@ -78,14 +78,14 @@ make demo
make test
python3 -m unittest tests.test_harness -v
python3 rmharness/tests/test_rmharness_plugin.py
-./greeneye.sh info
-./greeneye.sh demo
-./greeneye.sh demo --backend native
-./greeneye.sh probe
-./greeneye.sh inject
-./greeneye.sh symbols export --index <export.tsv> --bias 0 -o symbols-<ver>.json
-./greeneye.sh analyze dumps/<run> --symbols symbols-<ver>.json
-./greeneye.sh compare dumps/<a> dumps/<b> --symbols
+./risc-v-gsp-rm-debugger.sh info
+./risc-v-gsp-rm-debugger.sh demo
+./risc-v-gsp-rm-debugger.sh demo --backend native
+./risc-v-gsp-rm-debugger.sh probe
+./risc-v-gsp-rm-debugger.sh inject
+./risc-v-gsp-rm-debugger.sh symbols export --index <export.tsv> --bias 0 -o symbols-<ver>.json
+./risc-v-gsp-rm-debugger.sh analyze dumps/<run> --symbols symbols-<ver>.json
+./risc-v-gsp-rm-debugger.sh compare dumps/<a> dumps/<b> --symbols
```
Plus, on the current version:
@@ -120,8 +120,8 @@ Required results:
current version, or C7 is explicitly waived;
* [ ] `docs/21-CI-RELEASE-PIPELINE.md` exists and has run once on the
current version, or C5 is explicitly waived;
-* [ ] `GREEN-EYE-ROADMAP.md` and `docs/08` status claims match reality;
-* [ ] no local source paths, no invented command names, no unsupported
+* [ ] `RISC-V-GSP-RM-DEBUGGER-ROADMAP.md` and `docs/08` status claims match reality;
+* [ ] no non-public source paths, no invented command names, no unsupported
"supported/accurate" claims.
### 3.3 Golden sessions and regression data in place
diff --git a/debug/risc-v-gsp-rm-vm/docs/24-DEVICE-MAP.md b/debug/risc-v-gsp-rm-vm/docs/24-DEVICE-MAP.md
index 4430bf9..0dde6a8 100644
--- a/debug/risc-v-gsp-rm-vm/docs/24-DEVICE-MAP.md
+++ b/debug/risc-v-gsp-rm-vm/docs/24-DEVICE-MAP.md
@@ -62,7 +62,7 @@ absorbed; a read of a write-only register reads back zero.
```bash
# 1) run a bounded probe against the real image (QEMU path, existing command)
-./greeneye.sh probe # writes dumps/<stamp>-probe-<image>/
+./risc-v-gsp-rm-debugger.sh probe # writes dumps/<stamp>-probe-<image>/
# 2) turn that session into a device map
python3 -m greeneye.device_map harvest dumps/<stamp>-probe-<image> \
diff --git a/debug/risc-v-gsp-rm-vm/docs/25-VALUE-VALIDATION.md b/debug/risc-v-gsp-rm-vm/docs/25-VALUE-VALIDATION.md
index d47b8ea..3409039 100644
--- a/debug/risc-v-gsp-rm-vm/docs/25-VALUE-VALIDATION.md
+++ b/debug/risc-v-gsp-rm-vm/docs/25-VALUE-VALIDATION.md
@@ -9,7 +9,7 @@
## 1. Why this document exists
-green-eye is only worth its maintenance if it turns real firmware questions
+risc-v-gsp-rm-debugger is only worth its maintenance if it turns real firmware questions
into answers faster than static analysis and supervised hardware cycles. The
project handoffs record those questions and their costs in wall-clock and
cycles: the 0x59 RM-init chase (PART 91, 2026-10-01), the 20 GR counters
@@ -17,7 +17,7 @@ cycles: the 0x59 RM-init chase (PART 91, 2026-10-01), the 20 GR counters
P6 service wiring (PART 92 ADDENDA 5–11, 2026-10-02), and the version pairing
question (570.144 vs 570.211). This document maps each of them to a runnable
demonstration under [`harness/value_demos/`](../harness/value_demos/), states
-the baseline cost from the handoffs, and measures the green-eye path.
+the baseline cost from the handoffs, and measures the risc-v-gsp-rm-debugger path.
## 2. Methodology
@@ -25,14 +25,14 @@ the baseline cost from the handoffs, and measures the green-eye path.
| Class | Meaning | Where it appears |
|---|---|---|
-| **Measured (analog)** | Wall-clock of the green-eye path on the bundled `uproc_demo` firmware, native RV64 interpreter or QEMU; answers, counts, session bytes, trace slowdown | `result.json` per demo, `artifacts/results.json` |
+| **Measured (analog)** | Wall-clock of the risc-v-gsp-rm-debugger path on the bundled `uproc_demo` firmware, native RV64 interpreter or QEMU; answers, counts, session bytes, trace slowdown | `result.json` per demo, `artifacts/results.json` |
| **Recorded (real baseline)** | Cost actually paid on the physical path, as recorded in the handoffs (dates, cycles, PARTs, wall spans) | `real_case.static_baseline` in each `result.json`, §5 below |
| **Projected** | What the same tool path would save on the real firmware once H2.2 executes it; labelled `projected` | `real_case.projection`; never presented as a result |
| **Blocked** | Real firmware access requires the H2.2 QEMU device model; `blocked_on_device_model: true` | every real `.fwimage` scenario here |
Fidelity is exactly docs/06: L0 instruction semantics and L1 memory behaviour
are exercised; **L2 time/concurrency is not modelled** and **L3 device
-environment is absent**. A green-eye observation is evidence about the
+environment is absent**. A risc-v-gsp-rm-debugger observation is evidence about the
firmware, and anything that would change `open-iov-vfio` is escalated to a
physical capture before the product changes (docs/06 §6, docs/14 §7).
@@ -76,7 +76,7 @@ Measured on the reference host (CPython 3.12); numbers regenerate with
`python3 harness/value_demos/run_all.py`. Times below are from the
`run_all` aggregate (~18.4 s total).
-| # | Real scenario (source, date) | Green-eye tool | Static/Ghidra-only baseline (recorded) | Analog (measured) | Real-case projection |
+| # | Real scenario (source, date) | Risc-V GSP-RM debugger tool | Static/Ghidra-only baseline (recorded) | Analog (measured) | Real-case projection |
|---|---|---|---|---|---|
| s01 | 0x59 RM-init chase; fn72/fn73 (PART 91 + ADDENDA 2–7, 2026-10-01) | hook dispatcher, watch `result`, decode reply | cycles 2–13, ~11:40→16:52 ≈ 5 h 10 m; 10+ supervised boots (~5–6 min each); reply was generic `0x59` | **1.14 s**; 3/3 commands consumed and decoded; FAULT traps before the reply store | one hook + one watchpoint per command once H2.2 boots the image (blocked) |
| s02 | 20 GR per-channel counters (PARTs 46–64, 2026-09-24…29) | watch publication field, per-slot readback | ~5 days; PART 49 “only 4 of 20 counters ever moved”; ~2–3 s pin vs ~2 s client deadline | **1.34 s**; 20/20 slots published, 28 stores, store PCs captured | per-channel page watchpoints on real counter pages (blocked) |
@@ -280,7 +280,7 @@ every later version.
## 7. OODA-loop compression
-| Stage | Before (real path, as recorded) | After (green-eye analog, measured) |
+| Stage | Before (real path, as recorded) | After (risc-v-gsp-rm-debugger analog, measured) |
|---|---|---|
| **Observe** | one supervised boot + capture per hypothesis: 5–6 min, fail-safe discipline, one device-write experiment per cycle | launch 0.001–0.13 s, then hooks/watchpoints and bounded runs: 0.2–5.8 s per question |
| **Orient** | manual LOGINIT/LOGRM/NOCAT ring decode, static reports (REPORT3–10), hours per campaign; the ring was invisible until cycle 11 | `analyze`/`compare`/`Memory.diff` with named symbols: seconds, e.g. s05 attributes every changed byte to a schema field |
@@ -288,7 +288,7 @@ every later version.
| **Act** | rebuild + supervised boot; escalate every conclusion to a physical capture | re-run the session (seconds); product change still gated on physical confirmation (docs/06 §6, docs/14 §7) |
The compression is not “the simulator replaces the hardware”; it is the loop
-around each physical experiment. green-eye reduces the number of physical
+around each physical experiment. risc-v-gsp-rm-debugger reduces the number of physical
cycles needed to reach a confident hypothesis and produces the evidence pack
that makes the eventual physical confirmation cheap (s10).
diff --git a/debug/risc-v-gsp-rm-vm/docs/26-ARCHITECTURE.md b/debug/risc-v-gsp-rm-vm/docs/26-ARCHITECTURE.md
index ab8414a..d8c30dd 100644
--- a/debug/risc-v-gsp-rm-vm/docs/26-ARCHITECTURE.md
+++ b/debug/risc-v-gsp-rm-vm/docs/26-ARCHITECTURE.md
@@ -1,14 +1,14 @@
-# 26 — green-eye architecture: full picture, workflow and API surfaces
+# 26 — risc-v-gsp-rm-debugger architecture: full picture, workflow and API surfaces
> **# TOOL IN DEVELOPMENT - NOT READY YET!**
-> The architecture map for the green-eye suite: how the pieces fit, which
+> The architecture map for the risc-v-gsp-rm-debugger suite: how the pieces fit, which
> surface to call, and which document specifies each part. Every claim here is
> implemented in the tree or explicitly marked as a gated roadmap design.
> Development-only: never shipped, never a driver dependency, never in a guest.
-## 1. What green-eye is (and is not)
+## 1. What risc-v-gsp-rm-debugger is (and is not)
-green-eye runs GSP/uproc firmware in a controllable machine, observes it with
+risc-v-gsp-rm-debugger runs GSP/uproc firmware in a controllable machine, observes it with
Frida-like primitives, records a durable session, changes the machine's inputs
(including injected code), and compares runs as evidence for `open-iov-vfio`
emulation changes.
@@ -224,7 +224,7 @@ sequenceDiagram
| `greeneye.ghidra.export_hits` | session hits → `addr<TAB>hits<TAB>symbol<TAB>annotation` | 05 |
| `ExportForGreenEye.java` | Ghidra → `addr<TAB>name<TAB>size` TSV | 05 |
| `MarkGreenEyeHits.java` | annotate functions with runtime hits + bookmarks | 05 |
-| `GreenEyeControl.java` + `greeneye.sh ghidra` | drive a live session from GhidraScripts over localhost JSON-lines | [13](13-GHIDRA-CONTROL.md) |
+| `GreenEyeControl.java` + `risc-v-gsp-rm-debugger.sh ghidra` | drive a live session from GhidraScripts over localhost JSON-lines | [13](13-GHIDRA-CONTROL.md) |
Bridge commands: `ping`, `info`, `resolve`, `bp_set`, `bp_clear`, `bp_list`,
`watch_set`, `run_until`, `run`, `step`, `read_mem`, `write_mem`, `read_reg`,
@@ -343,7 +343,7 @@ The canonical loop (H4.5, 06 §5, 07 P4, 25 §7). Each stage names its gate.
| 5. Compare | `compare` against a reference (old firmware, hardware/VFIO capture, self-diff) | deltas explained symbolically; self-diff is zero | unexplained hit/watch/write delta → investigate first |
| 6. Decide | fill M1–M6 with the reference method (06 §5); mutation/triage for error paths | metric table improves or stays equal | metric claimed without a reference capture |
| 7. Implement | change `open-iov-vfio` (never the simulator for a product fix); keep the stimulus | physical confirmation for behaviour changes (06 §6, 14 §7) | product change from a simulator-only observation |
-| 8. Regression | re-run step 3 with an unchanged stimulus; golden sessions/CI (`make test`, `greeneye.yml`) | profile improves or stays equal; CI green | regression → revert and re-derive |
+| 8. Regression | re-run step 3 with an unchanged stimulus; golden sessions/CI (`make test`, `risc-v-gsp-rm-debugger.yml`) | profile improves or stays equal; CI green | regression → revert and re-derive |
```mermaid
flowchart LR
@@ -358,12 +358,12 @@ flowchart LR
```
OODA compression evidence (analog, measured) is in 25 §7: hardware cycles are
-minutes and campaigns hours/days; the green-eye path for the same question
+minutes and campaigns hours/days; the risc-v-gsp-rm-debugger path for the same question
class is sub-second to seconds plus scripting.
## 12. API surfaces by tool
-### 12.1 CLI (`greeneye.sh`, `greeneye/cli.py`; usage in [02](02-USAGE.md))
+### 12.1 CLI (`risc-v-gsp-rm-debugger.sh`, `greeneye/cli.py`; usage in [02](02-USAGE.md))
| Command | Purpose | Not for |
|---|---|---|
@@ -447,7 +447,7 @@ dispatch (01, 03); §4 backends (01 §8, 16 §4–5); §5 recording (01 §6, 09,
§6, 16 §10, 17 §5); §6 injection (11, 12); §7 Ghidra (05, 13); §8 MCP (20);
§9 harness (18, 19, 21, 28, 29); §10 device map (24, 16 §7); §11 OODA (06, 07 P4, 25
§7). Roadmap keys: R3 = MCP (08), R5 = mutation (18), R6 = multi-version (18,
-21), H1.3 = RM service injection (GREEN-EYE-ROADMAP), H2.2 = QEMU device
+21), H1.3 = RM service injection (RISC-V-GSP-RM-DEBUGGER-ROADMAP), H2.2 = QEMU device
model, H3/M1–M6 = native simulator (16), H4 = adversarial navigation (14),
H7 = agentic platform (15, 20).
diff --git a/debug/risc-v-gsp-rm-vm/docs/27-TOOL-AUDIT.md b/debug/risc-v-gsp-rm-vm/docs/27-TOOL-AUDIT.md
index 86f2b06..9c4f61e 100644
--- a/debug/risc-v-gsp-rm-vm/docs/27-TOOL-AUDIT.md
+++ b/debug/risc-v-gsp-rm-vm/docs/27-TOOL-AUDIT.md
@@ -1,4 +1,4 @@
-# 27 — green-eye tool audit
+# 27 — risc-v-gsp-rm-debugger tool audit
> **# TOOL IN DEVELOPMENT - NOT READY YET!** See [00-OVERVIEW](00-OVERVIEW.md)
> for status and [06-ACCURACY](06-ACCURACY.md) for fidelity limits.
@@ -17,7 +17,7 @@ Environment: QEMU 8.2.2 (`qemu-system-riscv64`), Python 3.12, clang/lld.
Every safe smoke below was executed from the tool root; device/WPR paths were
not touched.
-* all 13 `./greeneye.sh <cmd> --help` parsers, `--version`;
+* all 13 `./risc-v-gsp-rm-debugger.sh <cmd> --help` parsers, `--version`;
* `info`, `demo --backend native`, `record --backend native --trace`,
`analyze`, `compare`, `plugins`, `inject --backend native`;
* `probe --instructions 400` against the real 570.144 `.fwimage`;
@@ -44,11 +44,11 @@ tests/demos/docs), `not used yet` (no caller found; decision recorded),
`needs improvement` (concrete weakness; fixed where safe), `prune candidate`
(clearly dead; none found).
-## 1. Master table — `greeneye.sh` CLI
+## 1. Master table — `risc-v-gsp-rm-debugger.sh` CLI
| surface | purpose | API / entry points | tests | used by | status | notes/actions |
|---|---|---|---|---|---|---|
-| `info` | environment/tooling check | `greeneye/cli.py:173`, `greeneye.sh info` | indirect (smoke) | README, 00, 02 | verified useful | ran; native sim + fwimage + CUDA names detection all correct |
+| `info` | environment/tooling check | `greeneye/cli.py:173`, `risc-v-gsp-rm-debugger.sh info` | indirect (smoke) | README, 00, 02 | verified useful | ran; native sim + fwimage + CUDA names detection all correct |
| `demo` | canned demo boot + hooks/watch/diff/trap | `cli.py:209` | smoke via `test_smoke_qemu.py` | README, 00, 02; `make demo-run` | verified useful | ran on `--backend native`; 17 hook lines, diff + trap work |
| `run` | run a Python instrumentation script | `cli.py:272` | `test_injection.py` (REPL), `test_sim_trace.py` | 02, 03, examples scripts | needs improvement (fixed) | the exec namespace lacked `__file__`, so the documented `dump_diff.py` failed; namespace now sets `__file__`/`__name__`, doc 03 notes it |
| `attach` | interactive REPL | `cli.py:486`, `GreenEyeRepl` | `test_injection.py:68` | README, 02 | verified useful | REPL commands all back onto tested Session APIs |
@@ -105,21 +105,21 @@ tests/demos/docs), `not used yet` (no caller found; decision recorded),
| `plugins/mcp_server.py` | MCP server (stdio/loopback) | `--stdio`, `--tcp`, `--allow-write`, `--allow-inject` | `test_mcp.py` (431 lines) | 08/R3, 15, 20 | verified useful | read-only default; structured `not_available` fallbacks |
| `plugins/rmharness_plugin.py` | REPL commands for host RM oracle | `register(ge)`; commands `rmtool/rmtop/rmq` | `rmharness/tests/test_rmharness_plugin.py` (3 tests) | 17, 23 | verified useful | write-named args refused (`rm_harness_skip`) |
| `qemu/greeneye_trace.c` | full TCG exec/access JSONL trace | `make -C qemu`; `-plugin greeneye-trace.so,path=…` | none automated; **live-verified in this audit** | 10, 16, 14 | verified useful | 8M exec events in 1 s on the demo; vendored `qemu-plugin.h` builds out of the box |
-| `qemu/launch.sh` | one-line `greeneye launch` wrapper | `qemu/launch.sh --kernel <elf>` | smoke | qemu/README | verified useful | thin `exec` of `greeneye.sh launch` |
+| `qemu/launch.sh` | one-line `greeneye launch` wrapper | `qemu/launch.sh --kernel <elf>` | smoke | qemu/README | verified useful | thin `exec` of `risc-v-gsp-rm-debugger.sh launch` |
| `ghidra/*.java` (Export/Mark/Control) | static/dynamic join inside Ghidra | `analyzeHeadless -postScript …` | protocol counterpart covered by `test_bridge.py`; no Ghidra installed here | 05, 13 | verified useful (static) | README documents exact command lines; Java not executed in this environment |
| `rmharness/rmtool.sh` | RM oracle wrapper | passthrough to `tools/rmtool` | `harness.sh` capture smoke (`gpu list`) | 17, 23 | verified useful | builds tool on first use; read-only |
| `rmharness/rmtop.sh` | dashboard wrapper | passthrough to `tools/rmtop` | `--help` | 17 | verified useful | `--once` for captures |
| `rmharness/rmq.sh` | pre-existing rmq wrapper | passthrough to `tools/rmq` | `--help` | 17 | needs improvement (fixed) | `--help` used to fall through and open the RM; wrapper now answers help itself |
-| `rmharness/harness.sh` | capture tool run into a green-eye session | `--session DIR -- TOOL ARGS` | capture smoke (verified event + blobs) | 17, 22 | verified useful | additive recording; read-only allowlist enforced |
+| `rmharness/harness.sh` | capture tool run into a risc-v-gsp-rm-debugger session | `--session DIR -- TOOL ARGS` | capture smoke (verified event + blobs) | 17, 22 | verified useful | additive recording; read-only allowlist enforced |
| `rmharness/tests/` | plugin registration check | `python3 rmharness/tests/test_rmharness_plugin.py` | 3 tests, run and green | 17 | needs improvement (open) | not part of `tests/` discovery nor CI; kept separate by design, documented in 17/README — consider CI step when the workflow is next edited |
| `sdk/injected_demo.c` | position-independent service SDK | `make sdk` | `test_injection.py`; `inject` smoke | 11, 12 | verified useful | direct + firmware call paths |
| `firmware/uproc_demo/` | bundled RV64 uproc (mailbox RPC/state/trap) | `make demo` | many integration tests | README, 00, 02 | verified useful | self-test + scripted stimulus work |
-| `examples/scripts/dump_diff.py` | schema decode + snapshot diff demo | `./greeneye.sh run examples/scripts/dump_diff.py` | verified after `__file__` fix | 02 | needs improvement (fixed) | was broken by the `run` namespace gap; now prints decoded ctrl + changed bytes |
-| `examples/scripts/trace_rpc.py` | hook every RPC handler | `./greeneye.sh run …` | ran | 02, 16, 18 | verified useful | 17 hook events from the demo |
+| `examples/scripts/dump_diff.py` | schema decode + snapshot diff demo | `./risc-v-gsp-rm-debugger.sh run examples/scripts/dump_diff.py` | verified after `__file__` fix | 02 | needs improvement (fixed) | was broken by the `run` namespace gap; now prints decoded ctrl + changed bytes |
+| `examples/scripts/trace_rpc.py` | hook every RPC handler | `./risc-v-gsp-rm-debugger.sh run …` | ran | 02, 16, 18 | verified useful | 17 hook events from the demo |
| `examples/scripts/sim_bench.py` | native throughput benchmark | standalone CLI | ran (0.92 MIPS untraced, pure Python) | 16 | verified useful | self-bootstraps `sys.path`, works from anywhere |
| `examples/scripts/sim_diff.py` | QEMU-vs-native differential | standalone CLI | ran: `PARITY: OK` | 16 | verified useful | exit 1 on divergence, 0 on skip |
| `examples/probes/demo_probes.json` | declarative probe spec sample | loaded by `greeneye.probes.install` | installed + fired via `greeneye run` | 03 §9 | verified useful | 3 probes, hits `[1, 3, 0]` on the demo |
-| `tests/` (15 files) | unit + live QEMU integration | `python3 -m unittest discover -s tests -t .` | **155 tests OK** | CI (`greeneye.yml`) | verified useful | includes live QEMU, native parity, MCP, bridge, harness, value demos |
+| `tests/` (15 files) | unit + live QEMU integration | `python3 -m unittest discover -s tests -t .` | **155 tests OK** | CI (`risc-v-gsp-rm-debugger.yml`) | verified useful | includes live QEMU, native parity, MCP, bridge, harness, value demos |
## 4. Scripting API purpose review
@@ -177,7 +177,7 @@ Nothing was deleted.
## 7. Portability / extensibility / discoverability checks
-* **Portability.** Stdlib-only Python; `greeneye.sh` pins `PYTHONPATH` to the
+* **Portability.** Stdlib-only Python; `risc-v-gsp-rm-debugger.sh` pins `PYTHONPATH` to the
tool root. Harness tools and `run_all.py` bootstrap their own `sys.path`.
QEMU is optional (integration tests skip cleanly); the native backend makes
the suite largely hardware-free. `qemu-plugin.h` is vendored so the TCG
@@ -188,17 +188,17 @@ Nothing was deleted.
(`greeneye-device-map/1`, doc 24).
* **Discoverability.** `README.md` + `docs/00-OVERVIEW.md` doc maps were
completed for docs 17–27 (previously they stopped at 16); `plugins/` and
- `harness/` are now listed in the README layout. `greeneye.sh --help` and
+ `harness/` are now listed in the README layout. `risc-v-gsp-rm-debugger.sh --help` and
`plugins/mcp_server.py --help` are self-describing.
-* **CI.** `.github/workflows/greeneye.yml` builds SDK+demo and runs the main
+* **CI.** `.github/workflows/risc-v-gsp-rm-debugger.yml` builds SDK+demo and runs the main
suite on Linux; `rmharness/tests` is the only suite the workflow misses.
## 8. How to tell if a tool is misbehaving (symptom → check → fix)
| tool | symptom | check | fix |
|---|---|---|---|
-| `greeneye.sh` / CLI | `greeneye error: …` on a valid path | `./greeneye.sh info` shows resolved paths; `--help` for arguments | correct the path/arg; check `GREENEYE_QEMU`/`GREENEYE_DUMPS`; bad symbol DBs now fail with a clear message |
-| `run` scripts | `NameError: __file__` (pre-fix) or names missing | `./greeneye.sh run` preloads `ge/session/s/memory/symbols/recorder/__file__`; run with `--backend native` to remove QEMU | keep scripts inside the tool tree and invoke through `greeneye.sh run`, not bare `python3` |
+| `risc-v-gsp-rm-debugger.sh` / CLI | `greeneye error: …` on a valid path | `./risc-v-gsp-rm-debugger.sh info` shows resolved paths; `--help` for arguments | correct the path/arg; check `GREENEYE_QEMU`/`GREENEYE_DUMPS`; bad symbol DBs now fail with a clear message |
+| `run` scripts | `NameError: __file__` (pre-fix) or names missing | `./risc-v-gsp-rm-debugger.sh run` preloads `ge/session/s/memory/symbols/recorder/__file__`; run with `--backend native` to remove QEMU | keep scripts inside the tool tree and invoke through `risc-v-gsp-rm-debugger.sh run`, not bare `python3` |
| hooks/watchpoints | callback never fires | hook an obviously-hit symbol (`rpc_sum`), `record` + `analyze`; check the session event counts | re-run demo to confirm firmware self-test; ensure the target is resumed (`run`) and the symbol exists (`symbols.get`) |
| `probe` | 0 faults reported | check `dumps/<run>/blobs/qemu.log` and `recorder.meta["qemu_fault_count"]` | expected for images that stay in mapped memory; use `--instructions` for a bounded step instead of `--duration` |
| native backend / trace | QEMU-vs-native diff fails | `python3 examples/scripts/sim_diff.py`; `analyze` on the trace blob | divergence means a real backend bug: capture both sessions and diff `exec`/`access` counts (see 16) |
diff --git a/debug/risc-v-gsp-rm-vm/docs/28-PORTING-AUTOMATION.md b/debug/risc-v-gsp-rm-vm/docs/28-PORTING-AUTOMATION.md
index 4669f93..f75c8ed 100644
--- a/debug/risc-v-gsp-rm-vm/docs/28-PORTING-AUTOMATION.md
+++ b/debug/risc-v-gsp-rm-vm/docs/28-PORTING-AUTOMATION.md
@@ -1,7 +1,7 @@
# 28 — Porting automation: driver-version sweep and new-device scaffold
> **# TOOL IN DEVELOPMENT - NOT READY YET!** See 00 for status and
-> [`GREEN-EYE-ROADMAP.md`](../GREEN-EYE-ROADMAP.md) H4/R6 for the program.
+> [`RISC-V-GSP-RM-DEBUGGER-ROADMAP.md`](../RISC-V-GSP-RM-DEBUGGER-ROADMAP.md) H4/R6 for the program.
Two stdlib-only orchestrators turn the docs/07 P1/P2 playbooks and the
docs/22 porting guide into one repeatable chain: a **driver-version sweep**
@@ -228,7 +228,7 @@ Output tree:
<out>/<device>/
device-port.json / device-port.md
port-checklist.json / port-checklist.md
- symbols/<device>.json merged ELF/Ghidra/green-eye DB + provenance
+ symbols/<device>.json merged ELF/Ghidra/risc-v-gsp-rm-debugger DB + provenance
sessions/<firmware>-probe/ recorded first-touch session
portability-matrix/ matrix report + sessions + compare
bundle-manifest.json sha256 of every artifact
diff --git a/debug/risc-v-gsp-rm-vm/docs/29-PACKAGING-AND-TRIALING.md b/debug/risc-v-gsp-rm-vm/docs/29-PACKAGING-AND-TRIALING.md
index 8be3704..c87806b 100644
--- a/debug/risc-v-gsp-rm-vm/docs/29-PACKAGING-AND-TRIALING.md
+++ b/debug/risc-v-gsp-rm-vm/docs/29-PACKAGING-AND-TRIALING.md
@@ -8,7 +8,7 @@
## 1. Purpose
-green-eye can already load an injected service into the native simulator and
+risc-v-gsp-rm-debugger can already load an injected service into the native simulator and
invoke it (docs/12, docs/16 §1.1, `harness/value_demos/s06_inject_service.py`).
That evidence lives in the tool tree: a reviewer needs the checkout, the built
demo and SDK, and the exact command sequence. `harness/package_sim.py` turns
@@ -111,7 +111,7 @@ not overwrite.
1. Receive `<package>.tar.gz` plus its sha256 out of band; verify
`sha256sum <package>.tar.gz`.
2. Extract and run: `./run.sh` (add `--budget N` for image packages). The
- script finds the green-eye tree by walking up, or via
+ script finds the risc-v-gsp-rm-debugger tree by walking up, or via
`GREENEYE_HOME=/path/to/risc-v-gsp-rm-vm`. Exit codes: `0` pass (or the
documented blocked image status), `1` assertion failure, `3` tree not found.
3. Read `results/results.md` first, then `results/results.json` for machines.
@@ -119,7 +119,7 @@ not overwrite.
flake: `assertions.failed` names the check (`handlers_slot_registered`,
`remote_ping`, `routes_agree`, `dispatch_hook_hits`, `uart_banner`, ...).
4. For deeper review, point the tools at `results/session/`:
- `./greeneye.sh analyze <pkg>/results/session` and
+ `./risc-v-gsp-rm-debugger.sh analyze <pkg>/results/session` and
`python3 -m greeneye compare baseline/results/session candidate/results/session`.
5. Verify provenance: each `components[].sha256` must match the packaged file;
`target.sha256`/`service.sha256` identify the inputs.
diff --git a/debug/risc-v-gsp-rm-vm/examples/scripts/dump_diff.py b/debug/risc-v-gsp-rm-vm/examples/scripts/dump_diff.py
index 329ffb1..11d1fbb 100644
--- a/debug/risc-v-gsp-rm-vm/examples/scripts/dump_diff.py
+++ b/debug/risc-v-gsp-rm-vm/examples/scripts/dump_diff.py
@@ -2,7 +2,7 @@
Run from the tool root:
- ./greeneye.sh run examples/scripts/dump_diff.py
+ ./risc-v-gsp-rm-debugger.sh run examples/scripts/dump_diff.py
Demonstrates: symbol -> structure schema decoding, snapshot + diff, host
stimulus via memory writes, and symbol-annotated output.
diff --git a/debug/risc-v-gsp-rm-vm/examples/scripts/trace_rpc.py b/debug/risc-v-gsp-rm-vm/examples/scripts/trace_rpc.py
index 12b912b..7f68d7f 100644
--- a/debug/risc-v-gsp-rm-vm/examples/scripts/trace_rpc.py
+++ b/debug/risc-v-gsp-rm-vm/examples/scripts/trace_rpc.py
@@ -2,7 +2,7 @@
Run from the tool root:
- ./greeneye.sh run examples/scripts/trace_rpc.py
+ ./risc-v-gsp-rm-debugger.sh run examples/scripts/trace_rpc.py
The script namespace provides ``s``/``session``, ``memory``, ``symbols``,
``recorder`` and ``ge`` (the greeneye package).
diff --git a/debug/risc-v-gsp-rm-vm/firmware/uproc_demo/Makefile b/debug/risc-v-gsp-rm-vm/firmware/uproc_demo/Makefile
index f406a52..f390f08 100644
--- a/debug/risc-v-gsp-rm-vm/firmware/uproc_demo/Makefile
+++ b/debug/risc-v-gsp-rm-vm/firmware/uproc_demo/Makefile
@@ -1,4 +1,4 @@
-# green-eye uproc demo firmware (RISC-V 64, bare metal)
+# risc-v-gsp-rm-debugger uproc demo firmware (RISC-V 64, bare metal)
#
# Uses clang + lld (no riscv64 GCC required):
# CC=clang, LD=ld.lld (absolute path to llvm-18 lld by default).
diff --git a/debug/risc-v-gsp-rm-vm/firmware/uproc_demo/linker.ld b/debug/risc-v-gsp-rm-vm/firmware/uproc_demo/linker.ld
index 7ad7af8..94f21f5 100644
--- a/debug/risc-v-gsp-rm-vm/firmware/uproc_demo/linker.ld
+++ b/debug/risc-v-gsp-rm-vm/firmware/uproc_demo/linker.ld
@@ -1,9 +1,9 @@
-/* green-eye uproc demo firmware - RISC-V 64 bare-metal test target.
+/* risc-v-gsp-rm-debugger uproc demo firmware - RISC-V 64 bare-metal test target.
*
* Mimics the shape of a GSP-side micro-service: a global control block with a
* magic, a handler table and counters; a mailbox-driven RPC dispatcher; a
* multi-stage state machine handler; and an intentional trap handler so
- * green-eye can demonstrate breakpoint/hook/watchpoint/trap workflows.
+ * risc-v-gsp-rm-debugger can demonstrate breakpoint/hook/watchpoint/trap workflows.
*
* Build: make -C firmware/uproc_demo
*/
diff --git a/debug/risc-v-gsp-rm-vm/firmware/uproc_demo/main.c b/debug/risc-v-gsp-rm-vm/firmware/uproc_demo/main.c
index 9b4f98a..e036499 100644
--- a/debug/risc-v-gsp-rm-vm/firmware/uproc_demo/main.c
+++ b/debug/risc-v-gsp-rm-vm/firmware/uproc_demo/main.c
@@ -1,4 +1,4 @@
-/* green-eye uproc demo firmware.
+/* risc-v-gsp-rm-debugger uproc demo firmware.
*
* A small, deterministic "GSP-like" service:
* - gsp_ctrl global control block (magic 0x47535031) in .gsp_data;
@@ -62,7 +62,7 @@ static u64 strlen_local(const char *s)
return n;
}
-/* ---- RPC handlers (kept as symbols for green-eye hooks) ---- */
+/* ---- RPC handlers (kept as symbols for risc-v-gsp-rm-debugger hooks) ---- */
__attribute__((noinline)) u64 rpc_ping(u64 a0, u64 a1)
{
@@ -128,7 +128,7 @@ __attribute__((noinline)) u64 rpc_fault(u64 a0, u64 a1)
{
(void)a0;
(void)a1;
- __asm__ volatile("ebreak"); /* debugger trap: green-eye stops here */
+ __asm__ volatile("ebreak"); /* debugger trap: risc-v-gsp-rm-debugger stops here */
return 0xdead;
}
@@ -204,7 +204,7 @@ int main(void)
ctl->buf[0] = '\0';
install_handlers();
- uart_puts("GREEN-EYE UPROC DEMO v1\n");
+ uart_puts("RISC-V GSP-RM DEBUGGER UPROC DEMO v1\n");
uart_puts("MAGIC ");
uart_hex(ctl->magic, 8);
uart_puts(" CTRL@");
@@ -213,7 +213,7 @@ int main(void)
/* Deterministic self-test so freshly attached instrumentation sees events. */
rpc_dispatch(1, 0x1111, 0, 0);
- rpc_dispatch(2, (u64)(unsigned long)"hello-green-eye", 0, 0);
+ rpc_dispatch(2, (u64)(unsigned long)"hello-risc-v-gsp-rm-debugger", 0, 0);
rpc_dispatch(3, 0x5a, 32, 0);
rpc_dispatch(4, (u64)(unsigned long)ctl->buf, 16, 0);
rpc_dispatch(5, 0, 0, 0);
diff --git a/debug/risc-v-gsp-rm-vm/firmware/uproc_demo/start.S b/debug/risc-v-gsp-rm-vm/firmware/uproc_demo/start.S
index 1341461..b55720a 100644
--- a/debug/risc-v-gsp-rm-vm/firmware/uproc_demo/start.S
+++ b/debug/risc-v-gsp-rm-vm/firmware/uproc_demo/start.S
@@ -1,4 +1,4 @@
-/* green-eye uproc demo firmware - reset/entry. */
+/* risc-v-gsp-rm-debugger uproc demo firmware - reset/entry. */
.section .text.start, "ax", @progbits
.global _start
.type _start, @function
diff --git a/debug/risc-v-gsp-rm-vm/ghidra/ExportForGreenEye.java b/debug/risc-v-gsp-rm-vm/ghidra/ExportForGreenEye.java
index 29cc1cd..14d29f6 100644
--- a/debug/risc-v-gsp-rm-vm/ghidra/ExportForGreenEye.java
+++ b/debug/risc-v-gsp-rm-vm/ghidra/ExportForGreenEye.java
@@ -1,4 +1,4 @@
-// Export functions as a green-eye-compatible symbol TSV.
+// Export functions as a risc-v-gsp-rm-debugger-compatible symbol TSV.
//
// Usage (Ghidra headless):
// analyzeHeadless <proj> <name> -process <program> -noanalysis \
@@ -6,10 +6,10 @@
// -postScript ExportForGreenEye.java /abs/path/ghidra-symbols.tsv
//
// Columns: addr (program address) <TAB> name <TAB> size.
-// green-eye's `symbols export --index` accepts this form directly.
+// risc-v-gsp-rm-debugger's `symbols export --index` accepts this form directly.
//
//@category OpenIOV
-//@menupath Tools.OpenIOV.Export for green-eye
+//@menupath Tools.OpenIOV.Export for risc-v-gsp-rm-debugger
import java.io.File;
import java.io.PrintWriter;
@@ -41,6 +41,6 @@ public class ExportForGreenEye extends GhidraScript {
count++;
}
}
- println("green-eye: exported " + count + " functions to " + out.getAbsolutePath());
+ println("risc-v-gsp-rm-debugger: exported " + count + " functions to " + out.getAbsolutePath());
}
}
diff --git a/debug/risc-v-gsp-rm-vm/ghidra/GreenEyeControl.java b/debug/risc-v-gsp-rm-vm/ghidra/GreenEyeControl.java
index abeee82..b0a6628 100644
--- a/debug/risc-v-gsp-rm-vm/ghidra/GreenEyeControl.java
+++ b/debug/risc-v-gsp-rm-vm/ghidra/GreenEyeControl.java
@@ -1,7 +1,7 @@
-// GreenEyeControl - drive a live green-eye session from Ghidra.
+// GreenEyeControl - drive a live risc-v-gsp-rm-debugger session from Ghidra.
//
-// The script connects to the green-eye JSON-lines bridge (start it with
-// `./greeneye.sh ghidra [--kernel <elf>]`), and exposes the operations a
+// The script connects to the risc-v-gsp-rm-debugger JSON-lines bridge (start it with
+// `./risc-v-gsp-rm-debugger.sh ghidra [--kernel <elf>]`), and exposes the operations a
// reverse engineer needs while reading the decompiler:
//
// ping() - check the bridge
@@ -59,14 +59,14 @@ public class GreenEyeControl extends GhidraScript {
int port = Integer.parseInt(args[0]);
try {
connect(port);
- println("green-eye: " + info());
+ println("risc-v-gsp-rm-debugger: " + info());
String target = args.length > 1 ? args[1] : null;
if (target == null && currentAddress != null) {
target = "0x" + Long.toHexString(currentAddress.getOffset());
}
if (target != null) {
- println("green-eye run_until " + target + " -> " + runUntil(target));
- println("green-eye hits: " + listHits());
+ println("risc-v-gsp-rm-debugger run_until " + target + " -> " + runUntil(target));
+ println("risc-v-gsp-rm-debugger hits: " + listHits());
}
} finally {
disconnect();
@@ -95,11 +95,11 @@ public class GreenEyeControl extends GhidraScript {
writer.println(request);
String response = reader.readLine();
if (response == null) {
- throw new Exception("green-eye bridge closed the connection");
+ throw new Exception("risc-v-gsp-rm-debugger bridge closed the connection");
}
Matcher ok = OK.matcher(response);
if (ok.find() && "false".equals(ok.group(1))) {
- throw new Exception("green-eye error: " + response);
+ throw new Exception("risc-v-gsp-rm-debugger error: " + response);
}
return response;
}
diff --git a/debug/risc-v-gsp-rm-vm/ghidra/MarkGreenEyeHits.java b/debug/risc-v-gsp-rm-vm/ghidra/MarkGreenEyeHits.java
index b140ddd..bff3dfd 100644
--- a/debug/risc-v-gsp-rm-vm/ghidra/MarkGreenEyeHits.java
+++ b/debug/risc-v-gsp-rm-vm/ghidra/MarkGreenEyeHits.java
@@ -1,4 +1,4 @@
-// Annotate green-eye runtime hits in the current Ghidra program.
+// Annotate risc-v-gsp-rm-debugger runtime hits in the current Ghidra program.
//
// Input: the TSV produced by greeneye.ghidra.export_hits():
// addr <TAB> hits <TAB> symbol <TAB> annotation
@@ -9,10 +9,10 @@
// -postScript MarkGreenEyeHits.java /abs/path/greeneye_hits.tsv
//
// For each address it adds a plate comment on the containing function
-// ("green-eye: N hits") and a bookmark at the exact address.
+// ("risc-v-gsp-rm-debugger: N hits") and a bookmark at the exact address.
//
//@category OpenIOV
-//@menupath Tools.OpenIOV.Mark green-eye hits
+//@menupath Tools.OpenIOV.Mark risc-v-gsp-rm-debugger hits
import java.io.BufferedReader;
import java.io.File;
@@ -62,7 +62,7 @@ public class MarkGreenEyeHits extends GhidraScript {
Address address = toAddr(addrValue);
Function function = getFunctionContaining(address);
if (function != null) {
- String note = "green-eye: " + hits + " hit(s)"
+ String note = "risc-v-gsp-rm-debugger: " + hits + " hit(s)"
+ (symbol.isEmpty() ? "" : " (" + symbol + ")");
String existing = function.getComment();
function.setComment(existing == null ? note : existing + "\n" + note);
@@ -70,10 +70,10 @@ public class MarkGreenEyeHits extends GhidraScript {
} else {
missed++;
}
- createBookmark(address, "Note", "green-eye");
+ createBookmark(address, "Note", "risc-v-gsp-rm-debugger");
}
}
- println("green-eye: annotated " + marked + " functions (" + missed
+ println("risc-v-gsp-rm-debugger: annotated " + marked + " functions (" + missed
+ " addresses outside any function) from " + in.getAbsolutePath());
}
}
diff --git a/debug/risc-v-gsp-rm-vm/ghidra/README.md b/debug/risc-v-gsp-rm-vm/ghidra/README.md
index e0bb2c0..ce7b4c7 100644
--- a/debug/risc-v-gsp-rm-vm/ghidra/README.md
+++ b/debug/risc-v-gsp-rm-vm/ghidra/README.md
@@ -4,8 +4,8 @@ Two Java scripts run inside Ghidra (GUI or headless):
| Script | Direction | Purpose |
|---|---|---|
-| `ExportForGreenEye.java` | Ghidra → green-eye | write `addr<TAB>name<TAB>size` for every function |
-| `MarkGreenEyeHits.java` | green-eye → Ghidra | annotate functions with runtime hit counts + bookmarks |
+| `ExportForGreenEye.java` | Ghidra → risc-v-gsp-rm-debugger | write `addr<TAB>name<TAB>size` for every function |
+| `MarkGreenEyeHits.java` | risc-v-gsp-rm-debugger → Ghidra | annotate functions with runtime hit counts + bookmarks |
Typical loop:
@@ -15,8 +15,8 @@ $GHIDRA/support/analyzeHeadless <proj_dir> <project> -process <program> -noanaly
-scriptPath debug/risc-v-gsp-rm-vm/ghidra \
-postScript ExportForGreenEye.java /tmp/ghidra-symbols.tsv
-# 2. Build a green-eye symbol DB from it.
-./greeneye.sh symbols export --index /tmp/ghidra-symbols.tsv -o symbols.json
+# 2. Build a risc-v-gsp-rm-debugger symbol DB from it.
+./risc-v-gsp-rm-debugger.sh symbols export --index /tmp/ghidra-symbols.tsv -o symbols.json
# 3. Run a session, then export its hits.
python3 - <<'PY'
diff --git a/debug/risc-v-gsp-rm-vm/greeneye/__init__.py b/debug/risc-v-gsp-rm-vm/greeneye/__init__.py
index 717160c..4d55b89 100644
--- a/debug/risc-v-gsp-rm-vm/greeneye/__init__.py
+++ b/debug/risc-v-gsp-rm-vm/greeneye/__init__.py
@@ -1,7 +1,7 @@
-"""green-eye: Frida-like runtime instrumentation for GSP/uproc firmware in a
+"""risc-v-gsp-rm-debugger: Frida-like runtime instrumentation for GSP/uproc firmware in a
RISC-V QEMU VM.
-green-eye talks to QEMU's gdbstub directly (no GDB dependency) and layers a
+risc-v-gsp-rm-debugger talks to QEMU's gdbstub directly (no GDB dependency) and layers a
scriptable instrumentation API on top: breakpoints, hooks, watchpoints,
memory inspection, structure decoding, session recording and post-run analysis.
diff --git a/debug/risc-v-gsp-rm-vm/greeneye/analyze.py b/debug/risc-v-gsp-rm-vm/greeneye/analyze.py
index 1c7e930..cc8b8f6 100644
--- a/debug/risc-v-gsp-rm-vm/greeneye/analyze.py
+++ b/debug/risc-v-gsp-rm-vm/greeneye/analyze.py
@@ -143,9 +143,9 @@ def render_summary_from(meta: dict, events: list[dict], symbols=None, max_rows:
if trace is None:
trace = [e for e in events if _trace_kind(e) in _TRACE_KINDS]
lines: list[str] = []
- lines.append(f"# green-eye session summary: {meta.get('name', '?')}")
+ lines.append(f"# risc-v-gsp-rm-debugger session summary: {meta.get('name', '?')}")
lines.append("")
- lines.append(f"* format: `{meta.get('format', '?')}` green-eye {meta.get('greeneye', '?')}")
+ lines.append(f"* format: `{meta.get('format', '?')}` risc-v-gsp-rm-debugger {meta.get('greeneye', '?')}")
lines.append(f"* directory: `{meta.get('dir', '.')}`")
lines.append(f"* events: {len(events)}")
counts = Counter(event.get("type", "?") for event in events)
@@ -396,7 +396,7 @@ def compare_sessions(a_dir: str, b_dir: str, symbols=None, max_rows: int = 40) -
a_meta, b_meta = load_meta(a_dir), load_meta(b_dir)
a_events, b_events = load_events(a_dir), load_events(b_dir)
a_trace, b_trace = load_trace(a_dir, a_meta), load_trace(b_dir, b_meta)
- lines = [f"# green-eye session comparison", "", f"* A: {a_meta.get('name')} ({a_dir})", f"* B: {b_meta.get('name')} ({b_dir})", ""]
+ lines = [f"# risc-v-gsp-rm-debugger session comparison", "", f"* A: {a_meta.get('name')} ({a_dir})", f"* B: {b_meta.get('name')} ({b_dir})", ""]
def trace_kind(record: dict) -> str:
kind = _trace_kind(record)
diff --git a/debug/risc-v-gsp-rm-vm/greeneye/cli.py b/debug/risc-v-gsp-rm-vm/greeneye/cli.py
index e7023ec..3f3c937 100644
--- a/debug/risc-v-gsp-rm-vm/greeneye/cli.py
+++ b/debug/risc-v-gsp-rm-vm/greeneye/cli.py
@@ -1,4 +1,4 @@
-"""green-eye command line interface.
+"""risc-v-gsp-rm-debugger command line interface.
Commands:
info environment/tooling check (incl. native simulator availability)
@@ -14,7 +14,7 @@ Commands:
ghidra serve a live session to GhidraScripts over the JSON-lines bridge
analyze render a recorded session to a symbol-annotated report
compare A/B two recorded sessions at the symbolic level
- symbols build/inspect a green-eye symbol database from Ghidra exports
+ symbols build/inspect a risc-v-gsp-rm-debugger symbol database from Ghidra exports
plugins list discoverable plugins
"""
from __future__ import annotations
@@ -108,7 +108,7 @@ def _start_session(
def _print_session_dir(session) -> None:
directory = getattr(session.recorder, "dir", None)
if directory:
- print(f"[green-eye] session: {directory}")
+ print(f"[risc-v-gsp-rm-debugger] session: {directory}")
def _add_backend_arg(parser) -> None:
@@ -176,7 +176,7 @@ def _trace_spec(args):
def cmd_info(args) -> int:
from .target import DEFAULT_QEMU
- print(f"green-eye {ge.__version__}")
+ print(f"risc-v-gsp-rm-debugger {ge.__version__}")
print(f"tool root: {TOOL_ROOT}")
qemu = os.environ.get("GREENEYE_QEMU", DEFAULT_QEMU)
import shutil
@@ -314,8 +314,8 @@ def cmd_run(args) -> int:
class GreenEyeRepl(cmd.Cmd):
- intro = "green-eye interactive instrumentation. Type 'help' for commands."
- prompt = "greeneye> "
+ intro = "risc-v-gsp-rm-debugger interactive instrumentation. Type 'help' for commands."
+ prompt = "risc-v-gsp-rm-debugger> "
def __init__(self, session, manager):
super().__init__()
@@ -519,15 +519,15 @@ def cmd_launch(args) -> int:
raise GreenEyeError(f"kernel not found: {kernel}")
session = ge.launch(kernel=str(kernel), record=args.record, name="launch", keep_alive=True)
port = session.target.port
- print(f"[green-eye] target running: {kernel}")
- print(f"[green-eye] gdbstub: 127.0.0.1:{port}")
- print(f"[green-eye] attach: ./greeneye.sh attach --port {port} --kernel {kernel}")
- print("[green-eye] Ctrl-C stops waiting; QEMU keeps running for attach.")
+ print(f"[risc-v-gsp-rm-debugger] target running: {kernel}")
+ print(f"[risc-v-gsp-rm-debugger] gdbstub: 127.0.0.1:{port}")
+ print(f"[risc-v-gsp-rm-debugger] attach: ./risc-v-gsp-rm-debugger.sh attach --port {port} --kernel {kernel}")
+ print("[risc-v-gsp-rm-debugger] Ctrl-C stops waiting; QEMU keeps running for attach.")
try:
while True:
time.sleep(1)
except KeyboardInterrupt:
- print("[green-eye] detached (QEMU still running)")
+ print("[risc-v-gsp-rm-debugger] detached (QEMU still running)")
return 0
@@ -678,10 +678,10 @@ def cmd_ghidra(args) -> int:
)
bridge = GhidraBridge(session, port=args.bridge_port)
port = bridge.start()
- print(f"[green-eye] ghidra bridge on 127.0.0.1:{port}")
- print(f"[green-eye] session: {getattr(session.recorder, 'dir', None)}")
- print("[green-eye] in Ghidra: analyzeHeadless ... -postScript GreenEyeControl.java " + str(port))
- print("[green-eye] Ctrl-C to stop the bridge")
+ print(f"[risc-v-gsp-rm-debugger] ghidra bridge on 127.0.0.1:{port}")
+ print(f"[risc-v-gsp-rm-debugger] session: {getattr(session.recorder, 'dir', None)}")
+ print("[risc-v-gsp-rm-debugger] in Ghidra: analyzeHeadless ... -postScript GreenEyeControl.java " + str(port))
+ print("[risc-v-gsp-rm-debugger] Ctrl-C to stop the bridge")
try:
bridge.serve_forever()
except KeyboardInterrupt:
@@ -754,8 +754,8 @@ def cmd_plugins(args) -> int:
def build_parser() -> argparse.ArgumentParser:
- parser = argparse.ArgumentParser(prog="greeneye", description=__doc__.splitlines()[0])
- parser.add_argument("--version", action="version", version=f"green-eye {ge.__version__}")
+ parser = argparse.ArgumentParser(prog="risc-v-gsp-rm-debugger", description=__doc__.splitlines()[0])
+ parser.add_argument("--version", action="version", version=f"risc-v-gsp-rm-debugger {ge.__version__}")
sub = parser.add_subparsers(dest="command", required=True)
sub.add_parser("info", help="environment/tooling check").set_defaults(fn=cmd_info)
@@ -798,7 +798,7 @@ def build_parser() -> argparse.ArgumentParser:
probe.add_argument("--no-relocate", action="store_true")
probe.add_argument("--instructions", type=int, default=0)
probe.add_argument("--duration", type=float, default=1.0)
- probe.add_argument("--symbols", help="green-eye symbol DB JSON to annotate the stop")
+ probe.add_argument("--symbols", help="risc-v-gsp-rm-debugger symbol DB JSON to annotate the stop")
probe.add_argument("--record", nargs="?", const=True, default=None)
probe.set_defaults(fn=cmd_probe)
@@ -881,7 +881,7 @@ def main(argv: list[str] | None = None) -> int:
try:
return args.fn(args)
except GreenEyeError as exc:
- print(f"green-eye error: {exc}", file=sys.stderr)
+ print(f"risc-v-gsp-rm-debugger error: {exc}", file=sys.stderr)
return 2
except KeyboardInterrupt:
print("interrupted", file=sys.stderr)
diff --git a/debug/risc-v-gsp-rm-vm/greeneye/device_map.py b/debug/risc-v-gsp-rm-vm/greeneye/device_map.py
index 11ac656..2acb2a5 100644
--- a/debug/risc-v-gsp-rm-vm/greeneye/device_map.py
+++ b/debug/risc-v-gsp-rm-vm/greeneye/device_map.py
@@ -515,7 +515,7 @@ def _cmd_demo(args) -> int:
def main(argv: list[str] | None = None) -> int:
parser = argparse.ArgumentParser(
prog="python3 -m greeneye.device_map",
- description="Harvest, inspect and merge green-eye first-touch device maps.",
+ description="Harvest, inspect and merge risc-v-gsp-rm-debugger first-touch device maps.",
)
sub = parser.add_subparsers(dest="cmd", required=True)
diff --git a/debug/risc-v-gsp-rm-vm/greeneye/elf.py b/debug/risc-v-gsp-rm-vm/greeneye/elf.py
index abfccd9..3b8f04a 100644
--- a/debug/risc-v-gsp-rm-vm/greeneye/elf.py
+++ b/debug/risc-v-gsp-rm-vm/greeneye/elf.py
@@ -7,7 +7,7 @@ Needed for three things:
* entry-point detection for the first-fault firmware probe.
This is not a full ELF library; it parses headers, PT_LOAD segments and
-``.symtab`` symbols, which is all green-eye needs.
+``.symtab`` symbols, which is all risc-v-gsp-rm-debugger needs.
"""
from __future__ import annotations
diff --git a/debug/risc-v-gsp-rm-vm/greeneye/errors.py b/debug/risc-v-gsp-rm-vm/greeneye/errors.py
index fab5874..dc5771b 100644
--- a/debug/risc-v-gsp-rm-vm/greeneye/errors.py
+++ b/debug/risc-v-gsp-rm-vm/greeneye/errors.py
@@ -1,9 +1,9 @@
-"""green-eye error types. Keep them few and meaningful."""
+"""risc-v-gsp-rm-debugger error types. Keep them few and meaningful."""
from __future__ import annotations
class GreenEyeError(Exception):
- """Base class for all green-eye errors."""
+ """Base class for all risc-v-gsp-rm-debugger errors."""
class RspError(GreenEyeError):
diff --git a/debug/risc-v-gsp-rm-vm/greeneye/gdbridge.py b/debug/risc-v-gsp-rm-vm/greeneye/gdbridge.py
index cc06e43..eafac39 100644
--- a/debug/risc-v-gsp-rm-vm/greeneye/gdbridge.py
+++ b/debug/risc-v-gsp-rm-vm/greeneye/gdbridge.py
@@ -1,4 +1,4 @@
-"""Ghidra control bridge: let GhidraScripts drive a green-eye session.
+"""Ghidra control bridge: let GhidraScripts drive a risc-v-gsp-rm-debugger session.
A tiny JSON-lines server over localhost. Each request is one line::
@@ -20,6 +20,9 @@ import threading
from .errors import GreenEyeError
+#: The bridge is unauthenticated and write-capable; it must never be exposed.
+LOOPBACK_HOSTS = ("127.0.0.1", "localhost", "::1")
+
class GhidraBridge:
def __init__(self, session, host: str = "127.0.0.1", port: int = 0):
@@ -34,6 +37,8 @@ class GhidraBridge:
# -- lifecycle ---------------------------------------------------------
def start(self) -> int:
+ if self.host not in LOOPBACK_HOSTS:
+ raise ValueError(f"refusing non-loopback bind {self.host!r}; the Ghidra bridge is local-only")
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server.bind((self.host, self.port))
@@ -46,12 +51,21 @@ class GhidraBridge:
def stop(self) -> None:
self._stop.set()
- if self._server is not None:
+ server = self._server
+ self._server = None
+ if server is not None:
+ # shutdown() wakes a thread blocked in accept(); close() alone does
+ # not, which left the listener up after a <close> command.
+ try:
+ server.shutdown(socket.SHUT_RDWR)
+ except OSError:
+ pass
try:
- self._server.close()
+ server.close()
except OSError:
pass
- self._server = None
+ if self._thread is not None and self._thread.is_alive() and threading.current_thread() is not self._thread:
+ self._thread.join(timeout=2.0)
def serve_forever(self) -> None:
if self._thread is None:
diff --git a/debug/risc-v-gsp-rm-vm/greeneye/ghidra.py b/debug/risc-v-gsp-rm-vm/greeneye/ghidra.py
index 399a355..a7d547a 100644
--- a/debug/risc-v-gsp-rm-vm/greeneye/ghidra.py
+++ b/debug/risc-v-gsp-rm-vm/greeneye/ghidra.py
@@ -2,14 +2,14 @@
Two flows:
-*out of Ghidra*: export function names/addresses/sizes to a green-eye JSON
+*out of Ghidra*: export function names/addresses/sizes to a risc-v-gsp-rm-debugger JSON
symbol database (from ``names.tsv``, ``decompiled_index.tsv``, exports or ELF);
*hits*: turn a recorded session into ``greeneye_hits.tsv``
(``addr<TAB>hits<TAB>symbol``) that ``MarkGreenEyeHits.java`` can annotate in
the Ghidra project.
This is the static/dynamic join: Ghidra owns the address space and
-decompilation, green-eye owns what actually executed.
+decompilation, risc-v-gsp-rm-debugger owns what actually executed.
"""
from __future__ import annotations
diff --git a/debug/risc-v-gsp-rm-vm/greeneye/inject.py b/debug/risc-v-gsp-rm-vm/greeneye/inject.py
index f9605fc..eb4b16a 100644
--- a/debug/risc-v-gsp-rm-vm/greeneye/inject.py
+++ b/debug/risc-v-gsp-rm-vm/greeneye/inject.py
@@ -1,4 +1,4 @@
-"""Frida-like service injection for green-eye.
+"""Frida-like service injection for risc-v-gsp-rm-debugger.
Loads a position-independent RV64 service blob into a live target, registers
its dispatch entry with the firmware (on the demo uproc: a handler-table slot
@@ -8,7 +8,7 @@ firmware's own mailbox dispatcher.
On a future GSP-RM simulator the same shape becomes "inject an RM engine and
register it with the simulated RM core"; see ``docs/12-INJECTION-SDK.md`` and
-``GREEN-EYE-ROADMAP.md``.
+``RISC-V-GSP-RM-DEBUGGER-ROADMAP.md``.
"""
from __future__ import annotations
diff --git a/debug/risc-v-gsp-rm-vm/greeneye/plugins.py b/debug/risc-v-gsp-rm-vm/greeneye/plugins.py
index af4545f..6c597ac 100644
--- a/debug/risc-v-gsp-rm-vm/greeneye/plugins.py
+++ b/debug/risc-v-gsp-rm-vm/greeneye/plugins.py
@@ -1,4 +1,4 @@
-"""green-eye plugin system.
+"""risc-v-gsp-rm-debugger plugin system.
A plugin is a normal Python module that exposes::
@@ -7,7 +7,7 @@ A plugin is a normal Python module that exposes::
ge.add_command("mycmd", run_mycmd, help="…")
ge.hook("rpc_sum", on_enter=lambda hit: ge.log(f"sum({hit.arg(0)})"))
-Plugins can extend green-eye with:
+Plugins can extend risc-v-gsp-rm-debugger with:
* new CLI commands (including an MCP server later - roadmap);
* runtime RE tools (extra watchpoint strategies, structure probes, coverage);
diff --git a/debug/risc-v-gsp-rm-vm/greeneye/record.py b/debug/risc-v-gsp-rm-vm/greeneye/record.py
index 0b025b5..91c7fb5 100644
--- a/debug/risc-v-gsp-rm-vm/greeneye/record.py
+++ b/debug/risc-v-gsp-rm-vm/greeneye/record.py
@@ -1,6 +1,6 @@
"""Session recording: events.jsonl + snapshots + summary.
-A recorded session is the durable artifact green-eye produces: a complete,
+A recorded session is the durable artifact risc-v-gsp-rm-debugger produces: a complete,
symbol-annotatable map of what the firmware did (hook hits, watch hits,
memory writes, snapshots, coverage steps) that can be replayed offline,
diffed between runs (bare-metal vs VFIO-mdev, old GSP vs new GSP) and
diff --git a/debug/risc-v-gsp-rm-vm/greeneye/rsp.py b/debug/risc-v-gsp-rm-vm/greeneye/rsp.py
index 0263c63..b482f4c 100644
--- a/debug/risc-v-gsp-rm-vm/greeneye/rsp.py
+++ b/debug/risc-v-gsp-rm-vm/greeneye/rsp.py
@@ -1,6 +1,6 @@
"""Pure-Python GDB Remote Serial Protocol (RSP) client for QEMU's gdbstub.
-green-eye deliberately avoids GDB: the whole instrumentation stack is a Python
+risc-v-gsp-rm-debugger deliberately avoids GDB: the whole instrumentation stack is a Python
library, so sessions, probes and plugins are scriptable end to end. This
module implements the RSP subset QEMU needs: packet framing/acks, no-ack mode,
registers (with layout read from ``target.xml``), memory, software/hardware
diff --git a/debug/risc-v-gsp-rm-vm/greeneye/session.py b/debug/risc-v-gsp-rm-vm/greeneye/session.py
index fffc60e..2ef13a4 100644
--- a/debug/risc-v-gsp-rm-vm/greeneye/session.py
+++ b/debug/risc-v-gsp-rm-vm/greeneye/session.py
@@ -1,4 +1,4 @@
-"""green-eye instrumentation session: hooks, breakpoints, watchpoints, events.
+"""risc-v-gsp-rm-debugger instrumentation session: hooks, breakpoints, watchpoints, events.
This is the Frida-like core. It is deliberately transport-agnostic; the RSP
client is the default backend, and a Session can also be constructed around a
@@ -18,14 +18,22 @@ from .rsp import RspClient, StopReply
from .symbols import Symbol, SymbolDB
#: Registers saved and restored around ``Session.call`` (RISC-V ABI + pc).
+#: ``fp`` is x8/s0 under QEMU's target.xml name; both spellings are listed so
+#: the restore works whichever name the transport exposes.
RESTORE_REGS = (
- ["ra", "sp", "gp", "tp", "t0", "t1", "t2", "s0", "s1"]
+ ["ra", "sp", "gp", "tp", "t0", "t1", "t2", "s0", "fp", "s1"]
+ [f"a{i}" for i in range(8)]
+ [f"s{i}" for i in range(2, 12)]
+ [f"t{i}" for i in range(3, 7)]
+ ["pc"]
)
+#: Budget for the stop reply after a budget-interrupt. The default client
+#: socket timeout can be exhausted on a heavily loaded host before QEMU gets
+#: scheduled; a longer explicit budget keeps a probe from being misclassified
+#: as an error just because the host was busy.
+INTERRUPT_TIMEOUT = 30.0
+
@dataclass
class Hit:
@@ -392,7 +400,7 @@ class Session:
try:
stop = self.client.continue_(timeout=remaining)
except RspTimeout:
- self.client.interrupt()
+ self.client.interrupt(timeout=INTERRUPT_TIMEOUT)
raise RspTimeout(f"run_until {addr:#x}: not reached in {timeout}s")
hit = self._dispatch_stop(stop)
if hit is not None and hit.addr == addr and hit.kind == "breakpoint":
@@ -433,7 +441,7 @@ class Session:
try:
stop = self.client.continue_(timeout=remaining)
except RspTimeout:
- self.client.interrupt()
+ self.client.interrupt(timeout=INTERRUPT_TIMEOUT)
raise RspTimeout(f"call {addr:#x}: no return in {timeout}s")
hit = self._dispatch_stop(stop)
pc = self.client.pc
@@ -483,7 +491,7 @@ class Session:
except RspTimeout:
if deadline is None:
raise
- stop = self.client.interrupt()
+ stop = self.client.interrupt(timeout=INTERRUPT_TIMEOUT)
interrupted = True
stops += 1
self._dispatch_stop(stop)
@@ -496,7 +504,7 @@ class Session:
return stops
def stop(self) -> Hit | None:
- stop = self.client.interrupt()
+ stop = self.client.interrupt(timeout=INTERRUPT_TIMEOUT)
return self._dispatch_stop(stop)
# -- stop dispatch -----------------------------------------------------
diff --git a/debug/risc-v-gsp-rm-vm/greeneye/sim_backend.py b/debug/risc-v-gsp-rm-vm/greeneye/sim_backend.py
index d17076f..a2d2c6a 100644
--- a/debug/risc-v-gsp-rm-vm/greeneye/sim_backend.py
+++ b/debug/risc-v-gsp-rm-vm/greeneye/sim_backend.py
@@ -1,4 +1,4 @@
-"""Native green-eye execution backend (M1): deterministic RV64IMAC in Python.
+"""Native risc-v-gsp-rm-debugger execution backend (M1): deterministic RV64IMAC in Python.
``ge.launch(kernel=..., backend="native")`` builds a :class:`SimTarget` around
:class:`sim.machine.Machine` and exposes a :class:`SimClient` whose method
diff --git a/debug/risc-v-gsp-rm-vm/greeneye/symbols.py b/debug/risc-v-gsp-rm-vm/greeneye/symbols.py
index cb11f7f..d240fc4 100644
--- a/debug/risc-v-gsp-rm-vm/greeneye/symbols.py
+++ b/debug/risc-v-gsp-rm-vm/greeneye/symbols.py
@@ -1,4 +1,4 @@
-"""Symbol resolution and address translation for green-eye.
+"""Symbol resolution and address translation for risc-v-gsp-rm-debugger.
Inputs supported (all optional, merged into one database):
@@ -8,7 +8,7 @@ Inputs supported (all optional, merged into one database):
- ``decompiled_index.tsv`` / bucket TSVs
``<program_addr>\t<file_addr>\t<size>\t<name>\t<bucket>\t<line>\t<status>``,
- ``exports.tsv`` ``addr\tfile_addr\tsize\tname``,
-* green-eye native JSON (``greeneye-symbols.json``).
+* risc-v-gsp-rm-debugger native JSON (``greeneye-symbols.json``).
Address conventions (matching the project docs):
* Ghidra program address = file vaddr + image base (``0x100000`` for libcuda);
@@ -193,7 +193,7 @@ class SymbolDB:
return count
def load_json(self, path: str) -> int:
- """Load a green-eye JSON symbol DB; raise GreenEyeError on bad input."""
+ """Load a risc-v-gsp-rm-debugger JSON symbol DB; raise GreenEyeError on bad input."""
try:
with open(path, "r", encoding="utf-8") as fh:
payload = json.load(fh)
diff --git a/debug/risc-v-gsp-rm-vm/greeneye/target.py b/debug/risc-v-gsp-rm-vm/greeneye/target.py
index 273f216..669a55d 100644
--- a/debug/risc-v-gsp-rm-vm/greeneye/target.py
+++ b/debug/risc-v-gsp-rm-vm/greeneye/target.py
@@ -1,4 +1,4 @@
-"""QEMU target lifecycle for green-eye.
+"""QEMU target lifecycle for risc-v-gsp-rm-debugger.
Owns the ``qemu-system-riscv64`` process, the gdbstub endpoint, the serial
capture and the QEMU trace log. Both firmware paths are supported:
@@ -76,8 +76,10 @@ class QemuTarget:
os.makedirs(self.workdir, exist_ok=True)
self.uart_log = uart_log or os.path.join(self.workdir, "uart.log")
self.qemu_log = qemu_log or os.path.join(self.workdir, "qemu.log")
+ self.stderr_log = os.path.join(self.workdir, "qemu.stderr.log")
self.keep_alive = keep_alive
self.process: subprocess.Popen | None = None
+ self._stderr_fh = None
self._segment_files: list[str] = []
self._cmd: list[str] = []
@@ -118,15 +120,19 @@ class QemuTarget:
def start(self, paused: bool = True, timeout: float = 15.0) -> "QemuTarget":
self._cmd = self._build_command(paused)
+ # Never use an undrained stderr=PIPE: a chatty QEMU would block once
+ # the pipe buffer fills and then stop answering the gdbstub.
+ self._stderr_fh = open(self.stderr_log, "ab")
try:
self.process = subprocess.Popen(
self._cmd,
stdout=subprocess.DEVNULL,
- stderr=subprocess.PIPE,
+ stderr=self._stderr_fh,
cwd=self.workdir,
start_new_session=True,
)
except OSError as exc:
+ self._close_stderr()
raise TargetError(f"cannot start QEMU: {exc}") from exc
try:
self.wait_for_port(timeout=timeout)
@@ -140,11 +146,11 @@ class QemuTarget:
while time.monotonic() < deadline:
if self.process is not None and self.process.poll() is not None:
stderr = b""
- if self.process.stderr is not None:
- try:
- stderr = self.process.stderr.read() or b""
- except OSError:
- pass
+ try:
+ with open(self.stderr_log, "rb") as fh:
+ stderr = fh.read()
+ except OSError:
+ pass
raise TargetError(
f"QEMU exited early rc={self.process.returncode}: "
f"{stderr.decode('utf-8', 'replace')[-2000:]}"
@@ -159,8 +165,17 @@ class QemuTarget:
def alive(self) -> bool:
return self.process is not None and self.process.poll() is None
+ def _close_stderr(self) -> None:
+ if self._stderr_fh is not None:
+ try:
+ self._stderr_fh.close()
+ except OSError:
+ pass
+ self._stderr_fh = None
+
def kill(self, timeout: float = 5.0) -> None:
if self.process is None:
+ self._close_stderr()
return
if self.process.poll() is None:
try:
@@ -181,11 +196,7 @@ class QemuTarget:
except ProcessLookupError:
pass
self.process.wait(timeout=timeout)
- if self.process.stderr is not None:
- try:
- self.process.stderr.close()
- except OSError:
- pass
+ self._close_stderr()
self.process = None
# -- observation -------------------------------------------------------
diff --git a/debug/risc-v-gsp-rm-vm/harness/__init__.py b/debug/risc-v-gsp-rm-vm/harness/__init__.py
index d99d547..0f644dd 100644
--- a/debug/risc-v-gsp-rm-vm/harness/__init__.py
+++ b/debug/risc-v-gsp-rm-vm/harness/__init__.py
@@ -1,4 +1,4 @@
-"""green-eye automation harness.
+"""risc-v-gsp-rm-debugger automation harness.
Two stdlib-only orchestration tools:
diff --git a/debug/risc-v-gsp-rm-vm/harness/ci_release.py b/debug/risc-v-gsp-rm-vm/harness/ci_release.py
index dbc1f6f..ca1ab2c 100644
--- a/debug/risc-v-gsp-rm-vm/harness/ci_release.py
+++ b/debug/risc-v-gsp-rm-vm/harness/ci_release.py
@@ -1,5 +1,5 @@
#!/usr/bin/env python3
-"""Release triage orchestration for green-eye (planned docs/21).
+"""Release triage orchestration for risc-v-gsp-rm-debugger (planned docs/21).
Given an old and a new firmware target it runs, in order:
@@ -345,8 +345,8 @@ def build_parser() -> argparse.ArgumentParser:
parser.add_argument("--new-label", help="report label for the new target")
parser.add_argument("--release", help="release label; an rm610 release is gated by docs/23")
parser.add_argument("--approval-token", help=f"explicit RM610 token ({RM610_TOKEN})")
- parser.add_argument("--old-symbols", help="green-eye symbol DB JSON for the old target")
- parser.add_argument("--new-symbols", help="green-eye symbol DB JSON for the new target")
+ parser.add_argument("--old-symbols", help="risc-v-gsp-rm-debugger symbol DB JSON for the old target")
+ parser.add_argument("--new-symbols", help="risc-v-gsp-rm-debugger symbol DB JSON for the new target")
parser.add_argument("--matrix-symbols", help="one symbol DB JSON applied to both matrix targets")
parser.add_argument("--old-ghidra-names", help="Ghidra names.tsv for the old target")
parser.add_argument("--new-ghidra-names", help="Ghidra names.tsv for the new target")
@@ -359,7 +359,7 @@ def build_parser() -> argparse.ArgumentParser:
parser.add_argument("--corpus-diff", nargs=2, metavar=("OLD_TSV", "NEW_TSV"),
help="diff two decompiled_index.tsv corpus exports")
parser.add_argument("--corpus-report", help="attach a previously produced corpus diff report")
- parser.add_argument("--stimulus", help="green-eye script replacing the builtin demo scenario")
+ parser.add_argument("--stimulus", help="risc-v-gsp-rm-debugger script replacing the builtin demo scenario")
parser.add_argument("--probe-instructions", type=int, default=2000)
parser.add_argument("--behavior-duration", type=float, default=0.4)
parser.add_argument("--max-rows", type=int, default=40)
diff --git a/debug/risc-v-gsp-rm-vm/harness/common.py b/debug/risc-v-gsp-rm-vm/harness/common.py
index 74dabe0..849f208 100644
--- a/debug/risc-v-gsp-rm-vm/harness/common.py
+++ b/debug/risc-v-gsp-rm-vm/harness/common.py
@@ -1,5 +1,5 @@
#!/usr/bin/env python3
-"""Shared helpers for the green-eye automation harness.
+"""Shared helpers for the risc-v-gsp-rm-debugger automation harness.
The harness scripts run from the tool root without installation, so this
module bootstraps the tool root onto ``sys.path`` before importing greeneye.
diff --git a/debug/risc-v-gsp-rm-vm/harness/control_discovery.py b/debug/risc-v-gsp-rm-vm/harness/control_discovery.py
index b44636a..ca671d2 100644
--- a/debug/risc-v-gsp-rm-vm/harness/control_discovery.py
+++ b/debug/risc-v-gsp-rm-vm/harness/control_discovery.py
@@ -804,7 +804,7 @@ def render_markdown(report: dict, options: "DiscoveryOptions") -> str:
for row in per_id.values():
grouped.setdefault(primary_class(row), []).append(row["id"])
lines = [
- "# green-eye control discovery report",
+ "# risc-v-gsp-rm-debugger control discovery report",
"",
"> TOOL IN DEVELOPMENT - NOT READY YET! Generated by `harness/control_discovery.py`.",
"",
diff --git a/debug/risc-v-gsp-rm-vm/harness/mutation_harness.py b/debug/risc-v-gsp-rm-vm/harness/mutation_harness.py
index 7b558bd..9b4d102 100644
--- a/debug/risc-v-gsp-rm-vm/harness/mutation_harness.py
+++ b/debug/risc-v-gsp-rm-vm/harness/mutation_harness.py
@@ -7,7 +7,7 @@ region), runs it for a bounded budget, and classifies the outcome: normal,
trap (ebreak / control transfer to an invalid PC), fault (first new QEMU
exception, parsed from the guest_errors/int log), no-progress, or
unexpected-result against a small demo oracle. Every attempt is recorded as a
-green-eye session and a compact finding.
+risc-v-gsp-rm-debugger session and a compact finding.
Strategies: invalid command IDs, boundary values, single bit flips of valid
inputs, and buffer length boundaries for the ECHO/FILL/SUM commands.
@@ -437,7 +437,7 @@ def write_summary(options: HarnessOptions, findings: list[dict]) -> str:
classes = Counter(finding["outcome"] for finding in findings)
strategies = Counter(finding["strategy"] for finding in findings)
lines = [
- "# green-eye mutation findings",
+ "# risc-v-gsp-rm-debugger mutation findings",
"",
"> TOOL IN DEVELOPMENT - NOT READY YET! Generated by `harness/mutation_harness.py`.",
"",
diff --git a/debug/risc-v-gsp-rm-vm/harness/package_sim.py b/debug/risc-v-gsp-rm-vm/harness/package_sim.py
index 28f54c4..98484c3 100644
--- a/debug/risc-v-gsp-rm-vm/harness/package_sim.py
+++ b/debug/risc-v-gsp-rm-vm/harness/package_sim.py
@@ -1,5 +1,5 @@
#!/usr/bin/env python3
-"""Package the native green-eye simulator together with injected code.
+"""Package the native risc-v-gsp-rm-debugger simulator together with injected code.
Builds a self-contained trial directory (or deterministic ``.tar.gz``):
@@ -240,7 +240,7 @@ def write_deterministic_tar(out_dir: str, tar_path: str) -> str:
# -- request/build ----------------------------------------------------------
RUN_SH = """#!/bin/sh
-# green-eye trial runner (generated by harness/package_sim.py; inspect before use).
+# risc-v-gsp-rm-debugger trial runner (generated by harness/package_sim.py; inspect before use).
# Usage: ./run.sh [scenario args] Environment: GREENEYE_HOME overrides the tool root.
set -eu
here=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)
@@ -252,7 +252,7 @@ else
root=$(dirname "$root")
done
if [ ! -f "$root/greeneye/__init__.py" ]; then
- echo "run.sh: green-eye tool root not found; set GREENEYE_HOME" >&2
+ echo "run.sh: risc-v-gsp-rm-debugger tool root not found; set GREENEYE_HOME" >&2
exit 3
fi
fi
@@ -286,11 +286,11 @@ def _readme_text(
preinject: dict | None,
) -> str:
lines = [
- "# green-eye trial package",
+ "# risc-v-gsp-rm-debugger trial package",
"",
"Generated by `harness/package_sim.py` (`greeneye-trial/1`). This package",
"bundles a target, an injected service blob and a pre-scripted scenario",
- "that runs on the deterministic native RV64 simulator in the green-eye",
+ "that runs on the deterministic native RV64 simulator in the risc-v-gsp-rm-debugger",
"tool tree. It needs no QEMU, no GPU and no guest.",
"",
"## Contents",
@@ -309,7 +309,7 @@ def _readme_text(
"./run.sh --budget 200000",
"```",
"",
- "Requires Python 3.10+ and the green-eye tool tree. `run.sh` finds the",
+ "Requires Python 3.10+ and the risc-v-gsp-rm-debugger tool tree. `run.sh` finds the",
"tree by walking up from this directory; set `GREENEYE_HOME=/path/to/risc-v-gsp-rm-vm`",
"if the package was moved. Exit code 0 means the assertions passed (or an",
"image package produced its documented blocked status), 1 means an",
@@ -651,7 +651,7 @@ def run_package(out: str, *, timeout: float = DEFAULT_RUN_TIMEOUT, args: list[st
def main(argv: list[str] | None = None) -> int:
parser = argparse.ArgumentParser(
prog="python3 harness/package_sim.py",
- description="Build a self-contained green-eye trial package (simulator + injected service).",
+ description="Build a self-contained risc-v-gsp-rm-debugger trial package (simulator + injected service).",
)
parser.add_argument("--target", choices=("demo", "image"), default="demo",
help="demo uproc (default) or a real .fwimage")
@@ -702,7 +702,7 @@ def main(argv: list[str] | None = None) -> int:
# -- generated scenario -----------------------------------------------------
BUILTIN_SCENARIO = r'''#!/usr/bin/env python3
-"""Pre-scripted green-eye trial scenario (generated by harness/package_sim.py).
+"""Pre-scripted risc-v-gsp-rm-debugger trial scenario (generated by harness/package_sim.py).
Boots the packaged target on the native simulator, loads and registers the
injected service, invokes it directly and through the firmware mailbox, runs
@@ -725,7 +725,7 @@ SUM_A0 = 0x10
SUM_A1 = 0x20
EXPECTED_PING = PING_ARG ^ 0xBEEF
EXPECTED_SUM = SUM_A0 + SUM_A1
-UART_BANNER = "GREEN-EYE UPROC DEMO v1"
+UART_BANNER = "RISC-V GSP-RM DEBUGGER UPROC DEMO v1"
UART_SELFTEST = "SELFTEST DONE"
@@ -790,7 +790,7 @@ def hexv(value):
def render_md(manifest, data):
target = data.get("target", {})
- lines = ["# green-eye trial results", ""]
+ lines = ["# risc-v-gsp-rm-debugger trial results", ""]
lines.append(f"- status: **{data.get('status')}**")
lines.append(f"- target: `{target.get('file', '?')}` ({target.get('kind', '?')})")
service = data.get("service")
@@ -1117,7 +1117,7 @@ def run_image(pkg, manifest, budget=None):
def main(argv=None):
- parser = argparse.ArgumentParser(description="Run a packaged green-eye trial.")
+ parser = argparse.ArgumentParser(description="Run a packaged risc-v-gsp-rm-debugger trial.")
parser.add_argument("--package", default=os.path.dirname(os.path.abspath(__file__)))
parser.add_argument("--budget", type=int, default=None,
help="image probe budget in instructions (default from manifest)")
diff --git a/debug/risc-v-gsp-rm-vm/harness/port_driver_versions.py b/debug/risc-v-gsp-rm-vm/harness/port_driver_versions.py
index e751d42..f12b8e9 100644
--- a/debug/risc-v-gsp-rm-vm/harness/port_driver_versions.py
+++ b/debug/risc-v-gsp-rm-vm/harness/port_driver_versions.py
@@ -873,7 +873,7 @@ def _table(headers: list[str], rows: list[list]) -> list[str]:
def render_version_markdown(entry: dict) -> str:
lines = [
- f"# green-eye port version {entry['version']}",
+ f"# risc-v-gsp-rm-debugger port version {entry['version']}",
"",
"> TOOL IN DEVELOPMENT - NOT READY YET! Generated by `harness/port_driver_versions.py`.",
"",
@@ -904,7 +904,7 @@ def render_version_markdown(entry: dict) -> str:
def render_sweep_markdown(report: dict) -> str:
lines = [
- "# green-eye driver-version port sweep",
+ "# risc-v-gsp-rm-debugger driver-version port sweep",
"",
"> TOOL IN DEVELOPMENT - NOT READY YET! Generated by `harness/port_driver_versions.py`.",
"",
@@ -1027,7 +1027,7 @@ def build_parser() -> argparse.ArgumentParser:
parser.add_argument("--target", action="append", default=[], metavar="VERSION=PATH",
help="explicit local target for a version (repeatable; skips discovery)")
parser.add_argument("--symbols", action="append", default=[], metavar="VERSION=PATH",
- help="green-eye symbol DB JSON for a version (repeatable)")
+ help="risc-v-gsp-rm-debugger symbol DB JSON for a version (repeatable)")
parser.add_argument("--ghidra-exports", action="append", default=[], metavar="VERSION=PATH",
help="Ghidra exports TSV for a version (repeatable)")
parser.add_argument("--out", help="sweep output directory (required for --run)")
diff --git a/debug/risc-v-gsp-rm-vm/harness/port_new_device.py b/debug/risc-v-gsp-rm-vm/harness/port_new_device.py
index 56522ec..8ed1a0c 100644
--- a/debug/risc-v-gsp-rm-vm/harness/port_new_device.py
+++ b/debug/risc-v-gsp-rm-vm/harness/port_new_device.py
@@ -6,7 +6,7 @@ device facts (PCI IDs, BARs, FB geometry, engine inventory, interrupt topology,
ROM/VBIOS notes) and then drives, on the local QEMU backend only:
1. probe-first-touch on the device's firmware (first unmapped access, bounded);
-2. a symbol inventory (ELF .symtab + optional Ghidra/green-eye DB sources);
+2. a symbol inventory (ELF .symtab + optional Ghidra/risc-v-gsp-rm-debugger DB sources);
3. a portability matrix run of the device against a reference firmware;
4. a port checklist report against the docs/07 evidence checklist.
@@ -466,7 +466,7 @@ def build_checklist(profile: dict, firmware: str, reference: str | None, results
def render_checklist_markdown(checklist: dict) -> str:
lines = [
- f"# green-eye port checklist: {checklist['device']}",
+ f"# risc-v-gsp-rm-debugger port checklist: {checklist['device']}",
"",
"> TOOL IN DEVELOPMENT - NOT READY YET! Generated by `harness/port_new_device.py`.",
"",
@@ -585,7 +585,7 @@ def run_device_port(options: DeviceOptions) -> dict:
def render_report_markdown(report: dict) -> str:
lines = [
- f"# green-eye device port: {report['device']}",
+ f"# risc-v-gsp-rm-debugger device port: {report['device']}",
"",
"> TOOL IN DEVELOPMENT - NOT READY YET! Generated by `harness/port_new_device.py`.",
"",
@@ -643,7 +643,7 @@ def build_parser() -> argparse.ArgumentParser:
parser.add_argument("--profile", help="profile JSON path (default: <out>/profiles/<device>.json)")
parser.add_argument("--firmware", help="device GSP firmware image or re-hosted ELF (overrides profile)")
parser.add_argument("--reference", help="reference firmware for the portability matrix")
- parser.add_argument("--symbols", help="green-eye symbol DB JSON for the device firmware")
+ parser.add_argument("--symbols", help="risc-v-gsp-rm-debugger symbol DB JSON for the device firmware")
parser.add_argument("--ghidra-exports", help="Ghidra exports TSV for the device firmware")
parser.add_argument("--ghidra-bias", type=lambda value: int(value, 0), default=0)
parser.add_argument("--out", help="evidence bundle directory (required for --run)")
diff --git a/debug/risc-v-gsp-rm-vm/harness/portability_matrix.py b/debug/risc-v-gsp-rm-vm/harness/portability_matrix.py
index 82af458..68ffdd3 100644
--- a/debug/risc-v-gsp-rm-vm/harness/portability_matrix.py
+++ b/debug/risc-v-gsp-rm-vm/harness/portability_matrix.py
@@ -8,9 +8,9 @@ each on the QEMU backend:
1. bounded probe: relocate into virt RAM and run/step a fixed budget,
capturing the first exception via ``parse_qemu_faults``;
2. symbol DB build: ELF symbols plus optional Ghidra exports / an existing
- green-eye JSON DB, saved per target;
+ risc-v-gsp-rm-debugger JSON DB, saved per target;
3. scripted demo run with handler hooks and a control-block watchpoint,
- recorded as a normal green-eye session;
+ recorded as a normal risc-v-gsp-rm-debugger session;
4. cross-target comparison with ``greeneye.analyze.compare_sessions`` plus
explicit hit/watch/write profile deltas and the docs/06 M1-M6 skeleton
(metrics without a reference capture are marked "not measured").
@@ -563,11 +563,11 @@ def _profile_tables(title: str, profile: dict, max_rows: int) -> list[str]:
def render_markdown(report: dict, options: MatrixOptions) -> str:
lines = [
- "# green-eye portability delta report",
+ "# risc-v-gsp-rm-debugger portability delta report",
"",
"> TOOL IN DEVELOPMENT - NOT READY YET! Generated by `harness/portability_matrix.py`.",
"",
- f"* format: `{report['format']}` (green-eye {_greeneye_version()})",
+ f"* format: `{report['format']}` (risc-v-gsp-rm-debugger {_greeneye_version()})",
f"* backend: `{report['backend']}` (qemu available: {report['qemu_available']})",
f"* targets: {len(report['targets'])}",
"",
@@ -726,7 +726,7 @@ def build_parser() -> argparse.ArgumentParser:
parser.add_argument("--scenario-duration", type=float, default=0.4, help="budget for each scenario phase")
parser.add_argument("--max-stops", type=int, default=5000, help="safety bound on serviced stops per scenario phase")
parser.add_argument("--max-rows", type=int, default=40, help="table row cap in reports")
- parser.add_argument("--scenario-script", help="replace the builtin scenario with a green-eye script")
+ parser.add_argument("--scenario-script", help="replace the builtin scenario with a risc-v-gsp-rm-debugger script")
return parser
diff --git a/debug/risc-v-gsp-rm-vm/harness/reach.py b/debug/risc-v-gsp-rm-vm/harness/reach.py
index 9df0c4c..68934b1 100644
--- a/debug/risc-v-gsp-rm-vm/harness/reach.py
+++ b/debug/risc-v-gsp-rm-vm/harness/reach.py
@@ -8,7 +8,7 @@ I trigger it, what arguments does it need, and what happens when it runs?*
Methods attempted (``--method auto`` tries them in this order and stops at the
first hit unless ``--all-methods`` is given):
-* ``stimulus`` -- run a supplied green-eye script (``--stimulus script.py``)
+* ``stimulus`` -- run a supplied risc-v-gsp-rm-debugger script (``--stimulus script.py``)
or probe spec (``--probe probe.json``) under instrumentation;
* ``trigger`` -- discover the dispatch entry that routes to the target (the
demo's handler table), apply that command, and run bounded;
@@ -671,7 +671,7 @@ def trace_window(success: Attempt | None) -> dict | None:
def render_markdown(report: dict, options: ReachOptions) -> str:
lines = [
- "# green-eye reachability report",
+ "# risc-v-gsp-rm-debugger reachability report",
"",
"> TOOL IN DEVELOPMENT - NOT READY YET! Generated by `harness/reach.py`.",
"",
@@ -874,7 +874,7 @@ def build_parser() -> argparse.ArgumentParser:
parser.add_argument("--arg-fill", choices=("zero", "sentinel"), default="zero", help="auto-fill value policy")
parser.add_argument("--timeout", type=float, default=0.5, help="per-attempt budget (seconds)")
parser.add_argument("--settle", type=float, default=2.0, help="self-test settle budget before trigger")
- parser.add_argument("--stimulus", help="green-eye script to run under instrumentation")
+ parser.add_argument("--stimulus", help="risc-v-gsp-rm-debugger script to run under instrumentation")
parser.add_argument("--probe", help="JSON probe spec to replay (see --emit-probe)")
parser.add_argument("--emit-probe", help="where to write the repeatable probe spec (default <out>/probe.json)")
parser.add_argument("--record", nargs="?", const=True, default=None, help="record attempts under DIR/<method>")
diff --git a/debug/risc-v-gsp-rm-vm/harness/value_demos/README.md b/debug/risc-v-gsp-rm-vm/harness/value_demos/README.md
index e1a450c..96ce4d9 100644
--- a/debug/risc-v-gsp-rm-vm/harness/value_demos/README.md
+++ b/debug/risc-v-gsp-rm-vm/harness/value_demos/README.md
@@ -1,19 +1,19 @@
-# green-eye value-validation demos
+# risc-v-gsp-rm-debugger value-validation demos
-Runnable demonstrations that tie green-eye tool capabilities to **real**
+Runnable demonstrations that tie risc-v-gsp-rm-debugger tool capabilities to **real**
Open-IOV scenarios (cited from `Handoff-vGPU-IO.md` and the project docs) and
measure the time-to-value against the static/Ghidra-only baseline.
Each demo:
* names the real scenario (handoff PART/addendum + date) and what it cost;
-* prints the question, the green-eye commands used, the answer, the evidence
+* prints the question, the risc-v-gsp-rm-debugger commands used, the answer, the evidence
artifact and the elapsed wall-clock;
* writes a machine-readable `result.json` under `artifacts/<demo>/`;
* labels what is **measured on the analog** vs **projected for the real
case**; device-model-blocked scenarios say so explicitly.
-> green-eye is development-only tooling (docs/00); these demos never touch
+> risc-v-gsp-rm-debugger is development-only tooling (docs/00); these demos never touch
> hardware, a guest or a kernel module. The real `.fwimage` cannot boot
> without the H2 device model (docs/06 §3), so every demo is honest about
> being a *shape* reproduction on the bundled `uproc_demo` firmware + native
@@ -58,7 +58,7 @@ per-demo timeout and the full suite runs in ~18 s on the reference host
| s09 | `s09_grabbing_a_ghidra_address.py` | static/dynamic join; GPFIFO GET fault `0x40000` vs `0x101000` (PART 91 ADDENDUM 9 cycle 24) | hypothesis unproven until the decoded status-queue fault (8 cycles) | Ghidra addr + bias = runtime; hook hit + `greeneye_hits.tsv` (0.72 s) |
| s10 | `s10_full_session_evidence.py` | evidence pack for a milestone (docs/14 §6; cycles 11–13, 2026-10-01) | hashes/sessions/logs/compare gathered by hand per cycle | one run → analyze + compare + hits + manifest + M1–M6 (4.92 s) |
-Times are the measured green-eye path on the reference host (native for
+Times are the measured risc-v-gsp-rm-debugger path on the reference host (native for
s01–s08, QEMU for s09/s10); see `artifacts/results.json` for a fresh run.
## Projected vs measured
diff --git a/debug/risc-v-gsp-rm-vm/harness/value_demos/__init__.py b/debug/risc-v-gsp-rm-vm/harness/value_demos/__init__.py
index 87cabe7..727f0c0 100644
--- a/debug/risc-v-gsp-rm-vm/harness/value_demos/__init__.py
+++ b/debug/risc-v-gsp-rm-vm/harness/value_demos/__init__.py
@@ -1 +1 @@
-"""green-eye value-validation demos (see docs/25-VALUE-VALIDATION.md)."""
+"""risc-v-gsp-rm-debugger value-validation demos (see docs/25-VALUE-VALIDATION.md)."""
diff --git a/debug/risc-v-gsp-rm-vm/harness/value_demos/_common.py b/debug/risc-v-gsp-rm-vm/harness/value_demos/_common.py
index f70ef1f..0733c48 100644
--- a/debug/risc-v-gsp-rm-vm/harness/value_demos/_common.py
+++ b/debug/risc-v-gsp-rm-vm/harness/value_demos/_common.py
@@ -1,9 +1,9 @@
#!/usr/bin/env python3
-"""Shared plumbing for the green-eye value-validation demos.
+"""Shared plumbing for the risc-v-gsp-rm-debugger value-validation demos.
Every demo maps one *real* Open-IOV scenario (cited from the handoffs) onto a
runnable demonstration on the bundled demo firmware / native RV64 simulator,
-prints the question, the green-eye commands, the answer, the evidence artifact
+prints the question, the risc-v-gsp-rm-debugger commands, the answer, the evidence artifact
and the measured wall-clock, and emits one machine-readable ``RESULT_JSON``
line so ``run_all.py`` can aggregate.
diff --git a/debug/risc-v-gsp-rm-vm/harness/value_demos/s05_snapshot_diff.py b/debug/risc-v-gsp-rm-vm/harness/value_demos/s05_snapshot_diff.py
index fd89131..d6b6871 100644
--- a/debug/risc-v-gsp-rm-vm/harness/value_demos/s05_snapshot_diff.py
+++ b/debug/risc-v-gsp-rm-vm/harness/value_demos/s05_snapshot_diff.py
@@ -83,7 +83,7 @@ def run() -> dict:
ctrl = session.symbols.lookup("gsp_ctrl")
session.run(duration=0.25)
before = session.snapshot(ctrl, C.CTRL_SIZE, "before-echo")
- message = b"hello-green-eye"
+ message = b"hello-risc-v-gsp-rm-debugger"
# Locate the string literal in the loaded image so the stimulus is
# self-describing (no hardcoded address).
hits = session.memory.search(0x80000000, 0x2000, message)
diff --git a/debug/risc-v-gsp-rm-vm/harness/value_demos/s07_version_diff.py b/debug/risc-v-gsp-rm-vm/harness/value_demos/s07_version_diff.py
index e4748d7..eaad957 100644
--- a/debug/risc-v-gsp-rm-vm/harness/value_demos/s07_version_diff.py
+++ b/debug/risc-v-gsp-rm-vm/harness/value_demos/s07_version_diff.py
@@ -29,8 +29,8 @@ except ImportError:
#: addiw a1, a1, -0x111 (the 0xbeef PING key) -> -0x110 (0xbef0)
ADDW_OLD = bytes.fromhex("9b85f5ee")
ADDW_NEW = bytes.fromhex("9b8505ef")
-STRING_OLD = b"hello-green-eye"
-STRING_NEW = b"hello-green-eyf"
+STRING_OLD = b"hello-risc-v-gsp-rm-debugger"
+STRING_NEW = b"hello-risc-v-gsp-rm-debuggef"
def _make_variant(src: str, dst: str) -> dict:
@@ -89,7 +89,7 @@ def run() -> dict:
"comparison; the pairing hypothesis took cycles 2 and 3 back-to-back"
),
projection=(
- "green-eye cannot boot the real image without the H2 device model; "
+ "risc-v-gsp-rm-debugger cannot boot the real image without the H2 device model; "
"the same same-stimulus/compare-sessions loop runs on re-hosted "
"firmware and the produced symbol/session deltas are the H4.1 artifact"
),
diff --git a/debug/risc-v-gsp-rm-vm/harness/value_demos/s08_mutation_triage.py b/debug/risc-v-gsp-rm-vm/harness/value_demos/s08_mutation_triage.py
index 8fcaed1..d961ee0 100644
--- a/debug/risc-v-gsp-rm-vm/harness/value_demos/s08_mutation_triage.py
+++ b/debug/risc-v-gsp-rm-vm/harness/value_demos/s08_mutation_triage.py
@@ -39,7 +39,7 @@ def _probe(ge, mutation: dict, backend: str) -> dict:
session.run(duration=0.15)
literal = 0
if mutation.get("arg0") == "hello":
- hits = session.memory.search(0x80000000, 0x2000, b"hello-green-eye")
+ hits = session.memory.search(0x80000000, 0x2000, b"hello-risc-v-gsp-rm-debugger")
literal = hits[0] if hits else ctrl + C.CTRL_BUF
before = session.memory.read_u64(ctrl + C.CTRL_RPC_COUNT)
session.memory.write_u64(ctrl + C.CTRL_ARG0, literal if mutation.get("arg0") == "hello" else mutation.get("arg0", 0))
diff --git a/debug/risc-v-gsp-rm-vm/harness/value_demos/s09_grabbing_a_ghidra_address.py b/debug/risc-v-gsp-rm-vm/harness/value_demos/s09_grabbing_a_ghidra_address.py
index 1577772..1d30b58 100644
--- a/debug/risc-v-gsp-rm-vm/harness/value_demos/s09_grabbing_a_ghidra_address.py
+++ b/debug/risc-v-gsp-rm-vm/harness/value_demos/s09_grabbing_a_ghidra_address.py
@@ -7,7 +7,7 @@ hypothesis (the GPFIFO GET encodes entry VA ``0x101000``) was only accepted
after the decoded status-queue fault showed the engine actually fetched
``0x40000`` because the GET field dropped the high VA bits (fix ``6f9cbfa``).
The static/dynamic join is exactly this: Ghidra owns addresses and
-decompilation, green-eye answers "did it execute here".
+decompilation, risc-v-gsp-rm-debugger answers "did it execute here".
Analog: export a Ghidra-style ``names.tsv`` from the demo ELF *with a base
offset* (the classic program-address vs runtime-address trap), load it with
diff --git a/debug/risc-v-gsp-rm-vm/harness/version_diff.py b/debug/risc-v-gsp-rm-vm/harness/version_diff.py
index a95f244..ccc6a15 100644
--- a/debug/risc-v-gsp-rm-vm/harness/version_diff.py
+++ b/debug/risc-v-gsp-rm-vm/harness/version_diff.py
@@ -8,7 +8,7 @@ of aborting the report:
1. image/shape -- entry, PT_LOAD layout, ELF section sizes, hashes, span;
2. symbol inventory -- ELF ``.symtab`` plus Ghidra names/index/exports TSVs
(including the 3-column ``ExportForGreenEye`` form) and
- green-eye JSON DBs; added/removed/moved/resized with
+ risc-v-gsp-rm-debugger JSON DBs; added/removed/moved/resized with
the anonymous-shift matching discipline of
``userspace/cuda/tools/diff_corpus.py``;
3. decompiled hints -- a corpus diff over two ``decompiled_index.tsv`` files,
@@ -27,11 +27,15 @@ Everything is local and stdlib-only: nothing is downloaded. The RM 610 gate
Run from the tool root:
python3 harness/version_diff.py --old old.elf --new new.elf --out dumps/vdiff
+
+``--dry-run`` prints the plan (and enforces the RM 610 gate) without opening
+any target or creating ``--out``.
"""
from __future__ import annotations
import argparse
import contextlib
+import json
import os
import re
import shutil
@@ -102,6 +106,7 @@ from greeneye.symbols import Symbol # noqa: E402
from greeneye.target import QemuTarget # noqa: E402
FORMAT = "greeneye-version-diff/1"
+PLAN_FORMAT = "greeneye-version-diff-plan/1"
RM610_DOC = "docs/23-RM610-READINESS.md"
RM610_TOKEN = "RM610-APPROVED"
RM610_ENV = "GREENEYE_RM610_APPROVED"
@@ -1218,7 +1223,7 @@ def _hex(value) -> str:
def render_markdown(report: dict, options: VersionDiffOptions) -> str:
old, new = report["old"], report["new"]
lines = [
- "# green-eye version diff",
+ "# risc-v-gsp-rm-debugger version diff",
"",
"> **# TOOL IN DEVELOPMENT - NOT READY YET!** Generated by `harness/version_diff.py`.",
"",
@@ -1413,7 +1418,7 @@ def _short_json(value, limit: int = 72) -> str:
def _add_side_symbols(parser: argparse.ArgumentParser, side: str) -> None:
- parser.add_argument(f"--{side}-symbols", help="green-eye symbol DB JSON for the %s target" % side)
+ parser.add_argument(f"--{side}-symbols", help="risc-v-gsp-rm-debugger symbol DB JSON for the %s target" % side)
parser.add_argument(f"--{side}-ghidra-names", help="Ghidra names.tsv for the %s target" % side)
parser.add_argument(f"--{side}-ghidra-index", help="Ghidra decompiled_index.tsv for the %s target" % side)
parser.add_argument(
@@ -1428,7 +1433,8 @@ def build_parser() -> argparse.ArgumentParser:
parser = argparse.ArgumentParser(prog="version_diff", description=__doc__.splitlines()[0])
parser.add_argument("--old", required=True, help="old target (RISC-V ELF or raw .fwimage)")
parser.add_argument("--new", required=True, help="new target (RISC-V ELF or raw .fwimage)")
- parser.add_argument("--out", required=True, help="output directory for the report, sessions and DBs")
+ parser.add_argument("--out", help="output directory for the report, sessions and DBs (required unless --dry-run)")
+ parser.add_argument("--dry-run", action="store_true", help="print the plan and exit without opening targets or creating --out")
parser.add_argument("--old-label", help="report label for the old target (default: file stem)")
parser.add_argument("--new-label", help="report label for the new target (default: file stem)")
parser.add_argument("--release", help="release label; an rm610 release is gated by docs/23")
@@ -1438,7 +1444,7 @@ def build_parser() -> argparse.ArgumentParser:
parser.add_argument("--corpus-diff", nargs=2, metavar=("OLD_TSV", "NEW_TSV"),
help="diff two decompiled_index.tsv corpus exports")
parser.add_argument("--corpus-report", help="attach a previously produced corpus diff report")
- parser.add_argument("--stimulus", help="green-eye script replacing the builtin demo scenario")
+ parser.add_argument("--stimulus", help="risc-v-gsp-rm-debugger script replacing the builtin demo scenario")
parser.add_argument("--probe-instructions", type=int, default=2000,
help="probe step budget (0 = wall-clock --probe-duration)")
parser.add_argument("--probe-duration", type=float, default=0.5,
@@ -1456,7 +1462,7 @@ def options_from_args(args: argparse.Namespace) -> VersionDiffOptions:
return VersionDiffOptions(
old=args.old,
new=args.new,
- out=os.path.abspath(args.out),
+ out=os.path.abspath(args.out) if args.out else "",
old_label=args.old_label,
new_label=args.new_label,
release=args.release,
@@ -1483,9 +1489,39 @@ def options_from_args(args: argparse.Namespace) -> VersionDiffOptions:
)
+def build_plan(options: VersionDiffOptions) -> dict:
+ """Dry-run plan: gate + targets + output layout, nothing opened."""
+ check_rm610_gate(options.labels(), approval_token=options.approval_token)
+ return {
+ "format": PLAN_FORMAT,
+ "tool": "harness/version_diff.py",
+ "dry_run": True,
+ "status": "planned",
+ "rm610_gate": {"status": "passed", "labels": sorted(set(options.labels()))},
+ "old": {"label": options.label_for("old"), "path": options.old},
+ "new": {"label": options.label_for("new"), "path": options.new},
+ "out": os.path.abspath(options.out) if options.out else "<out>",
+ "sections": ["image", "symbols", "corpus", "probe", "behavior"],
+ "corpus_diff": list(options.corpus_diff) if options.corpus_diff else None,
+ "reports": {"json": "version-diff.json", "markdown": "version-diff.md"},
+ }
+
+
def main(argv: list[str] | None = None) -> int:
parser = build_parser()
args = parser.parse_args(argv)
+ if args.dry_run:
+ options = options_from_args(args)
+ try:
+ plan = build_plan(options)
+ except Rm610GateError as exc:
+ print(f"[version-diff] RM610 gate refused: {exc}", file=sys.stderr)
+ return 3
+ print(json.dumps(plan, indent=2, sort_keys=True))
+ print("[version-diff] dry-run: no target opened, nothing written")
+ return 0
+ if not args.out:
+ parser.error("--out is required unless --dry-run is used")
options = options_from_args(args)
try:
report = run_version_diff(options)
diff --git a/debug/risc-v-gsp-rm-vm/plugins/README.md b/debug/risc-v-gsp-rm-vm/plugins/README.md
index 7fe69da..6e3ac8a 100644
--- a/debug/risc-v-gsp-rm-vm/plugins/README.md
+++ b/debug/risc-v-gsp-rm-vm/plugins/README.md
@@ -1,4 +1,4 @@
-# green-eye plugins
+# risc-v-gsp-rm-debugger plugins
A plugin is a Python module exposing `register(ge)`:
@@ -20,7 +20,7 @@ Discovery: `--plugin PATH` (file or directory), then `GREENEYE_PLUGINS`
(colon-separated), then the bundled `plugins/` directory. A plugin that raises
is recorded as `plugin_error` and never breaks the session.
-Types of plugins that fit green-eye:
+Types of plugins that fit risc-v-gsp-rm-debugger:
1. **Runtime RE tools** — new watchpoint strategies, coverage collectors,
structure probes, heap/allocator graphs.
2. **Harnesses** — stimulus drivers that poke mailboxes/rings and assert on
diff --git a/debug/risc-v-gsp-rm-vm/plugins/example_plugin.py b/debug/risc-v-gsp-rm-vm/plugins/example_plugin.py
index 0bd382e..65d4292 100644
--- a/debug/risc-v-gsp-rm-vm/plugins/example_plugin.py
+++ b/debug/risc-v-gsp-rm-vm/plugins/example_plugin.py
@@ -1,4 +1,4 @@
-"""Example green-eye plugin.
+"""Example risc-v-gsp-rm-debugger plugin.
Load it explicitly with ``--plugin plugins/example_plugin.py`` (the bundled
``plugins/`` directory is discovered automatically), or set
diff --git a/debug/risc-v-gsp-rm-vm/plugins/mcp_server.py b/debug/risc-v-gsp-rm-vm/plugins/mcp_server.py
index b5e8f90..0059da2 100644
--- a/debug/risc-v-gsp-rm-vm/plugins/mcp_server.py
+++ b/debug/risc-v-gsp-rm-vm/plugins/mcp_server.py
@@ -1,12 +1,12 @@
-"""green-eye MCP server plugin (roadmap R3).
+"""risc-v-gsp-rm-debugger MCP server plugin (roadmap R3).
A stdlib-only Model Context Protocol server (JSON-RPC 2.0) that exposes the
-*active* green-eye session as MCP tools. Two ways to run it:
+*active* risc-v-gsp-rm-debugger session as MCP tools. Two ways to run it:
* **plugin mode** - load it into a live session and serve that session::
- ./greeneye.sh attach --plugin plugins/mcp_server.py
- greeneye> mcp-serve [--allow-write] [--allow-inject]
+ ./risc-v-gsp-rm-debugger.sh attach --plugin plugins/mcp_server.py
+ risc-v-gsp-rm-debugger> mcp-serve [--allow-write] [--allow-inject]
* **standalone mode** - launch its own session and serve it::
@@ -252,7 +252,7 @@ TOOLS: list[dict] = [
"instructions": _integer("step budget (0 = wall-clock duration)", 2000, 0),
"duration": _number("wall-clock seconds when instructions=0", 1.0),
"no_relocate": _boolean("do not relocate to 0x80000000", False),
- "symbols": _string("green-eye symbol DB JSON"),
+ "symbols": _string("risc-v-gsp-rm-debugger symbol DB JSON"),
"timeout": _number("subprocess timeout seconds", 300.0),
},
),
@@ -278,7 +278,7 @@ TOOLS: list[dict] = [
"out": _string("output directory (default: dumps/mcp-matrix)"),
"probe_instructions": _integer("probe step budget", 2000, 0),
"scenario_duration": _number("per-phase wall budget", 0.4),
- "symbols": _string("green-eye symbol DB JSON"),
+ "symbols": _string("risc-v-gsp-rm-debugger symbol DB JSON"),
"max_rows": _integer("report row cap", 40, 1, 1000),
},
("targets",),
@@ -438,7 +438,7 @@ class GreenEyeMCPServer:
"capabilities": {"tools": {"listChanged": False}},
"serverInfo": {"name": SERVER_NAME, "version": _version()},
"instructions": (
- "green-eye session server. Read/observe tools are always on; writes need "
+ "risc-v-gsp-rm-debugger session server. Read/observe tools are always on; writes need "
"--allow-write and injection needs --allow-inject. Never claim timing, cycles "
"or hardware behaviour; sessions are the evidence."
),
@@ -1021,7 +1021,7 @@ def _version() -> str:
def build_serve_parser(prog: str = "mcp-serve") -> argparse.ArgumentParser:
parser = argparse.ArgumentParser(
prog=prog,
- description="serve the active green-eye session over MCP (JSON-RPC over stdio or loopback TCP)",
+ description="serve the active risc-v-gsp-rm-debugger session over MCP (JSON-RPC over stdio or loopback TCP)",
)
parser.add_argument("--stdio", action="store_true", help="serve over stdin/stdout (default)")
parser.add_argument("--tcp", metavar="HOST:PORT", type=parse_tcp, help="serve over loopback TCP instead")
@@ -1031,7 +1031,7 @@ def build_serve_parser(prog: str = "mcp-serve") -> argparse.ArgumentParser:
def register(ge) -> None:
- """green-eye plugin hook: add the ``mcp-serve`` command."""
+ """risc-v-gsp-rm-debugger plugin hook: add the ``mcp-serve`` command."""
def mcp_serve(session, argv: list[str]) -> int:
parser = build_serve_parser()
@@ -1090,7 +1090,7 @@ def parse_tcp(text: str) -> tuple[str, int]:
def build_parser() -> argparse.ArgumentParser:
- parser = argparse.ArgumentParser(prog="mcp_server", description="green-eye MCP server (roadmap R3)")
+ parser = argparse.ArgumentParser(prog="mcp_server", description="risc-v-gsp-rm-debugger MCP server (roadmap R3)")
transport = parser.add_mutually_exclusive_group()
transport.add_argument("--stdio", action="store_true", help="serve over stdin/stdout (default)")
transport.add_argument("--tcp", metavar="HOST:PORT", type=parse_tcp, help="serve over loopback TCP instead")
diff --git a/debug/risc-v-gsp-rm-vm/plugins/rmharness_plugin.py b/debug/risc-v-gsp-rm-vm/plugins/rmharness_plugin.py
index 085751c..937c9fa 100644
--- a/debug/risc-v-gsp-rm-vm/plugins/rmharness_plugin.py
+++ b/debug/risc-v-gsp-rm-vm/plugins/rmharness_plugin.py
@@ -1,12 +1,12 @@
-"""green-eye plugin: RM host-oracle harness commands.
+"""risc-v-gsp-rm-debugger plugin: RM host-oracle harness commands.
Registers REPL commands that run the read-only Open-IOV RM tools through the
``rmharness`` wrapper scripts and record each run into the active session:
- greeneye> rmtool gpu list
- greeneye> rmtool mem stats --format=json
- greeneye> rmtop --once
- greeneye> rmq
+ risc-v-gsp-rm-debugger> rmtool gpu list
+ risc-v-gsp-rm-debugger> rmtool mem stats --format=json
+ risc-v-gsp-rm-debugger> rmtop --once
+ risc-v-gsp-rm-debugger> rmq
Every run is recorded as a ``rm_harness_run`` event with a captured
stdout+stderr blob (via ``ge.recorder.blob``); write/ownership operations are
diff --git a/debug/risc-v-gsp-rm-vm/qemu/README.md b/debug/risc-v-gsp-rm-vm/qemu/README.md
index a6be332..fede60e 100644
--- a/debug/risc-v-gsp-rm-vm/qemu/README.md
+++ b/debug/risc-v-gsp-rm-vm/qemu/README.md
@@ -1,4 +1,4 @@
-# green-eye QEMU helpers
+# risc-v-gsp-rm-debugger QEMU helpers
`greeneye_trace.c` is an optional QEMU TCG plugin that records **every**
instruction (opt-in) and every memory access as JSONL:
@@ -10,9 +10,9 @@ qemu-system-riscv64 -machine virt -m 256M -display none -serial file:/tmp/uart.l
-plugin qemu/greeneye-trace.so,path=/tmp/ge-trace.jsonl,start=0x80000000,end=0x80010000,exec=off
```
-This observes more than green-eye's gdbstub layer can: memory accesses
+This observes more than risc-v-gsp-rm-debugger's gdbstub layer can: memory accesses
between stops, instruction coverage, exact access sizes. Use it when you need
-a *complete* memory-activity map; use green-eye hooks/watchpoints when you
+a *complete* memory-activity map; use risc-v-gsp-rm-debugger hooks/watchpoints when you
need semantics (arguments, returns, structure decoding).
The plugin header `qemu-plugin.h` is vendored from QEMU v8.2.2
diff --git a/debug/risc-v-gsp-rm-vm/qemu/greeneye_trace.c b/debug/risc-v-gsp-rm-vm/qemu/greeneye_trace.c
index a20748a..f69ec07 100644
--- a/debug/risc-v-gsp-rm-vm/qemu/greeneye_trace.c
+++ b/debug/risc-v-gsp-rm-vm/qemu/greeneye_trace.c
@@ -1,9 +1,9 @@
/*
- * green-eye TCG trace plugin - full instruction/memory activity recording.
+ * risc-v-gsp-rm-debugger TCG trace plugin - full instruction/memory activity recording.
*
* This is the "complete map" upgrade from stop-based observation: QEMU calls
* the plugin for every translated instruction and every memory access. Output
- * is JSONL (one object per line), ready to be folded into a green-eye session:
+ * is JSONL (one object per line), ready to be folded into a risc-v-gsp-rm-debugger session:
*
* {"t":"exec","vcpu":0,"pc":"0x80000194"}
* {"t":"write","vcpu":0,"addr":"0x80000850","size":8}
@@ -93,7 +93,7 @@ static void plugin_exit(qemu_plugin_id_t id, void *userdata)
fclose(trace_fp);
trace_fp = NULL;
}
- qemu_plugin_outs("green-eye trace complete\n");
+ qemu_plugin_outs("risc-v-gsp-rm-debugger trace complete\n");
}
QEMU_PLUGIN_EXPORT int qemu_plugin_install(qemu_plugin_id_t id,
@@ -118,11 +118,11 @@ QEMU_PLUGIN_EXPORT int qemu_plugin_install(qemu_plugin_id_t id,
trace_fp = fopen(path, "w");
if (!trace_fp) {
- qemu_plugin_outs("green-eye: cannot open trace output\n");
+ qemu_plugin_outs("risc-v-gsp-rm-debugger: cannot open trace output\n");
return -1;
}
qemu_plugin_register_vcpu_tb_trans_cb(id, vcpu_tb_trans);
qemu_plugin_register_atexit_cb(id, plugin_exit, NULL);
- qemu_plugin_outs("green-eye trace plugin armed\n");
+ qemu_plugin_outs("risc-v-gsp-rm-debugger trace plugin armed\n");
return 0;
}
diff --git a/debug/risc-v-gsp-rm-vm/qemu/launch.sh b/debug/risc-v-gsp-rm-vm/qemu/launch.sh
index 54460db..bca0d17 100755
--- a/debug/risc-v-gsp-rm-vm/qemu/launch.sh
+++ b/debug/risc-v-gsp-rm-vm/qemu/launch.sh
@@ -1,5 +1,5 @@
#!/usr/bin/env bash
-# Start a green-eye target and keep it alive for `greeneye attach`.
+# Start a risc-v-gsp-rm-debugger target and keep it alive for `greeneye attach`.
set -euo pipefail
HERE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
-exec "$HERE/../greeneye.sh" launch "$@"
+exec "$HERE/../risc-v-gsp-rm-debugger.sh" launch "$@"
diff --git a/debug/risc-v-gsp-rm-vm/greeneye.sh b/debug/risc-v-gsp-rm-vm/risc-v-gsp-rm-debugger.sh
index f1c5a82..75c9052 100755
--- a/debug/risc-v-gsp-rm-vm/greeneye.sh
+++ b/debug/risc-v-gsp-rm-vm/risc-v-gsp-rm-debugger.sh
@@ -1,5 +1,5 @@
#!/usr/bin/env bash
-# green-eye launcher: run the package from this directory without installation.
+# risc-v-gsp-rm-debugger launcher: run the package from this directory without installation.
# TOOL IN DEVELOPMENT - NOT READY YET!
set -euo pipefail
HERE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
diff --git a/debug/risc-v-gsp-rm-vm/rmharness/README.md b/debug/risc-v-gsp-rm-vm/rmharness/README.md
index 6d33138..9481708 100644
--- a/debug/risc-v-gsp-rm-vm/rmharness/README.md
+++ b/debug/risc-v-gsp-rm-vm/rmharness/README.md
@@ -1,7 +1,7 @@
-# rmharness - host RM oracle integration for green-eye
+# rmharness - host RM oracle integration for risc-v-gsp-rm-debugger
`rmharness` wires the Open-IOV host RM userspace tools (`rmtool`, `rmtop`,
-`rmq`) into the green-eye workflow so host ground truth can be captured next
+`rmq`) into the risc-v-gsp-rm-debugger workflow so host ground truth can be captured next
to simulator sessions and compared later (docs/06-ACCURACY.md M1/M6).
All three tools are **read-only**: they query the host RM through
@@ -29,7 +29,7 @@ rmharness/
fake-`ge` plugin import/registration check
```
-The green-eye plugin lives next to the other bundled plugins:
+The risc-v-gsp-rm-debugger plugin lives next to the other bundled plugins:
`plugins/rmharness_plugin.py` (REPL commands `rmtool`, `rmtop`, `rmq`).
## Build and smoke
@@ -58,7 +58,7 @@ controls. They do not disturb a running CUDA job. If the driver is not bound
they fail cleanly. Commands that would allocate or mutate anything are refused
by the tools themselves.
-## Capturing into a green-eye session
+## Capturing into a risc-v-gsp-rm-debugger session
```bash
cd debug/risc-v-gsp-rm-vm
@@ -88,10 +88,10 @@ created. The event `t` field is `0.0` for externally recorded runs; use
and record the output through the live recorder:
```
-greeneye> rmtool gpu list
-greeneye> rmtool mem stats --format=json
-greeneye> rmtop --once
-greeneye> rmq
+risc-v-gsp-rm-debugger> rmtool gpu list
+risc-v-gsp-rm-debugger> rmtool mem stats --format=json
+risc-v-gsp-rm-debugger> rmtop --once
+risc-v-gsp-rm-debugger> rmq
```
Arguments naming write operations (`alloc`, `map`, `pin`, `start`, ...) are
diff --git a/debug/risc-v-gsp-rm-vm/rmharness/harness.sh b/debug/risc-v-gsp-rm-vm/rmharness/harness.sh
index 60fce8a..d4a193f 100755
--- a/debug/risc-v-gsp-rm-vm/rmharness/harness.sh
+++ b/debug/risc-v-gsp-rm-vm/rmharness/harness.sh
@@ -1,6 +1,6 @@
#!/usr/bin/env bash
# harness.sh - run a read-only RM tool, capture stdout/stderr, and record the
-# run into a green-eye session directory (blob + events.jsonl line).
+# run into a risc-v-gsp-rm-debugger session directory (blob + events.jsonl line).
#
# usage: harness.sh [--session DIR] [--name LABEL] -- TOOL [ARGS...]
# TOOL is one of: rmtool rmtop rmq
diff --git a/debug/risc-v-gsp-rm-vm/sdk/Makefile b/debug/risc-v-gsp-rm-vm/sdk/Makefile
index 8cccc66..c593551 100644
--- a/debug/risc-v-gsp-rm-vm/sdk/Makefile
+++ b/debug/risc-v-gsp-rm-vm/sdk/Makefile
@@ -1,4 +1,4 @@
-# green-eye injected-service SDK: builds a position-independent RV64 blob.
+# risc-v-gsp-rm-debugger injected-service SDK: builds a position-independent RV64 blob.
#
# The service ELF is linked at address 0 and loaded by the injector at a
# runtime address; all code is PC-relative (medany + PIC, no globals), so no
diff --git a/debug/risc-v-gsp-rm-vm/sdk/greeneye_service.h b/debug/risc-v-gsp-rm-vm/sdk/greeneye_service.h
index d5218cc..8be481e 100644
--- a/debug/risc-v-gsp-rm-vm/sdk/greeneye_service.h
+++ b/debug/risc-v-gsp-rm-vm/sdk/greeneye_service.h
@@ -1,6 +1,6 @@
-/* green-eye injected-service SDK header.
+/* risc-v-gsp-rm-debugger injected-service SDK header.
*
- * A green-eye service is position-independent RV64 code loaded into the
+ * A risc-v-gsp-rm-debugger service is position-independent RV64 code loaded into the
* target's RAM by the debugger. Nothing in the firmware links against it,
* so it must not reference globals, absolute addresses or libc: every
* function it calls must be one it brings with it (or a function whose
diff --git a/debug/risc-v-gsp-rm-vm/sdk/injected_demo.c b/debug/risc-v-gsp-rm-vm/sdk/injected_demo.c
index 8d836fe..47b95a5 100644
--- a/debug/risc-v-gsp-rm-vm/sdk/injected_demo.c
+++ b/debug/risc-v-gsp-rm-vm/sdk/injected_demo.c
@@ -1,4 +1,4 @@
-/* Example green-eye injected service.
+/* Example risc-v-gsp-rm-debugger injected service.
*
* Position-independent, no globals, no libc: safe to load at any address.
* Commands (matching the demo firmware's injected command range):
diff --git a/debug/risc-v-gsp-rm-vm/sim/__init__.py b/debug/risc-v-gsp-rm-vm/sim/__init__.py
index 5d7ab1f..ad20893 100644
--- a/debug/risc-v-gsp-rm-vm/sim/__init__.py
+++ b/debug/risc-v-gsp-rm-vm/sim/__init__.py
@@ -1,4 +1,4 @@
-"""green-eye native RV64IMAC simulator (M1).
+"""risc-v-gsp-rm-debugger native RV64IMAC simulator (M1).
Pure-Python, deterministic, stdlib-only. :class:`sim.machine.Machine` executes
RV64IMAC from a 256 MiB RAM region with an NS16550A UART; the debugger-facing
diff --git a/debug/risc-v-gsp-rm-vm/tests/test_bridge.py b/debug/risc-v-gsp-rm-vm/tests/test_bridge.py
index 7eeb46c..966399a 100644
--- a/debug/risc-v-gsp-rm-vm/tests/test_bridge.py
+++ b/debug/risc-v-gsp-rm-vm/tests/test_bridge.py
@@ -5,6 +5,7 @@ import json
import os
import shutil
import socket
+import time
import unittest
import greeneye as ge
@@ -23,6 +24,36 @@ class GhidraCommandTests(unittest.TestCase):
self.assertIn("MarkGreenEyeHits.java /tmp/hits.tsv", cmd)
+class BridgeLifecycleTests(unittest.TestCase):
+ """No target needed: start/stop/close are transport-level."""
+
+ def test_refuses_non_loopback_bind(self):
+ bridge = GhidraBridge(object(), host="0.0.0.0", port=0)
+ with self.assertRaises(ValueError):
+ bridge.start()
+
+ def test_close_command_takes_down_the_listener(self):
+ bridge = GhidraBridge(object(), port=0)
+ port = bridge.start()
+ with socket.create_connection(("127.0.0.1", port), timeout=10) as sock:
+ stream = sock.makefile("rwb")
+ stream.write((json.dumps({"id": 1, "cmd": "close", "args": {}}) + "\n").encode())
+ stream.flush()
+ response = json.loads(stream.readline())
+ self.assertTrue(response["ok"])
+ self.assertTrue(response["close"])
+ deadline = time.monotonic() + 5.0
+ while True:
+ try:
+ with socket.create_connection(("127.0.0.1", port), timeout=0.5):
+ pass
+ except OSError:
+ break
+ if time.monotonic() > deadline:
+ self.fail("listener still accepting connections after <close>")
+ time.sleep(0.05)
+
+
def qemu_available() -> bool:
return bool(os.environ.get("GREENEYE_QEMU") or shutil.which("qemu-system-riscv64"))
diff --git a/debug/risc-v-gsp-rm-vm/tests/test_harness.py b/debug/risc-v-gsp-rm-vm/tests/test_harness.py
index 55938ae..2e079cd 100644
--- a/debug/risc-v-gsp-rm-vm/tests/test_harness.py
+++ b/debug/risc-v-gsp-rm-vm/tests/test_harness.py
@@ -1,4 +1,4 @@
-"""Tests for the green-eye automation harness (roadmap R5/R6, H4.1/H4.3).
+"""Tests for the risc-v-gsp-rm-debugger automation harness (roadmap R5/R6, H4.1/H4.3).
The integration tests drive the two harness CLIs as subprocesses against the
bundled demo firmware and skip cleanly when qemu-system-riscv64 or the demo
diff --git a/debug/risc-v-gsp-rm-vm/tests/test_mcp.py b/debug/risc-v-gsp-rm-vm/tests/test_mcp.py
index 614d397..2df8a4a 100644
--- a/debug/risc-v-gsp-rm-vm/tests/test_mcp.py
+++ b/debug/risc-v-gsp-rm-vm/tests/test_mcp.py
@@ -1,4 +1,4 @@
-"""Tests for the green-eye MCP server plugin (roadmap R3).
+"""Tests for the risc-v-gsp-rm-debugger MCP server plugin (roadmap R3).
The protocol and tool tests drive an in-memory Session over a stub RSP-shaped
client, so they need no QEMU and no simulator. A standalone subprocess test
@@ -278,7 +278,7 @@ class ReadOnlyToolTests(McpTestCase):
)
payload, is_error = self.call_tool(server, "analyze_current")
self.assertFalse(is_error)
- self.assertIn("# green-eye session summary", payload["report"])
+ self.assertIn("# risc-v-gsp-rm-debugger session summary", payload["report"])
finally:
session.close()
diff --git a/debug/risc-v-gsp-rm-vm/tests/test_session_call.py b/debug/risc-v-gsp-rm-vm/tests/test_session_call.py
new file mode 100644
index 0000000..aab173c
--- /dev/null
+++ b/debug/risc-v-gsp-rm-vm/tests/test_session_call.py
@@ -0,0 +1,195 @@
+"""Session.call and Session.close invariant tests with a fake RSP client.
+
+These lock in two contracts that hardware behavior alone did not cover:
+
+* ``Session.call`` restores every ABI register plus ``pc`` after both a normal
+ return and a timeout. QEMU names x8 ``fp`` (not ``s0``), so both spellings
+ must be handled.
+* ``Session.close`` clears every breakpoint and watchpoint it registered and
+ closes the transport.
+"""
+from __future__ import annotations
+
+import os
+import shutil
+import unittest
+
+import greeneye as ge
+from greeneye.errors import RspTimeout
+from greeneye.rsp import StopReply
+from greeneye.session import RESTORE_REGS, Session
+
+HERE = os.path.dirname(os.path.abspath(__file__))
+TOOL_ROOT = os.path.abspath(os.path.join(HERE, ".."))
+DEMO_ELF = os.path.join(TOOL_ROOT, "firmware", "uproc_demo", "build", "uproc_demo.elf")
+
+#: QEMU's target.xml spelling: x8 is ``fp`` and ``s0`` is not present.
+QEMU_REG_NAMES = (
+ ["zero", "ra", "sp", "gp", "tp", "t0", "t1", "t2", "fp", "s1"]
+ + [f"s{i}" for i in range(2, 12)]
+ + [f"a{i}" for i in range(8)]
+ + [f"t{i}" for i in range(3, 7)]
+ + ["pc"]
+)
+
+
+class FakeClient:
+ """Minimal RSP client double with breakpoint/watchpoint accounting."""
+
+ def __init__(self, *, timeout_on_continue: bool = False, retval: int = 0x1234):
+ self.regs = {name: 0x100 + index for index, name in enumerate(QEMU_REG_NAMES)}
+ self.regs["pc"] = 0x80000000
+ self.writes: list[tuple[str, int]] = []
+ self.sw_breaks: set[int] = set()
+ self.hw_breaks: set[int] = set()
+ self.watches: set[tuple[int, int, str]] = set()
+ self.closed = False
+ self.timeout_on_continue = timeout_on_continue
+ self.retval = retval
+ self.continue_count = 0
+
+ def read_registers(self) -> dict[str, int]:
+ return dict(self.regs)
+
+ def read_reg(self, name: str) -> int:
+ return self.regs["fp" if name == "s0" and "s0" not in self.regs else name]
+
+ def write_reg(self, name: str, value: int) -> None:
+ key = "fp" if name == "s0" and "s0" not in self.regs else name
+ self.regs[key] = value
+ self.writes.append((name, value))
+
+ @property
+ def pc(self) -> int:
+ return self.regs["pc"]
+
+ def set_sw_break(self, addr: int, kind: int = 4) -> None:
+ self.sw_breaks.add(addr)
+
+ def clear_sw_break(self, addr: int, kind: int = 4) -> None:
+ self.sw_breaks.discard(addr)
+
+ def set_hw_break(self, addr: int, kind: int = 4) -> None:
+ self.hw_breaks.add(addr)
+
+ def clear_hw_break(self, addr: int, kind: int = 4) -> None:
+ self.hw_breaks.discard(addr)
+
+ def set_watch(self, addr: int, size: int = 8, kind: str = "w") -> None:
+ self.watches.add((addr, size, kind))
+
+ def clear_watch(self, addr: int, size: int = 8, kind: str = "w") -> None:
+ self.watches.discard((addr, size, kind))
+
+ def continue_(self, timeout: float | None = None) -> StopReply:
+ self.continue_count += 1
+ if self.timeout_on_continue:
+ raise RspTimeout("target never returned")
+ self.regs["pc"] = self.regs["ra"] # returns to the scratch trampoline
+ self.regs["a0"] = self.retval
+ return StopReply(raw="T05")
+
+ def interrupt(self, timeout: float | None = None) -> StopReply:
+ return StopReply(raw="T02")
+
+ def close(self) -> None:
+ self.closed = True
+
+
+class CallRestoreTests(unittest.TestCase):
+ def _restored(self, client: FakeClient, saved: dict[str, int]) -> list[str]:
+ missing = []
+ for name, value in saved.items():
+ if name not in RESTORE_REGS:
+ continue
+ if client.regs.get(name) != value:
+ missing.append(name)
+ if saved.get("fp") != client.regs.get("fp"):
+ missing.append("fp")
+ return missing
+
+ def test_call_success_restores_abi_regs_and_pc(self):
+ client = FakeClient(retval=0xCAFE)
+ session = Session(client=client, name="fake-success")
+ saved = session.read_regs()
+ result = session.call(0x80001000, (0x41, 0x42), timeout=1.0, scratch=0x801FF000)
+ self.assertEqual(result, 0xCAFE)
+ self.assertEqual(self._restored(client, saved), [])
+ self.assertEqual(client.sw_breaks, set(), "temporary call breakpoint must be gone")
+ session.close()
+
+ def test_call_timeout_restores_abi_regs_and_pc(self):
+ client = FakeClient(timeout_on_continue=True)
+ session = Session(client=client, name="fake-timeout")
+ saved = session.read_regs()
+ with self.assertRaises(RspTimeout):
+ session.call(0x80001000, (), timeout=0.05, scratch=0x801FF000)
+ self.assertEqual(self._restored(client, saved), [])
+ self.assertIn("fp", [name for name, _ in client.writes], "x8/fp must be restored under QEMU's name")
+ self.assertEqual(client.sw_breaks, set(), "temporary call breakpoint must be gone")
+ session.close()
+
+ @unittest.skipUnless(shutil.which("qemu-system-riscv64"), "qemu-system-riscv64 not installed")
+ @unittest.skipUnless(os.path.exists(DEMO_ELF), "demo firmware not built")
+ def test_real_qemu_register_names_include_fp_not_s0(self):
+ session = ge.launch(kernel=DEMO_ELF, name="unittest-call-names")
+ try:
+ regs = session.read_regs()
+ self.assertIn("fp", regs)
+ self.assertNotIn("s0", regs)
+ self.assertLessEqual(set(RESTORE_REGS) - {"s0"}, set(regs))
+ finally:
+ session.close()
+
+ @unittest.skipUnless(shutil.which("qemu-system-riscv64"), "qemu-system-riscv64 not installed")
+ @unittest.skipUnless(os.path.exists(DEMO_ELF), "demo firmware not built")
+ def test_real_qemu_loop_call_timeout_restores_registers(self):
+ session = ge.launch(kernel=DEMO_ELF, name="unittest-call-loop")
+ loop_addr = 0x80200000 # free RAM past the firmware segments
+ try:
+ session.client.write_mem(loop_addr, b"\x6f\x00\x00\x00") # jal x0, 0
+ saved = session.read_regs()
+ with self.assertRaises(RspTimeout):
+ session.call(loop_addr, (), timeout=0.3, scratch=0x801FF000)
+ after = session.read_regs()
+ for name in RESTORE_REGS:
+ if name in saved and name != "s0":
+ self.assertEqual(after.get(name), saved[name], f"{name} not restored after timeout")
+ self.assertEqual(after.get("fp"), saved.get("fp"), "fp (x8/s0) not restored after timeout")
+ finally:
+ session.close()
+
+
+class CloseCleanupTests(unittest.TestCase):
+ def test_close_clears_breakpoints_watchpoints_and_transport(self):
+ client = FakeClient()
+ session = Session(client=client, name="fake-close")
+ session.hook(0x80001000)
+ session.hook(0x80001000) # two on one address: only drop after the last
+ session.breakpoint(0x80002000, kind="hw")
+ session.watch(0x80003000, size=8, kind="w")
+ session.watch(0x80003040, size=4, kind="r")
+ self.assertTrue(client.sw_breaks)
+ self.assertTrue(client.hw_breaks)
+ self.assertEqual(len(client.watches), 2)
+
+ session.close()
+
+ self.assertEqual(client.sw_breaks, set())
+ self.assertEqual(client.hw_breaks, set())
+ self.assertEqual(client.watches, set())
+ self.assertTrue(client.closed)
+
+ def test_close_removes_only_last_breakpoint_at_address(self):
+ client = FakeClient()
+ session = Session(client=client, name="fake-last-bp")
+ first = session.hook(0x80001000)
+ session.hook(0x80001000)
+ first.detach()
+ self.assertEqual(client.sw_breaks, {0x80001000})
+ session.close()
+ self.assertEqual(client.sw_breaks, set())
+
+
+if __name__ == "__main__":
+ unittest.main()
diff --git a/debug/risc-v-gsp-rm-vm/tests/test_sim_backend.py b/debug/risc-v-gsp-rm-vm/tests/test_sim_backend.py
index a0635ab..1ccfb04 100644
--- a/debug/risc-v-gsp-rm-vm/tests/test_sim_backend.py
+++ b/debug/risc-v-gsp-rm-vm/tests/test_sim_backend.py
@@ -118,7 +118,7 @@ class NativeSmokeTests(unittest.TestCase):
watch_hits = []
session.watch(ctrl + 16, size=8, kind="w", callback=lambda hit: watch_hits.append(hit))
session.run(duration=0.6)
- self.assertTrue(session.target.wait_for_uart("GREEN-EYE UPROC DEMO", timeout=1.0))
+ self.assertTrue(session.target.wait_for_uart("RISC-V GSP-RM DEBUGGER UPROC DEMO", timeout=1.0))
self.assertGreaterEqual(len(hits), 1, "rpc_sum hook never fired")
self.assertGreaterEqual(len(watch_hits), 7, "rpc_count watchpoint never fired")
self.assertEqual(watch_hits[0].addr, ctrl + 16)
diff --git a/debug/risc-v-gsp-rm-vm/tests/test_smoke_qemu.py b/debug/risc-v-gsp-rm-vm/tests/test_smoke_qemu.py
index c0354d2..850942f 100644
--- a/debug/risc-v-gsp-rm-vm/tests/test_smoke_qemu.py
+++ b/debug/risc-v-gsp-rm-vm/tests/test_smoke_qemu.py
@@ -31,7 +31,7 @@ class QemuSmokeTests(unittest.TestCase):
session.hook("rpc_sum", on_enter=lambda hit: hits.append(hit))
session.watch(ctrl + 16, size=8, kind="w")
session.run(duration=0.6)
- self.assertTrue(session.target.wait_for_uart("GREEN-EYE UPROC DEMO", timeout=1.0))
+ self.assertTrue(session.target.wait_for_uart("RISC-V GSP-RM DEBUGGER UPROC DEMO", timeout=1.0))
self.assertGreaterEqual(len(hits), 1, "rpc_sum hook never fired")
after = session.snapshot(ctrl, 0x188, "ctrl")
self.assertEqual(int.from_bytes(after[0:4], "little"), 0x47535031)
diff --git a/debug/risc-v-gsp-rm-vm/tests/test_value_demos.py b/debug/risc-v-gsp-rm-vm/tests/test_value_demos.py
index 7640e13..2a8e957 100644
--- a/debug/risc-v-gsp-rm-vm/tests/test_value_demos.py
+++ b/debug/risc-v-gsp-rm-vm/tests/test_value_demos.py
@@ -73,7 +73,7 @@ class ValueDemoTests(unittest.TestCase):
result = _run_demo("s05_snapshot_diff.py", "native")
self.assertTrue(result["success"], result)
self.assertTrue({"result", "rpc_count", "last_rpc", "buf"}.issubset(set(result["changed_field_names"])))
- self.assertEqual(result["after"]["result"], 15)
+ self.assertEqual(result["after"]["result"], len(b"hello-risc-v-gsp-rm-debugger"))
def test_s09_ghidra_join(self):
result = _run_demo("s09_grabbing_a_ghidra_address.py", "qemu")
diff --git a/debug/risc-v-gsp-rm-vm/tests/test_version_diff.py b/debug/risc-v-gsp-rm-vm/tests/test_version_diff.py
index df704df..d20e780 100644
--- a/debug/risc-v-gsp-rm-vm/tests/test_version_diff.py
+++ b/debug/risc-v-gsp-rm-vm/tests/test_version_diff.py
@@ -262,6 +262,44 @@ class RunVersionDiffTests(unittest.TestCase):
self.assertTrue(os.path.exists(os.path.join(out, "version-diff.json")))
+class VersionDiffDryRunTests(unittest.TestCase):
+ def test_dry_run_exits_zero_and_touches_nothing(self):
+ with tempfile.TemporaryDirectory() as tmp:
+ old = os.path.join(tmp, "old.bin")
+ new = os.path.join(tmp, "new.bin")
+ for path in (old, new):
+ with open(path, "wb") as fh:
+ fh.write(NOP * 8)
+ before = {}
+ for name in ("old.bin", "new.bin"):
+ path = os.path.join(tmp, name)
+ with open(path, "rb") as fh:
+ before[name] = (os.path.getmtime(path), fh.read())
+ out = os.path.join(tmp, "out")
+ rc, stdout, _ = _run_main(
+ version_diff_main,
+ ["--old", old, "--new", new, "--out", out, "--dry-run", "--probe-instructions", "4"],
+ )
+ self.assertEqual(rc, 0)
+ plan = json.loads(stdout[: stdout.find("\n[version-diff]")])
+ self.assertEqual(plan["format"], "greeneye-version-diff-plan/1")
+ self.assertEqual(plan["status"], "planned")
+ self.assertFalse(os.path.exists(out), "dry-run must not create --out")
+ for name, (mtime, data) in before.items():
+ path = os.path.join(tmp, name)
+ self.assertEqual(os.path.getmtime(path), mtime)
+ with open(path, "rb") as fh:
+ self.assertEqual(fh.read(), data)
+
+ def test_dry_run_rm610_refused(self):
+ rc, _, err = _run_main(
+ version_diff_main,
+ ["--old", "rm610.elf", "--new", "new.elf", "--dry-run"],
+ )
+ self.assertEqual(rc, 3)
+ self.assertIn("docs/23", err)
+
+
class CiReleaseTests(unittest.TestCase):
def test_dry_run_exits_zero_and_touches_nothing(self):
with tempfile.TemporaryDirectory() as tmp: