fix(ghidra): preserve MIPS overrides and filter entry metadata

This commit is contained in:
morluto committed 2026-10-15 03:43:29 +08:00
1 parent 6add17a317
commit 50dd9fcad1
3 files changed
+57 -1

No files matched your search

+2 -1
View File
@@ -1340,7 +1340,8 @@ public final class ReaGhidraBridge extends HeadlessScript {
ReferenceIterator incomingIterator = currentProgram.getReferenceManager().getReferencesTo(address);
while (incomingIterator.hasNext()) {
monitor.checkCancelled();
addReference(incoming, incomingIterator.next());
Reference reference = incomingIterator.next();
if (!reference.isEntryPointReference()) addReference(incoming, reference);
}
List<Reference> orderedIncoming = new ArrayList<>(incoming.values());
orderedIncoming.sort(REFERENCE_ORDER);
+4
View File
@@ -14,6 +14,7 @@ import type { AnalysisError } from "../domain/analysisErrorBase.js";
import { err, ok, type Result } from "../domain/result.js";
import type { GhidraInstallationInspection } from "./GhidraInstallation.js";
import {
isLegacyMipsAdmission,
ghidraMipsProfileParameters,
ghidraMipsLanguageOverride,
} from "./GhidraMipsProfile.js";
@@ -164,9 +165,12 @@ export const resolveGhidraAnalysisProfile = async (
const dosCom = target.format === "dos-com";
const dos = dosMz || dosCom;
const pinnedLanguage = ghidraPinnedLanguage(target);
const callerMaySelectLegacyMipsLanguage =
target.architecture === "mips" && isLegacyMipsAdmission(target);
if (
pinnedLanguage !== undefined &&
target.architecture !== "powerpc" &&
!callerMaySelectLegacyMipsLanguage &&
languageOverride !== undefined &&
(languageOverride.languageId !== pinnedLanguage.languageId ||
(languageOverride.compilerSpecId !== undefined &&
+51
View File
@@ -39,6 +39,16 @@ const X86_LDEFS = `<?xml version="1.0" encoding="UTF-8"?>
</language_definitions>
`;
const MIPS_LDEFS = `<?xml version="1.0" encoding="UTF-8"?>
<language_definitions>
<language processor="MIPS" endian="little" size="32" variant="default"
id="MIPS:LE:32:default">
<description>MIPS 32-bit little endian</description>
<compiler name="default" spec="mips32.cspec" id="default"/>
</language>
</language_definitions>
`;
const pe: BinaryTarget = {
path: "/fixture.exe",
sha256: "a".repeat(64),
@@ -50,6 +60,23 @@ const pe: BinaryTarget = {
managed: false,
};
const legacyMips: BinaryTarget = {
path: "/fixture-mips.elf",
sha256: "b".repeat(64),
kind: "executable",
format: "elf",
architecture: "mips",
availableArchitectures: ["mips"],
mips: {
elfClass: 32,
byteOrder: "little",
type: 2,
flags: 0x50000001,
abiFlags: null,
gnuAttributes: null,
},
};
let installDir = "";
beforeAll(async () => {
installDir = await mkdtemp(join(tmpdir(), "rea-ghidra-languages-"));
@@ -276,6 +303,30 @@ describe("Ghidra language override profile", () => {
});
});
it("accepts the caller-selected language on the legacy MIPS lane", async () => {
const mipsLanguages = join(
installDir,
"Ghidra/Processors/MIPS/data/languages",
);
await mkdir(mipsLanguages, { recursive: true });
const definition = join(mipsLanguages, "mips.ldefs");
await writeFile(definition, MIPS_LDEFS);
try {
const resolved = await provider({
REA_GHIDRA_LANGUAGE_ID: "MIPS:LE:32:default",
REA_GHIDRA_COMPILER_SPEC_ID: "default",
}).resolveAnalysisProfile(legacyMips);
if (!resolved.ok) throw resolved.error;
expect(resolved.value.profile?.parameters).toMatchObject({
language_id: "MIPS:LE:32:default",
compiler_spec_id: "default",
language_selection: "configured-v1",
});
} finally {
await rm(mipsLanguages, { recursive: true, force: true });
}
});
it("records the language default when no compiler spec is configured", async () => {
const resolved = await provider({
REA_GHIDRA_LANGUAGE_ID: "x86:LE:32:default",