mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-06 03:50:02 +02:00
GP-1822: consolidate navigate functions
This commit is contained in:
parent
9ae62b1e63
commit
e3892f914f
3 changed files with 81 additions and 123 deletions
|
@ -45,6 +45,7 @@ import ghidra.app.plugin.core.debug.gui.DebuggerResources;
|
||||||
import ghidra.app.plugin.core.debug.gui.DebuggerResources.*;
|
import ghidra.app.plugin.core.debug.gui.DebuggerResources.*;
|
||||||
import ghidra.app.plugin.core.debug.gui.objects.actions.*;
|
import ghidra.app.plugin.core.debug.gui.objects.actions.*;
|
||||||
import ghidra.app.plugin.core.debug.gui.objects.components.*;
|
import ghidra.app.plugin.core.debug.gui.objects.components.*;
|
||||||
|
import ghidra.app.plugin.core.debug.mapping.DebuggerMemoryMapper;
|
||||||
import ghidra.app.services.*;
|
import ghidra.app.services.*;
|
||||||
import ghidra.async.*;
|
import ghidra.async.*;
|
||||||
import ghidra.dbg.*;
|
import ghidra.dbg.*;
|
||||||
|
@ -63,8 +64,7 @@ import ghidra.framework.options.annotation.*;
|
||||||
import ghidra.framework.plugintool.*;
|
import ghidra.framework.plugintool.*;
|
||||||
import ghidra.framework.plugintool.annotation.AutoConfigStateField;
|
import ghidra.framework.plugintool.annotation.AutoConfigStateField;
|
||||||
import ghidra.framework.plugintool.annotation.AutoServiceConsumed;
|
import ghidra.framework.plugintool.annotation.AutoServiceConsumed;
|
||||||
import ghidra.program.model.address.Address;
|
import ghidra.program.model.address.*;
|
||||||
import ghidra.program.model.address.AddressRange;
|
|
||||||
import ghidra.program.model.listing.Program;
|
import ghidra.program.model.listing.Program;
|
||||||
import ghidra.trace.model.Trace;
|
import ghidra.trace.model.Trace;
|
||||||
import ghidra.trace.model.thread.TraceThread;
|
import ghidra.trace.model.thread.TraceThread;
|
||||||
|
@ -1253,6 +1253,21 @@ public class DebuggerObjectsProvider extends ComponentProviderAdapter
|
||||||
|
|
||||||
groupTargetIndex++;
|
groupTargetIndex++;
|
||||||
|
|
||||||
|
new ActionBuilder("GoTo", plugin.getName())
|
||||||
|
.keyBinding("G")
|
||||||
|
.toolBarGroup(DebuggerResources.GROUP_CONTROL, "X" + groupTargetIndex)
|
||||||
|
.popupMenuPath("&GoTo")
|
||||||
|
.popupMenuGroup(DebuggerResources.GROUP_CONTROL, "X" + groupTargetIndex)
|
||||||
|
.helpLocation(AbstractToggleAction.help(plugin))
|
||||||
|
.enabledWhen(ctx -> isInstance(ctx, TargetObject.class))
|
||||||
|
.popupWhen(ctx -> isInstance(ctx, TargetObject.class))
|
||||||
|
.onAction(ctx -> performNavigate(ctx))
|
||||||
|
.enabled(false)
|
||||||
|
.buildAndInstallLocal(this);
|
||||||
|
|
||||||
|
groupTargetIndex++;
|
||||||
|
|
||||||
|
|
||||||
displayAsTreeAction = new DisplayAsTreeAction(tool, plugin.getName(), this);
|
displayAsTreeAction = new DisplayAsTreeAction(tool, plugin.getName(), this);
|
||||||
displayAsTableAction = new DisplayAsTableAction(tool, plugin.getName(), this);
|
displayAsTableAction = new DisplayAsTableAction(tool, plugin.getName(), this);
|
||||||
displayAsGraphAction = new DisplayAsGraphAction(tool, plugin.getName(), this);
|
displayAsGraphAction = new DisplayAsGraphAction(tool, plugin.getName(), this);
|
||||||
|
@ -1545,6 +1560,16 @@ public class DebuggerObjectsProvider extends ComponentProviderAdapter
|
||||||
}, "Couldn't configure one or more options");
|
}, "Couldn't configure one or more options");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void performNavigate(ActionContext context) {
|
||||||
|
performAction(context, false, TargetObject.class, t -> {
|
||||||
|
if (t != null) {
|
||||||
|
Object value = t.getCachedAttribute(TargetObject.VALUE_ATTRIBUTE_NAME);
|
||||||
|
navigateToSelectedObject(t, value);
|
||||||
|
}
|
||||||
|
return AsyncUtils.NIL;
|
||||||
|
}, "Couldn't toggle");
|
||||||
|
}
|
||||||
|
|
||||||
public void initiateConsole(ActionContext context) {
|
public void initiateConsole(ActionContext context) {
|
||||||
performAction(context, false, TargetInterpreter.class, interpreter -> {
|
performAction(context, false, TargetInterpreter.class, interpreter -> {
|
||||||
getPlugin().showConsole(interpreter);
|
getPlugin().showConsole(interpreter);
|
||||||
|
@ -1840,4 +1865,47 @@ public class DebuggerObjectsProvider extends ComponentProviderAdapter
|
||||||
return listener.queue.in;
|
return listener.queue.in;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void navigateToSelectedObject(TargetObject selectedObject, Object value) {
|
||||||
|
if (listingService != null && value != null) {
|
||||||
|
Address addr = null;
|
||||||
|
if (value instanceof Address) {
|
||||||
|
addr = (Address) value;
|
||||||
|
}
|
||||||
|
if (value instanceof AddressRangeImpl) {
|
||||||
|
AddressRangeImpl range = (AddressRangeImpl) value;
|
||||||
|
addr = range.getMinAddress();
|
||||||
|
}
|
||||||
|
if (value instanceof Long) {
|
||||||
|
Long lval = (Long) value;
|
||||||
|
addr = selectedObject.getModel().getAddress("ram", lval);
|
||||||
|
}
|
||||||
|
if (value instanceof String) {
|
||||||
|
String sval = (String) value;
|
||||||
|
addr = stringToAddress(selectedObject, addr, sval);
|
||||||
|
}
|
||||||
|
if (modelService != null && addr != null) {
|
||||||
|
TraceRecorder recorder = modelService.getRecorderForSuccessor(selectedObject);
|
||||||
|
DebuggerMemoryMapper memoryMapper = recorder.getMemoryMapper();
|
||||||
|
Address traceAddr = memoryMapper.targetToTrace(addr);
|
||||||
|
listingService.goTo(traceAddr, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Address stringToAddress(TargetObject selectedObject, Address addr, String sval) {
|
||||||
|
Integer base = 16;
|
||||||
|
if (selectedObject instanceof TargetConfigurable) {
|
||||||
|
TargetConfigurable configurable = (TargetConfigurable) selectedObject;
|
||||||
|
base =
|
||||||
|
(Integer) configurable.getCachedAttribute(TargetConfigurable.BASE_ATTRIBUTE_NAME);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
Long lval = Long.parseLong(sval, base);
|
||||||
|
addr = selectedObject.getModel().getAddress("ram", lval);
|
||||||
|
}
|
||||||
|
catch (NumberFormatException nfe) {
|
||||||
|
// IGNORE
|
||||||
|
}
|
||||||
|
return addr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,11 +27,7 @@ import docking.widgets.table.AbstractSortedTableModel;
|
||||||
import docking.widgets.table.EnumeratedColumnTableModel;
|
import docking.widgets.table.EnumeratedColumnTableModel;
|
||||||
import ghidra.app.plugin.core.debug.gui.objects.DebuggerObjectsProvider;
|
import ghidra.app.plugin.core.debug.gui.objects.DebuggerObjectsProvider;
|
||||||
import ghidra.app.plugin.core.debug.gui.objects.ObjectContainer;
|
import ghidra.app.plugin.core.debug.gui.objects.ObjectContainer;
|
||||||
import ghidra.app.plugin.core.debug.mapping.DebuggerMemoryMapper;
|
|
||||||
import ghidra.app.services.*;
|
|
||||||
import ghidra.dbg.target.TargetObject;
|
import ghidra.dbg.target.TargetObject;
|
||||||
import ghidra.program.model.address.Address;
|
|
||||||
import ghidra.program.model.address.AddressRangeImpl;
|
|
||||||
import ghidra.util.Swing;
|
import ghidra.util.Swing;
|
||||||
import ghidra.util.table.GhidraTable;
|
import ghidra.util.table.GhidraTable;
|
||||||
import resources.ResourceManager;
|
import resources.ResourceManager;
|
||||||
|
@ -45,8 +41,6 @@ public class ObjectTable<R> implements ObjectPane {
|
||||||
private AbstractSortedTableModel<R> model;
|
private AbstractSortedTableModel<R> model;
|
||||||
private GhidraTable table;
|
private GhidraTable table;
|
||||||
private JScrollPane component;
|
private JScrollPane component;
|
||||||
private DebuggerListingService listingService;
|
|
||||||
private DebuggerModelService modelService;
|
|
||||||
|
|
||||||
public ObjectTable(ObjectContainer container, Class<R> clazz,
|
public ObjectTable(ObjectContainer container, Class<R> clazz,
|
||||||
AbstractSortedTableModel<R> model) {
|
AbstractSortedTableModel<R> model) {
|
||||||
|
@ -55,8 +49,6 @@ public class ObjectTable<R> implements ObjectPane {
|
||||||
this.container = container;
|
this.container = container;
|
||||||
this.clazz = clazz;
|
this.clazz = clazz;
|
||||||
this.model = model;
|
this.model = model;
|
||||||
this.listingService = container.getProvider().getListingService();
|
|
||||||
this.modelService = container.getProvider().getModelService();
|
|
||||||
|
|
||||||
table.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
|
table.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
|
||||||
@Override
|
@Override
|
||||||
|
@ -72,7 +64,11 @@ public class ObjectTable<R> implements ObjectPane {
|
||||||
@Override
|
@Override
|
||||||
public void mouseClicked(MouseEvent e) {
|
public void mouseClicked(MouseEvent e) {
|
||||||
if (e.getClickCount() == 2) {
|
if (e.getClickCount() == 2) {
|
||||||
navigateToSelectedObject();
|
int selectedRow = table.getSelectedRow();
|
||||||
|
int selectedColumn = table.getSelectedColumn();
|
||||||
|
Object value = table.getValueAt(selectedRow, selectedColumn);
|
||||||
|
container.getProvider()
|
||||||
|
.navigateToSelectedObject(container.getTargetObject(), value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -279,54 +275,4 @@ public class ObjectTable<R> implements ObjectPane {
|
||||||
container.setTargetObject(targetObject);
|
container.setTargetObject(targetObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void navigateToSelectedObject() {
|
|
||||||
if (listingService != null) {
|
|
||||||
int selectedRow = table.getSelectedRow();
|
|
||||||
int selectedColumn = table.getSelectedColumn();
|
|
||||||
Object value = table.getValueAt(selectedRow, selectedColumn);
|
|
||||||
Address addr = null;
|
|
||||||
if (value instanceof Address) {
|
|
||||||
addr = (Address) value;
|
|
||||||
}
|
|
||||||
if (value instanceof AddressRangeImpl) {
|
|
||||||
AddressRangeImpl range = (AddressRangeImpl) value;
|
|
||||||
addr = range.getMinAddress();
|
|
||||||
}
|
|
||||||
if (value instanceof Long) {
|
|
||||||
Long lval = (Long) value;
|
|
||||||
addr = container.getTargetObject().getModel().getAddress("ram", lval);
|
|
||||||
}
|
|
||||||
if (value instanceof String) {
|
|
||||||
String sval = (String) value;
|
|
||||||
addr = stringToAddress(container.getTargetObject(), addr, sval);
|
|
||||||
}
|
|
||||||
if (modelService != null) {
|
|
||||||
TraceRecorder recorder =
|
|
||||||
modelService.getRecorderForSuccessor(container.getTargetObject());
|
|
||||||
DebuggerMemoryMapper memoryMapper = recorder.getMemoryMapper();
|
|
||||||
Address traceAddr = memoryMapper.targetToTrace(addr);
|
|
||||||
listingService.goTo(traceAddr, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private Address stringToAddress(TargetObject selectedObject, Address addr, String sval) {
|
|
||||||
try {
|
|
||||||
Long lval = Long.decode(sval);
|
|
||||||
addr = selectedObject.getModel().getAddress("ram", lval);
|
|
||||||
}
|
|
||||||
catch (NumberFormatException nfe) {
|
|
||||||
// IGNORE
|
|
||||||
}
|
|
||||||
if (addr == null) {
|
|
||||||
try {
|
|
||||||
Long lval = Long.decode("0x" + sval);
|
|
||||||
addr = selectedObject.getModel().getAddress("ram", lval);
|
|
||||||
}
|
|
||||||
catch (NumberFormatException nfe) {
|
|
||||||
// IGNORE
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return addr;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,15 +35,11 @@ import docking.widgets.tree.support.GTreeSelectionEvent.EventOrigin;
|
||||||
import docking.widgets.tree.support.GTreeSelectionListener;
|
import docking.widgets.tree.support.GTreeSelectionListener;
|
||||||
import ghidra.app.plugin.core.debug.gui.objects.DebuggerObjectsProvider;
|
import ghidra.app.plugin.core.debug.gui.objects.DebuggerObjectsProvider;
|
||||||
import ghidra.app.plugin.core.debug.gui.objects.ObjectContainer;
|
import ghidra.app.plugin.core.debug.gui.objects.ObjectContainer;
|
||||||
import ghidra.app.plugin.core.debug.mapping.DebuggerMemoryMapper;
|
|
||||||
import ghidra.app.services.*;
|
|
||||||
import ghidra.async.AsyncUtils;
|
import ghidra.async.AsyncUtils;
|
||||||
import ghidra.async.TypeSpec;
|
import ghidra.async.TypeSpec;
|
||||||
import ghidra.dbg.DebugModelConventions;
|
import ghidra.dbg.DebugModelConventions;
|
||||||
import ghidra.dbg.target.TargetAccessConditioned;
|
import ghidra.dbg.target.TargetAccessConditioned;
|
||||||
import ghidra.dbg.target.TargetObject;
|
import ghidra.dbg.target.TargetObject;
|
||||||
import ghidra.program.model.address.Address;
|
|
||||||
import ghidra.program.model.address.AddressRangeImpl;
|
|
||||||
import ghidra.util.*;
|
import ghidra.util.*;
|
||||||
import ghidra.util.task.SwingUpdateManager;
|
import ghidra.util.task.SwingUpdateManager;
|
||||||
import resources.ResourceManager;
|
import resources.ResourceManager;
|
||||||
|
@ -63,17 +59,11 @@ public class ObjectTree implements ObjectPane {
|
||||||
private SwingUpdateManager restoreTreeStateManager =
|
private SwingUpdateManager restoreTreeStateManager =
|
||||||
new SwingUpdateManager(this::restoreTreeState);
|
new SwingUpdateManager(this::restoreTreeState);
|
||||||
|
|
||||||
private DebuggerListingService listingService;
|
|
||||||
private DebuggerModelService modelService;
|
|
||||||
|
|
||||||
public ObjectTree(ObjectContainer container) {
|
public ObjectTree(ObjectContainer container) {
|
||||||
this.root = new ObjectNode(this, null, container);
|
this.root = new ObjectNode(this, null, container);
|
||||||
addToMap(null, container, root);
|
addToMap(null, container, root);
|
||||||
this.tree = new GTree(root);
|
this.tree = new GTree(root);
|
||||||
|
|
||||||
this.listingService = container.getProvider().getListingService();
|
|
||||||
this.modelService = container.getProvider().getModelService();
|
|
||||||
|
|
||||||
tree.addGTreeSelectionListener(new GTreeSelectionListener() {
|
tree.addGTreeSelectionListener(new GTreeSelectionListener() {
|
||||||
@Override
|
@Override
|
||||||
public void valueChanged(GTreeSelectionEvent e) {
|
public void valueChanged(GTreeSelectionEvent e) {
|
||||||
|
@ -165,7 +155,12 @@ public class ObjectTree implements ObjectPane {
|
||||||
@Override
|
@Override
|
||||||
public void mouseClicked(MouseEvent e) {
|
public void mouseClicked(MouseEvent e) {
|
||||||
if (e.getClickCount() == 2) {
|
if (e.getClickCount() == 2) {
|
||||||
navigateToSelectedObject();
|
TargetObject selectedObject = getSelectedObject();
|
||||||
|
if (selectedObject != null) {
|
||||||
|
Object value =
|
||||||
|
selectedObject.getCachedAttribute(TargetObject.VALUE_ATTRIBUTE_NAME);
|
||||||
|
container.getProvider().navigateToSelectedObject(selectedObject, value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -407,55 +402,4 @@ public class ObjectTree implements ObjectPane {
|
||||||
nodeMap.remove(path(node.getContainer()));
|
nodeMap.remove(path(node.getContainer()));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void navigateToSelectedObject() {
|
|
||||||
if (listingService != null) {
|
|
||||||
TargetObject selectedObject = getSelectedObject();
|
|
||||||
if (selectedObject == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Object value = selectedObject.getCachedAttribute(TargetObject.VALUE_ATTRIBUTE_NAME);
|
|
||||||
Address addr = null;
|
|
||||||
if (value instanceof Address) {
|
|
||||||
addr = (Address) value;
|
|
||||||
}
|
|
||||||
if (value instanceof AddressRangeImpl) {
|
|
||||||
AddressRangeImpl range = (AddressRangeImpl) value;
|
|
||||||
addr = range.getMinAddress();
|
|
||||||
}
|
|
||||||
if (value instanceof Long) {
|
|
||||||
Long lval = (Long) value;
|
|
||||||
addr = selectedObject.getModel().getAddress("ram", lval);
|
|
||||||
}
|
|
||||||
if (value instanceof String) {
|
|
||||||
String sval = (String) value;
|
|
||||||
addr = stringToAddress(selectedObject, addr, sval);
|
|
||||||
}
|
|
||||||
if (modelService != null && addr != null) {
|
|
||||||
TraceRecorder recorder = modelService.getRecorderForSuccessor(selectedObject);
|
|
||||||
DebuggerMemoryMapper memoryMapper = recorder.getMemoryMapper();
|
|
||||||
Address traceAddr = memoryMapper.targetToTrace(addr);
|
|
||||||
listingService.goTo(traceAddr, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private Address stringToAddress(TargetObject selectedObject, Address addr, String sval) {
|
|
||||||
try {
|
|
||||||
Long lval = Long.decode(sval);
|
|
||||||
addr = selectedObject.getModel().getAddress("ram", lval);
|
|
||||||
}
|
|
||||||
catch (NumberFormatException nfe) {
|
|
||||||
// IGNORE
|
|
||||||
}
|
|
||||||
if (addr == null) {
|
|
||||||
try {
|
|
||||||
Long lval = Long.decode("0x" + sval);
|
|
||||||
addr = selectedObject.getModel().getAddress("ram", lval);
|
|
||||||
}
|
|
||||||
catch (NumberFormatException nfe) {
|
|
||||||
// IGNORE
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return addr;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue