[PR #1898] [MERGED] feat(ghidra): admit recordless legacy MIPS32 ELFs with a pinned 32-bit language #4890

Closed
opened 2026-10-31 00:56:28 +00:00 by bsakaguchi · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/morluto/rea/pull/1898
Author: @BaaRai
Created: 10/11/2026
Status: ✅ Merged
Merged: 10/13/2026
Merged by: @morluto

Base: main ← Head: feat/mips-legacy-admission


📝 Commits (10+)

  • 1ecb8ea feat(ghidra): admit recordless legacy MIPS32 ELFs with a pinned 32-bit language
  • b4cefe2 fix(ghidra): require an inspected absence for the recordless MIPS lane
  • 6ae210e fix(ghidra): tighten the recordless MIPS admission boundaries
  • 6f98144 fix(ghidra): reject EF_MIPS_ABI_ON32 from the recordless MIPS lane
  • e03ae33 Merge origin/main into feat/mips-legacy-admission
  • 29e8d1e fix(ghidra): keep recordless relocatable MIPS objects off the legacy lane
  • 5061817 fix(ghidra): name the ET_EXEC scope for recordless objects and probe the legacy lane
  • 17d34f8 Merge remote-tracking branch 'origin/main' into feat/mips-legacy-admission
  • 0a71e51 fix(ghidra): bind legacy MIPS language to the current target
  • 4dcc6cb fix(ghidra): retain the concrete ELF32 legacy compiler pin

📊 Changes

8 files changed (+707 additions, -39 deletions)

View changed files

📝 docs/ghidra-mips.md (+30 -6)
📝 scripts/verify-real-ghidra-mips.mjs (+152 -0)
📝 src/ghidra/GhidraAnalysisProfile.ts (+4 -5)
📝 src/ghidra/GhidraMipsProfile.test.ts (+178 -1)
📝 src/ghidra/GhidraMipsProfile.ts (+115 -12)
📝 src/ghidra/GhidraProviderClient.ts (+48 -8)
📝 tests/conformance/ghidra/mips-checks.mjs (+83 -1)
📝 tests/conformance/ghidra/mips-fixture.mjs (+97 -6)

📄 Description

Summary

Fixes #1620.

Admits recordless legacy MIPS32 ELF executables (EF_MIPS_ARCH_32 or EF_MIPS_ARCH_32R2, unspecified ABI field, EF_MIPS_ABI2 clear, no ABI flags record) with the 32-bit Ghidra language pinned, so 2000s pre-ABI-flags firmware stops being refused and stops being analyzed as a 64-bit R6 image by header auto-selection.

Problem and expected behavior

The lane refused these files before provider selection, while Ghidra's own auto-selection picks MIPS:LE:64:64-32R6addr for exactly this shape, so simple relaxation would mislabel MIPS32 firmware. The issue asks for admission with o32 as a recorded assumption, a pinned -processor MIPS:<LE|BE>:32:default checked against the bridge-reported language after import, evidence that records the ABI as inferred, and unchanged refusals elsewhere.

Change and scope

  • Admission: ELF32 ET_EXEC with EF_MIPS_ARCH_32/_32R2, ABI field 0, EF_MIPS_ABI2 clear and no observed ABI flags record is admitted. FP64/NAN2008/ASE/machine-variant/ELF64/n32 refusals are unchanged; a declared o32 field without a record is still refused.
  • Profile: the lane identity is versioned elf32-exec-arch32-legacy-pinned-v1 with mips_abi_basis: inferred-o32-assumption-v1. The import language is pinned through a provider-pinned-v1 selection that drives -processor MIPS:<LE|BE>:32:default -cspec default and is checked against the bridge-reported language_id after import (the same expectedLanguageId mechanism DOS uses). A caller-selected REA_GHIDRA_LANGUAGE_ID still wins; combining the pin with an env override is a typed refusal.
  • Evidence: sessions on this admission carry the limitations that the header declares no ABI, that o32 conventions are an analysis assumption, not a declared fact, and that floating-point ABI semantics are unverified.

Verification

Locally verified on Linux with Ghidra 12.1.4 PUBLIC, clang 21.1.8 (Debian), lld 21.1.8 and GNU readelf 2.47; fork PRs currently receive no CI check runs in this repository, so results below are from this machine:

  • verify:ghidra:mips passes with a new recordless legacy round for both byte orders: the fixture is built with -march=mips32, then the ABI record declarations are stripped (PT_MIPS_ABIFLAGS to PT_NULL, SHT_MIPS_ABIFLAGS to SHT_PROGBITS, section renamed in the string table) and the header ABI field zeroed; GNU readelf independently confirms the recordless header; REA's interpretation is checked against it; the pinned language is asserted after import; decoded probe instructions, entry symbols, pseudocode and the retained assumption limitations are asserted through a snapshot round-trip.
  • The pre-existing standard lane round still passes unchanged (o32/32R2 with record).
  • vitest src/ghidra/GhidraMipsProfile.test.ts (new admission/pinning/refusal cases), tsc --noEmit clean, oxlint 0 errors on touched files.
  • The pre-change tree refuses the same fixture with "requires an inspected ABI flags record".

🔄 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/1898 **Author:** [@BaaRai](https://github.com/BaaRai) **Created:** 10/11/2026 **Status:** ✅ Merged **Merged:** 10/13/2026 **Merged by:** [@morluto](https://github.com/morluto) **Base:** `main` ← **Head:** `feat/mips-legacy-admission` --- ### 📝 Commits (10+) - [`1ecb8ea`](https://github.com/morluto/rea/commit/1ecb8eabb1b4faa4adecf708c6538bce1f4321d1) feat(ghidra): admit recordless legacy MIPS32 ELFs with a pinned 32-bit language - [`b4cefe2`](https://github.com/morluto/rea/commit/b4cefe275c6c1696180d95617aa9574f31568604) fix(ghidra): require an inspected absence for the recordless MIPS lane - [`6ae210e`](https://github.com/morluto/rea/commit/6ae210e0d639d023fcbf69e7e317068382cbdd69) fix(ghidra): tighten the recordless MIPS admission boundaries - [`6f98144`](https://github.com/morluto/rea/commit/6f98144d86b111432d1095f60871da1828244066) fix(ghidra): reject EF_MIPS_ABI_ON32 from the recordless MIPS lane - [`e03ae33`](https://github.com/morluto/rea/commit/e03ae337456da002efd972ea6f324392f8ff18e2) Merge origin/main into feat/mips-legacy-admission - [`29e8d1e`](https://github.com/morluto/rea/commit/29e8d1e4d4fd10dbeb8415c37735589f2e75c314) fix(ghidra): keep recordless relocatable MIPS objects off the legacy lane - [`5061817`](https://github.com/morluto/rea/commit/5061817f7ce4a970a7580893e121b41b8ef1a807) fix(ghidra): name the ET_EXEC scope for recordless objects and probe the legacy lane - [`17d34f8`](https://github.com/morluto/rea/commit/17d34f89b13fd8e4357e0b5b2b30c4f29ed8af01) Merge remote-tracking branch 'origin/main' into feat/mips-legacy-admission - [`0a71e51`](https://github.com/morluto/rea/commit/0a71e51fc11dd313fd04cb7da58fc12a398317d5) fix(ghidra): bind legacy MIPS language to the current target - [`4dcc6cb`](https://github.com/morluto/rea/commit/4dcc6cbb482ee867a0201a556ee09dc1479847e5) fix(ghidra): retain the concrete ELF32 legacy compiler pin ### 📊 Changes **8 files changed** (+707 additions, -39 deletions) <details> <summary>View changed files</summary> 📝 `docs/ghidra-mips.md` (+30 -6) 📝 `scripts/verify-real-ghidra-mips.mjs` (+152 -0) 📝 `src/ghidra/GhidraAnalysisProfile.ts` (+4 -5) 📝 `src/ghidra/GhidraMipsProfile.test.ts` (+178 -1) 📝 `src/ghidra/GhidraMipsProfile.ts` (+115 -12) 📝 `src/ghidra/GhidraProviderClient.ts` (+48 -8) 📝 `tests/conformance/ghidra/mips-checks.mjs` (+83 -1) 📝 `tests/conformance/ghidra/mips-fixture.mjs` (+97 -6) </details> ### 📄 Description ## Summary Fixes #1620. Admits recordless legacy MIPS32 ELF executables (EF_MIPS_ARCH_32 or EF_MIPS_ARCH_32R2, unspecified ABI field, EF_MIPS_ABI2 clear, no ABI flags record) with the 32-bit Ghidra language pinned, so 2000s pre-ABI-flags firmware stops being refused and stops being analyzed as a 64-bit R6 image by header auto-selection. ## Problem and expected behavior The lane refused these files before provider selection, while Ghidra's own auto-selection picks `MIPS:LE:64:64-32R6addr` for exactly this shape, so simple relaxation would mislabel MIPS32 firmware. The issue asks for admission with o32 as a recorded assumption, a pinned `-processor MIPS:<LE|BE>:32:default` checked against the bridge-reported language after import, evidence that records the ABI as inferred, and unchanged refusals elsewhere. ## Change and scope - Admission: ELF32 `ET_EXEC` with `EF_MIPS_ARCH_32`/`_32R2`, ABI field 0, `EF_MIPS_ABI2` clear and no observed ABI flags record is admitted. FP64/NAN2008/ASE/machine-variant/ELF64/n32 refusals are unchanged; a declared o32 field without a record is still refused. - Profile: the lane identity is versioned `elf32-exec-arch32-legacy-pinned-v1` with `mips_abi_basis: inferred-o32-assumption-v1`. The import language is pinned through a `provider-pinned-v1` selection that drives `-processor MIPS:<LE|BE>:32:default -cspec default` and is checked against the bridge-reported `language_id` after import (the same `expectedLanguageId` mechanism DOS uses). A caller-selected `REA_GHIDRA_LANGUAGE_ID` still wins; combining the pin with an env override is a typed refusal. - Evidence: sessions on this admission carry the limitations that the header declares no ABI, that o32 conventions are an analysis assumption, not a declared fact, and that floating-point ABI semantics are unverified. ## Verification Locally verified on Linux with Ghidra 12.1.4 PUBLIC, clang 21.1.8 (Debian), lld 21.1.8 and GNU readelf 2.47; fork PRs currently receive no CI check runs in this repository, so results below are from this machine: - `verify:ghidra:mips` passes with a new recordless legacy round for both byte orders: the fixture is built with `-march=mips32`, then the ABI record declarations are stripped (PT_MIPS_ABIFLAGS to PT_NULL, SHT_MIPS_ABIFLAGS to SHT_PROGBITS, section renamed in the string table) and the header ABI field zeroed; GNU readelf independently confirms the recordless header; REA's interpretation is checked against it; the pinned language is asserted after import; decoded probe instructions, entry symbols, pseudocode and the retained assumption limitations are asserted through a snapshot round-trip. - The pre-existing standard lane round still passes unchanged (o32/32R2 with record). - `vitest` `src/ghidra/GhidraMipsProfile.test.ts` (new admission/pinning/refusal cases), `tsc --noEmit` clean, `oxlint` 0 errors on touched files. - The pre-change tree refuses the same fixture with "requires an inspected ABI flags record". --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
bsakaguchi 2026-10-31 00:56:28 +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#4890
No description provided.