* fix(native): find procedures by the secondary names exact lookup accepts search_procedures matched only each procedure's primary name, while exact lookup also accepts Kuna inventory aliases (versioned-symbol and generated sub_ names) and Ghidra symbols at an exact function entry. A search for a name procedure_address resolves returned nothing, and trace_feature silently missed the procedure. Both providers now match the same names their exact lookup accepts. A procedure still appears once under its primary name; the optional matched_aliases field lists the secondary names that matched, so aliases never become procedures of their own and list_procedures is unchanged. The shared domain helper owns that row rule for Kuna and for the Ghidra host-side Unicode folding pass. The Ghidra analysis profile records the new search semantics so older snapshots cannot replay alias-blind results. Fixes #8330 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(ghidra): match leaf spellings of procedure names in search procedure_address accepts each entry symbol's leaf or namespace-qualified spelling, but procedure search tested only qualified names, so a regex such as ^audit_alias$ missed a secondary symbol ns::audit_alias (and ^same$ missed a primary alpha::same) that exact lookup selects. Lookup and search now share one bridge definition of the names that select a procedure, so they cannot drift. Matching secondary symbols are still reported by their qualified names; because a leaf ends its qualified spelling, the host's Unicode literal pass stays exact over those names. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
88 lines
2.6 KiB
TypeScript
88 lines
2.6 KiB
TypeScript
import { writeFile } from "node:fs/promises";
|
|
import { join } from "node:path";
|
|
import { describe, expect } from "vitest";
|
|
|
|
import { elf } from "../../../src/domain/binaryTarget.fixture.js";
|
|
import { createTestTempDirectory } from "../../fixtures/temporaryDirectory.js";
|
|
import { cliTest } from "../../support/cli/cliFixture.js";
|
|
import { writeFakeKuna } from "../providers/kuna/fakeKuna.js";
|
|
|
|
describe("procedure alias search CLI", () => {
|
|
cliTest(
|
|
"finds and traces a procedure by an alias exact lookup accepts",
|
|
async ({ cli }) => {
|
|
const root = await createTestTempDirectory("rea-alias-search-cli-");
|
|
const kuna = await writeFakeKuna(root, {
|
|
functions: [
|
|
{ name: "main", addr: "0x1000" },
|
|
{
|
|
name: "audit_v1",
|
|
addr: "0x1334",
|
|
aliases: ["audit_transform", "sub_1334"],
|
|
},
|
|
{
|
|
name: "audit_v2",
|
|
addr: "0x133a",
|
|
aliases: ["audit_transform", "sub_133a"],
|
|
},
|
|
],
|
|
});
|
|
const target = join(root, "target.elf");
|
|
await writeFile(target, elf(2, 1, 62));
|
|
const run = async (...arguments_: string[]) => {
|
|
const result = await cli.run({
|
|
arguments: [...arguments_, "--provider", "kuna", "--format", "json"],
|
|
cwd: root,
|
|
environment: {
|
|
REA_LOG_LEVEL: "silent",
|
|
REA_KUNA_COMMAND: kuna,
|
|
REA_KUNA_CACHE_DIR: join(root, "cache"),
|
|
},
|
|
});
|
|
expect(result.exitCode, JSON.stringify(result.json)).toBe(0);
|
|
return result.json;
|
|
};
|
|
|
|
expect(
|
|
await run(
|
|
"search",
|
|
target,
|
|
"audit_transform",
|
|
"--kind",
|
|
"procedures",
|
|
"--mode",
|
|
"regex",
|
|
),
|
|
).toMatchObject({
|
|
operation: "search_procedures",
|
|
normalized_result: [
|
|
{
|
|
address: "0x1334",
|
|
value: "audit_v1",
|
|
matched_aliases: ["audit_transform"],
|
|
},
|
|
{
|
|
address: "0x133a",
|
|
value: "audit_v2",
|
|
matched_aliases: ["audit_transform"],
|
|
},
|
|
],
|
|
});
|
|
expect(await run("trace", target, "sub_1334")).toMatchObject({
|
|
operation: "trace_feature",
|
|
normalized_result: {
|
|
matches: [
|
|
{
|
|
type: "procedure",
|
|
address: "0x1334",
|
|
value: "audit_v1",
|
|
matched_aliases: ["sub_1334"],
|
|
},
|
|
],
|
|
references: [{ target_address: "0x1334", source_address: "0x1004" }],
|
|
},
|
|
});
|
|
},
|
|
);
|
|
});
|