GT-2848: Refactor DependencyGraph with Deterministic version

This commit is contained in:
ghizard 2019-05-07 10:24:41 -04:00
parent dace9682fb
commit fa558af9c2
11 changed files with 744 additions and 343 deletions

View file

@ -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();

View file

@ -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));