[GH-ISSUE #8195] [Design] Evaluate a bounded RISC-V ELF investigation lane for Kuna #6478

Open
opened 2026-11-01 21:11:28 +00:00 by bsakaguchi · 4 comments
Owner

Originally created by @morluto on GitHub (Oct 30, 2026).
Original GitHub issue: https://github.com/morluto/rea/issues/8195

Before submitting

  • I searched open and closed issues and pull requests for a related discussion.
  • I understand the contribution scope must be reviewed before integration; open questions are welcome here.
  • This discussion does not include credentials, private samples, or sensitive target data.

Decision needed

Is a narrowly verified RISC-V ELF lane useful for REA/Kuna, and what target/ABI constraints and real-provider evidence would justify admitting it? The goal would be a reliable existing REA investigation workflow, not exposing upstream commands by default.

Context and evidence

REA currently documents Kuna support for x86-64, AArch64 and ARM, and correctly refuses RISC-V under that boundary. On macOS arm64, I compiled the repository's source-owned freestanding RISC-V fixture for RV32 and RV64 (little-endian executable ELF, RVC and double-float ABI; targets were not executed).

  • Direct Kuna 1.986 functions reported the four fixture procedures for each image. Individual decompile returned the source-consistent value * 3 + rea_riscv_global and double-addition expressions; xrefs --from rea_riscv_entry reported both expected call targets. decompile-project --jobs 1 reported four bodies and zero failures on each fixture.
  • Real REA/Ghidra 12.1.4 MCP opened both images, listed the four procedures, decompiled the leaf and floating-point functions, returned the two call references, and decoded a two-byte compressed instruction. REA CLI and MCP returned the same leaf pseudocode for each fixture.
  • REA/Kuna open_binary refused both targets as unsupported. This is consistent with the current documented boundary, not a provider bug or a claim of RISC-V support across platforms.

Fixture SHA-256 values: RV32 768de91765e7ea1ecf15971dd284af6e3d712190df695d328efa6c8b3b89373e; RV64 815e8f9df1d33824e786db776c782d98eb3e39284553425ee593b8e614ea5e4f.

Expected interaction with targets

Read existing local ELF files and launch the caller-supplied static provider. No target execution, binary mutation, or automatic provider installation is proposed.

Boundary details (optional)

Architecture, ELF class and byte order, ABI/flags, instruction extensions, loader assumptions, address coordinates, provider release identity and coverage should be explicit. Do not infer support for all RISC-V ELF variants from these two tiny examples. Preserve unknowns and unsupported-target diagnostics for variants outside any verified lane.

Options and tradeoffs

Compare the coverage and analyst value of the existing Ghidra lane with a constrained Kuna lane; reuse REA's existing provider-neutral operations and Evidence contracts. A format/architecture admission change alone does not establish correct decompilation, reference semantics, or cleanup.

Verification available so far

I have a prototype or observed results.

Success criteria and open questions

Before integration, exercise both CLI/MCP paths, cold and warm exports, instruction and call/reference behavior, ABI/extension cases, malformed and incompatible ELF admission, provider/target identity, and process cleanup on supported hosts. Establish the release and host matrix; state what remains unverified.

References

REA source d48e472fa plus the Kuna 1.986 baseline update in #8187. Related: #8190 (partial outgoing references) and #8175 (raw-image boundary).

Originally created by @morluto on GitHub (Oct 30, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/8195 ### Before submitting - [x] I searched open and closed issues and pull requests for a related discussion. - [x] I understand the contribution scope must be reviewed before integration; open questions are welcome here. - [x] This discussion does not include credentials, private samples, or sensitive target data. ### Decision needed Is a narrowly verified RISC-V ELF lane useful for REA/Kuna, and what target/ABI constraints and real-provider evidence would justify admitting it? The goal would be a reliable existing REA investigation workflow, not exposing upstream commands by default. ### Context and evidence REA currently documents Kuna support for x86-64, AArch64 and ARM, and correctly refuses RISC-V under that boundary. On macOS arm64, I compiled the repository's source-owned freestanding RISC-V fixture for RV32 and RV64 (little-endian executable ELF, RVC and double-float ABI; targets were not executed). - Direct Kuna 1.986 `functions` reported the four fixture procedures for each image. Individual `decompile` returned the source-consistent `value * 3 + rea_riscv_global` and double-addition expressions; `xrefs --from rea_riscv_entry` reported both expected call targets. `decompile-project --jobs 1` reported four bodies and zero failures on each fixture. - Real REA/Ghidra 12.1.4 MCP opened both images, listed the four procedures, decompiled the leaf and floating-point functions, returned the two call references, and decoded a two-byte compressed instruction. REA CLI and MCP returned the same leaf pseudocode for each fixture. - REA/Kuna `open_binary` refused both targets as unsupported. This is consistent with the current documented boundary, not a provider bug or a claim of RISC-V support across platforms. Fixture SHA-256 values: RV32 `768de91765e7ea1ecf15971dd284af6e3d712190df695d328efa6c8b3b89373e`; RV64 `815e8f9df1d33824e786db776c782d98eb3e39284553425ee593b8e614ea5e4f`. ### Expected interaction with targets Read existing local ELF files and launch the caller-supplied static provider. No target execution, binary mutation, or automatic provider installation is proposed. ### Boundary details (optional) Architecture, ELF class and byte order, ABI/flags, instruction extensions, loader assumptions, address coordinates, provider release identity and coverage should be explicit. Do not infer support for all RISC-V ELF variants from these two tiny examples. Preserve unknowns and unsupported-target diagnostics for variants outside any verified lane. ### Options and tradeoffs Compare the coverage and analyst value of the existing Ghidra lane with a constrained Kuna lane; reuse REA's existing provider-neutral operations and Evidence contracts. A format/architecture admission change alone does not establish correct decompilation, reference semantics, or cleanup. ### Verification available so far I have a prototype or observed results. ### Success criteria and open questions Before integration, exercise both CLI/MCP paths, cold and warm exports, instruction and call/reference behavior, ABI/extension cases, malformed and incompatible ELF admission, provider/target identity, and process cleanup on supported hosts. Establish the release and host matrix; state what remains unverified. ### References REA source `d48e472fa` plus the Kuna 1.986 baseline update in #8187. Related: #8190 (partial outgoing references) and #8175 (raw-image boundary).
Author
Owner

@morluto commented on GitHub (Oct 31, 2026):

Looping in @gensokyo-dev @kaoru0822-kitauji @N0zoM1z0 for visibility on the Ghidra, Kuna, and REA tool-design investigation.

<!-- gh-comment-id:6538793256 --> @morluto commented on GitHub (Oct 31, 2026): Looping in @gensokyo-dev @kaoru0822-kitauji @N0zoM1z0 for visibility on the Ghidra, Kuna, and REA tool-design investigation.
Author
Owner

@morluto commented on GitHub (Oct 31, 2026):

Further real-provider control narrows what the earlier successful decompilation establishes. On both original RV32/RV64 fixtures, direct Kuna 1.986 and source-built upstream main returned the expected global expression in rea_riscv_leaf pseudocode but returned zero xrefs both from that function and to the global. REA/Ghidra 12.1.4 on the same files identified the respective lw instructions as typed READ references to the globals; independent LLVM disassembly shows the lui + lw address calculation. Calls remained discoverable in the earlier controls.

I reduced this to a second pair of self-contained RV32/RV64 fixtures with a direct caller, reproduced the same xref discrepancy and filed Kuna #1345 with source, commands and build/version limits. Both original and reduced targets were analyzed statically, not executed or modified. REA/Kuna still correctly rejects RISC-V under its current boundary; no REA/Kuna RISC-V integration was exercised.

For any future admission decision, a useful task-level check should include a known global read with independent typed/reference evidence as well as call discovery and plausible pseudocode. Do not infer broad RISC-V xref behavior or invent a read edge from a decompiler's named expression; these are two small fixture families, not an ABI/architecture coverage estimate.

<!-- gh-comment-id:6544142780 --> @morluto commented on GitHub (Oct 31, 2026): Further real-provider control narrows what the earlier successful decompilation establishes. On both original RV32/RV64 fixtures, direct Kuna 1.986 and source-built upstream main returned the expected global expression in `rea_riscv_leaf` pseudocode but returned zero xrefs both from that function and to the global. REA/Ghidra 12.1.4 on the same files identified the respective `lw` instructions as typed READ references to the globals; independent LLVM disassembly shows the `lui` + `lw` address calculation. Calls remained discoverable in the earlier controls. I reduced this to a second pair of self-contained RV32/RV64 fixtures with a direct caller, reproduced the same xref discrepancy and filed [Kuna #1345](https://github.com/Noelo-Lab/kuna/issues/1345) with source, commands and build/version limits. Both original and reduced targets were analyzed statically, not executed or modified. REA/Kuna still correctly rejects RISC-V under its current boundary; no REA/Kuna RISC-V integration was exercised. For any future admission decision, a useful task-level check should include a known global read with independent typed/reference evidence as well as call discovery and plausible pseudocode. Do not infer broad RISC-V xref behavior or invent a read edge from a decompiler's named expression; these are two small fixture families, not an ABI/architecture coverage estimate.
Author
Owner

@morluto commented on GitHub (Oct 31, 2026):

Upstream follow-up: the reduced RV32 and RV64 controls also reproduced against a fresh debug build of current Kuna main facd4d4369b3b37ddb5f70b67591c219664b939b, using the 1.986 compiled SLEIGH tree. The named global remains in pseudocode, the corresponding xref queries are empty, and the direct call remains present. Build/specification conditions and limits are recorded in Kuna #1345. This still does not exercise or authorize REA/Kuna RISC-V admission.

<!-- gh-comment-id:6544167668 --> @morluto commented on GitHub (Oct 31, 2026): Upstream follow-up: the reduced RV32 and RV64 controls also reproduced against a fresh debug build of current Kuna main `facd4d4369b3b37ddb5f70b67591c219664b939b`, using the 1.986 compiled SLEIGH tree. The named global remains in pseudocode, the corresponding xref queries are empty, and the direct call remains present. Build/specification conditions and limits are recorded in [Kuna #1345](https://github.com/Noelo-Lab/kuna/issues/1345#issuecomment-6544166524). This still does not exercise or authorize REA/Kuna RISC-V admission.
Author
Owner

@morluto commented on GitHub (Oct 31, 2026):

REA recovery after explicit provider refusal

Real REA b43c329 stdio MCP on the reduced, unexecuted RV64 ELF:

  • Opening explicitly with Kuna 1.986 returned capability_unavailable, selection_reason: target_unsupported, and a Kuna architecture-unsupported reason. Immediately afterward binary_session was closed with no cleanup pending.
  • In that same connection, explicitly opening Ghidra 12.1.4 succeeded. procedure_pseudo_code returned the leaf expression; procedure_references returned the typed READ 0x111a6 -> 0x121d0; trace_call_path from audit_entry to audit_leaf returned reached. The xref list also included separate ELF metadata addresses, so a caller should not interpret every address-only row as an instruction.
  • In a separate fresh session, after the same explicit Kuna refusal I opened the target without specifying a provider. Automatic selection chose Ghidra on this host, and the typed READ and call-path controls succeeded. This is an explicit second open, not an automatic silent change to the original caller's provider choice.

A separate active-session control opened Ghidra first, renamed audit_leaf in its ephemeral database, then requested the same target with Kuna. The unsupported switch was rejected; binary_session remained open/no cleanup pending, the renamed selector still resolved, and the typed READ remained available. This is an early target-admission refusal; it does not contradict the different successful-switch state loss documented in #8289.

All target hashes remained unchanged and sessions closed. These are one host, one target and specific call paths; static reachability is not runtime execution, and no general provider-availability guarantee follows.

<!-- gh-comment-id:6544183873 --> @morluto commented on GitHub (Oct 31, 2026): ### REA recovery after explicit provider refusal Real REA `b43c329` stdio MCP on the reduced, unexecuted RV64 ELF: - Opening explicitly with Kuna 1.986 returned `capability_unavailable`, `selection_reason: target_unsupported`, and a Kuna architecture-unsupported reason. Immediately afterward `binary_session` was closed with no cleanup pending. - In that same connection, explicitly opening Ghidra 12.1.4 succeeded. `procedure_pseudo_code` returned the leaf expression; `procedure_references` returned the typed READ `0x111a6 -> 0x121d0`; `trace_call_path` from `audit_entry` to `audit_leaf` returned `reached`. The xref list also included separate ELF metadata addresses, so a caller should not interpret every address-only row as an instruction. - In a separate fresh session, after the same explicit Kuna refusal I opened the target without specifying a provider. Automatic selection chose Ghidra on this host, and the typed READ and call-path controls succeeded. This is an explicit second open, not an automatic silent change to the original caller's provider choice. A separate active-session control opened Ghidra first, renamed `audit_leaf` in its ephemeral database, then requested the same target with Kuna. The unsupported switch was rejected; `binary_session` remained open/no cleanup pending, the renamed selector still resolved, and the typed READ remained available. This is an early target-admission refusal; it does not contradict the different successful-switch state loss documented in #8289. All target hashes remained unchanged and sessions closed. These are one host, one target and specific call paths; static reachability is not runtime execution, and no general provider-availability guarantee follows.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
morluto/rea#6478
No description provided.