mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-05 19:42:36 +02:00
Merge remote-tracking branch 'origin/GT-3446-dragonmacher-refs-to-key-binding'
This commit is contained in:
commit
87839a58eb
10 changed files with 219 additions and 178 deletions
|
@ -111,21 +111,27 @@
|
|||
"help/topics/Tool/ToolOptions_Dialog.htm">Edit Tool Options</A> dialog for control over
|
||||
certain Navigation behaviors.</P>
|
||||
|
||||
|
||||
<A name="Show_Xrefs"></A>
|
||||
<P>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.</P>
|
||||
|
||||
<BLOCKQUOTE>
|
||||
<P><IMG border="0" src="../../shared/tip.png" alt=""> Double-clicking on the "<FONT color=
|
||||
"green"><TT>[more]</TT></FONT>" text will cause a <A href=
|
||||
"help/topics/LocationReferencesPlugin/Location_References.html#LocationReferencesPlugin">Location
|
||||
References Dialog</A> to appear. Also, double-clicking on the XREF header text (<FONT
|
||||
color="green"><TT>XREF[n]:</TT></FONT>) will too show this dialog.</P>
|
||||
"green"><TT>XREF[n]:</TT></FONT> or <FONT><TT>[more]</TT></FONT>" text will cause a
|
||||
dialog containing all the Xrefs to appear.</P>
|
||||
<P>
|
||||
This differs from the <A href=
|
||||
"help/topics/LocationReferencesPlugin/Location_References.html#LocationReferencesPlugin">
|
||||
<B>Show References to ...</B></A> feature in that the Xrefs dialog is simply a display
|
||||
of what already exists in the database, whereas <B>Show References to ...</B> will
|
||||
perform a search to find references additional to what is in the database.
|
||||
</P>
|
||||
</BLOCKQUOTE>
|
||||
|
||||
<P align="left">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.</P>
|
||||
the browser to navigate to that address</P>
|
||||
</BLOCKQUOTE>
|
||||
|
||||
<H2><A NAME="Keyboard_Controls">Keyboard Controls</H2>
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -32,12 +32,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 +62,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 +124,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 +445,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 +477,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 +909,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 +942,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
|
||||
}
|
||||
|
||||
Set<Reference> refs = XReferenceUtil.getAllXrefs(location);
|
||||
XReferenceUtil.showAllXrefs(connectedProvider, tool, service, location, refs);
|
||||
}
|
||||
|
||||
private GhidraProgramTableModel<Address> createTableModel(CodeUnitIterator iterator,
|
||||
|
|
|
@ -449,6 +449,7 @@ public class CodeViewerProvider extends NavigatableComponentProviderAdapter
|
|||
|
||||
action = new GotoNextFunctionAction(tool, plugin.getName());
|
||||
tool.addAction(action);
|
||||
|
||||
}
|
||||
|
||||
void fieldOptionChanged(String fieldName, Object newValue) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -17,13 +17,23 @@ package ghidra.app.util;
|
|||
|
||||
import java.util.*;
|
||||
|
||||
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.data.DataUtilities;
|
||||
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 <b><code>maxNumber</code></b>
|
||||
* 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 <b><code>maxNumber</code></b> XREFs to the code unit
|
||||
* @return array first <b><code>maxNumber</code></b> 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<Address> xrefList = new ArrayList<Address>();
|
||||
//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 <b><code>maxNumber</code></b>
|
||||
* 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 <b><code>maxNumber</code></b> XREFs to the code unit
|
||||
* @return array first <b><code>maxNumber</code></b> 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<Reference> xrefList = new ArrayList<Reference>();
|
||||
//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<Address> offcutList = new ArrayList<Address>();
|
||||
// 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<Reference> offcutList = new ArrayList<Reference>();
|
||||
// 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<Reference> xrefs, List<Reference> offcuts) {
|
||||
public static void getVariableRefs(Variable var, List<Reference> xrefs,
|
||||
List<Reference> 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,73 @@ 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<Reference> getVariableRefs(Variable var) {
|
||||
|
||||
Set<Reference> 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 xrefs to show
|
||||
*/
|
||||
public static void showAllXrefs(Navigatable navigatable, ServiceProvider serviceProvider,
|
||||
TableService service, ProgramLocation location, Set<Reference> xrefs) {
|
||||
|
||||
ReferencesFromTableModel model =
|
||||
new ReferencesFromTableModel(new ArrayList<>(xrefs), serviceProvider,
|
||||
location.getProgram());
|
||||
TableComponentProvider<ReferenceEndpoint> 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<Reference> getAllXrefs(ProgramLocation location) {
|
||||
|
||||
CodeUnit cu = DataUtilities.getDataAtLocation(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<Reference> set = new HashSet<>();
|
||||
CollectionUtils.addAll(set, xrefs);
|
||||
CollectionUtils.addAll(set, offcuts);
|
||||
return set;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
*/
|
||||
package ghidra.app.util.viewer.field;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.Set;
|
||||
|
||||
import ghidra.app.nav.Navigatable;
|
||||
import ghidra.app.util.XReferenceUtil;
|
||||
|
@ -28,11 +28,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 +59,6 @@ public class VariableXRefFieldMouseHandler extends XRefFieldMouseHandler {
|
|||
return ((VariableXRefFieldLocation) programLocation).getIndex();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see XRefFieldMouseHandler#getSupportedProgramLocations()
|
||||
*/
|
||||
@Override
|
||||
public Class<?>[] getSupportedProgramLocations() {
|
||||
return SUPPORTED_CLASSES;
|
||||
|
@ -80,27 +76,10 @@ public class VariableXRefFieldMouseHandler extends XRefFieldMouseHandler {
|
|||
return;
|
||||
}
|
||||
|
||||
Address toAddress = location.getAddress();
|
||||
Program program = navigatable.getProgram();
|
||||
|
||||
VariableLocation variableLocation = (VariableLocation) location;
|
||||
Variable variable = variableLocation.getVariable();
|
||||
|
||||
List<Reference> refs = getReferences(variable);
|
||||
showReferenceTable(navigatable, serviceProvider, service, toAddress, program, refs);
|
||||
}
|
||||
|
||||
private List<Reference> getReferences(Variable variable) {
|
||||
|
||||
List<Reference> refs = new ArrayList<>();
|
||||
List<Reference> offcutRefs = new ArrayList<>();
|
||||
XReferenceUtil.getVariableRefs(variable, refs, offcutRefs);
|
||||
|
||||
// Convert to a set before combining lists, to remove duplicates.
|
||||
Set<Reference> refsSet = new HashSet<Reference>(refs);
|
||||
Set<Reference> offcutRefsSet = new HashSet<Reference>(offcutRefs);
|
||||
refsSet.addAll(offcutRefsSet);
|
||||
|
||||
return new ArrayList<>(refsSet);
|
||||
Set<Reference> refs = XReferenceUtil.getVariableRefs(variable);
|
||||
XReferenceUtil.showAllXrefs(navigatable, serviceProvider, service, location, refs);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
package ghidra.app.util.viewer.field;
|
||||
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.util.*;
|
||||
import java.util.Set;
|
||||
|
||||
import docking.widgets.fieldpanel.field.FieldElement;
|
||||
import docking.widgets.fieldpanel.field.TextField;
|
||||
|
@ -26,14 +26,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 +98,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<Reference> refs = getReferences(cu);
|
||||
showReferenceTable(navigatable, serviceProvider, service, toAddress, program, refs);
|
||||
}
|
||||
|
||||
protected void showReferenceTable(Navigatable navigatable, ServiceProvider serviceProvider,
|
||||
TableService service, Address toAddress, Program program, List<Reference> refs) {
|
||||
ReferencesFromTableModel model =
|
||||
new ReferencesFromTableModel(refs, serviceProvider, program);
|
||||
service.showTable("XRefs to " + toAddress.toString(), "XRefs", model, "XRefs", navigatable);
|
||||
}
|
||||
|
||||
private List<Reference> 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<Reference> 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;
|
||||
Set<Reference> refs = XReferenceUtil.getAllXrefs(location);
|
||||
XReferenceUtil.showAllXrefs(navigatable, serviceProvider, service, location, refs);
|
||||
}
|
||||
|
||||
protected ProgramLocation getReferredToLocation(Navigatable sourceNavigatable,
|
||||
|
|
|
@ -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,20 +241,22 @@ public class ComponentPlaceholder {
|
|||
* Requests focus for the component associated with this placeholder.
|
||||
*/
|
||||
void requestFocus() {
|
||||
if (comp != null) {
|
||||
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
|
||||
comp.requestFocus();
|
||||
final Component tmp = comp;// put in temp variable in case another thread deletes it
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
if (tmp != null) {
|
||||
tmp.requestFocus();
|
||||
}
|
||||
|
||||
Swing.runLater(() -> {
|
||||
tmp.requestFocus();
|
||||
contextChanged();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// makes sure that the given window is not in an iconified state
|
||||
private void activateWindow() {
|
||||
|
@ -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<DockingActionIf> 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) {
|
||||
|
|
|
@ -326,20 +326,13 @@ public final class DataUtilities {
|
|||
|
||||
Address addr = loc.getAddress();
|
||||
Listing listing = loc.getProgram().getListing();
|
||||
CodeUnit cu = listing.getCodeUnitAt(addr);
|
||||
if (cu == null) {
|
||||
cu = listing.getCodeUnitContaining(addr);
|
||||
Data dataContaining = listing.getDataContaining(addr);
|
||||
if (dataContaining == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (cu instanceof Data) {
|
||||
Data d = (Data) cu;
|
||||
int[] compPath = loc.getComponentPath();
|
||||
if (compPath != null) {
|
||||
d = d.getComponent(compPath);
|
||||
}
|
||||
return d;
|
||||
}
|
||||
return null;
|
||||
Data dataAtAddr = dataContaining.getComponent(loc.getComponentPath());
|
||||
return dataAtAddr;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue