mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-04 02:09:44 +02:00
GP-3648 - Add Function Graph to Function Comparison display
This commit is contained in:
parent
6773801f6e
commit
3c90216365
116 changed files with 4228 additions and 1350 deletions
|
@ -4,9 +4,9 @@
|
|||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
@ -29,7 +29,7 @@ import ghidra.feature.vt.api.main.*;
|
|||
import ghidra.feature.vt.api.markuptype.VTMarkupType;
|
||||
import ghidra.feature.vt.gui.plugin.VTController;
|
||||
import ghidra.feature.vt.gui.task.ApplyMarkupAtDestinationAddressTask;
|
||||
import ghidra.features.base.codecompare.listing.ListingCodeComparisonPanel;
|
||||
import ghidra.features.base.codecompare.listing.ListingCodeComparisonView;
|
||||
import ghidra.program.model.address.Address;
|
||||
import ghidra.program.util.ProgramLocation;
|
||||
import ghidra.util.Msg;
|
||||
|
@ -41,7 +41,7 @@ public class VTDualListingDragNDropHandler implements Draggable, Droppable {
|
|||
private Duo<ListingPanel> listingPanels;
|
||||
|
||||
private VTController controller;
|
||||
ListingCodeComparisonPanel dualListingPanel;
|
||||
ListingCodeComparisonView dualListingProvider;
|
||||
|
||||
// Drag-N-Drop
|
||||
private DragSource dragSource;
|
||||
|
@ -53,11 +53,11 @@ public class VTDualListingDragNDropHandler implements Draggable, Droppable {
|
|||
private DataFlavor[] acceptableFlavors; // data flavors that are valid.
|
||||
|
||||
public VTDualListingDragNDropHandler(VTController controller,
|
||||
ListingCodeComparisonPanel dualListingPanel) {
|
||||
ListingCodeComparisonView dualListingProvider) {
|
||||
this.controller = controller;
|
||||
this.dualListingPanel = dualListingPanel;
|
||||
ListingPanel leftPanel = dualListingPanel.getListingPanel(LEFT);
|
||||
ListingPanel rightPanel = dualListingPanel.getListingPanel(RIGHT);
|
||||
this.dualListingProvider = dualListingProvider;
|
||||
ListingPanel leftPanel = dualListingProvider.getListingPanel(LEFT);
|
||||
ListingPanel rightPanel = dualListingProvider.getListingPanel(RIGHT);
|
||||
listingPanels = new Duo<>(leftPanel, rightPanel);
|
||||
setUpDragDrop();
|
||||
}
|
||||
|
@ -109,7 +109,7 @@ public class VTDualListingDragNDropHandler implements Draggable, Droppable {
|
|||
ProgramLocation programLocation = listingPanels.get(LEFT).getProgramLocation(p);
|
||||
VTMarkupItem markupItem =
|
||||
controller.getCurrentMarkupForLocation(programLocation,
|
||||
dualListingPanel.getProgram(LEFT));
|
||||
dualListingProvider.getProgram(LEFT));
|
||||
if (markupItem == null) {
|
||||
return false;
|
||||
}
|
||||
|
@ -131,7 +131,7 @@ public class VTDualListingDragNDropHandler implements Draggable, Droppable {
|
|||
|
||||
ProgramLocation programLocation = listingPanels.get(LEFT).getProgramLocation(p);
|
||||
VTMarkupItem markupItem = controller.getCurrentMarkupForLocation(programLocation,
|
||||
dualListingPanel.getProgram(LEFT));
|
||||
dualListingProvider.getProgram(LEFT));
|
||||
if (markupItem == null) {
|
||||
return null;
|
||||
}
|
||||
|
@ -151,16 +151,16 @@ public class VTDualListingDragNDropHandler implements Draggable, Droppable {
|
|||
ProgramLocation loc = listingPanels.get(RIGHT).getProgramLocation(p);
|
||||
|
||||
Address newDestinationAddress =
|
||||
markupType.getAddress(loc, dualListingPanel.getProgram(RIGHT));
|
||||
markupType.getAddress(loc, dualListingProvider.getProgram(RIGHT));
|
||||
if (newDestinationAddress == null) {
|
||||
Msg.showInfo(getClass(), dualListingPanel, "Invalid Drop Location",
|
||||
Msg.showInfo(getClass(), dualListingProvider, "Invalid Drop Location",
|
||||
markupType.getDisplayName() + " was not dropped at a valid location.");
|
||||
return;
|
||||
}
|
||||
if ((markupItem.getStatus() == VTMarkupItemStatus.SAME) &&
|
||||
(SystemUtilities.isEqual(markupItem.getDestinationAddress(), newDestinationAddress))) {
|
||||
// Dropped at expected address and already the same there.
|
||||
Msg.showInfo(getClass(), dualListingPanel, "Already The Same", markupType
|
||||
Msg.showInfo(getClass(), dualListingProvider, "Already The Same", markupType
|
||||
.getDisplayName() +
|
||||
" was dropped at its expected\ndestination where the value is already the same.");
|
||||
return;
|
||||
|
|
|
@ -4,9 +4,9 @@
|
|||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
@ -18,16 +18,16 @@ package ghidra.feature.vt.gui.duallisting;
|
|||
import docking.ComponentProvider;
|
||||
import ghidra.app.context.ListingActionContext;
|
||||
import ghidra.app.nav.Navigatable;
|
||||
import ghidra.features.base.codecompare.panel.CodeComparisonPanel;
|
||||
import ghidra.features.base.codecompare.panel.CodeComparisonPanelActionContext;
|
||||
import ghidra.features.base.codecompare.panel.CodeComparisonView;
|
||||
import ghidra.features.base.codecompare.panel.CodeComparisonViewActionContext;
|
||||
|
||||
/**
|
||||
* Action context for a version tracking listing.
|
||||
*/
|
||||
public class VTListingContext extends ListingActionContext
|
||||
implements CodeComparisonPanelActionContext {
|
||||
implements CodeComparisonViewActionContext {
|
||||
|
||||
private CodeComparisonPanel codeComparisonPanel = null;
|
||||
private CodeComparisonView codeComparisonView = null;
|
||||
|
||||
/**
|
||||
* Creates an action context for a VT listing.
|
||||
|
@ -40,15 +40,14 @@ public class VTListingContext extends ListingActionContext
|
|||
|
||||
/**
|
||||
* Sets the CodeComparisonPanel associated with this context.
|
||||
* @param codeComparisonPanel the code comparison panel.
|
||||
* @param codeComparisonView the code comparison panel.
|
||||
*/
|
||||
public void setCodeComparisonPanel(
|
||||
CodeComparisonPanel codeComparisonPanel) {
|
||||
this.codeComparisonPanel = codeComparisonPanel;
|
||||
public void setCodeComparisonPanel(CodeComparisonView codeComparisonView) {
|
||||
this.codeComparisonView = codeComparisonView;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CodeComparisonPanel getCodeComparisonPanel() {
|
||||
return codeComparisonPanel;
|
||||
public CodeComparisonView getCodeComparisonView() {
|
||||
return codeComparisonView;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,7 +20,6 @@ import javax.swing.Icon;
|
|||
import ghidra.app.nav.*;
|
||||
import ghidra.app.util.ListingHighlightProvider;
|
||||
import ghidra.app.util.viewer.listingpanel.ListingPanel;
|
||||
import ghidra.features.base.codecompare.listing.ListingCodeComparisonPanel;
|
||||
import ghidra.program.model.listing.Program;
|
||||
import ghidra.program.util.ProgramLocation;
|
||||
import ghidra.program.util.ProgramSelection;
|
||||
|
@ -28,14 +27,11 @@ import ghidra.util.UniversalIdGenerator;
|
|||
|
||||
public class VTListingNavigator implements Navigatable {
|
||||
|
||||
private final ListingCodeComparisonPanel dualListingPanel;
|
||||
private final ListingPanel listingPanel;
|
||||
private long id;
|
||||
|
||||
public VTListingNavigator(ListingCodeComparisonPanel dualListingPanel,
|
||||
ListingPanel listingPanel) {
|
||||
public VTListingNavigator(ListingPanel listingPanel) {
|
||||
|
||||
this.dualListingPanel = dualListingPanel;
|
||||
this.listingPanel = listingPanel;
|
||||
id = UniversalIdGenerator.nextID().getValue();
|
||||
}
|
||||
|
|
|
@ -87,9 +87,9 @@ public class VTPlugin extends Plugin {
|
|||
|
||||
private VTController controller;
|
||||
|
||||
// common resources
|
||||
|
||||
// destination-side resources
|
||||
// plugins we have to add to our tool manually
|
||||
private Set<String> additionalPluginNames = new HashSet<>(Set.of(
|
||||
"ghidra.features.codecompare.plugin.FunctionComparisonPlugin"));
|
||||
|
||||
private VTMatchTableProvider matchesProvider;
|
||||
private VTMarkupItemsTableProvider markupProvider;
|
||||
|
@ -99,16 +99,15 @@ public class VTPlugin extends Plugin {
|
|||
|
||||
public VTPlugin(PluginTool tool) {
|
||||
super(tool);
|
||||
|
||||
tool.setUnconfigurable();
|
||||
|
||||
OWNER = getName();
|
||||
controller = new VTControllerImpl(this);
|
||||
matchesProvider = new VTMatchTableProvider(controller);
|
||||
markupProvider = new VTMarkupItemsTableProvider(controller);
|
||||
impliedMatchesTable = new VTImpliedMatchesTableProvider(controller);
|
||||
functionAssociationProvider = new VTFunctionAssociationProvider(controller);
|
||||
registerServiceProvided(VTController.class, controller);
|
||||
|
||||
toolManager = new VTSubToolManager(this);
|
||||
createActions();
|
||||
registerServiceProvided(VTController.class, controller);
|
||||
tool.setUnconfigurable();
|
||||
|
||||
DockingActionIf saveAs = getToolAction("Save Tool As");
|
||||
tool.removeAction(saveAs);
|
||||
|
@ -116,11 +115,7 @@ public class VTPlugin extends Plugin {
|
|||
DockingActionIf export = getToolAction("Export Tool");
|
||||
tool.removeAction(export);
|
||||
|
||||
new MatchStatusUpdaterAssociationHook(controller);
|
||||
new ImpliedMatchAssociationHook(controller);
|
||||
|
||||
initializeOptions();
|
||||
|
||||
}
|
||||
|
||||
private DockingActionIf getToolAction(String actionName) {
|
||||
|
@ -145,9 +140,16 @@ public class VTPlugin extends Plugin {
|
|||
protected void init() {
|
||||
|
||||
removeUnwantedPlugins();
|
||||
|
||||
addCustomPlugins();
|
||||
|
||||
matchesProvider = new VTMatchTableProvider(controller);
|
||||
markupProvider = new VTMarkupItemsTableProvider(controller);
|
||||
impliedMatchesTable = new VTImpliedMatchesTableProvider(controller);
|
||||
functionAssociationProvider = new VTFunctionAssociationProvider(controller);
|
||||
|
||||
new MatchStatusUpdaterAssociationHook(controller);
|
||||
new ImpliedMatchAssociationHook(controller);
|
||||
|
||||
maybeShowHelp();
|
||||
}
|
||||
|
||||
|
@ -161,11 +163,11 @@ public class VTPlugin extends Plugin {
|
|||
|
||||
private void addCustomPlugins() {
|
||||
|
||||
List<String> names =
|
||||
new ArrayList<>(List.of("ghidra.features.codecompare.plugin.FunctionComparisonPlugin"));
|
||||
List<Plugin> plugins = tool.getManagedPlugins();
|
||||
Set<String> existingNames =
|
||||
plugins.stream().map(c -> c.getName()).collect(Collectors.toSet());
|
||||
Set<String> existingNames = new HashSet<>(
|
||||
plugins.stream()
|
||||
.map(c -> c.getName())
|
||||
.collect(Collectors.toSet()));
|
||||
|
||||
// Note: we check to see if the plugins we want to add have already been added to the tool.
|
||||
// We should not need to do this, but once the tool has been saved with the plugins added,
|
||||
|
@ -173,7 +175,7 @@ public class VTPlugin extends Plugin {
|
|||
// easier than modifying the default to file to load the plugins, since the amount of xml
|
||||
// required for that is non-trivial.
|
||||
try {
|
||||
for (String className : names) {
|
||||
for (String className : additionalPluginNames) {
|
||||
if (!existingNames.contains(className)) {
|
||||
tool.addPlugin(className);
|
||||
}
|
||||
|
|
|
@ -39,6 +39,7 @@ import docking.widgets.label.GDLabel;
|
|||
import docking.widgets.table.threaded.ThreadedTableModel;
|
||||
import generic.theme.GIcon;
|
||||
import generic.theme.GThemeDefaults.Colors;
|
||||
import ghidra.app.services.FunctionComparisonService;
|
||||
import ghidra.app.util.viewer.listingpanel.ListingPanel;
|
||||
import ghidra.feature.vt.api.db.DeletedMatch;
|
||||
import ghidra.feature.vt.api.impl.VTEvent;
|
||||
|
@ -48,7 +49,7 @@ import ghidra.feature.vt.gui.actions.*;
|
|||
import ghidra.feature.vt.gui.duallisting.VTListingNavigator;
|
||||
import ghidra.feature.vt.gui.plugin.*;
|
||||
import ghidra.feature.vt.gui.util.MatchInfo;
|
||||
import ghidra.features.base.codecompare.listing.ListingCodeComparisonPanel;
|
||||
import ghidra.features.base.codecompare.listing.ListingCodeComparisonView;
|
||||
import ghidra.features.base.codecompare.panel.FunctionComparisonPanel;
|
||||
import ghidra.framework.model.*;
|
||||
import ghidra.framework.options.Options;
|
||||
|
@ -218,10 +219,10 @@ public class VTFunctionAssociationProvider extends ComponentProviderAdapter
|
|||
@Override
|
||||
public List<DockingActionIf> getPopupActions(Tool t, ActionContext context) {
|
||||
if (context.getComponentProvider() == this) {
|
||||
ListingCodeComparisonPanel dualListingPanel =
|
||||
functionComparisonPanel.getDualListingPanel();
|
||||
if (dualListingPanel != null) {
|
||||
ListingPanel leftPanel = dualListingPanel.getListingPanel(LEFT);
|
||||
ListingCodeComparisonView dualListingProvider =
|
||||
functionComparisonPanel.getDualListingView();
|
||||
if (dualListingProvider != null) {
|
||||
ListingPanel leftPanel = dualListingProvider.getListingPanel(LEFT);
|
||||
return leftPanel.getHeaderActions(getOwner());
|
||||
}
|
||||
}
|
||||
|
@ -247,22 +248,22 @@ public class VTFunctionAssociationProvider extends ComponentProviderAdapter
|
|||
// Tool bar or function compare panel.
|
||||
if (isToolbarButtonAction || functionComparisonPanel.isAncestorOf(sourceComponent)) {
|
||||
|
||||
ListingCodeComparisonPanel dualListingPanel =
|
||||
functionComparisonPanel.getDualListingPanel();
|
||||
ListingCodeComparisonView dualListingProvider =
|
||||
functionComparisonPanel.getDualListingView();
|
||||
boolean isShowingDualListing =
|
||||
(dualListingPanel != null) && dualListingPanel.isVisible();
|
||||
(dualListingProvider != null) && dualListingProvider.isVisible();
|
||||
boolean sourceIsADualFieldPanel =
|
||||
isShowingDualListing && dualListingPanel.isAncestorOf(sourceComponent) &&
|
||||
isShowingDualListing && dualListingProvider.isAncestorOf(sourceComponent) &&
|
||||
(sourceComponent instanceof FieldPanel);
|
||||
|
||||
ListingPanel listingPanel = null; // Default is don't create a function association listing context.
|
||||
// Is the action being taken on the dual listing?
|
||||
if (sourceIsADualFieldPanel) {
|
||||
listingPanel = dualListingPanel.getListingPanel((FieldPanel) sourceComponent);
|
||||
listingPanel = dualListingProvider.getListingPanel((FieldPanel) sourceComponent);
|
||||
}
|
||||
// Is the action being taken on a toolbar button while the dual listing is visible?
|
||||
else if (isToolbarButtonAction && isShowingDualListing) {
|
||||
listingPanel = dualListingPanel.getActiveListingPanel();
|
||||
listingPanel = dualListingProvider.getActiveListingPanel();
|
||||
}
|
||||
// If the dual listing is showing and this is a toolbar action or the action is
|
||||
// on one of the listings in the ListingCodeComparisonPanel
|
||||
|
@ -270,14 +271,13 @@ public class VTFunctionAssociationProvider extends ComponentProviderAdapter
|
|||
// popup actions for the ListingDiff and also the function association actions
|
||||
// for the functions selected in the tables.
|
||||
if (listingPanel != null) {
|
||||
VTListingNavigator vtListingNavigator =
|
||||
new VTListingNavigator(dualListingPanel, listingPanel);
|
||||
VTListingNavigator vtListingNavigator = new VTListingNavigator(listingPanel);
|
||||
VTFunctionAssociationCompareContext vtListingContext =
|
||||
new VTFunctionAssociationCompareContext(this, vtListingNavigator, tool,
|
||||
sourceFunction, destinationFunction,
|
||||
getExistingMatch(sourceFunction, destinationFunction));
|
||||
vtListingContext.setCodeComparisonPanel(dualListingPanel);
|
||||
vtListingContext.setContextObject(dualListingPanel);
|
||||
vtListingContext.setCodeComparisonPanel(dualListingProvider);
|
||||
vtListingContext.setContextObject(dualListingProvider);
|
||||
vtListingContext.setSourceObject(source);
|
||||
return vtListingContext;
|
||||
}
|
||||
|
@ -334,6 +334,8 @@ public class VTFunctionAssociationProvider extends ComponentProviderAdapter
|
|||
destinationFunctionsTable.dispose();
|
||||
destinationTableFilterPanel.dispose();
|
||||
|
||||
functionComparisonPanel.dispose();
|
||||
|
||||
tool.removePopupActionProvider(this);
|
||||
}
|
||||
|
||||
|
@ -368,9 +370,12 @@ public class VTFunctionAssociationProvider extends ComponentProviderAdapter
|
|||
statusPanel.add(statusLabel, BorderLayout.CENTER);
|
||||
dualTablePanel.add(statusPanel, BorderLayout.SOUTH);
|
||||
|
||||
functionComparisonPanel = new FunctionComparisonPanel(tool, getOwner());
|
||||
// Note: this service should never be null, since it is added by the VTPlugin
|
||||
FunctionComparisonService fcService = tool.getService(FunctionComparisonService.class);
|
||||
functionComparisonPanel = fcService.createComparisonViewer();
|
||||
|
||||
addSpecificCodeComparisonActions();
|
||||
functionComparisonPanel.setCurrentTabbedComponent(ListingCodeComparisonPanel.NAME);
|
||||
functionComparisonPanel.setCurrentTabbedComponent(ListingCodeComparisonView.NAME);
|
||||
functionComparisonPanel.setTitlePrefixes("Source:", "Destination:");
|
||||
|
||||
comparisonSplitPane =
|
||||
|
@ -760,12 +765,9 @@ public class VTFunctionAssociationProvider extends ComponentProviderAdapter
|
|||
sourceFunctionsModel.setFilterSettings(filterSettings);
|
||||
destinationFunctionsModel.setFilterSettings(filterSettings);
|
||||
reload();
|
||||
functionComparisonPanel.readConfigState(getName(), saveState);
|
||||
}
|
||||
|
||||
public void writeConfigState(SaveState saveState) {
|
||||
// save config state here
|
||||
functionComparisonPanel.writeConfigState(getName(), saveState);
|
||||
saveState.putEnum(FILTER_SETTINGS_KEY, filterSettings);
|
||||
}
|
||||
|
||||
|
|
|
@ -4,9 +4,9 @@
|
|||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
@ -19,17 +19,17 @@ import java.util.List;
|
|||
|
||||
import docking.DefaultActionContext;
|
||||
import ghidra.feature.vt.api.main.VTMarkupItem;
|
||||
import ghidra.features.base.codecompare.panel.CodeComparisonPanel;
|
||||
import ghidra.features.base.codecompare.panel.CodeComparisonPanelActionContext;
|
||||
import ghidra.features.base.codecompare.panel.CodeComparisonView;
|
||||
import ghidra.features.base.codecompare.panel.CodeComparisonViewActionContext;
|
||||
|
||||
/**
|
||||
* Action context for the version tracking markup item provider.
|
||||
*/
|
||||
public class VTMarkupItemContext extends DefaultActionContext
|
||||
implements CodeComparisonPanelActionContext {
|
||||
implements CodeComparisonViewActionContext {
|
||||
|
||||
private final List<VTMarkupItem> selectedItems;
|
||||
private CodeComparisonPanel codeComparisonPanel = null;
|
||||
private CodeComparisonView codeComparisonView;
|
||||
|
||||
/**
|
||||
* Creates an action context for the VT markup item provider.
|
||||
|
@ -50,16 +50,15 @@ public class VTMarkupItemContext extends DefaultActionContext
|
|||
}
|
||||
|
||||
/**
|
||||
* Sets the CodeComparisonPanel associated with this context.
|
||||
* @param codeComparisonPanel the code comparison panel.
|
||||
* Sets the comparison provider associated with this context.
|
||||
* @param codeComparisonView the code comparison view.
|
||||
*/
|
||||
public void setCodeComparisonPanel(
|
||||
CodeComparisonPanel codeComparisonPanel) {
|
||||
this.codeComparisonPanel = codeComparisonPanel;
|
||||
public void setCodeComparisonView(CodeComparisonView codeComparisonView) {
|
||||
this.codeComparisonView = codeComparisonView;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CodeComparisonPanel getCodeComparisonPanel() {
|
||||
return codeComparisonPanel;
|
||||
public CodeComparisonView getCodeComparisonView() {
|
||||
return codeComparisonView;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,6 +39,7 @@ import docking.widgets.table.GTable;
|
|||
import docking.widgets.table.RowObjectTableModel;
|
||||
import docking.widgets.table.threaded.ThreadedTableModel;
|
||||
import generic.theme.GIcon;
|
||||
import ghidra.app.services.FunctionComparisonService;
|
||||
import ghidra.app.util.viewer.listingpanel.ListingPanel;
|
||||
import ghidra.app.util.viewer.listingpanel.ProgramLocationListener;
|
||||
import ghidra.feature.vt.api.main.*;
|
||||
|
@ -51,8 +52,8 @@ import ghidra.feature.vt.gui.filters.Filter.FilterEditingStatus;
|
|||
import ghidra.feature.vt.gui.plugin.*;
|
||||
import ghidra.feature.vt.gui.provider.markuptable.VTMarkupItemsTableModel.AppliedDestinationAddressTableColumn;
|
||||
import ghidra.feature.vt.gui.util.*;
|
||||
import ghidra.features.base.codecompare.listing.ListingCodeComparisonPanel;
|
||||
import ghidra.features.base.codecompare.panel.CodeComparisonPanel;
|
||||
import ghidra.features.base.codecompare.listing.ListingCodeComparisonView;
|
||||
import ghidra.features.base.codecompare.panel.CodeComparisonView;
|
||||
import ghidra.features.base.codecompare.panel.FunctionComparisonPanel;
|
||||
import ghidra.framework.model.DomainObjectChangedEvent;
|
||||
import ghidra.framework.options.Options;
|
||||
|
@ -154,28 +155,33 @@ public class VTMarkupItemsTableProvider extends ComponentProviderAdapter
|
|||
markupItemsTablePanel.add(tablePanel, BorderLayout.CENTER);
|
||||
markupItemsTablePanel.add(filterAreaPanel, BorderLayout.SOUTH);
|
||||
|
||||
functionComparisonPanel = new FunctionComparisonPanel(tool, getOwner());
|
||||
// Note: this service should never be null, since it is added by the VTPlugin
|
||||
FunctionComparisonService fcService = tool.getService(FunctionComparisonService.class);
|
||||
functionComparisonPanel = fcService.createComparisonViewer();
|
||||
|
||||
addSpecificCodeComparisonActions();
|
||||
functionComparisonPanel.setCurrentTabbedComponent(ListingCodeComparisonPanel.NAME);
|
||||
functionComparisonPanel.setCurrentTabbedComponent(ListingCodeComparisonView.NAME);
|
||||
functionComparisonPanel.getAccessibleContext().setAccessibleName("Function Comparison");
|
||||
functionComparisonPanel.setTitlePrefixes("Source:", "Destination:");
|
||||
ListingCodeComparisonPanel dualListingPanel = functionComparisonPanel.getDualListingPanel();
|
||||
if (dualListingPanel != null) {
|
||||
ListingCodeComparisonView dualListingProvider =
|
||||
functionComparisonPanel.getDualListingView();
|
||||
if (dualListingProvider != null) {
|
||||
|
||||
dualListingPanel.getListingPanel(LEFT)
|
||||
dualListingProvider.getListingPanel(LEFT)
|
||||
.setProgramLocationListener(new SourceProgramLocationListener());
|
||||
dualListingPanel.getListingPanel(RIGHT)
|
||||
dualListingProvider.getListingPanel(RIGHT)
|
||||
.setProgramLocationListener(
|
||||
new DestinationProgramLocationListener());
|
||||
|
||||
sourceHighlightProvider = new VTDualListingHighlightProvider(controller, true);
|
||||
destinationHighlightProvider = new VTDualListingHighlightProvider(controller, false);
|
||||
dualListingPanel.addHighlightProviders(sourceHighlightProvider,
|
||||
dualListingProvider.addHighlightProviders(sourceHighlightProvider,
|
||||
destinationHighlightProvider);
|
||||
sourceHighlightProvider.setListingPanel(dualListingPanel.getListingPanel(LEFT));
|
||||
destinationHighlightProvider.setListingPanel(dualListingPanel.getListingPanel(RIGHT));
|
||||
sourceHighlightProvider.setListingPanel(dualListingProvider.getListingPanel(LEFT));
|
||||
destinationHighlightProvider
|
||||
.setListingPanel(dualListingProvider.getListingPanel(RIGHT));
|
||||
|
||||
new VTDualListingDragNDropHandler(controller, dualListingPanel);
|
||||
new VTDualListingDragNDropHandler(controller, dualListingProvider);
|
||||
}
|
||||
|
||||
splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, markupItemsTablePanel,
|
||||
|
@ -250,8 +256,8 @@ public class VTMarkupItemsTableProvider extends ComponentProviderAdapter
|
|||
// the same destination address.
|
||||
processingMarkupItemSelected = true;
|
||||
|
||||
ListingCodeComparisonPanel dualListingPanel =
|
||||
functionComparisonPanel.getDualListingPanel();
|
||||
ListingCodeComparisonView dualListingPanel =
|
||||
functionComparisonPanel.getDualListingView();
|
||||
VTMarkupItem markupItem = null;
|
||||
if (table.getSelectedRowCount() == 1) {
|
||||
// we get out the model here in case it has been wrapped by one of the filters
|
||||
|
@ -358,7 +364,8 @@ public class VTMarkupItemsTableProvider extends ComponentProviderAdapter
|
|||
* Otherwise, hide it.
|
||||
*/
|
||||
private void showComparisonPanelWithinProvider(boolean show) {
|
||||
ListingCodeComparisonPanel dualListingPanel = functionComparisonPanel.getDualListingPanel();
|
||||
ListingCodeComparisonView dualListingProvider =
|
||||
functionComparisonPanel.getDualListingView();
|
||||
boolean contains = markupPanel.isAncestorOf(splitPane);
|
||||
if (show) {
|
||||
if (!contains) {
|
||||
|
@ -369,10 +376,10 @@ public class VTMarkupItemsTableProvider extends ComponentProviderAdapter
|
|||
splitPane.add(markupItemsTablePanel);
|
||||
splitPane.add(functionComparisonPanel);
|
||||
markupPanel.add(splitPane, BorderLayout.CENTER);
|
||||
if (dualListingPanel != null) {
|
||||
dualListingPanel.getListingPanel(LEFT)
|
||||
if (dualListingProvider != null) {
|
||||
dualListingProvider.getListingPanel(LEFT)
|
||||
.setProgramLocationListener(new SourceProgramLocationListener());
|
||||
dualListingPanel.getListingPanel(LEFT)
|
||||
dualListingProvider.getListingPanel(LEFT)
|
||||
.setProgramLocationListener(new DestinationProgramLocationListener());
|
||||
}
|
||||
|
||||
|
@ -386,9 +393,9 @@ public class VTMarkupItemsTableProvider extends ComponentProviderAdapter
|
|||
else {
|
||||
if (contains) {
|
||||
// Remove the split pane.
|
||||
if (dualListingPanel != null) {
|
||||
dualListingPanel.getListingPanel(LEFT).setProgramLocationListener(null);
|
||||
dualListingPanel.getListingPanel(RIGHT).setProgramLocationListener(null);
|
||||
if (dualListingProvider != null) {
|
||||
dualListingProvider.getListingPanel(LEFT).setProgramLocationListener(null);
|
||||
dualListingProvider.getListingPanel(RIGHT).setProgramLocationListener(null);
|
||||
}
|
||||
markupPanel.remove(splitPane);
|
||||
splitPane.remove(functionComparisonPanel);
|
||||
|
@ -471,9 +478,10 @@ public class VTMarkupItemsTableProvider extends ComponentProviderAdapter
|
|||
|
||||
@Override
|
||||
public List<DockingActionIf> getPopupActions(Tool t, ActionContext context) {
|
||||
ListingCodeComparisonPanel dualListingPanel = functionComparisonPanel.getDualListingPanel();
|
||||
if (context.getComponentProvider() == this && dualListingPanel != null) {
|
||||
ListingPanel sourcePanel = dualListingPanel.getListingPanel(LEFT);
|
||||
ListingCodeComparisonView dualListingProvider =
|
||||
functionComparisonPanel.getDualListingView();
|
||||
if (context.getComponentProvider() == this && dualListingProvider != null) {
|
||||
ListingPanel sourcePanel = dualListingProvider.getListingPanel(LEFT);
|
||||
return sourcePanel.getHeaderActions(getOwner());
|
||||
}
|
||||
return new ArrayList<>();
|
||||
|
@ -483,34 +491,35 @@ public class VTMarkupItemsTableProvider extends ComponentProviderAdapter
|
|||
public ActionContext getActionContext(MouseEvent event) {
|
||||
Object source = (event != null) ? event.getSource() : null;
|
||||
Component sourceComponent = (source instanceof Component) ? (Component) source : null;
|
||||
|
||||
// If action is on the markup table, return a markup item context for markup popup actions.
|
||||
if (event == null || tablePanel.isAncestorOf(sourceComponent)) {
|
||||
List<VTMarkupItem> selectedItems = getSelectedMarkupItems();
|
||||
VTMarkupItemContext vtMarkupItemContext = new VTMarkupItemContext(this, selectedItems);
|
||||
if (functionComparisonPanel.isVisible()) {
|
||||
CodeComparisonPanel displayedPanel =
|
||||
functionComparisonPanel.getDisplayedPanel();
|
||||
vtMarkupItemContext.setCodeComparisonPanel(displayedPanel);
|
||||
CodeComparisonView displayedProvider =
|
||||
functionComparisonPanel.getDisplayedView();
|
||||
vtMarkupItemContext.setCodeComparisonView(displayedProvider);
|
||||
}
|
||||
return vtMarkupItemContext;
|
||||
}
|
||||
|
||||
// Is the action being taken on the dual listing.
|
||||
ListingCodeComparisonPanel dualListingPanel = functionComparisonPanel.getDualListingPanel();
|
||||
if (dualListingPanel != null && dualListingPanel.isAncestorOf(sourceComponent)) {
|
||||
// If the action is on one of the listings in the ListingCodeComparisonPanel
|
||||
ListingCodeComparisonView listingView = functionComparisonPanel.getDualListingView();
|
||||
if (listingView != null && listingView.isAncestorOf(sourceComponent)) {
|
||||
// If the action is on one of the listings in the Listing view
|
||||
// then return a special version tracking listing context. This will allow
|
||||
// popup actions for the ListingDiff and also the markup item actions for the
|
||||
// current markup item.
|
||||
if (sourceComponent instanceof FieldPanel) {
|
||||
ListingPanel listingPanel =
|
||||
dualListingPanel.getListingPanel((FieldPanel) sourceComponent);
|
||||
listingView.getListingPanel((FieldPanel) sourceComponent);
|
||||
if (listingPanel != null) {
|
||||
VTListingNavigator vtListingNavigator =
|
||||
new VTListingNavigator(dualListingPanel, listingPanel);
|
||||
VTListingNavigator vtListingNavigator = new VTListingNavigator(listingPanel);
|
||||
VTListingContext vtListingContext =
|
||||
new VTListingContext(this, vtListingNavigator);
|
||||
vtListingContext.setCodeComparisonPanel(dualListingPanel);
|
||||
vtListingContext.setContextObject(dualListingPanel);
|
||||
vtListingContext.setCodeComparisonPanel(listingView);
|
||||
vtListingContext.setContextObject(listingView);
|
||||
vtListingContext.setSourceObject(source);
|
||||
return vtListingContext;
|
||||
}
|
||||
|
@ -542,6 +551,8 @@ public class VTMarkupItemsTableProvider extends ComponentProviderAdapter
|
|||
return;
|
||||
}
|
||||
|
||||
functionComparisonPanel.dispose();
|
||||
|
||||
// must remove the listener first to avoid callback whilst we are disposing
|
||||
ListSelectionModel selectionModel = markupItemsTable.getSelectionModel();
|
||||
selectionModel.removeListSelectionListener(markupItemSelectionListener);
|
||||
|
@ -564,9 +575,10 @@ public class VTMarkupItemsTableProvider extends ComponentProviderAdapter
|
|||
private void refresh() {
|
||||
markupItemsTableModel.reload(false);
|
||||
markupItemsTable.repaint();
|
||||
ListingCodeComparisonPanel dualListingPanel = functionComparisonPanel.getDualListingPanel();
|
||||
if (dualListingPanel != null) {
|
||||
dualListingPanel.updateListings();
|
||||
ListingCodeComparisonView dualListingProvider =
|
||||
functionComparisonPanel.getDualListingView();
|
||||
if (dualListingProvider != null) {
|
||||
dualListingProvider.updateListings();
|
||||
}
|
||||
sourceHighlightProvider.updateMarkup();
|
||||
destinationHighlightProvider.updateMarkup();
|
||||
|
@ -773,11 +785,12 @@ public class VTMarkupItemsTableProvider extends ComponentProviderAdapter
|
|||
* @return true if the dual listing is showing
|
||||
*/
|
||||
public boolean isDualListingShowing() {
|
||||
ListingCodeComparisonPanel dualListingPanel = functionComparisonPanel.getDualListingPanel();
|
||||
if (dualListingPanel == null) {
|
||||
ListingCodeComparisonView dualListingProvider =
|
||||
functionComparisonPanel.getDualListingView();
|
||||
if (dualListingProvider == null) {
|
||||
return false;
|
||||
}
|
||||
return dualListingPanel.isShowing();
|
||||
return dualListingProvider.isShowing();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -836,7 +849,6 @@ public class VTMarkupItemsTableProvider extends ComponentProviderAdapter
|
|||
* @param saveState the configuration state to restore
|
||||
*/
|
||||
public void readConfigState(SaveState saveState) {
|
||||
functionComparisonPanel.readConfigState(getName(), saveState);
|
||||
showComparisonPanelWithinProvider(saveState.getBoolean(SHOW_COMPARISON_PANEL, true));
|
||||
|
||||
for (Filter<VTMarkupItem> filter : filters) {
|
||||
|
@ -881,8 +893,6 @@ public class VTMarkupItemsTableProvider extends ComponentProviderAdapter
|
|||
* @param saveState the new configuration state
|
||||
*/
|
||||
public void writeConfigState(SaveState saveState) {
|
||||
// save config state here
|
||||
functionComparisonPanel.writeConfigState(getName(), saveState);
|
||||
saveState.putBoolean(SHOW_COMPARISON_PANEL, functionComparisonPanel.isShowing());
|
||||
|
||||
for (Filter<VTMarkupItem> filter : filters) {
|
||||
|
@ -947,6 +957,15 @@ public class VTMarkupItemsTableProvider extends ComponentProviderAdapter
|
|||
refilter(); // this will do nothing if we are frozen
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the function comparison panel component that possibly contains multiple different views
|
||||
* for comparing code such as a dual listing.
|
||||
* @return the function comparison panel
|
||||
*/
|
||||
public FunctionComparisonPanel getFunctionComparisonPanel() {
|
||||
return functionComparisonPanel;
|
||||
}
|
||||
|
||||
//==================================================================================================
|
||||
// Inner Classes
|
||||
//==================================================================================================
|
||||
|
@ -1010,13 +1029,4 @@ public class VTMarkupItemsTableProvider extends ComponentProviderAdapter
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the function comparison panel component that possibly contains multiple different views
|
||||
* for comparing code such as a dual listing.
|
||||
* @return the function comparison panel
|
||||
*/
|
||||
public FunctionComparisonPanel getFunctionComparisonPanel() {
|
||||
return functionComparisonPanel;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -52,7 +52,7 @@ import ghidra.feature.vt.gui.provider.onetomany.VTMatchSourceTableProvider;
|
|||
import ghidra.feature.vt.gui.task.*;
|
||||
import ghidra.feature.vt.gui.util.MatchInfo;
|
||||
import ghidra.feature.vt.gui.wizard.add.*;
|
||||
import ghidra.features.base.codecompare.listing.ListingCodeComparisonPanel;
|
||||
import ghidra.features.base.codecompare.listing.ListingCodeComparisonView;
|
||||
import ghidra.framework.main.DataTreeDialog;
|
||||
import ghidra.framework.main.datatree.DataTree;
|
||||
import ghidra.framework.main.datatree.ProjectDataTreePanel;
|
||||
|
@ -765,7 +765,7 @@ public class VersionTrackingPluginScreenShots extends GhidraScreenShotGenerator
|
|||
|
||||
JComponent component = provider.getComponent();
|
||||
Component listingComponent =
|
||||
findComponentByName(component, ListingCodeComparisonPanel.NAME);
|
||||
findComponentByName(component, ListingCodeComparisonView.NAME);
|
||||
if (listingComponent == null) {
|
||||
return false; // not in the parent's hierarchy
|
||||
}
|
||||
|
|
|
@ -4,9 +4,9 @@
|
|||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
@ -193,7 +193,7 @@ public class VTImpliedMatchCorrelatorTest extends AbstractVTCorrelatorTest {
|
|||
// get the resulting implied matches and verify that none of the matches that were already
|
||||
// created
|
||||
VTMatchSet impliedMatchSet = getVTMatchSet("Implied Match");
|
||||
Assert.assertNotEquals("vtMatchSet does not exist", null, impliedMatchSet);
|
||||
assertNotNull(impliedMatchSet);
|
||||
|
||||
// Now test that only the expected items are in this set for the given function we just
|
||||
// applied
|
||||
|
@ -276,9 +276,7 @@ public class VTImpliedMatchCorrelatorTest extends AbstractVTCorrelatorTest {
|
|||
protected VTMatch getMatch(VTMatchSet matches, Address sourceAddress,
|
||||
Address destinationAddress) {
|
||||
|
||||
Iterator<VTMatch> it = matches.getMatches().iterator();
|
||||
while (it.hasNext()) {
|
||||
VTMatch match = it.next();
|
||||
for (VTMatch match : matches.getMatches()) {
|
||||
if (match.getSourceAddress().equals(sourceAddress) &&
|
||||
match.getDestinationAddress().equals(destinationAddress)) {
|
||||
return match;
|
||||
|
|
|
@ -4,9 +4,9 @@
|
|||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
@ -33,9 +33,9 @@ import ghidra.feature.vt.api.db.VTSessionDB;
|
|||
import ghidra.feature.vt.api.main.*;
|
||||
import ghidra.feature.vt.api.util.VTOptions;
|
||||
import ghidra.feature.vt.gui.plugin.*;
|
||||
import ghidra.feature.vt.gui.provider.markuptable.VTMarkupItemsTableProvider;
|
||||
import ghidra.feature.vt.gui.provider.matchtable.VTMatchTableModel;
|
||||
import ghidra.feature.vt.gui.provider.matchtable.VTMatchTableProvider;
|
||||
import ghidra.framework.plugintool.Plugin;
|
||||
import ghidra.framework.plugintool.PluginTool;
|
||||
import ghidra.program.model.listing.Program;
|
||||
import ghidra.test.AbstractGhidraHeadedIntegrationTest;
|
||||
|
@ -56,9 +56,10 @@ public class VTTestEnv extends TestEnv {
|
|||
|
||||
public VTTestEnv() throws Exception {
|
||||
|
||||
PluginTool tool = getTool();
|
||||
tool.removePlugins(new Plugin[] { getPlugin(ProgramManagerPlugin.class) });
|
||||
tool.addPlugin(VTPlugin.class.getName());
|
||||
PluginTool pluignTool = getTool();
|
||||
pluignTool.removePlugins(List.of(getPlugin(ProgramManagerPlugin.class)));
|
||||
pluignTool.addPlugin(VTPlugin.class.getName());
|
||||
|
||||
plugin = getPlugin(VTPlugin.class);
|
||||
controller = (VTController) getInstanceField("controller", plugin);
|
||||
matchTableProvider = (VTMatchTableProvider) getInstanceField("matchesProvider", plugin);
|
||||
|
@ -238,7 +239,19 @@ public class VTTestEnv extends TestEnv {
|
|||
}
|
||||
|
||||
public void focusMatchTable() {
|
||||
runSwing(() -> matchTableProvider.getComponent().requestFocus());
|
||||
runSwing(() -> matchTableProvider.requestFocus());
|
||||
}
|
||||
|
||||
public VTMarkupItemsTableProvider getMarkupItemsProvider() {
|
||||
return (VTMarkupItemsTableProvider) getInstanceField("markupProvider", plugin);
|
||||
}
|
||||
|
||||
public void focusMarkupItemsTable() {
|
||||
VTMarkupItemsTableProvider markupProvider = getMarkupItemsProvider();
|
||||
runSwing(() -> {
|
||||
markupProvider.toFront();
|
||||
markupProvider.requestFocus();
|
||||
});
|
||||
}
|
||||
|
||||
public void triggerMatchTableDataChanged() {
|
||||
|
@ -250,4 +263,5 @@ public class VTTestEnv extends TestEnv {
|
|||
public VTMatchTableProvider getMatchTableProvider() {
|
||||
return matchTableProvider;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue