[PR #7014] [MERGED] fix(ghidra): admit recordless MIPS-I legacy targets #7573

Closed
opened 2026-11-03 13:38:49 +00:00 by bsakaguchi · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/morluto/rea/pull/7014
Author: @dhruvac29
Created: 10/24/2026
Status: ✅ Merged
Merged: 10/24/2026
Merged by: @morluto

Base: main ← Head: fix/6933-mips1-legacy-lane


📝 Commits (3)

  • 0f64521 fix(ghidra): admit recordless MIPS-I legacy targets
  • f9de490 fix(ghidra): bind MIPS profiles to their target
  • a27c13c Merge remote-tracking branch 'origin/main' into fix/6933-mips1-legacy-lane

📊 Changes

4 files changed (+290 additions, -73 deletions)

View changed files

📝 docs/ghidra-mips.md (+13 -4)
📝 src/ghidra/GhidraMipsProfile.test.ts (+172 -61)
📝 src/ghidra/GhidraMipsProfile.ts (+85 -7)
📝 src/ghidra/GhidraProviderClient.ts (+20 -1)

📄 Description

Summary

MIPS-I ELF executables declare a zero-valued ISA field (EF_MIPS_ARCH_1) and predate the .MIPS.abiflags record. REA's Ghidra admission refused every one of them at the first ISA gate, even when the ELF32/ET_EXEC header had the recordless shape the existing inferred-o32 legacy lane already handles.

This change admits recordless MIPS-I through that legacy path, pins the endian-matched 32-bit MIPS language, and gives the new interpretation its own support-lane identity. Declared-ABI MIPS-I headers remain refused because the declared-ABI lane is verified for MIPS32r2 only.

Fixes #6933.

Problem and expected behavior

Smallest trigger: an ELF32 ET_EXEC MIPS target with e_flags arch bits 0 (MIPS-I), an unspecified ABI field, no EF_MIPS_ABI2, and an inspected absence of any ABI flags record. Before this change, provider selection returned architecture_unsupported:

This Ghidra MIPS lane requires EF_MIPS_ARCH_32R2 or a recordless legacy EF_MIPS_ARCH_32 header; other ISA revisions need separate verification.

The header is a legitimate recordless legacy shape, not an unverified ISA revision. Expected: admit it through the existing inferred-o32 legacy lane, pin MIPS:<LE|BE>:32:default, and state the analysis assumptions. After this change, that fixture is supported, resolves a profile with lane elf32-exec-mips1-legacy-pinned-v1, and reports both the inferred-o32 and MIPS-I decoder limitations. MIPS-II through MIPS-V and declared-ABI MIPS-I remain refused.

Change and scope

  • src/ghidra/GhidraMipsProfile.ts: name the MIPS arch constants; include EF_MIPS_ARCH_1 in the recordless legacy header shape; let the first ISA gate reach the recordless branch; add isMips1LegacyAdmission and a MIPS-I lane identity; add ghidraMips1Limitations.
  • src/ghidra/GhidraProviderClient.ts: attach the MIPS-I limitation to the session.
  • src/ghidra/GhidraMipsProfile.test.ts: admit little- and big-endian recordless MIPS-I; cover the profile lane, pinned language, relocatable refusal, FP64 refusal, declared-ABI refusal, MIPS-II refusal, and the session limitation.
  • docs/ghidra-mips.md: document the MIPS-I recordless boundary and its language-assumption limitation.

Intentionally not included: MIPS-II through MIPS-V, declared-ABI MIPS-I, MIPS32r6, or any pass-through of unverified ISA revisions. The issue's alternative suggestion (document the ISA matrix) is covered for this lane, but the lane is widened rather than only documented.

Contribution scope: ordinary fix within the existing Ghidra MIPS admission boundary; no new provider, execution authority, mutation, or protection recovery. No maintainer scope decision is required.

Contract and boundary impact

  • Semantic owner and earliest changed stage: Ghidra MIPS provider admission in GhidraMipsProfile, consumed by target support, profile resolution, and session limitations.
  • Contribution scope fit and linked maintainer decision: ordinary fix; not applicable.
  • CLI and MCP/tool-catalog contract: none changed. The same architecture_unsupported error shape is used for still-refused ISA revisions; a previously refused recordless MIPS-I target now reaches provider selection.
  • Provider, bridge, target-format, or platform compatibility: Ghidra bridge, language names, and e_flags parsing are unchanged. The new support lane is bound into profile identity, so profile-bound snapshots invalidate. Windows Ghidra P0 still does not admit MIPS.
  • Evidence, artifact, provenance, or reconstruction contract: the header remains the source of declared ISA facts; MIPS-I subset conformance and floating-point semantics remain explicit uncertainties rather than inferred facts.
  • Target selection, authority, upstream behavior, and cleanup details: read-only admission; no target execution, mutation, network access, or cleanup path changed.
  • Generated metadata, package, or installation impact: none.

Expected effects (check known effects; use documentation-only on its own).
Unchecked items do not establish absence; leave uncertainties visible.

  • Read existing files or captured data.
  • Launch or attach to a process.
  • Inject instrumentation or run scripts/code.
  • Change process memory, registers, files, or configuration.
  • Contact network services.
  • Recover protected code or work around protections.
  • Documentation or usability only; no target interaction.
  • Not sure yet; investigation or maintainer guidance needed.

Evidence and regression coverage

  • Tests added or updated: src/ghidra/GhidraMipsProfile.test.ts (MIPS-I admission for both byte orders, lane identity, pinned language, relocatable refusal, FP64 refusal, declared-ABI refusal, MIPS-II refusal, session limitation).
  • Base reproduction or other evidence: source-derived. On the base revision the new recordless MIPS-I fixture fails the first ISA gate with the message quoted above; the new test asserts supported, the elf32-exec-mips1-legacy-pinned-v1 lane, and the pinned 32-bit language. I did not rerun the new test against the base revision in this environment.
  • User-visible CLI/MCP output: no schema change. A recordless MIPS-I target now reaches provider selection instead of returning the quoted architecture_unsupported refusal; a session on that lane reports the MIPS-I decoder limitation.
  • Remaining proof gaps: no real Ghidra installation or cross-MIPS toolchain was available here, so the real-provider MIPS lane and a source-owned MIPS-I fixture were not run locally. The issue reporter's evidence covers Ghidra 12.1.4 importing the sample directly; that is not a run of REA's pinned profile. The reported sample's e_flags ABI field was not stated, so this change deliberately admits only the recordless MIPS-I shape. Declared-ABI MIPS-I and MIPS-II through MIPS-V remain refused.

For evidence-bearing changes:

  • Observed, derived, and inferred claims remain distinguishable.
  • Artifact identity, source provenance, and failed attempts remain preserved.
  • Unsupported, incomplete, unavailable, or uncertain outcomes remain visible.

Validation performed

  • After merging main at 422ca5a8f (including #7021, which aligns the browser manifest-path test with the artifact error contract): npm run test:focused -- tests/boundary/filesystem/webScriptManifestPaths.test.ts src/ghidra/GhidraMipsProfile.test.ts src/ghidra/GhidraProvider.behavior.test.ts tests/boundary/filesystem/mipsAbiFlags.test.ts — 4 files, 305 tests passed with Node 24.22.1.
  • npm run check:fast — typecheck and lint passed.
  • npm run docs:check — generated documentation checks and 9 README consistency tests passed.
  • npm run format:check — all matched files use the correct format.
  • git diff --check — no whitespace errors.

Compatibility, safety, and release

  • Breaking changes or migration steps: none. A previously refused recordless MIPS-I target is now admitted; other ISA revisions and ABI shapes keep their refusals. The new support-lane string invalidates profile-bound snapshots for this newly admitted interpretation, not existing MIPS32/MIPS32r2 snapshots.
  • Real Hopper/Ghidra, browser, or OS coverage: not run locally; no real Ghidra or cross-MIPS toolchain was available. See the proof gaps above.
  • Package or release metadata impact: none.
  • Security, privacy, process, or containment review: read-only header interpretation; no new execution, mutation, network, or sensitive-data handling.

Author readiness

Human owner: @dhruvac29

  • I reviewed the final diff and relevant existing code, understand the change and its edge cases, and take responsibility for the complete PR, including AI-assisted work.
  • I checked the evidence above, confirmed it supports the current change, and recorded meaningful validation gaps.
  • I declare this PR ready for initial maintainer review.

Before merge

  • This PR addresses a concrete problem or an agreed enhancement.
  • Material scope and authority questions are resolved, and any required maintainer scope decision covers the final diff.
  • The PR has one focused outcome and the title follows type(scope): outcome.
  • Related issue is linked, or the reason for not linking one is stated above.
  • Tests cover changed observable behavior and meaningful failure paths.
  • Owning docs, contracts, and generated metadata are updated where needed.
  • User-visible CLI/MCP changes include representative output.
  • I checked the final diff for secrets, unrelated cleanup, and unsupported claims.

🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/morluto/rea/pull/7014 **Author:** [@dhruvac29](https://github.com/dhruvac29) **Created:** 10/24/2026 **Status:** ✅ Merged **Merged:** 10/24/2026 **Merged by:** [@morluto](https://github.com/morluto) **Base:** `main` ← **Head:** `fix/6933-mips1-legacy-lane` --- ### 📝 Commits (3) - [`0f64521`](https://github.com/morluto/rea/commit/0f645213a7fa12c767599a8775840a1bd60e6ef1) fix(ghidra): admit recordless MIPS-I legacy targets - [`f9de490`](https://github.com/morluto/rea/commit/f9de490e9b84aa92f14e33bb9c4468207c21d87e) fix(ghidra): bind MIPS profiles to their target - [`a27c13c`](https://github.com/morluto/rea/commit/a27c13c898d05d26c8395f93e6965977cdfddc2d) Merge remote-tracking branch 'origin/main' into fix/6933-mips1-legacy-lane ### 📊 Changes **4 files changed** (+290 additions, -73 deletions) <details> <summary>View changed files</summary> 📝 `docs/ghidra-mips.md` (+13 -4) 📝 `src/ghidra/GhidraMipsProfile.test.ts` (+172 -61) 📝 `src/ghidra/GhidraMipsProfile.ts` (+85 -7) 📝 `src/ghidra/GhidraProviderClient.ts` (+20 -1) </details> ### 📄 Description ## Summary MIPS-I ELF executables declare a zero-valued ISA field (`EF_MIPS_ARCH_1`) and predate the `.MIPS.abiflags` record. REA's Ghidra admission refused every one of them at the first ISA gate, even when the ELF32/`ET_EXEC` header had the recordless shape the existing inferred-o32 legacy lane already handles. This change admits recordless MIPS-I through that legacy path, pins the endian-matched 32-bit MIPS language, and gives the new interpretation its own support-lane identity. Declared-ABI MIPS-I headers remain refused because the declared-ABI lane is verified for MIPS32r2 only. Fixes #6933. ## Problem and expected behavior Smallest trigger: an ELF32 `ET_EXEC` MIPS target with `e_flags` arch bits `0` (MIPS-I), an unspecified ABI field, no `EF_MIPS_ABI2`, and an inspected absence of any ABI flags record. Before this change, provider selection returned `architecture_unsupported`: > This Ghidra MIPS lane requires EF_MIPS_ARCH_32R2 or a recordless legacy EF_MIPS_ARCH_32 header; other ISA revisions need separate verification. The header is a legitimate recordless legacy shape, not an unverified ISA revision. Expected: admit it through the existing inferred-o32 legacy lane, pin `MIPS:<LE|BE>:32:default`, and state the analysis assumptions. After this change, that fixture is `supported`, resolves a profile with lane `elf32-exec-mips1-legacy-pinned-v1`, and reports both the inferred-o32 and MIPS-I decoder limitations. MIPS-II through MIPS-V and declared-ABI MIPS-I remain refused. ## Change and scope - `src/ghidra/GhidraMipsProfile.ts`: name the MIPS arch constants; include `EF_MIPS_ARCH_1` in the recordless legacy header shape; let the first ISA gate reach the recordless branch; add `isMips1LegacyAdmission` and a MIPS-I lane identity; add `ghidraMips1Limitations`. - `src/ghidra/GhidraProviderClient.ts`: attach the MIPS-I limitation to the session. - `src/ghidra/GhidraMipsProfile.test.ts`: admit little- and big-endian recordless MIPS-I; cover the profile lane, pinned language, relocatable refusal, FP64 refusal, declared-ABI refusal, MIPS-II refusal, and the session limitation. - `docs/ghidra-mips.md`: document the MIPS-I recordless boundary and its language-assumption limitation. Intentionally not included: MIPS-II through MIPS-V, declared-ABI MIPS-I, MIPS32r6, or any pass-through of unverified ISA revisions. The issue's alternative suggestion (document the ISA matrix) is covered for this lane, but the lane is widened rather than only documented. Contribution scope: ordinary fix within the existing Ghidra MIPS admission boundary; no new provider, execution authority, mutation, or protection recovery. No maintainer scope decision is required. ## Contract and boundary impact - Semantic owner and earliest changed stage: Ghidra MIPS provider admission in `GhidraMipsProfile`, consumed by target support, profile resolution, and session limitations. - Contribution scope fit and linked maintainer decision: ordinary fix; not applicable. - CLI and MCP/tool-catalog contract: none changed. The same `architecture_unsupported` error shape is used for still-refused ISA revisions; a previously refused recordless MIPS-I target now reaches provider selection. - Provider, bridge, target-format, or platform compatibility: Ghidra bridge, language names, and e_flags parsing are unchanged. The new support lane is bound into profile identity, so profile-bound snapshots invalidate. Windows Ghidra P0 still does not admit MIPS. - Evidence, artifact, provenance, or reconstruction contract: the header remains the source of declared ISA facts; MIPS-I subset conformance and floating-point semantics remain explicit uncertainties rather than inferred facts. - Target selection, authority, upstream behavior, and cleanup details: read-only admission; no target execution, mutation, network access, or cleanup path changed. - Generated metadata, package, or installation impact: none. Expected effects (check known effects; use documentation-only on its own). Unchecked items do not establish absence; leave uncertainties visible. - [x] Read existing files or captured data. - [ ] Launch or attach to a process. - [ ] Inject instrumentation or run scripts/code. - [ ] Change process memory, registers, files, or configuration. - [ ] Contact network services. - [ ] Recover protected code or work around protections. - [ ] Documentation or usability only; no target interaction. - [ ] Not sure yet; investigation or maintainer guidance needed. ## Evidence and regression coverage - Tests added or updated: `src/ghidra/GhidraMipsProfile.test.ts` (MIPS-I admission for both byte orders, lane identity, pinned language, relocatable refusal, FP64 refusal, declared-ABI refusal, MIPS-II refusal, session limitation). - Base reproduction or other evidence: source-derived. On the base revision the new recordless MIPS-I fixture fails the first ISA gate with the message quoted above; the new test asserts `supported`, the `elf32-exec-mips1-legacy-pinned-v1` lane, and the pinned 32-bit language. I did not rerun the new test against the base revision in this environment. - User-visible CLI/MCP output: no schema change. A recordless MIPS-I target now reaches provider selection instead of returning the quoted `architecture_unsupported` refusal; a session on that lane reports the MIPS-I decoder limitation. - Remaining proof gaps: no real Ghidra installation or cross-MIPS toolchain was available here, so the real-provider MIPS lane and a source-owned MIPS-I fixture were not run locally. The issue reporter's evidence covers Ghidra 12.1.4 importing the sample directly; that is not a run of REA's pinned profile. The reported sample's `e_flags` ABI field was not stated, so this change deliberately admits only the recordless MIPS-I shape. Declared-ABI MIPS-I and MIPS-II through MIPS-V remain refused. For evidence-bearing changes: - [x] Observed, derived, and inferred claims remain distinguishable. - [x] Artifact identity, source provenance, and failed attempts remain preserved. - [x] Unsupported, incomplete, unavailable, or uncertain outcomes remain visible. ## Validation performed - After merging `main` at `422ca5a8f` (including #7021, which aligns the browser manifest-path test with the artifact error contract): `npm run test:focused -- tests/boundary/filesystem/webScriptManifestPaths.test.ts src/ghidra/GhidraMipsProfile.test.ts src/ghidra/GhidraProvider.behavior.test.ts tests/boundary/filesystem/mipsAbiFlags.test.ts` — 4 files, 305 tests passed with Node 24.22.1. - `npm run check:fast` — typecheck and lint passed. - `npm run docs:check` — generated documentation checks and 9 README consistency tests passed. - `npm run format:check` — all matched files use the correct format. - `git diff --check` — no whitespace errors. ## Compatibility, safety, and release - Breaking changes or migration steps: none. A previously refused recordless MIPS-I target is now admitted; other ISA revisions and ABI shapes keep their refusals. The new support-lane string invalidates profile-bound snapshots for this newly admitted interpretation, not existing MIPS32/MIPS32r2 snapshots. - Real Hopper/Ghidra, browser, or OS coverage: not run locally; no real Ghidra or cross-MIPS toolchain was available. See the proof gaps above. - Package or release metadata impact: none. - Security, privacy, process, or containment review: read-only header interpretation; no new execution, mutation, network, or sensitive-data handling. ## Author readiness Human owner: @dhruvac29 - [x] I reviewed the final diff and relevant existing code, understand the change and its edge cases, and take responsibility for the complete PR, including AI-assisted work. - [x] I checked the evidence above, confirmed it supports the current change, and recorded meaningful validation gaps. - [x] I declare this PR ready for initial maintainer review. ## Before merge - [ ] This PR addresses a concrete problem or an agreed enhancement. - [ ] Material scope and authority questions are resolved, and any required maintainer scope decision covers the final diff. - [ ] The PR has one focused outcome and the title follows `type(scope): outcome`. - [ ] Related issue is linked, or the reason for not linking one is stated above. - [ ] Tests cover changed observable behavior and meaningful failure paths. - [ ] Owning docs, contracts, and generated metadata are updated where needed. - [ ] User-visible CLI/MCP changes include representative output. - [x] I checked the final diff for secrets, unrelated cleanup, and unsupported claims. --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
bsakaguchi 2026-11-03 13:38:49 +00:00
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#7573
No description provided.