mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-04 10:19:23 +02:00
GT-2848: Refactor DependencyGraph with Deterministic version
This commit is contained in:
parent
dace9682fb
commit
fa558af9c2
11 changed files with 744 additions and 343 deletions
|
@ -22,6 +22,7 @@ import ghidra.program.model.listing.*;
|
|||
import ghidra.program.model.symbol.Reference;
|
||||
import ghidra.program.model.symbol.ReferenceManager;
|
||||
import ghidra.util.exception.CancelledException;
|
||||
import ghidra.util.graph.AbstractDependencyGraph;
|
||||
import ghidra.util.graph.DependencyGraph;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
|
||||
|
@ -84,10 +85,10 @@ public class AcyclicCallGraphBuilder {
|
|||
* @return the DependencyGraph for the acyclic call graph represented by this object.
|
||||
* @throws CancelledException if the monitor was cancelled.
|
||||
*/
|
||||
public DependencyGraph<Address> getDependencyGraph(TaskMonitor monitor)
|
||||
public AbstractDependencyGraph<Address> getDependencyGraph(TaskMonitor monitor)
|
||||
throws CancelledException {
|
||||
|
||||
DependencyGraph<Address> graph = new DependencyGraph<>();
|
||||
AbstractDependencyGraph<Address> graph = new DependencyGraph<>();
|
||||
Deque<Address> startPoints = findStartPoints();
|
||||
Set<Address> unprocessed = new TreeSet<>(functionSet); // reliable processing order
|
||||
|
||||
|
@ -158,7 +159,7 @@ public class AcyclicCallGraphBuilder {
|
|||
children.toArray(node.children);
|
||||
}
|
||||
|
||||
private void processForward(DependencyGraph<Address> graph, Set<Address> unprocessed,
|
||||
private void processForward(AbstractDependencyGraph<Address> graph, Set<Address> unprocessed,
|
||||
Address startFunction, TaskMonitor monitor) throws CancelledException {
|
||||
VisitStack stack = new VisitStack(startFunction);
|
||||
StackNode curnode = stack.peek();
|
||||
|
|
|
@ -27,7 +27,7 @@ import ghidra.program.model.*;
|
|||
import ghidra.program.model.address.*;
|
||||
import ghidra.program.model.listing.*;
|
||||
import ghidra.program.model.symbol.ReferenceManager;
|
||||
import ghidra.util.graph.DependencyGraph;
|
||||
import ghidra.util.graph.AbstractDependencyGraph;
|
||||
|
||||
public class AcyclicCallGraphBuilderTest extends AbstractGenericTest {
|
||||
|
||||
|
@ -102,7 +102,7 @@ public class AcyclicCallGraphBuilderTest extends AbstractGenericTest {
|
|||
node(3, 4);
|
||||
|
||||
AcyclicCallGraphBuilder builder = new AcyclicCallGraphBuilder(program, functions, false);
|
||||
DependencyGraph<Address> graph = builder.getDependencyGraph(DUMMY_MONITOR);
|
||||
AbstractDependencyGraph<Address> graph = builder.getDependencyGraph(DUMMY_MONITOR);
|
||||
|
||||
Assert.assertEquals(4, graph.size());
|
||||
|
||||
|
@ -119,7 +119,7 @@ public class AcyclicCallGraphBuilderTest extends AbstractGenericTest {
|
|||
node(2,3);
|
||||
|
||||
AcyclicCallGraphBuilder builder = new AcyclicCallGraphBuilder(program,functions,false);
|
||||
DependencyGraph<Address> graph = builder.getDependencyGraph(DUMMY_MONITOR);
|
||||
AbstractDependencyGraph<Address> graph = builder.getDependencyGraph(DUMMY_MONITOR);
|
||||
|
||||
Assert.assertEquals(3, graph.size());
|
||||
|
||||
|
@ -135,7 +135,7 @@ public class AcyclicCallGraphBuilderTest extends AbstractGenericTest {
|
|||
node(3, 1);
|
||||
|
||||
AcyclicCallGraphBuilder builder = new AcyclicCallGraphBuilder(program, functions, false);
|
||||
DependencyGraph<Address> graph = builder.getDependencyGraph(DUMMY_MONITOR);
|
||||
AbstractDependencyGraph<Address> graph = builder.getDependencyGraph(DUMMY_MONITOR);
|
||||
|
||||
Assert.assertEquals(3, graph.size());
|
||||
|
||||
|
@ -152,7 +152,7 @@ public class AcyclicCallGraphBuilderTest extends AbstractGenericTest {
|
|||
node(2, 2);
|
||||
|
||||
AcyclicCallGraphBuilder builder = new AcyclicCallGraphBuilder(program, functions, false);
|
||||
DependencyGraph<Address> graph = builder.getDependencyGraph(DUMMY_MONITOR);
|
||||
AbstractDependencyGraph<Address> graph = builder.getDependencyGraph(DUMMY_MONITOR);
|
||||
|
||||
Assert.assertEquals(3, graph.size());
|
||||
|
||||
|
@ -168,7 +168,7 @@ public class AcyclicCallGraphBuilderTest extends AbstractGenericTest {
|
|||
node(3, 1);
|
||||
|
||||
AcyclicCallGraphBuilder builder = new AcyclicCallGraphBuilder(program, functions, false);
|
||||
DependencyGraph<Address> graph = builder.getDependencyGraph(DUMMY_MONITOR);
|
||||
AbstractDependencyGraph<Address> graph = builder.getDependencyGraph(DUMMY_MONITOR);
|
||||
|
||||
Assert.assertEquals(3, graph.size());
|
||||
|
||||
|
@ -197,7 +197,7 @@ public class AcyclicCallGraphBuilderTest extends AbstractGenericTest {
|
|||
thunkNode(17, 18, false);
|
||||
|
||||
AcyclicCallGraphBuilder builder = new AcyclicCallGraphBuilder(program, functions, false);
|
||||
DependencyGraph<Address> graph = builder.getDependencyGraph(DUMMY_MONITOR);
|
||||
AbstractDependencyGraph<Address> graph = builder.getDependencyGraph(DUMMY_MONITOR);
|
||||
|
||||
Assert.assertEquals(18, graph.size());
|
||||
|
||||
|
@ -241,7 +241,7 @@ public class AcyclicCallGraphBuilderTest extends AbstractGenericTest {
|
|||
thunkNode(17, 18, false);
|
||||
|
||||
AcyclicCallGraphBuilder builder = new AcyclicCallGraphBuilder(program, functions, true);
|
||||
DependencyGraph<Address> graph = builder.getDependencyGraph(DUMMY_MONITOR);
|
||||
AbstractDependencyGraph<Address> graph = builder.getDependencyGraph(DUMMY_MONITOR);
|
||||
|
||||
Assert.assertEquals(8, graph.size());
|
||||
|
||||
|
@ -265,7 +265,7 @@ public class AcyclicCallGraphBuilderTest extends AbstractGenericTest {
|
|||
|
||||
thunkNode(5, 3, true); // Thunk node hits recursion from different point
|
||||
AcyclicCallGraphBuilder builder = new AcyclicCallGraphBuilder(program, functions, true);
|
||||
DependencyGraph<Address> graph = builder.getDependencyGraph(DUMMY_MONITOR);
|
||||
AbstractDependencyGraph<Address> graph = builder.getDependencyGraph(DUMMY_MONITOR);
|
||||
|
||||
Assert.assertEquals(4, graph.size());
|
||||
assertDependents(graph, 2, 1);
|
||||
|
@ -274,7 +274,7 @@ public class AcyclicCallGraphBuilderTest extends AbstractGenericTest {
|
|||
Assert.assertFalse(graph.hasCycles());
|
||||
}
|
||||
|
||||
private void assertDependents(DependencyGraph<Address> graph, int fromID, int... toIDs) {
|
||||
private void assertDependents(AbstractDependencyGraph<Address> graph, int fromID, int... toIDs) {
|
||||
Set<Address> expectedSet = new HashSet<Address>();
|
||||
for (int toAddr : toIDs) {
|
||||
expectedSet.add(functionAddress(toAddr));
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue