GP-1511- fixing more duplicate actions in debugger tool

This commit is contained in:
ghidravore
2021-11-18 14:43:20 -05:00
parent 53e4f2ff9b
commit cb3c5b92e7
5 changed files with 126 additions and 133 deletions
@@ -19,7 +19,8 @@ import java.awt.Color;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.math.BigInteger;
import java.util.*;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
import javax.swing.ImageIcon;
@@ -27,25 +28,19 @@ import javax.swing.JComponent;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import docking.ActionContext;
import docking.action.DockingAction;
import docking.action.MenuData;
import docking.action.builder.ActionBuilder;
import docking.tool.ToolConstants;
import docking.widgets.fieldpanel.*;
import docking.widgets.fieldpanel.field.Field;
import docking.widgets.fieldpanel.support.FieldLocation;
import docking.widgets.fieldpanel.support.FieldSelection;
import ghidra.GhidraOptions;
import ghidra.app.context.ListingActionContext;
import ghidra.app.events.ProgramHighlightPluginEvent;
import ghidra.app.events.ProgramSelectionPluginEvent;
import ghidra.app.nav.Navigatable;
import ghidra.app.plugin.core.codebrowser.hover.ListingHoverService;
import ghidra.app.plugin.core.table.TableComponentProvider;
import ghidra.app.services.*;
import ghidra.app.util.*;
import ghidra.app.util.query.TableService;
import ghidra.app.util.HighlightProvider;
import ghidra.app.util.ProgramDropProvider;
import ghidra.app.util.viewer.field.ListingField;
import ghidra.app.util.viewer.field.ListingTextField;
import ghidra.app.util.viewer.format.*;
@@ -58,15 +53,11 @@ import ghidra.framework.options.*;
import ghidra.framework.plugintool.Plugin;
import ghidra.framework.plugintool.PluginTool;
import ghidra.program.model.address.*;
import ghidra.program.model.listing.*;
import ghidra.program.model.symbol.Reference;
import ghidra.program.model.listing.Data;
import ghidra.program.model.listing.Program;
import ghidra.program.util.ProgramLocation;
import ghidra.program.util.ProgramSelection;
import ghidra.util.*;
import ghidra.util.datastruct.Accumulator;
import ghidra.util.exception.CancelledException;
import ghidra.util.table.*;
import ghidra.util.task.TaskMonitor;
import resources.ResourceManager;
public abstract class AbstractCodeBrowserPlugin<P extends CodeViewerProvider> extends Plugin
@@ -96,9 +87,6 @@ public abstract class AbstractCodeBrowserPlugin<P extends CodeViewerProvider> ex
private ChangeListener markerChangeListener;
private FocusingMouseListener focusingMouseListener = new FocusingMouseListener();
private DockingAction tableFromSelectionAction;
private DockingAction showXrefsAction;
private Color cursorHighlightColor;
private boolean isHighlightCursorLine;
private ProgramDropProvider dndProvider;
@@ -122,7 +110,6 @@ public abstract class AbstractCodeBrowserPlugin<P extends CodeViewerProvider> ex
initOptions(fieldOptions);
initDisplayOptions(displayOptions);
initMiscellaneousOptions();
initActions();
displayOptions.addOptionsChangeListener(this);
fieldOptions.addOptionsChangeListener(this);
tool.setDefaultComponent(connectedProvider);
@@ -231,10 +218,6 @@ public abstract class AbstractCodeBrowserPlugin<P extends CodeViewerProvider> ex
@Override
public void serviceAdded(Class<?> interfaceClass, Object service) {
if (interfaceClass == TableService.class) {
tool.addAction(tableFromSelectionAction);
tool.addAction(showXrefsAction);
}
if (interfaceClass == ViewManagerService.class && viewManager == null) {
viewManager = (ViewManagerService) service;
viewChanged(viewManager.getCurrentView());
@@ -262,12 +245,6 @@ public abstract class AbstractCodeBrowserPlugin<P extends CodeViewerProvider> ex
@Override
public void serviceRemoved(Class<?> interfaceClass, Object service) {
if (interfaceClass == TableService.class) {
if (tool != null) {
tool.removeAction(tableFromSelectionAction);
tool.removeAction(showXrefsAction);
}
}
if ((service == viewManager) && (currentProgram != null)) {
viewManager = null;
viewChanged(currentProgram.getMemory());
@@ -666,81 +643,6 @@ public abstract class AbstractCodeBrowserPlugin<P extends CodeViewerProvider> ex
}
public void initActions() {
// note: these actions gets added later when the TableService is added
tableFromSelectionAction = new DockingAction("Create Table From Selection", getName()) {
ImageIcon markerIcon = ResourceManager.loadImage("images/searchm_obj.gif");
@Override
public void actionPerformed(ActionContext context) {
Listing listing = currentProgram.getListing();
ProgramSelection selection = connectedProvider.getSelection();
CodeUnitIterator codeUnits = listing.getCodeUnits(selection, true);
TableService tableService = tool.getService(TableService.class);
if (!codeUnits.hasNext()) {
tool.setStatusInfo(
"Unable to create table from selection: no " + "code units in selection");
return;
}
GhidraProgramTableModel<Address> model = createTableModel(codeUnits, selection);
String title = "Selection Table";
TableComponentProvider<Address> tableProvider =
tableService.showTableWithMarkers(title + " " + model.getName(), "Selection",
model, PluginConstants.SEARCH_HIGHLIGHT_COLOR, markerIcon, title, null);
tableProvider.installRemoveItemsAction();
}
@Override
public boolean isEnabledForContext(ActionContext context) {
ProgramSelection programSelection = connectedProvider.getSelection();
return programSelection != null && !programSelection.isEmpty();
}
};
tableFromSelectionAction.setEnabled(false);
tableFromSelectionAction.setMenuBarData(new MenuData(
new String[] { ToolConstants.MENU_SELECTION, "Create Table From Selection" }, null,
"SelectUtils"));
tableFromSelectionAction
.setHelpLocation(new HelpLocation("CodeBrowserPlugin", "Selection_Table"));
showXrefsAction = new ActionBuilder("Show Xrefs", getName())
.description("Show the Xrefs to the code unit containing the cursor")
.validContextWhen(context -> context instanceof ListingActionContext)
.onAction(context -> showXrefs(context))
.build();
}
private void showXrefs(ActionContext context) {
TableService service = tool.getService(TableService.class);
if (service == null) {
return;
}
ListingActionContext lac = (ListingActionContext) context;
ProgramLocation location = lac.getLocation();
if (location == null) {
return; // not sure if this can happen
}
Set<Reference> refs = XReferenceUtil.getAllXrefs(location);
XReferenceUtil.showAllXrefs(connectedProvider, tool, service, location, refs);
}
private GhidraProgramTableModel<Address> createTableModel(CodeUnitIterator iterator,
ProgramSelection selection) {
CodeUnitFromSelectionTableModelLoader loader =
new CodeUnitFromSelectionTableModelLoader(iterator, selection);
return new CustomLoadingAddressTableModel(" - from " + selection.getMinAddress(), tool,
currentProgram, loader, null, true);
}
@Override
public void updateDisplay() {
connectedProvider.getListingPanel().updateDisplay(false);
@@ -1040,30 +942,4 @@ public abstract class AbstractCodeBrowserPlugin<P extends CodeViewerProvider> ex
}
}
private class CodeUnitFromSelectionTableModelLoader implements TableModelLoader<Address> {
private CodeUnitIterator iterator;
private ProgramSelection selection;
CodeUnitFromSelectionTableModelLoader(CodeUnitIterator iterator,
ProgramSelection selection) {
this.iterator = iterator;
this.selection = selection;
}
@Override
public void load(Accumulator<Address> accumulator, TaskMonitor monitor)
throws CancelledException {
long size = selection.getNumAddresses();
monitor.initialize(size);
while (iterator.hasNext()) {
monitor.checkCanceled();
CodeUnit cu = iterator.next();
accumulator.add(cu.getMinAddress());
monitor.incrementProgress(cu.getLength());
}
}
}
}
@@ -15,15 +15,28 @@
*/
package ghidra.app.plugin.core.codebrowser;
import javax.swing.ImageIcon;
import docking.action.builder.ActionBuilder;
import docking.tool.ToolConstants;
import ghidra.app.CorePluginPackage;
import ghidra.app.plugin.PluginCategoryNames;
import ghidra.app.plugin.core.table.TableComponentProvider;
import ghidra.app.util.HelpTopics;
import ghidra.app.util.PluginConstants;
import ghidra.app.util.query.TableService;
import ghidra.framework.plugintool.*;
import ghidra.framework.plugintool.util.PluginStatus;
import ghidra.program.model.address.Address;
import ghidra.program.model.listing.*;
import ghidra.program.util.ProgramSelection;
import ghidra.util.HelpLocation;
import ghidra.util.Msg;
import ghidra.util.datastruct.Accumulator;
import ghidra.util.exception.CancelledException;
import ghidra.util.table.*;
import ghidra.util.task.TaskMonitor;
import resources.ResourceManager;
/**
* Plugin for adding some basic selection actions for Code Browser Listings.
@@ -78,6 +91,77 @@ public class CodeBrowserSelectionPlugin extends Plugin {
.onAction(c -> ((CodeViewerProvider) c.getComponentProvider()).selectComplement())
.buildAndInstall(tool);
new ActionBuilder("Create Table From Selection", getName())
.menuPath(ToolConstants.MENU_SELECTION, "Create Table From Selection")
.menuGroup("SelectUtils")
.helpLocation(new HelpLocation("CodeBrowserPlugin", "Selection_Table"))
.supportsDefaultToolContext(true)
.withContext(CodeViewerActionContext.class)
.inWindow(ActionBuilder.When.CONTEXT_MATCHES)
.onAction(c -> createTable((CodeViewerProvider) c.getComponentProvider()))
.buildAndInstall(tool);
}
private void createTable(CodeViewerProvider componentProvider) {
TableService tableService = tool.getService(TableService.class);
if (tableService == null) {
Msg.showWarn(this, null, "No Table Service", "Please add the TableServicePlugin.");
return;
}
Program program = componentProvider.getProgram();
Listing listing = program.getListing();
ProgramSelection selection = componentProvider.getSelection();
CodeUnitIterator codeUnits = listing.getCodeUnits(selection, true);
if (!codeUnits.hasNext()) {
tool.setStatusInfo(
"Unable to create table from selection: no " + "code units in selection");
return;
}
GhidraProgramTableModel<Address> model = createTableModel(program, codeUnits, selection);
String title = "Selection Table";
ImageIcon markerIcon = ResourceManager.loadImage("images/searchm_obj.gif");
TableComponentProvider<Address> tableProvider =
tableService.showTableWithMarkers(title + " " + model.getName(), "Selection",
model, PluginConstants.SEARCH_HIGHLIGHT_COLOR, markerIcon, title, null);
tableProvider.installRemoveItemsAction();
}
private GhidraProgramTableModel<Address> createTableModel(Program program,
CodeUnitIterator iterator, ProgramSelection selection) {
CodeUnitFromSelectionTableModelLoader loader =
new CodeUnitFromSelectionTableModelLoader(iterator, selection);
return new CustomLoadingAddressTableModel(" - from " + selection.getMinAddress(), tool,
program, loader, null, true);
}
private class CodeUnitFromSelectionTableModelLoader implements TableModelLoader<Address> {
private CodeUnitIterator iterator;
private ProgramSelection selection;
CodeUnitFromSelectionTableModelLoader(CodeUnitIterator iterator,
ProgramSelection selection) {
this.iterator = iterator;
this.selection = selection;
}
@Override
public void load(Accumulator<Address> accumulator, TaskMonitor monitor)
throws CancelledException {
long size = selection.getNumAddresses();
monitor.initialize(size);
while (iterator.hasNext()) {
monitor.checkCanceled();
CodeUnit cu = iterator.next();
accumulator.add(cu.getMinAddress());
monitor.incrementProgress(cu.getLength());
}
}
}
}
@@ -17,7 +17,9 @@ package ghidra.app.plugin.core.navigation.locationreferences;
import java.util.*;
import docking.ActionContext;
import docking.action.DockingAction;
import docking.action.builder.ActionBuilder;
import ghidra.app.CorePluginPackage;
import ghidra.app.context.ListingActionContext;
import ghidra.app.events.ProgramClosedPluginEvent;
@@ -26,12 +28,15 @@ import ghidra.app.plugin.PluginCategoryNames;
import ghidra.app.plugin.core.navigation.FindAppliedDataTypesService;
import ghidra.app.services.GoToService;
import ghidra.app.services.ProgramManager;
import ghidra.app.util.XReferenceUtils;
import ghidra.app.util.query.TableService;
import ghidra.framework.options.ToolOptions;
import ghidra.framework.plugintool.*;
import ghidra.framework.plugintool.util.PluginStatus;
import ghidra.program.model.data.Composite;
import ghidra.program.model.data.DataType;
import ghidra.program.model.listing.Program;
import ghidra.program.model.symbol.Reference;
import ghidra.program.util.ProgramLocation;
import ghidra.util.HelpLocation;
import ghidra.util.Msg;
@@ -104,6 +109,34 @@ public class LocationReferencesPlugin extends Plugin
// that point.
//
DeleteTableRowAction.registerDummy(tool, getName());
// Note: the following action has no access (no menu path, no key binding, etc.) It exists
// only so the user can bind a key binding to it if they wish.
new ActionBuilder("Show Xrefs", getName())
.description("Show the Xrefs to the code unit containing the cursor")
.validContextWhen(context -> context instanceof ListingActionContext)
.helpLocation(new HelpLocation("CodeBrowserPlugin", "Show_Xrefs"))
.onAction(context -> showXrefs(context))
.buildAndInstall(tool);
}
private void showXrefs(ActionContext context) {
TableService service = tool.getService(TableService.class);
if (service == null) {
Msg.showWarn(this, null, "No Table Service", "Please add the TableServicePlugin.");
return;
}
ListingActionContext lac = (ListingActionContext) context;
ProgramLocation location = lac.getLocation();
if (location == null) {
return; // not sure if this can happen
}
Set<Reference> refs = XReferenceUtils.getAllXrefs(location);
XReferenceUtils.showXrefs(lac.getNavigatable(), tool, service, location, refs);
}
void displayProvider(ListingActionContext context) {
@@ -81,7 +81,7 @@ public class CodeBrowserTest extends AbstractGhidraHeadedIntegrationTest {
cb = env.getPlugin(CodeBrowserPlugin.class);
fp = cb.getFieldPanel();
adjustFieldPanelSize(15);
adjustFieldPanelSize(20);
env.showTool();
cb.updateNow();
@@ -158,7 +158,7 @@ public class CodeBrowserTest extends AbstractGhidraHeadedIntegrationTest {
public void testTableFromSelection() {
ProgramSelection ps = dragToMakeSelection();
DockingActionIf createTableAction = getAction(cb, "Create Table From Selection");
DockingActionIf createTableAction = getAction(tool, "Create Table From Selection");
performAction(createTableAction, true);
TableComponentProvider<?> tableProvider =
@@ -147,7 +147,7 @@ public class CodeBrowserPluginScreenShots extends GhidraScreenShotGenerator {
positionListingTop(0x0406bd7);
makeSelection(0x0406be1, 0x0406bf1);
performAction("Create Table From Selection", "CodeBrowserPlugin", true);
performAction("Create Table From Selection", "CodeBrowserSelectionPlugin", true);
Window window = waitForWindowByTitleContaining("Selection Table");
Point loc = plugin.getListingPanel().getLocationOnScreen();
Dimension size = window.getSize();