# 46 — Surgical rehost of firmware functions (in development) > **Status: in development (2026-10-06, rehost wave).** Documents > `harness/rehost.py`: run one bounded function of a real/modelled firmware > image on the native emulator, starting at a chosen entry with a crafted > register/memory state, and record a session + report. This is the workflow > the RE review ranks first for the live GR wall (docs/39 U2): answer > server-side hypotheses from rehosted execution with hooks/watchpoints/ > memory tools instead of another static read or another hardware cycle. > > Development-only: executes firmware on the simulator. Never touches a GPU, > kernel module, mdev, guest or network. No timing/cycle claim (L0/L1). > > **See also:** `39-RE-WORKFLOW-REVIEW.md` (U2), `44-GMMU-ORACLE-AND-WORKFLOW.md` > (the same evidence discipline), `03-SCRIPTING.md` (hooks/watch/memory), > `16-CUSTOM-SIMULATOR.md` (backend design), `45-RM-RPC-CAPTURE-AND-REPLAY.md` > (the capture whose sequence a rehost can seed). ## 1. What it does * Loads an ELF image into the native machine exactly like `sim.gsp_boot` (device registry from the profile, optional boot shim, libos syscall model, lenient MMIO). * Writes caller-supplied memory (`--mem addr=hex`), sets `a0..a7` (`--arg`), installs a return trampoline (`ra` + `ebreak` sentinel) and a private stack, and starts at `--entry` (hex address or ELF symbol). * Runs under `--budget` instructions and a wall-clock `--timeout`, stopping on return (`R_BP` at the sentinel), fault, unhandled ecall, timeout or budget. * Snapshots regions before/after (`--snap addr:size`) with per-region changed bytes, first-difference offset and sha256s; dumps nonzero registers on entry and exit; records a `greeneye-session/1` directory and a `greeneye-rehost/1` report. ``` python3 harness/rehost.py run --entry 0x5b01210 --arg 0 --budget 50000 \ --snap 0x1000000:64 --out dumps/rehost-gate python3 harness/rehost.py demo # synthetic self-test (demo firmware) ``` ## 2. Report schema (`greeneye-rehost/1`) `status` is one of `return | fault | ecall | timeout | budget`; `fault` carries the trap cause and `tval`; `retval` is `a0` at the stop; snapshots carry the before/after diff. The report states its limits explicitly: it is **not a boot** (the function ran with only the supplied state), a fault is the **first missing state observed**, not a product defect, and there is no timing claim. ## 3. First probes on the 570.144 image (2026-10-06) All offline, one bounded call each, `a0=0`, budget 300k (numeric vaddrs from the campaign analysis): | entry | status | stop pc | `a0` at stop | insns | fault | |---|---|---|---|---|---| | GR per-buffer commit gate `0x5b01210` | fault | `0x0` | `0x40` | 24 | illegal @ `0x0` | | per-buffer commit `0x5b00d2c` | budget | `0x5b0110c` | `0x40` | 189 | — | | commit caller `0x5b00dd8` | budget | `0x5b0120c` | `0x40` | 110 | — | | engine-ctx memdesc install `0x514cab8` | fault | `0x0` | `0x429b450` | 97 | illegal @ `0x0` | | promote handler `0x526a530` | budget | `0x5244134` | `0x40` | 167 | — | | per-entry commit `0x5290a48` | budget | `0x5897fdc` | `0x40` | 258 | — | | engine-class commit `0x5350078` | budget | `0x5350484` | `0x40` | 197 | — | Reading: with no engine-context state, the whole gate family bottoms out in `NV_ERR_INVALID_STATE (0x40)` — the same family the live campaign observes — and the memdesc-install path faults on a NULL callback early. That is a reproduction of known behaviour, not an answer: the next step is to **seed the context objects** (from the B4 message-loop state or from crafted structures) and A/B the promote entry shapes against these entries. ## 4. Admission record (draft — pending maintainer filing) Per the project admission rule (docs/eng-ops.md §2), all five fields: | Field | Value | |---|---| | Scenario | dynamic-RE loop: run the GR promote/commit functions of the real 570.144 image off-hardware at a chosen entry with crafted state, to answer server-side hypotheses (gate/entry/context requirements) without hardware cycles. | | Measurable outcome | sessions per hypothesis; wall time per probe; zero hardware cycles; rehost status/fault map. | | Baseline | the live campaign's modes 4–22 day (docs/39: 730+ lines of static RE, three wedge-reboot cycles for one accepted root cause). | | Evaluation threshold | ≥1 wall hypothesis answered with a session pair and **zero** hardware cycles; probe loop ≤ 2 minutes per entry (measured: ≈0.1 s per probe); deterministic status/`a0` across runs. | | Failure signal | a probe cannot be driven because required device semantics are absent, and crafted-state seeding cannot reach the failing branch after two bounded attempts → record the gap and fall back to static + physical. | ## 5. Limits * Not a boot: entry-state dependence is the whole difficulty; a `budget` stop usually means the entry is mid-function or the path loops without returning. * The first probes use caller-supplied `a0`; the real argument conventions and context layouts are to be supplied by seeding (or by B4/B5 state). * Single hart, flat memory, no interrupts/scheduling; unknown MMIO is lenient and counted, and can mask environment dependence. * No cycle/timing/security claim; L0/L1 fidelity only.