* feat(domain): parse and validate GameCube/Wii DOL headers Add a pure parser for the 0x100-byte DOL header (7 text and 11 data slots, BSS, entry point). Used slots must lie after the header and inside the file and the 0x80000000..0x81800000 load window; text slots are 4-byte aligned; sections may not overlap in memory or in the file; the entry point must be inside a text section. BSS may overlap data sections, as .sdata/.sdata2 do in shipped DOLs. Refs #1741 * feat(binary): admit caller-selected GameCube/Wii DOL targets * feat(ghidra): import GameCube/Wii DOL targets through a section-map pre-script * test(ghidra): cover DOL launcher arguments, attestation and raw profile digests * test(ghidra): add the real verify:ghidra:dol lane and DOL docs * fix(ghidra): read only the DOL header and section ranges instead of the whole file * test(ghidra): derive DOL lane addresses from readelf and admit Gekko from the install catalog * fix(ghidra): attest DOL block permissions, space, overlay and load state * fix(ghidra): keep load-image permissions optional for older inspections * fix(contracts): accept DOL targets in binary_session output * fix(ghidra): adapt the DOL lane to the current upstream address schema Validate DOL load-image coordinates with the upstream observed-address schema, drop a duplicate import left by the rebase, and re-pin the raw profile digests to the unmodified upstream resolver. * fix(ghidra): preserve bridge inventory symbol provenance * fix(ghidra): align DOL verification with shared workflow contracts * feat(domain): parse and validate GameCube/Wii DOL headers Add a pure parser for the 0x100-byte DOL header (7 text and 11 data slots, BSS, entry point). Used slots must lie after the header and inside the file and the 0x80000000..0x81800000 load window; text slots are 4-byte aligned; sections may not overlap in memory or in the file; the entry point must be inside a text section. BSS may overlap data sections, as .sdata/.sdata2 do in shipped DOLs. Refs #1741 * feat(binary): admit caller-selected GameCube/Wii DOL targets * feat(ghidra): import GameCube/Wii DOL targets through a section-map pre-script * test(ghidra): cover DOL launcher arguments, attestation and raw profile digests * test(ghidra): add the real verify:ghidra:dol lane and DOL docs * fix(ghidra): read only the DOL header and section ranges instead of the whole file * test(ghidra): derive DOL lane addresses from readelf and admit Gekko from the install catalog * fix(ghidra): attest DOL block permissions, space, overlay and load state * fix(ghidra): keep load-image permissions optional for older inspections * fix(contracts): accept DOL targets in binary_session output * fix(ghidra): adapt the DOL lane to the current upstream address schema Validate DOL load-image coordinates with the upstream observed-address schema, drop a duplicate import left by the rebase, and re-pin the raw profile digests to the unmodified upstream resolver. * docs(ghidra): qualify the DOL memory window * refactor(ghidra): own DOL BSS ranges in the parsed header * docs(ghidra): record real DOL workflows and task costs * docs(ghidra): record final DOL integration verification * fix(mcp): share the native procedure search row contract * docs(ghidra): record public procedure search verification --------- Co-authored-by: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com>
5.5 KiB
GameCube DOL analysis through Ghidra
This lane imports 32-bit big-endian PowerPC GameCube/Wii DOL images through Ghidra. It does not execute the image. DOL is a headerless format with no magic number, so REA never detects it: the caller must select it explicitly.
Only the cached MEM1 window 0x80000000..0x81800000 is admitted. Wii MEM2
and uncached aliases are outside this lane.
Not covered: small-data anchors (r2/r13), REL, RPX, and IDA or Hopper
support. See Not supported yet.
Select the format
CLI:
rea inspect /absolute/path/to/main.dol --target-format gamecube-dol --provider ghidra --json
rea function /absolute/path/to/main.dol 0x80003130 --target-format gamecube-dol --provider ghidra --json
MCP, with the existing open_binary tool:
{
"path": "/absolute/path/to/main.dol",
"provider_id": "ghidra",
"format": "gamecube-dol"
}
The architecture comes from the DOL header (powerpc). Do not pass
architecture with gamecube-dol; it is rejected. entry_point is optional,
and if given it must equal the header entry.
Omitting format never imports a file as a DOL. Detection does not run for DOL.
What the import does
REA reads the 256-byte DOL header at admission. It checks every section's file range and load address. It records BSS/data overlaps and computes the exact uninitialized BSS gaps once. Malformed headers are refused before Ghidra starts.
Ghidra then runs in two steps:
- The standard
BinaryLoadermaps the whole file at base0x0, with-processorand-cspectaken from the language selection below. - The pre-script
bridge/ghidra/ReaGhidraPrepareDol.javareads a section file that REA wrote from the parsed header, with versioned collection counts. It creates one initialized block per used text and data section at its load address, with file bytes from the section's file offset. The whole-file block is removed before the section blocks are created. Text is read-execute and data is read-write. It sets the entry point and labels the entry__start.
Sections that the header marks unused are not mapped. The 256-byte header and any bytes between sections are not mapped either.
BSS
A DOL has one BSS range, and it is not always disjoint from the data sections. The domain parser computes the parts of BSS that no data section covers. Both the pre-script and load-image attestation consume those parsed ranges. The pre-script creates uninitialized read-write blocks only in those gaps. Where BSS overlaps a data slot, that slot keeps its file bytes. Overlapping slot indexes are reported by the parser.
Bound language
The default language is PowerPC:BE:32:default with compiler spec default,
which ships with Ghidra. The load-image attestation checks the language Ghidra
reports, not only the requested one.
Optional Gekko/Broadway override
REA_GHIDRA_LANGUAGE_ID=PowerPC:BE:32:Gekko_Broadway selects the Gekko/Broadway
variant. The language is not in stock Ghidra. It comes from the GameCubeLoader
extension, by Cuyler, licensed under Apache-2.0. The extension ships
ppc_gekko_broadway.ldefs under its data/languages directory and must be
installed in the Ghidra installation's Ghidra/Extensions directory. The stock
lane never requires it.
Any other language id must start with PowerPC:BE:32:. Other languages are
refused with a specific constraint.
Paired-single limitation
The stock PowerPC:BE:32:default language does not decode the paired-single
instructions that Gekko and Broadway add. Those words decode as bad or undefined
instructions. Use the Gekko override to decode them.
Verification
The source-owned fixture is built from tests/conformance/c/ppc.c,
tests/conformance/c/dol.c, tests/conformance/ghidra/ppc-probe.S and the
linker script tests/conformance/ghidra/dol-fixture.ld. It is converted to a DOL
by tests/conformance/ghidra/dol-fixture.mjs. Its text is at 0x80003100, and
its single BSS range overlaps data slot 1 and leaves a gap. The fixture is
never executed. The real GameCube or Wii game images are never used.
GHIDRA_INSTALL_DIR=/absolute/path/to/ghidra npm run verify:ghidra:dol
The lane needs the same toolchain as the PowerPC ELF lane: REA_PPC_CLANG,
REA_PPC_READELF and LLD. An independent DOL header reader and GNU readelf
(run on the source ELF) check the section table, file bytes, entry and BSS gap
before Ghidra starts. The checks never use REA's parser.
After import, the lane checks the load-image attestation (verified), the
bound language, the __start entry procedure, a direct call to the leaf
function, decompilation, and bytes at the data, tail, marker and BSS-gap
addresses. It also checks CLI identity.
The Gekko pass runs only when PowerPC:BE:32:Gekko_Broadway is in the Ghidra
installation's language catalog, the same catalog REA uses to admit
REA_GHIDRA_LANGUAGE_ID. A language that exists only in a user extension under
~/Library/ghidra is not admitted, so the lane prints
skipped: PowerPC:BE:32:Gekko_Broadway (not in the Ghidra installation catalog that REA admits); stock lane still verified
and still succeeds on the stock checks.
The ELF lane (npm run verify:ghidra:ppc) is separate. See
PowerPC ELF analysis through Ghidra.
Not supported yet
- Small-data anchors:
r2andr13are not seeded from the DOL header. - REL (relocatable modules) and RPX (Wii U) are not admitted.
- IDA and Hopper refuse
gamecube-dol. Ghidra is the only provider. - Disc images (ISO/GCM) are not supported. Pass an extracted DOL file.