[GH-ISSUE #4246] [Design] Caller-selected Ghidra language and base address for raw-binary imports #1669

Open
opened 2026-10-16 21:08:49 +00:00 by bsakaguchi · 6 comments
Owner

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

Before submitting

  • I searched the 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

Should open_binary format=raw-binary accept a caller-selected Ghidra language ID (and optional compiler spec), validated against the installed language catalog and reported as unverified coverage, alongside the current per-family lanes? Separately, should it accept a load base address that differs from the entry point?

Context and evidence

Observed in source at the REA baseline below: raw-binary admits only x86, x86_64, arm, arm64, and 6502 (src/domain/rawBinary.ts:11-17), each mapped to one fixed little-endian Ghidra language (src/ghidra/GhidraRawBinaryLanguage.ts:16-51). REA_GHIDRA_LANGUAGE_ID is refused for raw-binary with "REA_GHIDRA_LANGUAGE_ID cannot override the admitted raw-binary import." (src/ghidra/GhidraAnalysisProfile.ts:110-118). docs/raw-binary.md lists big-endian, Thumb-only, Cortex-M, and other processor variants as unsupported, and the single entry_point is both the load address of file offset 0 and the entry (src/ghidra/GhidraProviderClient.ts:601-606).

Source-derived reasoning: headerless images for MIPS (BE and LE), big-endian ARM, PowerPC, Xtensa, SuperH, and Cortex-M are common in embedded firmware, and Ghidra already ships languages for them. Each family currently needs its own lane (#3532 for SH-4, open PR #4018 for big-endian m68k). A bootloader or kernel image is also often linked at a base address that is not its entry point; with base fixed to entry, absolute references in such an image resolve to the wrong addresses.

Precedent: the PowerPC ELF lane already lets a caller-selected REA_GHIDRA_LANGUAGE_ID replace the lane default, admitted against the installed language catalog (docs/ghidra-ppc.md:28-34; PR #1747 exempted PowerPC from the override restriction that MIPS and RISC-V keep). AGENTS.md requires unverified coverage to be reported explicitly, which a generic language selection would need for every language without a verified lane.

Unknown: whether ReaGhidraPrepareRaw.java and load-image verification (src/ghidra/GhidraLoadImageValues.ts:343-380) can obtain the default address space and address width from the installed language catalog instead of the fixed mapping.

Expected interaction with targets

Read existing files or captured data

Boundary details (optional)

The change concerns how a caller-selected local file is imported by a caller-configured Ghidra installation; it adds no execution of the target, no network, and no new provider. The evidence invariant to keep: an unverified language must never be reported with the coverage claims of a verified lane, and a refused or unknown language must fail before analysis rather than fall back to a different one.

Options and tradeoffs

  • Option A, keep per-family lanes only: strongest verification per family, but each new CPU needs a code change and a real-Ghidra verifier.
  • Option B, generic language passthrough: add an optional language_id (and compiler_spec_id) for raw-binary, validated against the installed .ldefs catalog, with Evidence and limitations marking the language as unverified unless it matches a verified lane. This matches the PowerPC precedent, at the cost of weaker guarantees for unverified languages.
  • Option C, B plus a separate base_address: keeps file offset 0 mapped at base_address and seeds the entry at entry_point, with validation that the entry lies inside the mapped image. This changes the persisted analysis profile and snapshot identity.

Verification available so far

I can suggest a sample or manual check

Success criteria and open questions

  • With a verified language, results and Evidence match today's lane behavior exactly.
  • With a catalog-valid but unverified language (for example MIPS:BE:32:default on a self-compiled objcopy -O binary image), the import succeeds, procedures and pseudocode are readable, and every result carries an explicit unverified-language limitation.
  • A language absent from the installed catalog is refused before analysis with a diagnostic naming the catalog checked.
  • With a separate base address, absolute references in a self-built image linked at a non-zero base resolve to the linked addresses.
  • Open: should Option B allow REA_GHIDRA_LANGUAGE_ID for raw-binary, or only an explicit open_binary input? How should snapshot reuse key on the selected language and base?

References

  • REA baseline: main at 0cc56493be (package 6.5.0): docs/raw-binary.md, docs/ghidra-ppc.md, docs/testing.md (raw lanes), src/ghidra/GhidraLauncher.ts:649-681, bridge/ghidra/ReaGhidraPrepareRaw.java.
  • Related: #1836 and #1868 (original caller-supplied raw-binary design, which listed a load address independent of entry as out of scope), #3532 (SH-4 lane), PR #4018 (big-endian m68k lane), #3930 and PR #4103 (raw-binary override refusal diagnostics), #3483 (Xtensa ELF), #3178 (pinned-profile override fix), #1747 (PowerPC override precedent).
  • Search: all issues and pull requests were listed and searched locally for raw-binary, language ID, big-endian, Cortex-M, Thumb, base address, load address, and processor; no generic proposal or maintainer decision on one was found.
Originally created by @coygeek on GitHub (Oct 15, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/4246 ### Before submitting - [X] I searched the open and closed issues and pull requests for a related discussion. - [X] I understand the [contribution scope](https://github.com/morluto/rea/blob/main/CONTRIBUTING.md#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 Should `open_binary format=raw-binary` accept a caller-selected Ghidra language ID (and optional compiler spec), validated against the installed language catalog and reported as unverified coverage, alongside the current per-family lanes? Separately, should it accept a load base address that differs from the entry point? ### Context and evidence Observed in source at the REA baseline below: raw-binary admits only `x86`, `x86_64`, `arm`, `arm64`, and `6502` (`src/domain/rawBinary.ts:11-17`), each mapped to one fixed little-endian Ghidra language (`src/ghidra/GhidraRawBinaryLanguage.ts:16-51`). `REA_GHIDRA_LANGUAGE_ID` is refused for raw-binary with "REA_GHIDRA_LANGUAGE_ID cannot override the admitted raw-binary import." (`src/ghidra/GhidraAnalysisProfile.ts:110-118`). `docs/raw-binary.md` lists big-endian, Thumb-only, Cortex-M, and other processor variants as unsupported, and the single `entry_point` is both the load address of file offset 0 and the entry (`src/ghidra/GhidraProviderClient.ts:601-606`). Source-derived reasoning: headerless images for MIPS (BE and LE), big-endian ARM, PowerPC, Xtensa, SuperH, and Cortex-M are common in embedded firmware, and Ghidra already ships languages for them. Each family currently needs its own lane (#3532 for SH-4, open PR #4018 for big-endian m68k). A bootloader or kernel image is also often linked at a base address that is not its entry point; with base fixed to entry, absolute references in such an image resolve to the wrong addresses. Precedent: the PowerPC ELF lane already lets a caller-selected `REA_GHIDRA_LANGUAGE_ID` replace the lane default, admitted against the installed language catalog (`docs/ghidra-ppc.md:28-34`; PR #1747 exempted PowerPC from the override restriction that MIPS and RISC-V keep). `AGENTS.md` requires unverified coverage to be reported explicitly, which a generic language selection would need for every language without a verified lane. Unknown: whether `ReaGhidraPrepareRaw.java` and load-image verification (`src/ghidra/GhidraLoadImageValues.ts:343-380`) can obtain the default address space and address width from the installed language catalog instead of the fixed mapping. ### Expected interaction with targets Read existing files or captured data ### Boundary details (optional) The change concerns how a caller-selected local file is imported by a caller-configured Ghidra installation; it adds no execution of the target, no network, and no new provider. The evidence invariant to keep: an unverified language must never be reported with the coverage claims of a verified lane, and a refused or unknown language must fail before analysis rather than fall back to a different one. ### Options and tradeoffs - Option A, keep per-family lanes only: strongest verification per family, but each new CPU needs a code change and a real-Ghidra verifier. - Option B, generic language passthrough: add an optional `language_id` (and `compiler_spec_id`) for raw-binary, validated against the installed `.ldefs` catalog, with Evidence and limitations marking the language as unverified unless it matches a verified lane. This matches the PowerPC precedent, at the cost of weaker guarantees for unverified languages. - Option C, B plus a separate `base_address`: keeps file offset 0 mapped at `base_address` and seeds the entry at `entry_point`, with validation that the entry lies inside the mapped image. This changes the persisted analysis profile and snapshot identity. ### Verification available so far I can suggest a sample or manual check ### Success criteria and open questions - With a verified language, results and Evidence match today's lane behavior exactly. - With a catalog-valid but unverified language (for example `MIPS:BE:32:default` on a self-compiled `objcopy -O binary` image), the import succeeds, procedures and pseudocode are readable, and every result carries an explicit unverified-language limitation. - A language absent from the installed catalog is refused before analysis with a diagnostic naming the catalog checked. - With a separate base address, absolute references in a self-built image linked at a non-zero base resolve to the linked addresses. - Open: should Option B allow `REA_GHIDRA_LANGUAGE_ID` for raw-binary, or only an explicit `open_binary` input? How should snapshot reuse key on the selected language and base? ### References - REA baseline: `main` at 0cc56493be167309bd72040273de603ad75ad9e0 (package 6.5.0): `docs/raw-binary.md`, `docs/ghidra-ppc.md`, `docs/testing.md` (raw lanes), `src/ghidra/GhidraLauncher.ts:649-681`, `bridge/ghidra/ReaGhidraPrepareRaw.java`. - Related: #1836 and #1868 (original caller-supplied raw-binary design, which listed a load address independent of entry as out of scope), #3532 (SH-4 lane), PR #4018 (big-endian m68k lane), #3930 and PR #4103 (raw-binary override refusal diagnostics), #3483 (Xtensa ELF), #3178 (pinned-profile override fix), #1747 (PowerPC override precedent). - Search: all issues and pull requests were listed and searched locally for raw-binary, language ID, big-endian, Cortex-M, Thumb, base address, load address, and processor; no generic proposal or maintainer decision on one was found.
Author
Owner

@onionmixer commented on GitHub (Oct 17, 2026):

Thank you for writing this up. I hope a concrete use case is helpful for the second question (a load base that differs from the entry); please disregard it if it is out of scope.

Use case (observed). I have been looking at a 68000 main-CPU program from a Mega-CD (Sega CD) game with REA's raw m68k lane. The image is loaded at 0x200000, and its first 256 bytes are a 68000 vector table; the reset vector points to 0x200200. With a single entry_point, I can only map the file correctly by using entry_point=0x200000. ReaGhidraPrepareRaw.java then calls disassemble() and createFunction(..., "entry") at 0x200000, so the vector table is decoded as code before auto-analysis and before any REA_GHIDRA_SEED_FILE seeds are applied. In my case, that early flow reached a large part of the program.

Why it mattered here (observed, with a caveat). This program's trap handlers read inline parameter words placed after the trap instruction. The early flow from the entry decoded those words as instructions. Because of that, seeds alone could not correct those places afterwards: code seeds refuse addresses that are already inside an instruction. I worked around it locally with a different change, which I describe separately below. I did not isolate how much of the difference comes from the entry seeding alone, so I would not want to overstate it.

What a separate base would allow. If open_binary accepted a load base (0x200000) separately from the entry (0x200200), this image could be imported without decoding the vector table as code. The vector table could then be left for seeds or labels. The firmware and bootloader images mentioned in this issue probably have the same layout.

Linux run of the m68k lane (observed). In case it is useful for the "Linux has not been exercised" note in docs/raw-binary.md: on Ubuntu 22.04 x64 with Ghidra 12.1 (not the 12.1.4 verified build) and OpenJDK 21.0.12, node scripts/verify-real-ghidra-m68k.mjs reported "ok":true for every check. I ran it on rea-agents-6.5.0 with #4018 cherry-picked, not on current main.

I cannot share the program itself because it is commercial game code. A small synthetic image with a vector table and an inline-operand trap reproduces the same pattern, and I would be glad to prepare one if that would help.

Prepared with help from an AI coding assistant; I have checked the statements above against my local runs.

<!-- gh-comment-id:6233624820 --> @onionmixer commented on GitHub (Oct 17, 2026): Thank you for writing this up. I hope a concrete use case is helpful for the second question (a load base that differs from the entry); please disregard it if it is out of scope. **Use case (observed).** I have been looking at a 68000 main-CPU program from a Mega-CD (Sega CD) game with REA's raw m68k lane. The image is loaded at `0x200000`, and its first 256 bytes are a 68000 vector table; the reset vector points to `0x200200`. With a single `entry_point`, I can only map the file correctly by using `entry_point=0x200000`. `ReaGhidraPrepareRaw.java` then calls `disassemble()` and `createFunction(..., "entry")` at `0x200000`, so the vector table is decoded as code before auto-analysis and before any `REA_GHIDRA_SEED_FILE` seeds are applied. In my case, that early flow reached a large part of the program. **Why it mattered here (observed, with a caveat).** This program's trap handlers read inline parameter words placed after the `trap` instruction. The early flow from the entry decoded those words as instructions. Because of that, seeds alone could not correct those places afterwards: code seeds refuse addresses that are already inside an instruction. I worked around it locally with a different change, which I describe separately below. I did **not** isolate how much of the difference comes from the entry seeding alone, so I would not want to overstate it. **What a separate base would allow.** If `open_binary` accepted a load base (`0x200000`) separately from the entry (`0x200200`), this image could be imported without decoding the vector table as code. The vector table could then be left for seeds or labels. The firmware and bootloader images mentioned in this issue probably have the same layout. **Linux run of the m68k lane (observed).** In case it is useful for the "Linux has not been exercised" note in `docs/raw-binary.md`: on Ubuntu 22.04 x64 with Ghidra **12.1** (not the 12.1.4 verified build) and OpenJDK 21.0.12, `node scripts/verify-real-ghidra-m68k.mjs` reported `"ok":true` for every check. I ran it on `rea-agents-6.5.0` with #4018 cherry-picked, not on current main. I cannot share the program itself because it is commercial game code. A small synthetic image with a vector table and an inline-operand trap reproduces the same pattern, and I would be glad to prepare one if that would help. <sub>Prepared with help from an AI coding assistant; I have checked the statements above against my local runs.</sub>
Author
Owner

@Entrpi commented on GitHub (Oct 27, 2026):

To unblock Cortex-M flash dumps (#5744), I'm preparing an implementation of a minimal answer to this issue, for review:

  1. base_address, separate from entry_point. Targets that use none of the new inputs keep today's behaviour, identity and load image exactly.

  2. architecture_variant, naming the M profile:

    • armv6-m, armv7-m and armv7e-m → ARM:LE:32:Cortex;
    • armv8-m.base and armv8-m.main → ARM:LE:32:v8-m.

    Cortex lacks v8-M encodings such as MSR MSPLIM, so a single cortex-m value (as in #4927) can't map to one language.

  3. entry_point optional when a base is given. Under these variants, Reset is then read from the vector table, at the base or at vector_table_address for prefixed images such as RP2040 boot2 and MCUboot. An explicit odd entry is refused, and the error gives the even address.

  4. A new load-image shape for new targets only. Targets that use the new inputs get a minimal, versioned segments load image. That's a new saved-Evidence shape, so it needs your compatibility decision.

Language passthrough (option B) could follow later as an explicitly unverified override. I'll credit #4927's author and reuse its sound parts.

Please confirm or redirect any of this; it won't merge until a maintainer does.

<!-- gh-comment-id:6439631662 --> @Entrpi commented on GitHub (Oct 27, 2026): To unblock Cortex-M flash dumps (#5744), I'm preparing an implementation of a minimal answer to this issue, for review: 1. **`base_address`, separate from `entry_point`.** Targets that use none of the new inputs keep today's behaviour, identity and load image exactly. 2. **`architecture_variant`, naming the M profile:** - `armv6-m`, `armv7-m` and `armv7e-m` → `ARM:LE:32:Cortex`; - `armv8-m.base` and `armv8-m.main` → `ARM:LE:32:v8-m`. `Cortex` lacks v8-M encodings such as `MSR MSPLIM`, so a single `cortex-m` value (as in #4927) can't map to one language. 3. **`entry_point` optional when a base is given.** Under these variants, Reset is then read from the vector table, at the base or at `vector_table_address` for prefixed images such as RP2040 boot2 and MCUboot. An explicit odd entry is refused, and the error gives the even address. 4. **A new load-image shape for new targets only.** Targets that use the new inputs get a minimal, versioned `segments` load image. That's a new saved-Evidence shape, so it needs your compatibility decision. Language passthrough (option B) could follow later as an explicitly unverified override. I'll credit #4927's author and reuse its sound parts. Please confirm or redirect any of this; it won't merge until a maintainer does.
Author
Owner

@Entrpi commented on GitHub (Oct 27, 2026):

The implementation of the proposal above is ready for design review on my fork: compare with main. I'm at this repository's open pull request limit, so it will become a draft PR when one of my slots frees.

The decision is a single commit, 56f27b3de: types, schemas, the owner table, docs and table-driven tests. The commits after it implement it. Beyond the outline above:

  • base_address is refused without architecture_variant, because no verified lane covers a separate base for other families yet.
  • Two new saved shapes, both versioned: raw_load in the analysis profile and snapshot target, and a minimal segments load image. Loads without a variant keep today's profile, identity and load image.
  • Variant loads import without Ghidra's processor-defined labels (-loader-applyLabels false). ARMCortex.pspec labels 0x0–0x40 and marks every handler slot an entry, which would cover the image at base 0x0.

On real Ghidra 12.1.4 (Linux), a new verify:ghidra:cortex-m lane passes all five variants, including a prefixed image read through vector_table_address and v8-M.main's MSPLIM. The existing raw, m68k, 6502, COM, DOL and bridge-source lanes also pass.

Please confirm or redirect; it won't merge until a maintainer does.

Update (28 Oct): the branch now also covers armv8.1-m.main (Cortex-M55/M85), decoded with ARM:LE:32:v8-m, and the lane passes all six variants. Ghidra 12.1.4 gets the targets of the ARMv8.1-M low-overhead loop branches (wls, le) wrong, so code after such a loop is not disassembled; results for that variant carry this limitation.

<!-- gh-comment-id:6446107221 --> @Entrpi commented on GitHub (Oct 27, 2026): The implementation of the proposal above is ready for design review on my fork: [compare with `main`](https://github.com/morluto/rea/compare/main...Entrpi:rea:feat-ghidra-mprofile-raw). I'm at this repository's open pull request limit, so it will become a draft PR when one of my slots frees. The decision is a single commit, [`56f27b3de`](https://github.com/Entrpi/rea/commit/56f27b3deb97fee56c01a168df5f7a9404b8f42c): types, schemas, the owner table, docs and table-driven tests. The commits after it implement it. Beyond the outline above: - `base_address` is refused without `architecture_variant`, because no verified lane covers a separate base for other families yet. - Two new saved shapes, both versioned: `raw_load` in the analysis profile and snapshot target, and a minimal `segments` load image. Loads without a variant keep today's profile, identity and load image. - Variant loads import without Ghidra's processor-defined labels (`-loader-applyLabels false`). `ARMCortex.pspec` labels `0x0`–`0x40` and marks every handler slot an entry, which would cover the image at base `0x0`. On real Ghidra 12.1.4 (Linux), a new `verify:ghidra:cortex-m` lane passes all five variants, including a prefixed image read through `vector_table_address` and v8-M.main's `MSPLIM`. The existing raw, m68k, 6502, COM, DOL and bridge-source lanes also pass. Please confirm or redirect; it won't merge until a maintainer does. **Update (28 Oct):** the branch now also covers `armv8.1-m.main` (Cortex-M55/M85), decoded with `ARM:LE:32:v8-m`, and the lane passes all six variants. Ghidra 12.1.4 gets the targets of the ARMv8.1-M low-overhead loop branches (`wls`, `le`) wrong, so code after such a loop is not disassembled; results for that variant carry this limitation.
Author
Owner

@Reid-n0rc commented on GitHub (Oct 27, 2026):

A use case for Option B that the per-family lanes and the M-profile architecture_variant proposal would not cover: a language that exists only as a community processor module.

Use case (observed). Headerless Renesas RX (RXv2) firmware for an RX651-class MCU: a flat ROM image mapped at 0xFFF80000, with the reset vector at the fixed vector table near the top of the address space. Ghidra 12.1.4 ships no RX language. A community SLEIGH module (language ID rx62t:LE:32:default, compiler spec default) decodes this image well when its files are installed under the Ghidra installation's own Ghidra/Processors/<module>/data/languages/, so the language is present in the installation catalog that REA reads. With plain analyzeHeadless -processor rx62t:LE:32:default -loader BinaryLoader -loader-baseAddr 0xFFF80000, auto-analysis and decompilation work. Through REA:

  • format=raw-binary cannot select it: architecture is limited to the fixed families, and REA_GHIDRA_LANGUAGE_ID is refused for raw-binary (src/ghidra/GhidraAnalysisProfile.ts).
  • Wrapping the image in a minimal ELF (e_machine = EM_RX, 173) is rejected earlier with "unsupported ELF architecture" (elfArchitecture maps only x86, x86_64, mips, powerpc, arm, hexagon, arm64, riscv).
  • REA_GHIDRA_PROJECT_PATH cannot reuse an analyzed project, because project reuse admits only ELF, PE and Mach-O.

So Option B, validated against the installed .ldefs catalog and reported as unverified coverage, would be the only route for this class of target. It would also cover other community-only languages without a new lane each.

A second gap Option B alone doesn't close (question for the design). For MCU firmware, the language is necessary but not sufficient for readable output. The decompile becomes useful only after the analyst adds memory blocks that are not in the file: on-chip RAM, peripheral I/O registers, data flash, the C runtime's .data copy-down from ROM into RAM, and the relocatable interrupt vector table as function seeds. Without RAM and I/O blocks, every global and register access shows as an unmapped address. REA_GHIDRA_SEED_FILE covers the function seeds. Is a caller-supplied memory map for raw-binary (named uninitialized or initialized blocks, plus optional byte-copy ranges) in scope, perhaps as a separate decision from the language selection? Or would raw-binary project reuse be the preferred route, since snapshot identity would then follow the project content as it already does for ELF/PE/Mach-O?

Answers to the open questions, from this use case:

  • An explicit open_binary input reads better than REA_GHIDRA_LANGUAGE_ID: the language is a property of the target, and one server may analyze several headerless images with different CPUs.
  • Snapshot identity should key on the selected language ID, compiler spec and the catalog entry it resolved to. A community module can be updated in place under the same ID, so a digest of the resolved .ldefs/.sla would be safer than the ID alone.

I can run a self-built test image through a prototype if that helps verification.

<!-- gh-comment-id:6455913400 --> @Reid-n0rc commented on GitHub (Oct 27, 2026): A use case for Option B that the per-family lanes and the M-profile `architecture_variant` proposal would not cover: a language that exists only as a **community processor module**. **Use case (observed).** Headerless Renesas RX (RXv2) firmware for an RX651-class MCU: a flat ROM image mapped at `0xFFF80000`, with the reset vector at the fixed vector table near the top of the address space. Ghidra 12.1.4 ships no RX language. A community SLEIGH module (language ID `rx62t:LE:32:default`, compiler spec `default`) decodes this image well when its files are installed under the Ghidra installation's own `Ghidra/Processors/<module>/data/languages/`, so the language is present in the installation catalog that REA reads. With plain `analyzeHeadless -processor rx62t:LE:32:default -loader BinaryLoader -loader-baseAddr 0xFFF80000`, auto-analysis and decompilation work. Through REA: - `format=raw-binary` cannot select it: `architecture` is limited to the fixed families, and `REA_GHIDRA_LANGUAGE_ID` is refused for raw-binary (`src/ghidra/GhidraAnalysisProfile.ts`). - Wrapping the image in a minimal ELF (`e_machine` = `EM_RX`, 173) is rejected earlier with "unsupported ELF architecture" (`elfArchitecture` maps only x86, x86_64, mips, powerpc, arm, hexagon, arm64, riscv). - `REA_GHIDRA_PROJECT_PATH` cannot reuse an analyzed project, because project reuse admits only ELF, PE and Mach-O. So Option B, validated against the installed `.ldefs` catalog and reported as unverified coverage, would be the only route for this class of target. It would also cover other community-only languages without a new lane each. **A second gap Option B alone doesn't close (question for the design).** For MCU firmware, the language is necessary but not sufficient for readable output. The decompile becomes useful only after the analyst adds memory blocks that are not in the file: on-chip RAM, peripheral I/O registers, data flash, the C runtime's `.data` copy-down from ROM into RAM, and the relocatable interrupt vector table as function seeds. Without RAM and I/O blocks, every global and register access shows as an unmapped address. `REA_GHIDRA_SEED_FILE` covers the function seeds. Is a caller-supplied memory map for raw-binary (named uninitialized or initialized blocks, plus optional byte-copy ranges) in scope, perhaps as a separate decision from the language selection? Or would raw-binary project reuse be the preferred route, since snapshot identity would then follow the project content as it already does for ELF/PE/Mach-O? **Answers to the open questions, from this use case:** - An explicit `open_binary` input reads better than `REA_GHIDRA_LANGUAGE_ID`: the language is a property of the target, and one server may analyze several headerless images with different CPUs. - Snapshot identity should key on the selected language ID, compiler spec and the catalog entry it resolved to. A community module can be updated in place under the same ID, so a digest of the resolved `.ldefs`/`.sla` would be safer than the ID alone. I can run a self-built test image through a prototype if that helps verification.
Author
Owner

@Entrpi commented on GitHub (Oct 28, 2026):

Thanks, this is exactly the case for the language input (option B). I'd make it an explicit open_binary input, checked against the installed catalog and reported as unverified. Identity should cover a digest of the resolved .ldefs/.sla, as you say, not just the id.

The memory map is the other half of this design: a caller-declared load plan with named blocks, copy-down ranges and seeds. It changes load identity, so it's part of the refactor question in #7478.

I'll build the language input on my fork and ping you here; a self-built RX image would be a great check.

<!-- gh-comment-id:6458087948 --> @Entrpi commented on GitHub (Oct 28, 2026): Thanks, this is exactly the case for the language input (option B). I'd make it an explicit `open_binary` input, checked against the installed catalog and reported as unverified. Identity should cover a digest of the resolved `.ldefs`/`.sla`, as you say, not just the id. The memory map is the other half of this design: a caller-declared load plan with named blocks, copy-down ranges and seeds. It changes load identity, so it's part of the refactor question in #7478. I'll build the language input on my fork and ping you here; a self-built RX image would be a great check.
Author
Owner

@Entrpi commented on GitHub (Oct 28, 2026):

D1 is now open as draft #7951, and its decision record there is the current version. A three-model review changed four points since the outline above:

  • every architecture_variant requires base_address, because mapping a dump at its entry would put the vector table at Reset;
  • a vector table must be 128-byte aligned, as VTOR requires, and a Reset target inside the table is refused;
  • functions found from different entries of one image compare, because variant coordinates are keyed by the base rather than the entry;
  • the new load image is discriminated by layout: "segments", and a refused selection names its input in details.field.

Please confirm or redirect on #7951.

<!-- gh-comment-id:6483785045 --> @Entrpi commented on GitHub (Oct 28, 2026): D1 is now open as draft #7951, and its decision record there is the current version. A three-model review changed four points since the outline above: - every `architecture_variant` requires `base_address`, because mapping a dump at its entry would put the vector table at Reset; - a vector table must be 128-byte aligned, as VTOR requires, and a Reset target inside the table is refused; - functions found from different entries of one image compare, because variant coordinates are keyed by the base rather than the entry; - the new load image is discriminated by `layout: "segments"`, and a refused selection names its input in `details.field`. Please confirm or redirect on #7951.
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#1669
No description provided.