[GH-ISSUE #1186] [Bug] rea xrefs rejects the symbol-name selector its help advertises #419

Closed
opened 2026-10-15 18:24:54 +00:00 by bsakaguchi · 0 comments
Owner

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

Before submitting

  • I searched the open and closed issues for a related report.
  • I removed credentials, tokens, private paths, and sensitive target data.

Area

CLI

Observed behavior

The Ghidra-backed rea xrefs CLI rejects a valid analyzed symbol name even though both its positional selector and --address option explicitly accept an "Address or symbol name." The rejection happens in input validation, before the provider can resolve the symbol. Supplying the canonical address returns the expected references. This affects the named-selector workflow; address-based inspection remains available.

Both named-selector forms reject _table_only with the following meaningful error fields on the release and main build:

{
  "code": "invalid_request",
  "details": {
    "operation": "xrefs",
    "issues": [{
      "path": ["address"],
      "reason": "invalid_format",
      "message": "Use hexadecimal digits, optionally prefixed with 0x, or an encoded address-space name followed by :0x and hexadecimal digits",
      "expected": "regex"
    }]
  }
}

The release CLI's address control exits 0 and its Evidence normalized_result contains ["0x1000006a4", "0x100008008", "0x10000c118"]. On both tested MCP servers, procedure_address with {"procedure":"_table_only"} resolves to 0x100000598, and xrefs with that address returns the same three reference-source addresses. An independent direct-Ghidra script imported a copy with default auto-analysis, reported _table_only at the same entry, and reported those references through ReferenceManager. The symbol is a function's actual analyzed name, so this is distinct from the imported _main alias selection tracked in issue #1170.

Reproduction

Use the runtime baselines below with an existing Ghidra installation and full JDK. Save this fixture as fixture.c:

#include <stdio.h>
typedef unsigned short char16_t;
const char *utf8 = "REA café 日本語";
const char16_t utf16[] = u"REA wide Ω string";
volatile int state;
__attribute__((noinline)) int table_only(int x) { return x + 37; }
int (*volatile pointer_table[])(int) = { table_only };
__attribute__((noinline)) int recur(int x) { return x ? x + recur(x-1) : 0; }
__attribute__((noinline)) int leaf(int x) { puts("REA leaf text"); return x*3; }
__attribute__((noinline)) int entry(int x) { state = utf16[1]; puts(utf8); return leaf(x)+recur(x)+pointer_table[0](x); }
int main(int argc, char **argv) { return entry(argc); }

Compile the thin arm64 fixture and inspect the CLI's selector contract:

clang -O0 -arch arm64 fixture.c -o c-arm64
export GHIDRA_INSTALL_DIR=/path/to/ghidra_12.1.4_PUBLIC
export JAVA_HOME=/path/to/jdk-21
npx -y rea-agents@6.1.0 xrefs --help
npx -y rea-agents@6.1.0 search ./c-arm64 '.*' --kind procedures --mode regex --provider ghidra --json
npx -y rea-agents@6.1.0 xrefs ./c-arm64 _table_only --provider ghidra --json
npx -y rea-agents@6.1.0 xrefs ./c-arm64 --address _table_only --provider ghidra --json

Both named-selector calls exit 1. The procedure search returns _table_only at 0x100000598 for the observed build. Use the address returned for your build as the control:

npx -y rea-agents@6.1.0 xrefs ./c-arm64 0x100000598 --provider ghidra --json

Repeat the two failing calls with node /path/to/rea/scripts/rea.mjs in place of the package runner to confirm the main-build behavior. The known fixture is not claimed to be minimized.

Expected behavior

The xrefs command's help declares the positional address argument to be an "Address or symbol name" and describes --address identically. A valid exact analyzed symbol should therefore select the same address and return the same references as that address's canonical hexadecimal spelling.

Impact and scope

A documented CLI selector fails deterministically for an ordinary valid analyzed symbol, blocking name-based cross-reference inspection while preserving address-based inspection. Impact assessment: P2 (supported).

Workaround (available): Resolve the symbol from procedure search or the MCP name inventory, then pass its canonical address; the release CLI and both tested MCP servers returned the independently observed references for that address.

REA version

rea-agents@6.1.0 from npm, and main at b34bdcdb28 built locally with npm ci && npm run build:cached.

Runtime and platform

  • Release: rea-agents@6.1.0 from npm.
  • Main build: morluto/rea commit b34bdcdb2877be394c59c9cbf70269dc1841ff78, using its already-built CLI and MCP entry point.
  • Provider: Ghidra 12.1.4 with the macOS arm64 native decompiler, default auto-analysis, and no added extensions.
  • Java: Homebrew OpenJDK 21.0.12.1, 64-bit full JDK.
  • Node: v24.21.0.
  • Host: macOS 27.0.1 arm64, Apple clang, and Xcode command-line tools.

Target and artifact context

Thin arm64 Mach-O C executable (Ghidra provider)

Interface

CLI

Earliest failure stage

Request parsing or validation

Relevant output or evidence

  • Expected source: The observed rea xrefs --help argument and option descriptions on the tested entry points; source locator src/cli/coreBinaryCommands.ts:195 and :203 declares "Address or symbol name" for both forms.
  • Failure source: The two executed named-selector forms above returned exit 1 with details.operation: "xrefs", path: ["address"], and reason: "invalid_format"; the release CLI address control and both MCP address controls returned the oracle's three source addresses. Source breadcrumbs are src/cli/coreBinaryCommands.ts:217, which forwards the selector as address, and src/ghidra/GhidraFunctionValues.ts:104, which admits only hexadecimal address syntax.
  • Evidence provenance: observed
  • Local verification: reproduced
  • Reproduction completeness: complete

Typed outcome or recovery expected

For the same fixture, both rea xrefs ./c-arm64 _table_only --provider ghidra --json and the equivalent --address _table_only form must exit 0 and return the same reference-source addresses as xrefs with _table_only's canonical entry address. Confirm the named selector against the actual analyzed inventory, retain the existing hexadecimal-address behavior, and keep a nonexistent name distinguishable from a resolved symbol with no references. A change that only removes "symbol name" from help would abandon the advertised workflow rather than restore it.

Analysis or suspected cause

No response

Additional context

Read-only deduplication checked the latest 300 open and closed issue titles and searched all issues for xrefs symbol and xref name; no matching issue appeared. This report concerns the CLI's advertised selector contract. MCP xrefs itself advertises an address, and its address behavior matched the oracle.

Originally created by @coygeek on GitHub (Oct 9, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/1186 ### Before submitting - [x] I searched the open and closed issues for a related report. - [x] I removed credentials, tokens, private paths, and sensitive target data. ### Area CLI ### Observed behavior The Ghidra-backed `rea xrefs` CLI rejects a valid analyzed symbol name even though both its positional selector and `--address` option explicitly accept an "Address or symbol name." The rejection happens in input validation, before the provider can resolve the symbol. Supplying the canonical address returns the expected references. This affects the named-selector workflow; address-based inspection remains available. Both named-selector forms reject `_table_only` with the following meaningful error fields on the release and main build: ```json { "code": "invalid_request", "details": { "operation": "xrefs", "issues": [{ "path": ["address"], "reason": "invalid_format", "message": "Use hexadecimal digits, optionally prefixed with 0x, or an encoded address-space name followed by :0x and hexadecimal digits", "expected": "regex" }] } } ``` The release CLI's address control exits 0 and its Evidence `normalized_result` contains `["0x1000006a4", "0x100008008", "0x10000c118"]`. On both tested MCP servers, `procedure_address` with `{"procedure":"_table_only"}` resolves to `0x100000598`, and `xrefs` with that address returns the same three reference-source addresses. An independent direct-Ghidra script imported a copy with default auto-analysis, reported `_table_only` at the same entry, and reported those references through `ReferenceManager`. The symbol is a function's actual analyzed name, so this is distinct from the imported `_main` alias selection tracked in issue #1170. ### Reproduction Use the runtime baselines below with an existing Ghidra installation and full JDK. Save this fixture as `fixture.c`: ```c #include <stdio.h> typedef unsigned short char16_t; const char *utf8 = "REA café 日本語"; const char16_t utf16[] = u"REA wide Ω string"; volatile int state; __attribute__((noinline)) int table_only(int x) { return x + 37; } int (*volatile pointer_table[])(int) = { table_only }; __attribute__((noinline)) int recur(int x) { return x ? x + recur(x-1) : 0; } __attribute__((noinline)) int leaf(int x) { puts("REA leaf text"); return x*3; } __attribute__((noinline)) int entry(int x) { state = utf16[1]; puts(utf8); return leaf(x)+recur(x)+pointer_table[0](x); } int main(int argc, char **argv) { return entry(argc); } ``` Compile the thin arm64 fixture and inspect the CLI's selector contract: ```sh clang -O0 -arch arm64 fixture.c -o c-arm64 export GHIDRA_INSTALL_DIR=/path/to/ghidra_12.1.4_PUBLIC export JAVA_HOME=/path/to/jdk-21 npx -y rea-agents@6.1.0 xrefs --help npx -y rea-agents@6.1.0 search ./c-arm64 '.*' --kind procedures --mode regex --provider ghidra --json npx -y rea-agents@6.1.0 xrefs ./c-arm64 _table_only --provider ghidra --json npx -y rea-agents@6.1.0 xrefs ./c-arm64 --address _table_only --provider ghidra --json ``` Both named-selector calls exit 1. The procedure search returns `_table_only` at `0x100000598` for the observed build. Use the address returned for your build as the control: ```sh npx -y rea-agents@6.1.0 xrefs ./c-arm64 0x100000598 --provider ghidra --json ``` Repeat the two failing calls with `node /path/to/rea/scripts/rea.mjs` in place of the package runner to confirm the main-build behavior. The known fixture is not claimed to be minimized. ### Expected behavior The `xrefs` command's help declares the positional `address` argument to be an "Address or symbol name" and describes `--address` identically. A valid exact analyzed symbol should therefore select the same address and return the same references as that address's canonical hexadecimal spelling. ### Impact and scope A documented CLI selector fails deterministically for an ordinary valid analyzed symbol, blocking name-based cross-reference inspection while preserving address-based inspection. Impact assessment: P2 (supported). Workaround (available): Resolve the symbol from procedure search or the MCP name inventory, then pass its canonical address; the release CLI and both tested MCP servers returned the independently observed references for that address. ### REA version `rea-agents@6.1.0` from npm, and `main` at b34bdcdb2877be394c59c9cbf70269dc1841ff78 built locally with `npm ci && npm run build:cached`. ### Runtime and platform - Release: `rea-agents@6.1.0` from npm. - Main build: `morluto/rea` commit `b34bdcdb2877be394c59c9cbf70269dc1841ff78`, using its already-built CLI and MCP entry point. - Provider: Ghidra 12.1.4 with the macOS arm64 native decompiler, default auto-analysis, and no added extensions. - Java: Homebrew OpenJDK 21.0.12.1, 64-bit full JDK. - Node: v24.21.0. - Host: macOS 27.0.1 arm64, Apple clang, and Xcode command-line tools. ### Target and artifact context Thin arm64 Mach-O C executable (Ghidra provider) ### Interface CLI ### Earliest failure stage Request parsing or validation ### Relevant output or evidence - Expected source: The observed `rea xrefs --help` argument and option descriptions on the tested entry points; source locator `src/cli/coreBinaryCommands.ts:195` and `:203` declares "Address or symbol name" for both forms. - Failure source: The two executed named-selector forms above returned exit 1 with `details.operation: "xrefs"`, `path: ["address"]`, and `reason: "invalid_format"`; the release CLI address control and both MCP address controls returned the oracle's three source addresses. Source breadcrumbs are `src/cli/coreBinaryCommands.ts:217`, which forwards the selector as `address`, and `src/ghidra/GhidraFunctionValues.ts:104`, which admits only hexadecimal address syntax. - Evidence provenance: observed - Local verification: reproduced - Reproduction completeness: complete ### Typed outcome or recovery expected For the same fixture, both `rea xrefs ./c-arm64 _table_only --provider ghidra --json` and the equivalent `--address _table_only` form must exit 0 and return the same reference-source addresses as `xrefs` with `_table_only`'s canonical entry address. Confirm the named selector against the actual analyzed inventory, retain the existing hexadecimal-address behavior, and keep a nonexistent name distinguishable from a resolved symbol with no references. A change that only removes "symbol name" from help would abandon the advertised workflow rather than restore it. ### Analysis or suspected cause _No response_ ### Additional context Read-only deduplication checked the latest 300 open and closed issue titles and searched all issues for `xrefs symbol` and `xref name`; no matching issue appeared. This report concerns the CLI's advertised selector contract. MCP `xrefs` itself advertises an address, and its address behavior matched the oracle.
bsakaguchi 2026-10-15 18:24:54 +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#419
No description provided.