diff --git a/bridge/ghidra/ReaGhidraBridge.java b/bridge/ghidra/ReaGhidraBridge.java index 25256fcc90..af473c070b 100644 --- a/bridge/ghidra/ReaGhidraBridge.java +++ b/bridge/ghidra/ReaGhidraBridge.java @@ -1337,12 +1337,7 @@ public final class ReaGhidraBridge extends HeadlessScript { result.add("references", references); if (includeIncoming) { TreeMap incoming = new TreeMap<>(); - ReferenceIterator incomingIterator = currentProgram.getReferenceManager().getReferencesTo(address); - while (incomingIterator.hasNext()) { - monitor.checkCancelled(); - Reference reference = incomingIterator.next(); - if (!reference.isEntryPointReference()) addReference(incoming, reference); - } + visitObservedReferencesTo(address, reference -> addReference(incoming, reference)); List orderedIncoming = new ArrayList<>(incoming.values()); orderedIncoming.sort(REFERENCE_ORDER); JsonArray incomingReferences = new JsonArray(); @@ -1394,16 +1389,8 @@ public final class ReaGhidraBridge extends HeadlessScript { requireKeys(params, Set.of("document", "address")); requireDocument(params); Address address = requireAddress(params, "address"); - ReferenceIterator references = currentProgram.getReferenceManager().getReferencesTo(address); Set
sources = new HashSet<>(); - while (references.hasNext()) { - monitor.checkCancelled(); - Reference reference = references.next(); - if (reference.isEntryPointReference()) { - continue; - } - sources.add(reference.getFromAddress()); - } + visitObservedReferencesTo(address, reference -> sources.add(reference.getFromAddress())); List
ordered = new ArrayList<>(sources); ordered.sort(Address::compareTo); JsonArray result = new JsonArray(); @@ -3674,24 +3661,36 @@ public final class ReaGhidraBridge extends HeadlessScript { monitor.checkCancelled(); Address address = addresses.next(); if (outgoing) { - for (Reference reference : currentProgram.getReferenceManager() - .getReferencesFrom(address)) { - monitor.checkCancelled(); - if (!reference.isEntryPointReference()) visitor.accept(reference); - } + visitObservedReferencesFrom(address, visitor); } else { - ReferenceIterator iterator = currentProgram.getReferenceManager() - .getReferencesTo(address); - while (iterator.hasNext()) { - monitor.checkCancelled(); - Reference reference = iterator.next(); - if (!reference.isEntryPointReference()) visitor.accept(reference); - } + visitObservedReferencesTo(address, visitor); } } } + private void visitObservedReferencesFrom(Address address, ReferenceVisitor visitor) + throws Exception { + for (Reference reference : currentProgram.getReferenceManager().getReferencesFrom(address)) { + monitor.checkCancelled(); + visitObservedReference(reference, visitor); + } + } + + private void visitObservedReferencesTo(Address address, ReferenceVisitor visitor) + throws Exception { + ReferenceIterator references = currentProgram.getReferenceManager().getReferencesTo(address); + while (references.hasNext()) { + monitor.checkCancelled(); + visitObservedReference(references.next(), visitor); + } + } + + private static void visitObservedReference(Reference reference, ReferenceVisitor visitor) + throws Exception { + if (!reference.isEntryPointReference()) visitor.accept(reference); + } + private static void addReference(TreeMap observed, Reference reference) { String key = canonicalAddress(reference.getFromAddress()) + "\u0000" + canonicalAddress(reference.getToAddress()) + "\u0000" + diff --git a/src/ghidra/GhidraAnalysisProfile.ts b/src/ghidra/GhidraAnalysisProfile.ts index 01e87ac6b3..7d6a8e1223 100644 --- a/src/ghidra/GhidraAnalysisProfile.ts +++ b/src/ghidra/GhidraAnalysisProfile.ts @@ -42,6 +42,8 @@ import { } from "../domain/native/nativeAotPe.js"; const callRelationshipCoverage = "function-body-call-coverage-v5"; +const instructionReferenceCoverage = + "exact-address-incoming-without-synthetic-entry-v2"; /** * The processor language REA pins for this target, or undefined when Ghidra may @@ -136,7 +138,7 @@ export const resolveGhidraAnalysisProfile = async ( procedure_file_offset_resolution: "address-first-unique-target-source-mapping-v2", instruction_flow_evidence: "decoded-return-pcode-v1", - instruction_references: "exact-address-incoming-v1", + instruction_references: instructionReferenceCoverage, function_boundary_observations: "ghidra-function-boundary-limitations-v3", no_return_repair: @@ -236,7 +238,7 @@ export const resolveGhidraAnalysisProfile = async ( procedure_file_offset_resolution: "address-first-unique-target-source-mapping-v2", instruction_flow_evidence: "decoded-return-pcode-v1", - instruction_references: "exact-address-incoming-v1", + instruction_references: instructionReferenceCoverage, function_boundary_observations: "ghidra-function-boundary-limitations-v3", no_return_repair: diff --git a/src/ghidra/GhidraSnapshotCache.test.ts b/src/ghidra/GhidraSnapshotCache.test.ts index fa7b35c224..16dad277d8 100644 --- a/src/ghidra/GhidraSnapshotCache.test.ts +++ b/src/ghidra/GhidraSnapshotCache.test.ts @@ -192,7 +192,12 @@ describe("Ghidra snapshot profile admission", () => { it.each([ { parameter: "instruction_references", - current: "exact-address-incoming-v1", + current: "exact-address-incoming-without-synthetic-entry-v2", + legacy: "exact-address-incoming-v1", + }, + { + parameter: "instruction_references", + current: "exact-address-incoming-without-synthetic-entry-v2", legacy: undefined, }, {