[GH-ISSUE #8463] [Design] Admit ESP32-P4 ELF that declares Espressif vendor extensions, and report what Ghidra cannot decode #6613

Open
opened 2026-11-01 21:12:41 +00:00 by bsakaguchi · 0 comments
Owner

Originally created by @Entrpi on GitHub (Nov 1, 2026).
Original GitHub issue: https://github.com/morluto/rea/issues/8463

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 the decoded-extension rule of D3 (#7477) gain a vendor-extension mode? In that mode the single-float lane would admit an RV32I image whose Tag_RISCV_arch declares only decoded extensions plus Espressif's xesploop, xesppie and xespv. After analysis, the bridge would report each instruction that Ghidra 12.1.4 could not decode or decoded only as a placeholder. REA would no longer refuse these images.

Context and evidence

Every ESP32-P4 image declares Espressif extensions, so the ilp32f lane refuses all of them. ESP-IDF v5.5.2 builds hello_world for P4 with these declarations (observed):

  • default Kconfig, chip revision < 3: rv32i2p1_m2p0_a2p1_f2p2_c2p0_zicsr2p0_zifencei2p0_zmmul1p0_zaamo1p0_zalrsc1p0_xesploop1p0_xesppie1p0_xespv2p2
  • revision 3 (CONFIG_ESP32P4_SELECTS_REV_LESS_V3=n): the same without xesppie1p0.

From v5.5.6 on, rev 3 is the Kconfig default (source-derived from the tags v5.5.6, v6.0.3 and v6.1). Every ESP build that declares B also declares a vendor extension, so B support alone, such as NationalSecurityAgency/ghidra#8848, would admit no ESP build (source-derived).

Espressif GCC's backend has no vendor-instruction patterns (source-derived, not run), so its C output is standard. Hand-written assembly is not: FreeRTOS saves and restores the PIE registers in every P4 image.

I measured both hello_world builds and IDF's own gdbstub_runtime test app with Ghidra 12.1.4 and REA's ilp32f lane. A local experiment that only adds the names to the admission check let them through; it is not pushed. Observed:

  1. Footprint. Each image has 32 vendor instructions out of about 45,800, all in FreeRTOS's rtos_save_pie_coproc (portasm.S). newlib, libgcc and the other IDF components contain none. The test app adds one hardware-loop setup.
  2. Ghidra fails visibly on those 32. Their opcode classes have no RV32 constructor. Analysis records a "Bad Instruction" bookmark at the first word of each block and stops that flow: 102 of the routine's 260 bytes are disassembled.
  3. Silent cases exist. I decoded each of IDF's 360 PIE test instructions alone (table below). Some become opaque customN placeholders. Some of those model writes to s8, a6 or, for hardware loop 1's setup, ra. Others become unrelated draft instructions such as saes32.encsm. A hardware loop's back edge lives in loop CSRs, so Ghidra shows the body once. In the test app, test_xesppie_loops runs its body three times but decompiles as custom1.rd(); return;, with no warning.
  4. REA says nothing. With admission alone, rea analyze succeeds and the ilp32f policy refuses no signature (1,340 functions, 587 definitions). No limitation mentions a decode failure. One limitation becomes false: "Every declared extension is in the set this lane decodes". Only rea function on the routine shows Ghidra's halt_baddata() warning, inside the pseudocode.
  5. Not every bad instruction is a vendor word. Each image has 6 bookmarks: 2 PIE words, 1 intentional unimp in panic_abort, and 3 zero fills after calls to a ROM reset routine that never returns.
  6. The two PIE encodings differ. xesppie1p0 and xespv2p2 encode the same instructions as different words, and a default rev < 3 image declares both. Espressif's own objdump decodes none of that image's PIE words until a copy declares only xesppie.
Ghidra 12.1.4 decoding each instruction of IDF's PIE test file (rv_decode/xesppie.S), pinned RISCV:LE:32:default
Outcome xesppie1p0 (rev < 3) xespv2p2 (rev 3) esp.lp.* (7 forms)
No constructor: on a flow, a "Bad Instruction" bookmark 300 344 0
Opaque customN placeholder 58 15 6
Unrelated draft instruction with unimpl p-code 2 (radd16, saes32.encsm) 1 (saes32.encsm) 1
Decoded with real p-code 0 0 0
The six bad-instruction bookmarks in hello_world (rev < 3)
Function Source Address Word What it is
rtos_save_pie_coproc FreeRTOS portasm.S 0x4ff06506 8201223b first esp.vst.128.ip
rtos_save_pie_coproc FreeRTOS portasm.S 0x4ff06576 0201223b first esp.vld.128.ip
panic_abort esp_system/panic.c 0x4ff047ae 0000 unimp
esp_cpu_configure_region_protection esp_hw_support/cpu_region_protect.c 0x4000a38a, 0x4000a39e, 0x4000a3b2 zero fill after calls to esp_rom_software_reset_system

Inferred, not measured: GCC-built ESP-IDF 5.5 P4 apps without esp-dsp, esp-dl or other hand-written PIE assembly have this same small footprint. DSP-heavy apps have many more vendor instructions, including the silent kinds.

Expected interaction with targets

  • Read existing files or captured data

Boundary details (optional)

  • Static only. Ghidra imports the ELF into its ephemeral database. Nothing runs, nothing is emulated, and no bytes or Ghidra files change.
  • Admission uses a closed list of three Tag_RISCV_arch names. An image that also declares any other undecoded extension stays refused. That includes B (zba, zbb, zbc, zbs) and zcb, zcmp, zcmt: compilers emit those in ordinary code, and Ghidra would decode Zcmp and Zcmt silently as float stores (source-derived).
  • Which ESP-IDF builds that admits, source-derived from the release tags (only v5.5.2 is measured):
    • admitted by declaration: P4 builds that declare xesppie, which S31 builds from 6.1 do not declare, such as v5.5.2's default build before rev 3;
    • admitted only with a fact that identifies a P4 image (question 8): the other P4 builds the closed list covers, such as rev 3 builds from 5.5.x, 6.0–6.0.2 and 6.1, because S31 builds from 6.1, a preview target, declare the same names;
    • still refused: P4 rev 3 from 6.0.3 and the next 6.1.x, which add B; S31 from the next 6.1.x, which adds B and Zcb/Zcmp/Zcmt; H4 on 6.x (B and xespdsp); and any P4 rev 3 or S31 build that opts in to CONFIG_COMPILER_ENABLE_RISCV_ZCMP, which adds Zcb/Zcmp/Zcmt.
  • The rule reads declarations, not chips, and an S31 6.1 image declares the same names as a P4 rev 3 image. S31 is a preview target and no S31 image was measured, so this proposal does not admit S31 on P4's evidence. The ELF records no chip: ESP-IDF's app descriptor (esp_app_desc_t) has no chip ID, which only the flashed image header carries (source-derived, v5.5.2). Until REA can read a fact that identifies a P4 image (question 8), an image with that shared declaration stays refused.
  • The ilp32f signature check and its refusal stay as they are.
  • Non-goals: decoding Espressif instructions, modelling PIE state or hardware loops, and changing the generic lanes.

Options and tradeoffs

Proposed: a vendor mode with a decode report.

  • Lane. A new lane, elf32-exec-le-single-float-espressif-v1, with the same pinned language, compiler specification and __rea_ilp32f policy. The generic lane keeps its meaning. The profile commits riscv_vendor_extensions (the declared names) and a report policy such as riscv_decode_report: undecoded-instructions-v1. REA requires the report exactly when the profile commits it, as it does for riscv_calling_convention, and refuses the session when the report is missing or malformed.
  • Bridge. One pass after auto-analysis and the calling-convention script, before serving. It records:
    • each "Bad Instruction" bookmark, with its address, word, and the function that reaches it. The function comes from the bookmark's flow source, because the failed address lies outside every function body.
    • each custom-0 to custom-3 placeholder, and each instruction with unimpl p-code (the draft constructors that some vendor words land on).
    • custom-1 words as hardware-loop setups: unmodelled loops whose back edge Ghidra drops, whose placeholder may also write ra.
    • an opcode class for each word: vendor-capable (custom-0 to custom-3, the 48-, 64- and 80-bit prefixes, and the RV64-only OP-32 and OP-IMM-32) or other (such as unimp or zero fill). This classifies the encoding space; it does not decode.
  • Evidence. A session limitation gives the counts and names up to 8 functions, bounded like the ilp32f refusal. Function queries add a limitation for an affected function. A limitation that names the undecoded vendor extensions replaces "every declared extension is decoded".
  • Measured cost. The scan took 74–87 ms inside Ghidra over 45,800–52,600 instructions (one run each), against about 15 s for the whole headless import and analysis. For hello_world the report names 3 functions and 6 addresses.
  • Code: S–M. One admission row and lane, a Java pass of about 150 lines, a bounded handshake report and its parser, limitation text, a verifier fixture and docs.

Alternatives.

  1. Keep refusing. No cost, but P4 cannot be analyzed through Ghidra at all, although 99.9 % of hello_world's instructions are standard.
  2. Admit without a report. Measured above: REA's Evidence becomes silent or false. Not recommended.
  3. A caller-installed decoder extension, on the PSP ghidra-allegrex model (docs/ghidra-psp.md): REA fingerprints a bring-your-own extension and pins its language. This gives the best fidelity, but no such extension exists. Ghidra has no issue or PR for Espressif extensions. b1n4ri0/RP2350_RISCV_Ghidra patches the stock RISCV language in place, so REA could not pin it separately. An extension would need both PIE encodings, a way to choose one that does not rely on Tag_RISCV_arch alone, the Q/QACC/XACC state and hardware-loop flow. That is large work, better owned by Espressif or the community. The vendor mode stays useful until then and could select such an extension later.
  4. Report in every RISC-V lane. The non-vendor failures above probably occur in C3, C6 and H4 images that REA admits today (not checked). This changes existing lanes' Evidence and snapshots, so it is a separate decision.
  5. Neutralize vendor words before import, or ship a modified Ghidra language. This conflicts with REA's immutable-source and bring-your-own-Ghidra rules. Not proposed.

Verification available so far

I have a prototype or observed results

Success criteria and open questions

Proposed verification in npm run verify:ghidra:riscv, which acquires no tools:

  • A fixture assembled from committed sources with the existing LLVM tools. Vendor words go in as .4byte values: measured words of both PIE encodings, custom-2 and custom-3 placeholders, esp.lp.setup for loops 0 and 1, and esp.lp.count. The fixture also holds an unimp, and a call to an unknown routine followed by zero fill. llvm-objcopy --update-section then writes the rev < 3 and rev 3 attribute strings, like the lane's existing header mutations.
  • Over CLI and MCP, the report's counts, addresses, classes and functions equal the fixture's known layout, and they survive snapshot save and reopen. Adding zbb or zcmp to the declaration keeps the image refused. Generic-lane profile digests do not change.
  • An optional cross-check against a caller-supplied Espressif objdump. Calibration on locally built ESP-IDF images stays supplemental and is never committed.

Open questions

  1. A new lane id, or a vendor field in the existing single-float lane?
  2. Report only in the vendor mode (proposed), or in every RISC-V lane?
  3. Admit xespdsp now? No admissible image declares it without B, and its encodings are unmeasured. Proposed: not yet.
  4. Admit by name only? Versions change the encoding (xespv2p1, xespv2p2). Without decoding, the name is enough for admission; the version matters only for classification and for a future decoder.
  5. How many functions and addresses should the report name? Should a function's limitation also give how many bytes of its ELF symbol stay undisassembled? REA does not read ELF symbol sizes today.
  6. Should a custom-1 word count as a hardware-loop setup only when its fields match Espressif's esp.lp.* encodings?
  7. Not measured: esp-dsp and esp-dl images (they need a registry download), Clang-built images, any ESP-IDF 6.x image (their 6.x toolchain, esp-15.2.0_20251204, is not installed here; this includes the pre-rev-3 encoding xespv2p1), and whether ilp32f storage is correct for these images. No refusal is not verification.
  8. Which fact should identify a P4 image beyond its declaration, so that P4 rev 3 images are admitted and S31 images are not? Candidates are the image's memory map, if the chips' linker scripts place sections differently (not checked), or a chip that the caller selects. Without one, the vendor mode admits only P4 builds before rev 3.

References

  • #7477 (D3), #8229 (ilp32), #7955 (embedded roadmap), #7490 (not-in-listing is not a decode failure)
  • docs/ghidra-riscv.md (ISA declarations), docs/ghidra-psp.md (bring-your-own extension model)
  • ESP-IDF v5.5.2: components/freertos/FreeRTOS-Kernel/portable/riscv/portasm.S, components/esp_hw_support/port/esp32p4/Kconfig.hw_support, components/esp_hw_support/CMakeLists.txt, tools/cmake/toolchain-esp32p4.cmake, components/esp_gdbstub/test_gdbstub_host/rv_decode/xesppie.S, tools/test_apps/system/gdbstub_runtime
  • Ghidra 12.1.4: Ghidra/Processors/RISCV/data/languages/riscv.custom.sinc; NationalSecurityAgency/ghidra#8848 (ratified B) and NationalSecurityAgency/ghidra#6390 (WCH vendor extension, open since 2024); b1n4ri0/RP2350_RISCV_Ghidra
  • Tools: ESP-IDF toolchain esp-14.2.0_20251107 (GCC 14.2.0, binutils 2.43.1), Ghidra 12.1.4 PUBLIC, OpenJDK 21.0.12.1
Originally created by @Entrpi on GitHub (Nov 1, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/8463 ### Before submitting - [ ] I searched the open and closed issues and pull requests for a related discussion. - [ ] 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. - [ ] This discussion does not include credentials, private samples, or sensitive target data. ### Decision needed Should the decoded-extension rule of D3 (#7477) gain a vendor-extension mode? In that mode the single-float lane would admit an RV32I image whose `Tag_RISCV_arch` declares only decoded extensions plus Espressif's `xesploop`, `xesppie` and `xespv`. After analysis, the bridge would report each instruction that Ghidra 12.1.4 could not decode or decoded only as a placeholder. REA would no longer refuse these images. ### Context and evidence Every ESP32-P4 image declares Espressif extensions, so the ilp32f lane refuses all of them. ESP-IDF v5.5.2 builds `hello_world` for P4 with these declarations (observed): - default Kconfig, chip revision < 3: `rv32i2p1_m2p0_a2p1_f2p2_c2p0_zicsr2p0_zifencei2p0_zmmul1p0_zaamo1p0_zalrsc1p0_xesploop1p0_xesppie1p0_xespv2p2` - revision 3 (`CONFIG_ESP32P4_SELECTS_REV_LESS_V3=n`): the same without `xesppie1p0`. From v5.5.6 on, rev 3 is the Kconfig default (source-derived from the tags v5.5.6, v6.0.3 and v6.1). Every ESP build that declares B also declares a vendor extension, so B support alone, such as NationalSecurityAgency/ghidra#8848, would admit no ESP build (source-derived). Espressif GCC's backend has no vendor-instruction patterns (source-derived, not run), so its C output is standard. Hand-written assembly is not: FreeRTOS saves and restores the PIE registers in every P4 image. I measured both `hello_world` builds and IDF's own `gdbstub_runtime` test app with Ghidra 12.1.4 and REA's ilp32f lane. A local experiment that only adds the names to the admission check let them through; it is not pushed. Observed: 1. **Footprint.** Each image has 32 vendor instructions out of about 45,800, all in FreeRTOS's `rtos_save_pie_coproc` (`portasm.S`). newlib, libgcc and the other IDF components contain none. The test app adds one hardware-loop setup. 2. **Ghidra fails visibly on those 32.** Their opcode classes have no RV32 constructor. Analysis records a "Bad Instruction" bookmark at the first word of each block and stops that flow: 102 of the routine's 260 bytes are disassembled. 3. **Silent cases exist.** I decoded each of IDF's 360 PIE test instructions alone (table below). Some become opaque `customN` placeholders. Some of those model writes to `s8`, `a6` or, for hardware loop 1's setup, `ra`. Others become unrelated draft instructions such as `saes32.encsm`. A hardware loop's back edge lives in loop CSRs, so Ghidra shows the body once. In the test app, `test_xesppie_loops` runs its body three times but decompiles as `custom1.rd(); return;`, with no warning. 4. **REA says nothing.** With admission alone, `rea analyze` succeeds and the ilp32f policy refuses no signature (1,340 functions, 587 definitions). No limitation mentions a decode failure. One limitation becomes false: "Every declared extension is in the set this lane decodes". Only `rea function` on the routine shows Ghidra's `halt_baddata()` warning, inside the pseudocode. 5. **Not every bad instruction is a vendor word.** Each image has 6 bookmarks: 2 PIE words, 1 intentional `unimp` in `panic_abort`, and 3 zero fills after calls to a ROM reset routine that never returns. 6. **The two PIE encodings differ.** `xesppie1p0` and `xespv2p2` encode the same instructions as different words, and a default rev < 3 image declares both. Espressif's own objdump decodes none of that image's PIE words until a copy declares only `xesppie`. <details><summary>Ghidra 12.1.4 decoding each instruction of IDF's PIE test file (rv_decode/xesppie.S), pinned RISCV:LE:32:default</summary> | Outcome | `xesppie1p0` (rev < 3) | `xespv2p2` (rev 3) | `esp.lp.*` (7 forms) | | --- | --- | --- | --- | | No constructor: on a flow, a "Bad Instruction" bookmark | 300 | 344 | 0 | | Opaque `customN` placeholder | 58 | 15 | 6 | | Unrelated draft instruction with `unimpl` p-code | 2 (`radd16`, `saes32.encsm`) | 1 (`saes32.encsm`) | 1 | | Decoded with real p-code | 0 | 0 | 0 | </details> <details><summary>The six bad-instruction bookmarks in hello_world (rev < 3)</summary> | Function | Source | Address | Word | What it is | | --- | --- | --- | --- | --- | | `rtos_save_pie_coproc` | FreeRTOS `portasm.S` | `0x4ff06506` | `8201223b` | first `esp.vst.128.ip` | | `rtos_save_pie_coproc` | FreeRTOS `portasm.S` | `0x4ff06576` | `0201223b` | first `esp.vld.128.ip` | | `panic_abort` | `esp_system/panic.c` | `0x4ff047ae` | `0000` | `unimp` | | `esp_cpu_configure_region_protection` | `esp_hw_support/cpu_region_protect.c` | `0x4000a38a`, `0x4000a39e`, `0x4000a3b2` | zero fill | after calls to `esp_rom_software_reset_system` | </details> Inferred, not measured: GCC-built ESP-IDF 5.5 P4 apps without esp-dsp, esp-dl or other hand-written PIE assembly have this same small footprint. DSP-heavy apps have many more vendor instructions, including the silent kinds. ### Expected interaction with targets - Read existing files or captured data ### Boundary details (optional) - Static only. Ghidra imports the ELF into its ephemeral database. Nothing runs, nothing is emulated, and no bytes or Ghidra files change. - Admission uses a closed list of three `Tag_RISCV_arch` names. An image that also declares any other undecoded extension stays refused. That includes B (`zba`, `zbb`, `zbc`, `zbs`) and `zcb`, `zcmp`, `zcmt`: compilers emit those in ordinary code, and Ghidra would decode Zcmp and Zcmt silently as float stores (source-derived). - Which ESP-IDF builds that admits, source-derived from the release tags (only v5.5.2 is measured): - admitted by declaration: P4 builds that declare `xesppie`, which S31 builds from 6.1 do not declare, such as v5.5.2's default build before rev 3; - admitted only with a fact that identifies a P4 image (question 8): the other P4 builds the closed list covers, such as rev 3 builds from 5.5.x, 6.0–6.0.2 and 6.1, because S31 builds from 6.1, a preview target, declare the same names; - still refused: P4 rev 3 from 6.0.3 and the next 6.1.x, which add B; S31 from the next 6.1.x, which adds B and Zcb/Zcmp/Zcmt; H4 on 6.x (B and `xespdsp`); and any P4 rev 3 or S31 build that opts in to `CONFIG_COMPILER_ENABLE_RISCV_ZCMP`, which adds Zcb/Zcmp/Zcmt. - The rule reads declarations, not chips, and an S31 6.1 image declares the same names as a P4 rev 3 image. S31 is a preview target and no S31 image was measured, so this proposal does not admit S31 on P4's evidence. The ELF records no chip: ESP-IDF's app descriptor (`esp_app_desc_t`) has no chip ID, which only the flashed image header carries (source-derived, v5.5.2). Until REA can read a fact that identifies a P4 image (question 8), an image with that shared declaration stays refused. - The ilp32f signature check and its refusal stay as they are. - Non-goals: decoding Espressif instructions, modelling PIE state or hardware loops, and changing the generic lanes. ### Options and tradeoffs **Proposed: a vendor mode with a decode report.** - **Lane.** A new lane, `elf32-exec-le-single-float-espressif-v1`, with the same pinned language, compiler specification and `__rea_ilp32f` policy. The generic lane keeps its meaning. The profile commits `riscv_vendor_extensions` (the declared names) and a report policy such as `riscv_decode_report: undecoded-instructions-v1`. REA requires the report exactly when the profile commits it, as it does for `riscv_calling_convention`, and refuses the session when the report is missing or malformed. - **Bridge.** One pass after auto-analysis and the calling-convention script, before serving. It records: - each "Bad Instruction" bookmark, with its address, word, and the function that reaches it. The function comes from the bookmark's flow source, because the failed address lies outside every function body. - each custom-0 to custom-3 placeholder, and each instruction with `unimpl` p-code (the draft constructors that some vendor words land on). - custom-1 words as hardware-loop setups: unmodelled loops whose back edge Ghidra drops, whose placeholder may also write `ra`. - an opcode class for each word: vendor-capable (custom-0 to custom-3, the 48-, 64- and 80-bit prefixes, and the RV64-only OP-32 and OP-IMM-32) or other (such as `unimp` or zero fill). This classifies the encoding space; it does not decode. - **Evidence.** A session limitation gives the counts and names up to 8 functions, bounded like the ilp32f refusal. Function queries add a limitation for an affected function. A limitation that names the undecoded vendor extensions replaces "every declared extension is decoded". - **Measured cost.** The scan took 74–87 ms inside Ghidra over 45,800–52,600 instructions (one run each), against about 15 s for the whole headless import and analysis. For hello_world the report names 3 functions and 6 addresses. - **Code: S–M.** One admission row and lane, a Java pass of about 150 lines, a bounded handshake report and its parser, limitation text, a verifier fixture and docs. **Alternatives.** 1. **Keep refusing.** No cost, but P4 cannot be analyzed through Ghidra at all, although 99.9 % of hello_world's instructions are standard. 2. **Admit without a report.** Measured above: REA's Evidence becomes silent or false. Not recommended. 3. **A caller-installed decoder extension, on the PSP `ghidra-allegrex` model** (`docs/ghidra-psp.md`): REA fingerprints a bring-your-own extension and pins its language. This gives the best fidelity, but no such extension exists. Ghidra has no issue or PR for Espressif extensions. `b1n4ri0/RP2350_RISCV_Ghidra` patches the stock RISCV language in place, so REA could not pin it separately. An extension would need both PIE encodings, a way to choose one that does not rely on `Tag_RISCV_arch` alone, the Q/QACC/XACC state and hardware-loop flow. That is large work, better owned by Espressif or the community. The vendor mode stays useful until then and could select such an extension later. 4. **Report in every RISC-V lane.** The non-vendor failures above probably occur in C3, C6 and H4 images that REA admits today (not checked). This changes existing lanes' Evidence and snapshots, so it is a separate decision. 5. **Neutralize vendor words before import, or ship a modified Ghidra language.** This conflicts with REA's immutable-source and bring-your-own-Ghidra rules. Not proposed. ### Verification available so far I have a prototype or observed results ### Success criteria and open questions **Proposed verification** in `npm run verify:ghidra:riscv`, which acquires no tools: - A fixture assembled from committed sources with the existing LLVM tools. Vendor words go in as `.4byte` values: measured words of both PIE encodings, custom-2 and custom-3 placeholders, `esp.lp.setup` for loops 0 and 1, and `esp.lp.count`. The fixture also holds an `unimp`, and a call to an unknown routine followed by zero fill. `llvm-objcopy --update-section` then writes the rev < 3 and rev 3 attribute strings, like the lane's existing header mutations. - Over CLI and MCP, the report's counts, addresses, classes and functions equal the fixture's known layout, and they survive snapshot save and reopen. Adding `zbb` or `zcmp` to the declaration keeps the image refused. Generic-lane profile digests do not change. - An optional cross-check against a caller-supplied Espressif objdump. Calibration on locally built ESP-IDF images stays supplemental and is never committed. **Open questions** 1. A new lane id, or a vendor field in the existing single-float lane? 2. Report only in the vendor mode (proposed), or in every RISC-V lane? 3. Admit `xespdsp` now? No admissible image declares it without B, and its encodings are unmeasured. Proposed: not yet. 4. Admit by name only? Versions change the encoding (`xespv2p1`, `xespv2p2`). Without decoding, the name is enough for admission; the version matters only for classification and for a future decoder. 5. How many functions and addresses should the report name? Should a function's limitation also give how many bytes of its ELF symbol stay undisassembled? REA does not read ELF symbol sizes today. 6. Should a custom-1 word count as a hardware-loop setup only when its fields match Espressif's `esp.lp.*` encodings? 7. Not measured: esp-dsp and esp-dl images (they need a registry download), Clang-built images, any ESP-IDF 6.x image (their 6.x toolchain, `esp-15.2.0_20251204`, is not installed here; this includes the pre-rev-3 encoding `xespv2p1`), and whether ilp32f storage is correct for these images. No refusal is not verification. 8. Which fact should identify a P4 image beyond its declaration, so that P4 rev 3 images are admitted and S31 images are not? Candidates are the image's memory map, if the chips' linker scripts place sections differently (not checked), or a chip that the caller selects. Without one, the vendor mode admits only P4 builds before rev 3. ### References - #7477 (D3), #8229 (ilp32), #7955 (embedded roadmap), #7490 (`not-in-listing` is not a decode failure) - `docs/ghidra-riscv.md` (ISA declarations), `docs/ghidra-psp.md` (bring-your-own extension model) - ESP-IDF v5.5.2: `components/freertos/FreeRTOS-Kernel/portable/riscv/portasm.S`, `components/esp_hw_support/port/esp32p4/Kconfig.hw_support`, `components/esp_hw_support/CMakeLists.txt`, `tools/cmake/toolchain-esp32p4.cmake`, `components/esp_gdbstub/test_gdbstub_host/rv_decode/xesppie.S`, `tools/test_apps/system/gdbstub_runtime` - Ghidra 12.1.4: `Ghidra/Processors/RISCV/data/languages/riscv.custom.sinc`; NationalSecurityAgency/ghidra#8848 (ratified B) and NationalSecurityAgency/ghidra#6390 (WCH vendor extension, open since 2024); [b1n4ri0/RP2350_RISCV_Ghidra](https://github.com/b1n4ri0/RP2350_RISCV_Ghidra) - Tools: ESP-IDF toolchain `esp-14.2.0_20251107` (GCC 14.2.0, binutils 2.43.1), Ghidra 12.1.4 PUBLIC, OpenJDK 21.0.12.1
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#6613
No description provided.