From a48d7f8b5089c66679c9a8863c3be31ace3b75ea Mon Sep 17 00:00:00 2001 From: ghidragon <106987263+ghidragon@users.noreply.github.com> Date: Thu, 23 Mar 2023 15:35:00 -0400 Subject: [PATCH] GP-3250 changed default call graph action to always use "Isolated Entry" block model --- .../ghidra/graph/program/BlockGraphTask.java | 36 ++--- .../graph/program/ProgramGraphPlugin.java | 124 +++++++++--------- 2 files changed, 81 insertions(+), 79 deletions(-) diff --git a/Ghidra/Features/ProgramGraph/src/main/java/ghidra/graph/program/BlockGraphTask.java b/Ghidra/Features/ProgramGraph/src/main/java/ghidra/graph/program/BlockGraphTask.java index 1e620b0502..bc727990b9 100644 --- a/Ghidra/Features/ProgramGraph/src/main/java/ghidra/graph/program/BlockGraphTask.java +++ b/Ghidra/Features/ProgramGraph/src/main/java/ghidra/graph/program/BlockGraphTask.java @@ -141,13 +141,13 @@ public class BlockGraphTask extends Task { java.util.function.Function addressFunction) { display.addAction(new ActionBuilder("Rename Symbol", "Block Graph") - .popupMenuPath("Rename Symbol") - .withContext(VertexGraphActionContext.class) - .helpLocation(new HelpLocation("ProgramGraphPlugin", "Rename_Symbol")) - // only enable action when vertex corresponds to an address - .enabledWhen(c -> addressFunction.apply(c.getClickedVertex()) != null) - .onAction(c -> updateVertexName(addressFunction, c)) - .build()); + .popupMenuPath("Rename Symbol") + .withContext(VertexGraphActionContext.class) + .helpLocation(new HelpLocation("ProgramGraphPlugin", "Rename_Symbol")) + // only enable action when vertex corresponds to an address + .enabledWhen(c -> addressFunction.apply(c.getClickedVertex()) != null) + .onAction(c -> updateVertexName(addressFunction, c)) + .build()); } private void updateVertexName( @@ -231,16 +231,18 @@ public class BlockGraphTask extends Task { AddressSet set = new AddressSet(); set.add(function.getBody()); try { - CodeBlock block = blockModel.getCodeBlockAt(function.getEntryPoint(), taskMonitor); - CodeBlockReferenceIterator it = blockModel.getDestinations(block, taskMonitor); - while (it.hasNext()) { - CodeBlockReference next = it.next(); - set.add(next.getDestinationBlock()); - } - it = blockModel.getSources(block, taskMonitor); - while (it.hasNext()) { - CodeBlockReference next = it.next(); - set.add(next.getSourceBlock()); + for (CodeBlock block : blockModel.getCodeBlocksContaining(function.getEntryPoint(), + taskMonitor)) { + CodeBlockReferenceIterator it = blockModel.getDestinations(block, taskMonitor); + while (it.hasNext()) { + CodeBlockReference next = it.next(); + set.add(next.getDestinationBlock()); + } + it = blockModel.getSources(block, taskMonitor); + while (it.hasNext()) { + CodeBlockReference next = it.next(); + set.add(next.getSourceBlock()); + } } } catch (CancelledException e) { diff --git a/Ghidra/Features/ProgramGraph/src/main/java/ghidra/graph/program/ProgramGraphPlugin.java b/Ghidra/Features/ProgramGraph/src/main/java/ghidra/graph/program/ProgramGraphPlugin.java index ba88f53d4f..e23400d78c 100644 --- a/Ghidra/Features/ProgramGraph/src/main/java/ghidra/graph/program/ProgramGraphPlugin.java +++ b/Ghidra/Features/ProgramGraph/src/main/java/ghidra/graph/program/ProgramGraphPlugin.java @@ -73,7 +73,7 @@ public class ProgramGraphPlugin extends ProgramPlugin implements OptionsChangeListener, BlockModelServiceListener, GraphDisplayBrokerListener { private static final String PLUGIN_NAME = "Program Graph"; - + private static final String DEFAULT_BLOCK_MODEL_FOR_CALL_GRAPH = "Isolated Entry"; private static final String OPTIONS_PREFIX = PLUGIN_NAME + Options.DELIMITER; private static final String MAX_CODE_LINES_DISPLAYED = OPTIONS_PREFIX + "Max Code Lines Displayed"; @@ -189,79 +189,79 @@ public class ProgramGraphPlugin extends ProgramPlugin private void createActions() { new ActionBuilder("Graph Block Flow", getName()) - .menuPath(MENU_GRAPH, "&Block Flow") - .menuGroup(MENU_GRAPH, "A") - .onAction(c -> graphBlockFlow()) - .enabledWhen(this::canGraph) - .buildAndInstall(tool); + .menuPath(MENU_GRAPH, "&Block Flow") + .menuGroup(MENU_GRAPH, "A") + .onAction(c -> graphBlockFlow()) + .enabledWhen(this::canGraph) + .buildAndInstall(tool); new ActionBuilder("Graph Code Flow", getName()) - .menuPath(MENU_GRAPH, "C&ode Flow") - .menuGroup(MENU_GRAPH, "B") - .onAction(c -> graphCodeFlow()) - .enabledWhen(this::canGraph) - .buildAndInstall(tool); + .menuPath(MENU_GRAPH, "C&ode Flow") + .menuGroup(MENU_GRAPH, "B") + .onAction(c -> graphCodeFlow()) + .enabledWhen(this::canGraph) + .buildAndInstall(tool); new ActionBuilder("Graph Calls Using Default Model", getName()) - .menuPath(MENU_GRAPH, "&Calls") - .menuGroup(MENU_GRAPH, "C") - .onAction(c -> graphSubroutines()) - .enabledWhen(this::canGraph) - .buildAndInstall(tool); + .menuPath(MENU_GRAPH, "&Calls") + .menuGroup(MENU_GRAPH, "C") + .onAction(c -> createDefaultCallGraph()) + .enabledWhen(this::canGraph) + .buildAndInstall(tool); tool.setMenuGroup(new String[] { MENU_GRAPH, "Data" }, "Graph", "Data"); HelpLocation helpLoc = new HelpLocation(getName(), "Data_Reference_Graph"); new ActionBuilder("Graph To/From Data References", getName()) - .menuPath(MENU_GRAPH, "Data", "To/From &References") - .menuGroup(MENU_GRAPH, "Data") - .helpLocation(helpLoc) - .onAction(c -> graphDataReferences()) - .enabledWhen(this::canGraph) - .buildAndInstall(tool); + .menuPath(MENU_GRAPH, "Data", "To/From &References") + .menuGroup(MENU_GRAPH, "Data") + .helpLocation(helpLoc) + .onAction(c -> graphDataReferences()) + .enabledWhen(this::canGraph) + .buildAndInstall(tool); new ActionBuilder("Graph To Data References", getName()) - .menuPath(MENU_GRAPH, "Data", "&To References") - .menuGroup(MENU_GRAPH, "Data") - .helpLocation(helpLoc) - .onAction(c -> graphToDataReferences()) - .enabledWhen(this::canGraph) - .buildAndInstall(tool); + .menuPath(MENU_GRAPH, "Data", "&To References") + .menuGroup(MENU_GRAPH, "Data") + .helpLocation(helpLoc) + .onAction(c -> graphToDataReferences()) + .enabledWhen(this::canGraph) + .buildAndInstall(tool); new ActionBuilder("Graph From Data References", getName()) - .menuPath(MENU_GRAPH, "Data", "&From References") - .menuGroup(MENU_GRAPH, "Data") - .helpLocation(helpLoc) - .onAction(c -> graphFromDataReferences()) - .enabledWhen(this::canGraph) - .buildAndInstall(tool); + .menuPath(MENU_GRAPH, "Data", "&From References") + .menuGroup(MENU_GRAPH, "Data") + .helpLocation(helpLoc) + .onAction(c -> graphFromDataReferences()) + .enabledWhen(this::canGraph) + .buildAndInstall(tool); reuseGraphAction = new ToggleActionBuilder("Reuse Graph", getName()) - .menuPath(MENU_GRAPH, "Reuse Graph") - .menuGroup("Graph Options") - .selected(reuseGraph) - .onAction(c -> reuseGraph = reuseGraphAction.isSelected()) - .enabledWhen(this::canGraph) - .buildAndInstall(tool); + .menuPath(MENU_GRAPH, "Reuse Graph") + .menuGroup("Graph Options") + .selected(reuseGraph) + .onAction(c -> reuseGraph = reuseGraphAction.isSelected()) + .enabledWhen(this::canGraph) + .buildAndInstall(tool); appendGraphAction = new ToggleActionBuilder("Append Graph", getName()) - .menuPath(MENU_GRAPH, "Append Graph") - .menuGroup("Graph Options") - .selected(false) - .onAction(c -> updateAppendAndReuseGraph()) - .enabledWhen(this::canGraph) - .buildAndInstall(tool); - - forceLocationVisibleAction = new ToggleActionBuilder("Show Location in Graph", getName()) - .menuPath(MENU_GRAPH, "Show Location") - .description("Tell the graph to pan/scale as need to keep location changes visible") + .menuPath(MENU_GRAPH, "Append Graph") .menuGroup("Graph Options") - .onAction(c -> toggleForceLocationVisible()) + .selected(false) + .onAction(c -> updateAppendAndReuseGraph()) .enabledWhen(this::canGraph) .buildAndInstall(tool); + forceLocationVisibleAction = new ToggleActionBuilder("Show Location in Graph", getName()) + .menuPath(MENU_GRAPH, "Show Location") + .description("Tell the graph to pan/scale as need to keep location changes visible") + .menuGroup("Graph Options") + .onAction(c -> toggleForceLocationVisible()) + .enabledWhen(this::canGraph) + .buildAndInstall(tool); + updateSubroutineActions(); } @@ -309,12 +309,12 @@ public class ProgramGraphPlugin extends ProgramPlugin private DockingAction buildGraphActionWithModel(String blockModelName, HelpLocation helpLoc) { return new ActionBuilder("Graph Calls using " + blockModelName, getName()) - .menuPath(MENU_GRAPH, "Calls Using Model", blockModelName) - .menuGroup(MENU_GRAPH, "C") - .helpLocation(helpLoc) - .onAction(c -> graphSubroutinesUsing(blockModelName)) - .enabledWhen(this::canGraph) - .buildAndInstall(tool); + .menuPath(MENU_GRAPH, "Calls Using Model", blockModelName) + .menuGroup(MENU_GRAPH, "C") + .helpLocation(helpLoc) + .onAction(c -> createCallGraphUsing(blockModelName)) + .enabledWhen(this::canGraph) + .buildAndInstall(tool); } private void graphBlockFlow() { @@ -325,11 +325,11 @@ public class ProgramGraphPlugin extends ProgramPlugin graph(new CodeFlowGraphType(), blockModelService.getActiveBlockModelName()); } - private void graphSubroutines() { - graph(new CallGraphType(), blockModelService.getActiveSubroutineModelName()); + private void createDefaultCallGraph() { + createCallGraphUsing(DEFAULT_BLOCK_MODEL_FOR_CALL_GRAPH); } - private void graphSubroutinesUsing(String modelName) { + private void createCallGraphUsing(String modelName) { graph(new CallGraphType(), modelName); } @@ -351,8 +351,8 @@ public class ProgramGraphPlugin extends ProgramPlugin blockModelService.getNewModelByName(modelName, currentProgram, true); BlockGraphTask task = new BlockGraphTask(graphType, graphEntryPointNexus, - reuseGraph, appendToGraph, tool, currentSelection, currentLocation, model, - defaultGraphService); + reuseGraph, appendToGraph, tool, currentSelection, currentLocation, model, + defaultGraphService); task.setCodeLimitPerBlock(codeLimitPerBlock); new TaskLauncher(task, tool.getToolFrame()); }