* feat(ghidra): admit RISC-V ELF analysis through a pinned generic lane Refs #2063. Recognize `EM_RISCV` (243) as a provider-neutral family that carries its own ELF facts, and bound the first Ghidra lane to little-endian `ET_EXEC` images that declare the double-float ABI, pinned to `RISCV:LE:32:default` or `RISCV:LE:64:default` with the `gcc` compiler specification. Ghidra 12.1.4 is not reliable without the pin: its `riscv.opinion` pins `variant="default"` for the 64-bit constraint and leaves the 32-bit constraint with the comment that the loader "must choose between 'default' and 'AndeStar' variants". Measured on the installed release tree, a source-owned generic RV32 ELF with no Andes declaration imports as `RISCV:LE:32:AndeStar_v5:gcc`, while RV64 resolves to `RISCV:LE:64:default:gcc`. The lane therefore states the language per width and refuses any caller-selected processor outside it instead of inheriting the header guess. Refusals name the declaration rather than falling back to a guessed profile: big-endian images (Ghidra 12.1.4 ships no big-endian RISC-V language), non-`ET_EXEC` images, `EF_RISCV_RVE`, `EF_RISCV_TSO`, and every float ABI other than double, which the pinned generic compiler specifications model. The raw e_flags bits stay in Evidence as declarations, not as instruction semantics. Family recognition now has one owner for the ELF-metadata families: `ELF_METADATA_ARCHITECTURES`, `isElfMetadataArchitecture`, and `HeaderArchitecture` replace ten `Exclude<BinaryArchitecture, "mips">` sites that would each have needed a second hand-edited member. `ghidraPinnedLanguage` is that owner for the import commitment: the session readback previously re-derived only the MIPS pin, so a profile committing any second pinned language failed with a language-mismatch error before the bridge started. Hopper and IDA refuse RISC-V by name, matching the MIPS wording. Caller-supplied raw-binary entry keeps its existing four-family list; this lane is ELF-header admission only. Verification on macOS 15.7.7 arm64, Node 24.18.0, Ghidra 12.1.4 PUBLIC and JDK 21.0.12.1, with the host decompiler built from the release sources for `os/mac_arm_64`: `npm run check` passes; `npm run test:fast` passes 396 test files; `npm run verify:test-discovery` discovers all 917 test files exactly once. Source-owned RV32 and RV64 double-float `ET_EXEC` fixtures complete `rea analyze --provider ghidra` and `rea decompile rea_riscv_entry`, committing `RISCV:LE:32:default` and `RISCV:LE:64:default` with `language_selection: provider-pinned-v1`; the soft-float RV64 shape is refused with the named float-ABI reason, and the full refusal matrix including the RV32 and width-mismatch shapes is covered by unit tests. No `verify:ghidra:riscv` lane script is included in this change; the runs above were performed manually against the installed engine. Fork pull requests receive no CI check runs, so the real-provider scope above is the evidence available for review. * fix(ghidra): bound the RISC-V lane by declared flags and document it Address review feedback on #2151. `e_flags` bits outside `EF_RISCV_RVC | EF_RISCV_FLOAT_ABI` are now refused with the offending value named, so a reserved or newer producer declaration cannot enter the verified generic lane by falling through the RVE, TSO and float-ABI checks. Admission reads `e_type` only, so the refusal text no longer calls `ET_EXEC` static: a fixed-address declaration does not establish static linkage, and `PT_INTERP` and dynamic dependencies are not inspected. The session records that boundary as a limitation rather than inferring a load model. Add `docs/ghidra-riscv.md` in the shape of the MIPS lane guide (admission boundary, refusal table, why the language is pinned per class, Evidence fields, and what the fixtures do not establish), and correct `docs/firmware-analysis.md`, which still told users that MIPS and RISC-V decompilation had not been added. Verification after the change: `npm run check` and `npm run docs:check` pass; the RISC-V module tests pass (17 lane cases plus 9 parser cases); on Ghidra 12.1.4 with JDK 21.0.12.1 the RV32 and RV64 double-float fixtures still analyze and decompile with `RISCV:LE:32:default` / `RISCV:LE:64:default` and `language_selection: provider-pinned-v1`, the soft-float fixture is still refused by name, and the new linkage limitation appears in the emitted Evidence. * fix(ghidra): align RISC-V pinning with admission Reuse the complete lane admission boundary when selecting a language, retain unsigned unsupported flag bits in diagnostics, and derive float ABI metadata from the source declaration. * test(ghidra): verify RISC-V CLI and MCP workflows Build source-owned RV32/RV64 fixtures with Clang and LLD, establish independent ELF and symbol facts with LLVM readelf, and verify real provider evidence, instruction bytes, calls, decompilation, schema projections, snapshot replay, refusal diagnostics, source immutability and cleanup. Verified on macOS ARM64 with Ghidra 12.1.4, JDK 21 and LLVM/LLD 23.1.2. Dynamic linkage, big-endian, Andes and RVE/TSO workflows remain unverified; ISA attributes are not inspected. --------- Co-authored-by: morluto <76467478+morluto@users.noreply.github.com> |
||
|---|---|---|
| .. | ||
| android | ||
| c | ||
| contracts | ||
| ghidra | ||
| ida | ||
| inspector | ||
| interface-builder | ||
| napi | ||
| native | ||
| objc | ||
| providers | ||
| psp | ||
| readiness | ||
| swift | ||
| versions | ||
| README.md | ||
| readmeConsistency.test.ts | ||
| releaseConfiguration.test.ts | ||
README.md
Source-built conformance fixtures
These sources are deliberately small semantic oracles for REA providers. Run
npm run verify:fixtures on macOS or Linux to compile them into the ignored
build/conformance/ directory, emit a hash-and-toolchain manifest, and verify
their platform-native symbols and strings with local command-line tools. The
portable C, version, and large-inventory fixtures build as Mach-O on macOS and
ELF on Linux; Objective-C, Swift, and N-API-like fixtures remain macOS-only.
Only source files are versioned. Generated binaries, generated large-fixture
source, debug information, and manifests must remain under build/.
ghidra/inventory.c is also compiled into temporary Linux ELF debug and
stripped variants by npm run verify:ghidra. It fixes local functions, external
puts linkage, defined strings, and writable/executable memory needed to prove
the read-only Ghidra inventory contracts without committing a binary.
scripts/create-ghidra-windows-fixture.mjs separately emits a deterministic,
ignored native x86-64 PE application for the controlled Windows Ghidra P0 lane.
The generator and fixed SHA-256 are versioned; the .exe is never committed or
executed. npm run verify:ghidra:windows uses it to verify the admitted read-only operation inventory,
digest linkage, transport, and cleanup on the self-hosted real-Ghidra runner.
The C fixture fixes a known call chain and strings. The version pair fixes an added symbol, changed string, and changed call relationship. The generated large fixture contains 1,205 uniquely named functions and strings to verify that providers return complete inventories. Objective-C, Swift, and N-API-like fixtures provide metadata-oriented inputs without package or network dependencies.
readiness/ adds source-only generated JavaScript CLI and Electron fixtures for
the repository's reconstruction-readiness verifier. npm run verify:readiness
combines them with the compiled native fixtures, exercises CLI and MCP parity
for real analysis operations, and checks the internal machine-readable report
documented in docs/reconstruction-readiness.md.