diff --git a/Ghidra/Features/Base/src/main/help/help/topics/CodeBrowserPlugin/CodeBrowser.htm b/Ghidra/Features/Base/src/main/help/help/topics/CodeBrowserPlugin/CodeBrowser.htm
index 61e648d8e0..3ea8baa9cb 100644
--- a/Ghidra/Features/Base/src/main/help/help/topics/CodeBrowserPlugin/CodeBrowser.htm
+++ b/Ghidra/Features/Base/src/main/help/help/topics/CodeBrowserPlugin/CodeBrowser.htm
@@ -111,21 +111,27 @@
"help/topics/Tool/ToolOptions_Dialog.htm">Edit Tool Options dialog for control over
certain Navigation behaviors.
+
+
In the XRef field, sometimes there are too many addresses to display so the the field will
display "[more]" to indicate that one or more cross-reference addresses are not shown.
Double-clicking on the "[more]" text will cause a Location
- References Dialog to appear. Also, double-clicking on the XREF header text (XREF[n]:) will too show this dialog.
+ "green">XREF[n]: or [more]" text will cause a
+ dialog containing all the Xrefs to appear.
+
+ This differs from the
+ Show References to ... feature in that the Xrefs dialog is simply a display
+ of what already exists in the database, whereas Show References to ... will
+ perform a search to find references additional to what is in the database.
+
This dialog lists all the Xref addresses, any labels that are at that address
and a preview of the instruction at that address. Clicking on any row in the table will cause
- the browser to navigate to that address. Double-clicking will navigate and dismiss the
- dialog.
+ the browser to navigate to that address
diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/context/ProgramLocationActionContext.java b/Ghidra/Features/Base/src/main/java/ghidra/app/context/ProgramLocationActionContext.java
index 6e6018c5a0..d4c40daf1f 100644
--- a/Ghidra/Features/Base/src/main/java/ghidra/app/context/ProgramLocationActionContext.java
+++ b/Ghidra/Features/Base/src/main/java/ghidra/app/context/ProgramLocationActionContext.java
@@ -69,7 +69,8 @@ public class ProgramLocationActionContext extends ProgramActionContext {
}
/**
- * @return the code unit at the action's program location or null
+ * Returns the code unit containing the action's program location or null
+ * @return the code unit containing the action's program location or null
*/
public CodeUnit getCodeUnit() {
if (!codeUnitInitialized) {
diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/codebrowser/CodeBrowserPlugin.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/codebrowser/CodeBrowserPlugin.java
index b274c5d4ad..8e5c3411e9 100644
--- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/codebrowser/CodeBrowserPlugin.java
+++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/codebrowser/CodeBrowserPlugin.java
@@ -21,6 +21,7 @@ import java.awt.event.MouseEvent;
import java.math.BigInteger;
import java.util.*;
import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.function.Supplier;
import javax.swing.ImageIcon;
import javax.swing.JComponent;
@@ -32,12 +33,14 @@ import org.jdom.Element;
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.*;
import ghidra.GhidraOptions;
import ghidra.app.CorePluginPackage;
+import ghidra.app.context.ListingActionContext;
import ghidra.app.events.*;
import ghidra.app.nav.Navigatable;
import ghidra.app.plugin.PluginCategoryNames;
@@ -60,6 +63,7 @@ import ghidra.framework.plugintool.*;
import ghidra.framework.plugintool.util.PluginStatus;
import ghidra.program.model.address.*;
import ghidra.program.model.listing.*;
+import ghidra.program.model.symbol.Reference;
import ghidra.program.util.ProgramLocation;
import ghidra.program.util.ProgramSelection;
import ghidra.util.*;
@@ -121,6 +125,8 @@ public class CodeBrowserPlugin extends Plugin
private FocusingMouseListener focusingMouseListener = new FocusingMouseListener();
private DockingAction tableFromSelectionAction;
+ private DockingAction showXrefsAction;
+
private Color cursorHighlightColor;
private boolean isHighlightCursorLine;
private ProgramDropProvider dndProvider;
@@ -440,6 +446,7 @@ public class CodeBrowserPlugin extends Plugin
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;
@@ -471,6 +478,7 @@ public class CodeBrowserPlugin extends Plugin
if (interfaceClass == TableService.class) {
if (tool != null) {
tool.removeAction(tableFromSelectionAction);
+ tool.removeAction(showXrefsAction);
}
}
if ((service == viewManager) && (currentProgram != null)) {
@@ -902,6 +910,9 @@ public class CodeBrowserPlugin extends Plugin
}
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");
@@ -932,13 +943,35 @@ public class CodeBrowserPlugin extends Plugin
}
};
- // note: this action gets added later when the TableService is added
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
+ }
+
+ Supplier> refs = () -> XReferenceUtil.getAllXrefs(location);
+ XReferenceUtil.showAllXrefs(connectedProvider, tool, service, location, refs);
}
private GhidraProgramTableModel createTableModel(CodeUnitIterator iterator,
diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/codebrowser/CodeViewerProvider.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/codebrowser/CodeViewerProvider.java
index 0ff677a42c..ff7d25c0fe 100644
--- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/codebrowser/CodeViewerProvider.java
+++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/codebrowser/CodeViewerProvider.java
@@ -449,6 +449,7 @@ public class CodeViewerProvider extends NavigatableComponentProviderAdapter
action = new GotoNextFunctionAction(tool, plugin.getName());
tool.addAction(action);
+
}
void fieldOptionChanged(String fieldName, Object newValue) {
diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/navigation/locationreferences/LocationReferencesPanel.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/navigation/locationreferences/LocationReferencesPanel.java
index a7d27011a5..7b345cffb3 100644
--- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/navigation/locationreferences/LocationReferencesPanel.java
+++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/navigation/locationreferences/LocationReferencesPanel.java
@@ -22,7 +22,6 @@ import java.util.Collection;
import javax.swing.JPanel;
import javax.swing.ListSelectionModel;
-import javax.swing.border.TitledBorder;
import javax.swing.event.TableModelListener;
import ghidra.app.services.GoToService;
@@ -57,7 +56,6 @@ public class LocationReferencesPanel extends JPanel {
table.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
setLayout(new BorderLayout(10, 10));
- setBorder(new TitledBorder("Reference(s)"));
PluginTool tool = locationReferencesProvider.getTool();
GoToService goToService = tool.getService(GoToService.class);
diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/XReferenceUtil.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/XReferenceUtil.java
index b86ff6fa2c..b0b895840a 100644
--- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/XReferenceUtil.java
+++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/XReferenceUtil.java
@@ -16,14 +16,24 @@
package ghidra.app.util;
import java.util.*;
+import java.util.function.Supplier;
+import org.apache.commons.collections4.CollectionUtils;
+
+import ghidra.app.nav.Navigatable;
+import ghidra.app.plugin.core.table.TableComponentProvider;
+import ghidra.app.util.query.TableService;
+import ghidra.framework.plugintool.ServiceProvider;
import ghidra.program.model.address.*;
import ghidra.program.model.listing.*;
import ghidra.program.model.symbol.*;
+import ghidra.program.util.ProgramLocation;
+import ghidra.util.table.ReferencesFromTableModel;
+import ghidra.util.table.field.ReferenceEndpoint;
/**
* A utility class to handle the generation of
- * direct and offcut cross-reference (XREF) lists
+ * direct and offcut cross-reference (xref) lists
* on code units and stack variables.
*/
public class XReferenceUtil {
@@ -36,11 +46,11 @@ public class XReferenceUtil {
/**
* Returns an array containing all
- * direct XREF addresses to the specified code unit.
+ * direct xref addresses to the specified code unit.
*
- * @param cu the code unit to generate the XREFs
+ * @param cu the code unit to generate the xrefs
*
- * @return array of all XREFs to the code unit
+ * @return array of all xrefs to the code unit
*/
public final static Address[] getXRefList(CodeUnit cu) {
return getXRefList(cu, -1); // get all
@@ -48,13 +58,13 @@ public class XReferenceUtil {
/**
* Returns an array containing the first maxNumber
- * direct XREF addresses to the specified code unit.
+ * direct xref addresses to the specified code unit.
*
- * @param cu the code unit to generate the XREFs
- * @param maxNumber max number of XREFs to get,
+ * @param cu the code unit to generate the xrefs
+ * @param maxNumber max number of xrefs to get,
* or -1 to get all references
*
- * @return array first maxNumber
XREFs to the code unit
+ * @return array first maxNumber
xrefs to the code unit
*/
public final static Address[] getXRefList(CodeUnit cu, int maxNumber) {
Program prog = cu.getProgram();
@@ -62,7 +72,7 @@ public class XReferenceUtil {
return EMPTY_ADDR_ARRAY;
}
List xrefList = new ArrayList();
- //lookup the direct XREFs to the current code unit
+ //lookup the direct xrefs to the current code unit
//
ReferenceIterator iter = prog.getReferenceManager().getReferencesTo(cu.getMinAddress());
while (iter.hasNext()) {
@@ -80,13 +90,13 @@ public class XReferenceUtil {
/**
* Returns an array containing the first maxNumber
- * direct XREF references to the specified code unit.
+ * direct xref references to the specified code unit.
*
- * @param cu the code unit to generate the XREFs
- * @param maxNumber max number of XREFs to get,
+ * @param cu the code unit to generate the xrefs
+ * @param maxNumber max number of xrefs to get,
* or -1 to get all references
*
- * @return array first maxNumber
XREFs to the code unit
+ * @return array first maxNumber
xrefs to the code unit
*/
public final static Reference[] getXReferences(CodeUnit cu, int maxNumber) {
Program prog = cu.getProgram();
@@ -94,7 +104,7 @@ public class XReferenceUtil {
return EMPTY_REF_ARRAY;
}
List xrefList = new ArrayList();
- //lookup the direct XREFs to the current code unit
+ //lookup the direct xrefs to the current code unit
//
ReferenceIterator iter = prog.getReferenceManager().getReferencesTo(cu.getMinAddress());
while (iter.hasNext()) {
@@ -121,11 +131,11 @@ public class XReferenceUtil {
/**
* Returns an array containing all
- * offcut XREF addresses to the specified code unit.
+ * offcut xref addresses to the specified code unit.
*
- * @param cu the code unit to generate the offcut XREFs
+ * @param cu the code unit to generate the offcut xrefs
*
- * @return array of all offcut XREFs to the code unit
+ * @return array of all offcut xrefs to the code unit
*/
public final static Address[] getOffcutXRefList(CodeUnit cu) {
return getOffcutXRefList(cu, -1); // get all
@@ -133,13 +143,13 @@ public class XReferenceUtil {
/**
* Returns an array containing all
- * offcut XREF addresses to the specified code unit.
+ * offcut xref addresses to the specified code unit.
*
- * @param cu the code unit to generate the offcut XREFs
- * @param maxXRefs max number of offcut XREFs to get,
+ * @param cu the code unit to generate the offcut xrefs
+ * @param maxXRefs max number of offcut xrefs to get,
* or -1 to get all offcut references
*
- * @return array of all offcut XREFs to the code unit
+ * @return array of all offcut xrefs to the code unit
*/
public final static Address[] getOffcutXRefList(CodeUnit cu, int maxXRefs) {
Program prog = cu.getProgram();
@@ -147,7 +157,7 @@ public class XReferenceUtil {
return EMPTY_ADDR_ARRAY;
}
List offcutList = new ArrayList();
- // Lookup the offcut XREFs...
+ // Lookup the offcut xrefs...
//
if (cu.getLength() > 1) {
ReferenceManager refMgr = prog.getReferenceManager();
@@ -173,14 +183,12 @@ public class XReferenceUtil {
}
/**
- * Returns an array containing all
- * offcut XREF references to the specified code unit.
+ * Returns an array containing all offcut xref references to the specified code unit
*
- * @param cu the code unit to generate the offcut XREFs
- * @param maxXRefs max number of offcut XREFs to get,
- * or -1 to get all offcut references
+ * @param cu the code unit to generate the offcut xrefs
+ * @param maxXRefs max number of offcut xrefs to get, or -1 to get all offcut references
*
- * @return array of all offcut XREFs to the code unit
+ * @return array of all offcut xrefs to the code unit
*/
public final static Reference[] getOffcutXReferences(CodeUnit cu, int maxXRefs) {
Program prog = cu.getProgram();
@@ -188,7 +196,7 @@ public class XReferenceUtil {
return EMPTY_REF_ARRAY;
}
List offcutList = new ArrayList();
- // Lookup the offcut XREFs...
+ // Lookup the offcut xrefs...
//
if (cu.getLength() > 1) {
ReferenceManager refMgr = prog.getReferenceManager();
@@ -214,10 +222,9 @@ public class XReferenceUtil {
}
/**
- * Returns the count of all
- * offcut XREF addresses to the specified code unit.
- * @param cu the code unit to generate the offcut XREFs
- * @return count of all offcut XREFs to the code unit
+ * Returns the count of all offcut xref addresses to the specified code unit
+ * @param cu the code unit to generate the offcut xrefs
+ * @return count of all offcut xrefs to the code unit
*/
public static int getOffcutXRefCount(CodeUnit cu) {
Program prog = cu.getProgram();
@@ -243,18 +250,19 @@ public class XReferenceUtil {
}
/**
- * Populates the provided array lists with the direct and
- * offcut XREFs to the specified variable.
+ * Populates the provided lists with the direct and offcut xrefs to the specified variable
*
* @param var variable to get references
- * @param xrefs list to put direct references on
- * @param offcuts list to put offcut references on
+ * @param xrefs list to put direct references in
+ * @param offcuts list to put offcut references in
*/
- public static void getVariableRefs(Variable var, List xrefs, List offcuts) {
+ public static void getVariableRefs(Variable var, List xrefs,
+ List offcuts) {
Address addr = var.getMinAddress();
if (addr == null) {
return;
}
+
Program program = var.getFunction().getProgram();
ReferenceManager refMgr = program.getReferenceManager();
Reference[] vrefs = refMgr.getReferencesTo(var);
@@ -269,18 +277,93 @@ public class XReferenceUtil {
}
/**
- * Get the reference count to the min address of the given code unit.
- * If an external entry exists there, then subtract one from the count.
- * @param cu code unit
- * @return reference count, excluding an external entry reference
+ * Returns the direct and offcut xrefs to the specified variable
+ *
+ * @param var variable to get references
+ * @return the set of references
*/
- public static int getReferenceCount(CodeUnit cu) {
- Program program = cu.getProgram();
- Address toAddr = cu.getMinAddress();
- int count = program.getReferenceManager().getReferenceCountTo(toAddr);
- if (program.getSymbolTable().isExternalEntryPoint(toAddr)) {
- --count;
+ public static Set getVariableRefs(Variable var) {
+
+ Set results = new HashSet<>();
+ Address addr = var.getMinAddress();
+ if (addr == null) {
+ return results;
}
- return count;
+
+ Program program = var.getFunction().getProgram();
+ ReferenceManager refMgr = program.getReferenceManager();
+ Reference[] vrefs = refMgr.getReferencesTo(var);
+ for (Reference vref : vrefs) {
+ results.add(vref);
+ }
+ return results;
+ }
+
+ /**
+ * Shows all xrefs to the given location in a new table. These xrefs are retrieved
+ * from the given supplier. Thus, it is up to the client to determine which xrefs to show.
+ *
+ * @param navigatable the navigatable used for navigation from the table
+ * @param serviceProvider the service provider needed to wire navigation
+ * @param service the service needed to show the table
+ * @param location the location for which to find references
+ * @param xrefs the supplier of xrefs to show
+ */
+ public static void showAllXrefs(Navigatable navigatable, ServiceProvider serviceProvider,
+ TableService service, ProgramLocation location, Supplier> xrefs) {
+
+ Set refs = xrefs.get();
+
+ ReferencesFromTableModel model =
+ new ReferencesFromTableModel(new ArrayList<>(refs), serviceProvider,
+ location.getProgram());
+ TableComponentProvider provider = service.showTable(
+ "XRefs to " + location.getAddress().toString(), "XRefs", model, "XRefs", navigatable);
+ provider.installRemoveItemsAction();
+ }
+
+ /**
+ * Returns all xrefs to the given location. If in data, then xrefs to the specific data
+ * component will be returned. Otherwise, the code unit containing the address of the
+ * given location will be used as the source of the xrefs.
+ *
+ * @param location the location for which to get xrefs
+ * @return the xrefs
+ */
+ public static Set getAllXrefs(ProgramLocation location) {
+
+ CodeUnit cu = getImmediateDataContaining(location);
+ if (cu == null) {
+ Address toAddress = location.getAddress();
+ Listing listing = location.getProgram().getListing();
+ cu = listing.getCodeUnitContaining(toAddress);
+ }
+
+ Reference[] xrefs = getXReferences(cu, ALL_REFS);
+ Reference[] offcuts = getOffcutXReferences(cu, ALL_REFS);
+
+ // Remove duplicates
+ Set set = new HashSet<>();
+ CollectionUtils.addAll(set, xrefs);
+ CollectionUtils.addAll(set, offcuts);
+ return set;
+ }
+
+ /**
+ * Returns the nearest {@link Data} object containing a given address.
+ *
+ * @param location the program location within the data object
+ * @return the Data object
+ */
+ private static Data getImmediateDataContaining(ProgramLocation location) {
+ Address addr = location.getAddress();
+ Listing listing = location.getProgram().getListing();
+ Data dataContaining = listing.getDataContaining(addr);
+ if (dataContaining == null) {
+ return null;
+ }
+
+ Data dataAtAddr = dataContaining.getComponent(location.getComponentPath());
+ return dataAtAddr;
}
}
diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/viewer/field/VariableXRefFieldMouseHandler.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/viewer/field/VariableXRefFieldMouseHandler.java
index c71753f734..4171011fed 100644
--- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/viewer/field/VariableXRefFieldMouseHandler.java
+++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/viewer/field/VariableXRefFieldMouseHandler.java
@@ -15,7 +15,8 @@
*/
package ghidra.app.util.viewer.field;
-import java.util.*;
+import java.util.Set;
+import java.util.function.Supplier;
import ghidra.app.nav.Navigatable;
import ghidra.app.util.XReferenceUtil;
@@ -28,11 +29,10 @@ import ghidra.program.model.symbol.Reference;
import ghidra.program.util.*;
/**
- * A handler to process {@link VariableXRefFieldLocation} clicks.
+ * A handler to process {@link VariableXRefFieldLocation} clicks
*/
public class VariableXRefFieldMouseHandler extends XRefFieldMouseHandler {
-
private final static Class>[] SUPPORTED_CLASSES = new Class>[] {
VariableXRefFieldLocation.class, VariableXRefHeaderFieldLocation.class };
@@ -60,9 +60,6 @@ public class VariableXRefFieldMouseHandler extends XRefFieldMouseHandler {
return ((VariableXRefFieldLocation) programLocation).getIndex();
}
- /**
- * @see XRefFieldMouseHandler#getSupportedProgramLocations()
- */
@Override
public Class>[] getSupportedProgramLocations() {
return SUPPORTED_CLASSES;
@@ -80,27 +77,10 @@ public class VariableXRefFieldMouseHandler extends XRefFieldMouseHandler {
return;
}
- Address toAddress = location.getAddress();
- Program program = navigatable.getProgram();
-
VariableLocation variableLocation = (VariableLocation) location;
Variable variable = variableLocation.getVariable();
- List refs = getReferences(variable);
- showReferenceTable(navigatable, serviceProvider, service, toAddress, program, refs);
- }
-
- private List getReferences(Variable variable) {
-
- List refs = new ArrayList<>();
- List offcutRefs = new ArrayList<>();
- XReferenceUtil.getVariableRefs(variable, refs, offcutRefs);
-
- // Convert to a set before combining lists, to remove duplicates.
- Set refsSet = new HashSet(refs);
- Set offcutRefsSet = new HashSet(offcutRefs);
- refsSet.addAll(offcutRefsSet);
-
- return new ArrayList<>(refsSet);
+ Supplier> refs = () -> XReferenceUtil.getVariableRefs(variable);
+ XReferenceUtil.showAllXrefs(navigatable, serviceProvider, service, location, refs);
}
}
diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/viewer/field/XRefFieldMouseHandler.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/viewer/field/XRefFieldMouseHandler.java
index d3885188fd..e44c22a691 100644
--- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/viewer/field/XRefFieldMouseHandler.java
+++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/viewer/field/XRefFieldMouseHandler.java
@@ -16,7 +16,8 @@
package ghidra.app.util.viewer.field;
import java.awt.event.MouseEvent;
-import java.util.*;
+import java.util.Set;
+import java.util.function.Supplier;
import docking.widgets.fieldpanel.field.FieldElement;
import docking.widgets.fieldpanel.field.TextField;
@@ -26,14 +27,12 @@ import ghidra.app.util.XReferenceUtil;
import ghidra.app.util.query.TableService;
import ghidra.framework.plugintool.ServiceProvider;
import ghidra.program.model.address.Address;
-import ghidra.program.model.listing.*;
+import ghidra.program.model.listing.Program;
import ghidra.program.model.symbol.Reference;
import ghidra.program.util.*;
-import ghidra.util.table.ReferencesFromTableModel;
-import util.CollectionUtils;
/**
- * A handler to process {@link XRefFieldMouseHandler} clicks.
+ * A handler to process {@link XRefFieldMouseHandler} clicks
*/
public class XRefFieldMouseHandler implements FieldMouseHandlerExtension {
@@ -100,61 +99,15 @@ public class XRefFieldMouseHandler implements FieldMouseHandlerExtension {
return ((XRefFieldLocation) programLocation).getIndex();
}
- protected void showXRefDialog(Navigatable navigatable, ProgramLocation location,
+ private void showXRefDialog(Navigatable navigatable, ProgramLocation location,
ServiceProvider serviceProvider) {
TableService service = serviceProvider.getService(TableService.class);
if (service == null) {
return;
}
- Address toAddress = location.getAddress();
- Program program = navigatable.getProgram();
-
- CodeUnit cu = getImmediateDataContaining(location, program);
- if (cu == null) {
- Listing listing = program.getListing();
- cu = listing.getCodeUnitContaining(toAddress);
- }
-
- List refs = getReferences(cu);
- showReferenceTable(navigatable, serviceProvider, service, toAddress, program, refs);
- }
-
- protected void showReferenceTable(Navigatable navigatable, ServiceProvider serviceProvider,
- TableService service, Address toAddress, Program program, List refs) {
- ReferencesFromTableModel model =
- new ReferencesFromTableModel(refs, serviceProvider, program);
- service.showTable("XRefs to " + toAddress.toString(), "XRefs", model, "XRefs", navigatable);
- }
-
- private List getReferences(CodeUnit cu) {
- Reference[] xrefs = XReferenceUtil.getXReferences(cu, XReferenceUtil.ALL_REFS);
- Reference[] offcuts = XReferenceUtil.getOffcutXReferences(cu, XReferenceUtil.ALL_REFS);
-
- // Convert to a set before combining lists, to remove duplicates.
- Set set = CollectionUtils.asSet(xrefs);
- set.addAll(Arrays.asList(offcuts));
-
- return new ArrayList<>(set);
- }
-
- /**
- * Returns the nearest {@link Data} object containing a given address.
- *
- * @param location the program location within the data object
- * @param program the current program
- * @return the Data object
- */
- private Data getImmediateDataContaining(ProgramLocation location, Program program) {
- Address addr = location.getAddress();
- Listing listing = program.getListing();
- Data dataContaining = listing.getDataContaining(addr);
- if (dataContaining == null) {
- return null;
- }
-
- Data dataAtAddr = dataContaining.getComponent(location.getComponentPath());
- return dataAtAddr;
+ Supplier> refs = () -> XReferenceUtil.getAllXrefs(location);
+ XReferenceUtil.showAllXrefs(navigatable, serviceProvider, service, location, refs);
}
protected ProgramLocation getReferredToLocation(Navigatable sourceNavigatable,
diff --git a/Ghidra/Framework/Docking/src/main/java/docking/ComponentPlaceholder.java b/Ghidra/Framework/Docking/src/main/java/docking/ComponentPlaceholder.java
index 3327586c85..797a05fb98 100644
--- a/Ghidra/Framework/Docking/src/main/java/docking/ComponentPlaceholder.java
+++ b/Ghidra/Framework/Docking/src/main/java/docking/ComponentPlaceholder.java
@@ -24,6 +24,7 @@ import javax.swing.*;
import docking.action.DockingAction;
import docking.action.DockingActionIf;
+import ghidra.util.Swing;
import ghidra.util.exception.AssertException;
/**
@@ -60,10 +61,14 @@ public class ComponentPlaceholder {
/**
* XML Constructor!!!!!
- * @param name the name of the component.
- * @param owner the owner of the component.
- * @param show whether or not the component is showing.
- * @param node componentNode that has this placeholder.
+ *
+ * @param name the name of the component
+ * @param owner the owner of the component
+ * @param group the window group
+ * @param title the title
+ * @param show whether or not the component is showing
+ * @param node componentNode that has this placeholder
+ * @param instanceID the instance ID
*/
ComponentPlaceholder(String name, String owner, String group, String title, boolean show,
ComponentNode node, long instanceID) {
@@ -83,7 +88,8 @@ public class ComponentPlaceholder {
}
/**
- * Returns the componentNode containing this placeholder.
+ * Returns the componentNode containing this placeholder
+ * @return the node
*/
ComponentNode getNode() {
return compNode;
@@ -111,7 +117,8 @@ public class ComponentPlaceholder {
}
/**
- * Returns true if the component is not hidden.
+ * Returns true if the component is not hidden
+ * @return true if showing
*/
boolean isShowing() {
return isShowing && componentProvider != null;
@@ -234,19 +241,21 @@ public class ComponentPlaceholder {
* Requests focus for the component associated with this placeholder.
*/
void requestFocus() {
- if (comp != null) {
- compNode.makeSelectedTab(this);
- activateWindow();
-
- // make sure the tab has time to become active before trying to request focus
- comp.requestFocus();
- final Component tmp = comp;// put in temp variable in case another thread deletes it
- SwingUtilities.invokeLater(() -> {
- if (tmp != null) {
- tmp.requestFocus();
- }
- });
+ Component tmp = comp;// put in temp variable in case another thread deletes it
+ if (tmp == null) {
+ return;
}
+
+ compNode.makeSelectedTab(this);
+ activateWindow();
+
+ // make sure the tab has time to become active before trying to request focus
+ tmp.requestFocus();
+
+ Swing.runLater(() -> {
+ tmp.requestFocus();
+ contextChanged();
+ });
}
// makes sure that the given window is not in an iconified state
@@ -273,7 +282,8 @@ public class ComponentPlaceholder {
}
/**
- * Returns a Dockable component that wraps the component for this placeholder.
+ * Returns a Dockable component that wraps the component for this placeholder
+ * @return the component
*/
public DockableComponent getComponent() {
if (disposed) {
@@ -307,8 +317,8 @@ public class ComponentPlaceholder {
}
/**
- * Returns the title for this component.
- * @return the title for this component.
+ * Returns the title for this component
+ * @return the title for this component
*/
public String getTitle() {
return title;
@@ -339,14 +349,16 @@ public class ComponentPlaceholder {
}
/**
- * Returns the owner for the component.
+ * Returns the owner for the component
+ * @return the owner
*/
String getOwner() {
return owner;
}
/**
- * Returns the component associated with this placeholder.
+ * Returns the component associated with this placeholder
+ * @return the component
*/
JComponent getProviderComponent() {
if (componentProvider != null) {
@@ -356,7 +368,8 @@ public class ComponentPlaceholder {
}
/**
- * Returns true if this placeholder's component is currently in a tabbed pane with other components.
+ * Returns true if this placeholder's component is in a tabbed pane with other components
+ * @return true if in a tabbed pane
*/
boolean isStacked() {
if (compNode != null) {
@@ -368,13 +381,15 @@ public class ComponentPlaceholder {
/**
* Returns true if this placeholder is currently associated with a component. If it is not,
* then it exists as a place holder.
+ * @return true if this placeholder is currently associated with a component
*/
boolean hasProvider() {
return componentProvider != null;
}
/**
- * Sets the component provider for this placeholder.
+ * Sets the component provider for this placeholder
+ * @param newProvider the new provider
*/
void setProvider(ComponentProvider newProvider) {
this.componentProvider = newProvider;
@@ -488,15 +503,16 @@ public class ComponentPlaceholder {
}
/**
- * Return iterator over all the local actions defined for this component.
+ * Return iterator over all the local actions defined for this component
+ * @return the actions
*/
Iterator getActions() {
return actions.iterator();
}
/**
- * notifies the node that this component has focus.
- *
+ * Notifies the node that this component has focus
+ * @param state the state
*/
void setSelected(boolean state) {
if (comp != null) {