GP-256 - Graphing - fixed AST graph exceptions

This commit is contained in:
dragonmacher 2020-10-28 17:52:12 -04:00
parent 7764f965be
commit edc8efdbf6
7 changed files with 51 additions and 31 deletions

View file

@ -120,6 +120,10 @@ public abstract class AddressBasedGraphDisplayListener
return null; return null;
} }
String id = getVertexId(address); String id = getVertexId(address);
if (id == null) {
return null;
}
return graphDisplay.getGraph().getVertex(id); return graphDisplay.getGraph().getVertex(id);
} }
@ -202,6 +206,9 @@ public abstract class AddressBasedGraphDisplayListener
private void handleSymbolAddedOrRenamed(Address address, Symbol symbol) { private void handleSymbolAddedOrRenamed(Address address, Symbol symbol) {
AttributedVertex vertex = getVertex(address); AttributedVertex vertex = getVertex(address);
if (vertex == null) {
return;
}
graphDisplay.updateVertexName(vertex, symbol.getName()); graphDisplay.updateVertexName(vertex, symbol.getName());
} }

View file

@ -15,14 +15,14 @@
*/ */
package ghidra.test; package ghidra.test;
import java.util.ArrayList;
import java.util.List;
import ghidra.program.database.ProgramBuilder; import ghidra.program.database.ProgramBuilder;
import ghidra.program.model.address.*; import ghidra.program.model.address.*;
import ghidra.program.model.listing.Program; import ghidra.program.model.listing.Program;
import ghidra.program.model.mem.MemoryAccessException; import ghidra.program.model.mem.MemoryAccessException;
import java.util.ArrayList;
import java.util.List;
public class ToyProgramBuilder extends ProgramBuilder { public class ToyProgramBuilder extends ProgramBuilder {
private static final String TOY_LANGUAGE_ID_BE = "Toy:BE:32:builder"; private static final String TOY_LANGUAGE_ID_BE = "Toy:BE:32:builder";
@ -106,7 +106,7 @@ public class ToyProgramBuilder extends ProgramBuilder {
/** /**
* Get address in default ram space * Get address in default ram space
* @param offset address offset * @param offset address offset
* @return address * @return the address
*/ */
public Address getAddress(long offset) { public Address getAddress(long offset) {
return defaultSpace.getAddress(offset); return defaultSpace.getAddress(offset);

View file

@ -123,13 +123,7 @@ public class ASTGraphTask extends Task {
graphType == GraphType.DATA_FLOW_GRAPH ? "AST Data Flow" : "AST Control Flow"; graphType == GraphType.DATA_FLOW_GRAPH ? "AST Data Flow" : "AST Control Flow";
description = description + " for " + hfunction.getFunction().getName(); description = description + " for " + hfunction.getFunction().getName();
display.setGraph(graph, description, false, monitor); display.setGraph(graph, description, false, monitor);
// set the graph location setGraphLocation(display, displayListener);
if (location != null) {
AttributedVertex vertex = displayListener.getVertex(location);
// update graph location, but don't have it send out event
display.setFocusedVertex(vertex, EventTrigger.INTERNAL_ONLY);
}
} }
catch (GraphException e) { catch (GraphException e) {
Msg.showError(this, null, "Graph Error", e.getMessage()); Msg.showError(this, null, "Graph Error", e.getMessage());
@ -140,6 +134,20 @@ public class ASTGraphTask extends Task {
} }
private void setGraphLocation(GraphDisplay display, ASTGraphDisplayListener displayListener) {
if (location == null) {
return;
}
AttributedVertex vertex = displayListener.getVertex(location);
if (vertex == null) {
return; // location not in graph
}
// update graph location, but don't have it send out event
display.setFocusedVertex(vertex, EventTrigger.INTERNAL_ONLY);
}
protected void createDataFlowGraph(AttributedGraph graph, TaskMonitor monitor) protected void createDataFlowGraph(AttributedGraph graph, TaskMonitor monitor)
throws CancelledException { throws CancelledException {
Iterator<PcodeOpAST> opIter = hfunction.getPcodeOps(); Iterator<PcodeOpAST> opIter = hfunction.getPcodeOps();

View file

@ -770,7 +770,6 @@ public class DefaultGraphDisplay implements GraphDisplay {
} }
} }
/** /**
* set the {@link AttributedGraph} for visualization * set the {@link AttributedGraph} for visualization
* @param attributedGraph the {@link AttributedGraph} to visualize * @param attributedGraph the {@link AttributedGraph} to visualize
@ -784,7 +783,7 @@ public class DefaultGraphDisplay implements GraphDisplay {
configureViewerPreferredSize(); configureViewerPreferredSize();
Swing.runNow(() -> { Swing.runNow(() -> {
// set the graph but defer the layoutalgorithm setting // set the graph but defer the layout algorithm setting
viewer.getVisualizationModel().setGraph(graph, false); viewer.getVisualizationModel().setGraph(graph, false);
configureFilters(); configureFilters();
LayoutAlgorithm<AttributedVertex> initialLayoutAlgorithm = LayoutAlgorithm<AttributedVertex> initialLayoutAlgorithm =
@ -795,8 +794,8 @@ public class DefaultGraphDisplay implements GraphDisplay {
} }
/** /**
* Determines if a vertex is a root. For our purpose, a root either has no incomming edges * Determines if a vertex is a root. For our purpose, a root either has no incoming edges
* or has at least one outgoing "favored" edge and no incomming "favored" edge * or has at least one outgoing "favored" edge and no incoming "favored" edge
* @param vertex the vertex to test if it is a root * @param vertex the vertex to test if it is a root
* @return true if the vertex is a root * @return true if the vertex is a root
*/ */
@ -1208,7 +1207,6 @@ public class DefaultGraphDisplay implements GraphDisplay {
} }
/** /**
* Use the hide selected action states to determine what vertices are shown: * Use the hide selected action states to determine what vertices are shown:
* <ul> * <ul>

View file

@ -106,7 +106,7 @@ public class BlockGraphTask extends Task {
private CodeBlockModel blockModel; private CodeBlockModel blockModel;
private AddressSetView selection; private AddressSetView selection;
private ProgramLocation location; private ProgramLocation location;
private GraphDisplayProvider graphService; private GraphDisplayProvider graphProvider;
private boolean reuseGraph; private boolean reuseGraph;
private boolean appendGraph; private boolean appendGraph;
private PluginTool tool; private PluginTool tool;
@ -116,7 +116,7 @@ public class BlockGraphTask extends Task {
public BlockGraphTask(String actionName, boolean graphEntryPointNexus, boolean showCode, public BlockGraphTask(String actionName, boolean graphEntryPointNexus, boolean showCode,
boolean reuseGraph, boolean appendGraph, PluginTool tool, ProgramSelection selection, boolean reuseGraph, boolean appendGraph, PluginTool tool, ProgramSelection selection,
ProgramLocation location, CodeBlockModel blockModel, ProgramLocation location, CodeBlockModel blockModel,
GraphDisplayProvider graphService) { GraphDisplayProvider graphProvider) {
super("Graph Program", true, false, true); super("Graph Program", true, false, true);
this.actionName = actionName; this.actionName = actionName;
@ -127,7 +127,7 @@ public class BlockGraphTask extends Task {
this.appendGraph = appendGraph; this.appendGraph = appendGraph;
this.tool = tool; this.tool = tool;
this.blockModel = blockModel; this.blockModel = blockModel;
this.graphService = graphService; this.graphProvider = graphProvider;
this.colorizingService = tool.getService(ColorizingService.class); this.colorizingService = tool.getService(ColorizingService.class);
this.selection = selection; this.selection = selection;
this.location = location; this.location = location;
@ -142,7 +142,7 @@ public class BlockGraphTask extends Task {
AttributedGraph graph = createGraph(); AttributedGraph graph = createGraph();
monitor.setMessage("Generating Graph..."); monitor.setMessage("Generating Graph...");
try { try {
GraphDisplay display = graphService.getGraphDisplay(reuseGraph, monitor); GraphDisplay display = graphProvider.getGraphDisplay(reuseGraph, monitor);
BlockModelGraphDisplayListener listener = BlockModelGraphDisplayListener listener =
new BlockModelGraphDisplayListener(tool, blockModel, display); new BlockModelGraphDisplayListener(tool, blockModel, display);
display.setGraphDisplayListener(listener); display.setGraphDisplayListener(listener);

View file

@ -30,6 +30,10 @@ import ghidra.program.model.mem.MemoryAccessException;
import ghidra.test.*; import ghidra.test.*;
public class AbstractBlockGraphTest extends AbstractGhidraHeadedIntegrationTest { public class AbstractBlockGraphTest extends AbstractGhidraHeadedIntegrationTest {
protected static final String CALLER_FUNCTION_ADDRESS = "01002200";
protected static final String SIMPLE_FUNCTION_ADDRESS = "01002239";
protected PluginTool tool; protected PluginTool tool;
protected ProgramDB program; protected ProgramDB program;
protected TestEnv env; protected TestEnv env;
@ -37,10 +41,6 @@ public class AbstractBlockGraphTest extends AbstractGhidraHeadedIntegrationTest
private ToyProgramBuilder builder; private ToyProgramBuilder builder;
protected CodeBrowserPlugin codeBrowser; protected CodeBrowserPlugin codeBrowser;
protected Address addr(long addr) {
return builder.getAddress(addr);
}
@Before @Before
public void setUp() throws Exception { public void setUp() throws Exception {
@ -50,7 +50,6 @@ public class AbstractBlockGraphTest extends AbstractGhidraHeadedIntegrationTest
tool = env.getTool(); tool = env.getTool();
initializeTool(); initializeTool();
} }
@After @After
@ -80,14 +79,15 @@ public class AbstractBlockGraphTest extends AbstractGhidraHeadedIntegrationTest
builder = new ToyProgramBuilder("sample", true); builder = new ToyProgramBuilder("sample", true);
builder.createMemory("caller", "0x01002200", 8); builder.createMemory("caller", "0x01002200", 8);
builder.createMemory("simple", "0x01002239", 8); builder.createMemory("simple", "0x01002239", 8);
builder.createMemory("not_graphed", "0x01002300", 8);
buildCallerFunction(builder); buildCallerFunction();
buildSimpleFunction(builder); buildSimpleFunction();
program = builder.getProgram(); program = builder.getProgram();
} }
private void buildCallerFunction(ToyProgramBuilder builder) throws MemoryAccessException { private void buildCallerFunction() throws MemoryAccessException {
// just a function that calls another // just a function that calls another
builder.addBytesNOP("0x01002200", 1); builder.addBytesNOP("0x01002200", 1);
builder.addBytesCall("0x01002201", "0x01002239");// jump to C builder.addBytesCall("0x01002201", "0x01002239");// jump to C
@ -98,7 +98,7 @@ public class AbstractBlockGraphTest extends AbstractGhidraHeadedIntegrationTest
builder.createLabel("0x01002200", "entry");// function label builder.createLabel("0x01002200", "entry");// function label
} }
private void buildSimpleFunction(ToyProgramBuilder builder) throws MemoryAccessException { private void buildSimpleFunction() throws MemoryAccessException {
// just a function to render in the graph so that we can clear out settings/cache // just a function to render in the graph so that we can clear out settings/cache
// 01002239 // 01002239
@ -128,4 +128,12 @@ public class AbstractBlockGraphTest extends AbstractGhidraHeadedIntegrationTest
builder.createLabel("0x01002239", "simple");// function label builder.createLabel("0x01002239", "simple");// function label
} }
protected Address addr(long addr) {
return builder.getAddress(addr);
}
protected Address addr(String addressString) {
return builder.addr(addressString);
}
} }

View file

@ -79,7 +79,7 @@ public class GraphActionTest extends AbstractGhidraHeadedIntegrationTest {
assertTrue(selectedVertices.contains(b)); assertTrue(selectedVertices.contains(b));
// now try and select a second vertex // now try and select a second vertex
context = new VertexGraphActionContext(graphComponentProvider, graph, null, null,d); context = new VertexGraphActionContext(graphComponentProvider, graph, null, null, d);
performAction(action, context, true); performAction(action, context, true);
selectedVertices = display.getSelectedVertices(); selectedVertices = display.getSelectedVertices();
assertEquals(2, selectedVertices.size()); assertEquals(2, selectedVertices.size());
@ -197,7 +197,6 @@ public class GraphActionTest extends AbstractGhidraHeadedIntegrationTest {
assertTrue(selectedVerticeIds.contains(c)); assertTrue(selectedVerticeIds.contains(c));
} }
@Test @Test
public void testGrowSelectionIn() { public void testGrowSelectionIn() {
select(d); select(d);