mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-06-01 02:34:37 +08:00
Merge remote-tracking branch 'origin/GP-1822_d-millar_navigation_improvements' into patch
This commit is contained in:
+1
@@ -170,6 +170,7 @@ public class DbgModelTargetRegisterContainerImpl extends DbgModelTargetObjectImp
|
|||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public Map<String, byte[]> getCachedRegisters() {
|
public Map<String, byte[]> getCachedRegisters() {
|
||||||
return values;
|
return values;
|
||||||
}
|
}
|
||||||
|
|||||||
+8
-3
@@ -25,9 +25,14 @@ import ghidra.dbg.target.TargetRegister;
|
|||||||
import ghidra.dbg.target.schema.*;
|
import ghidra.dbg.target.schema.*;
|
||||||
import ghidra.dbg.util.PathUtils;
|
import ghidra.dbg.util.PathUtils;
|
||||||
|
|
||||||
@TargetObjectSchemaInfo(name = "RegisterDescriptor", elements = {
|
@TargetObjectSchemaInfo(
|
||||||
@TargetElementType(type = Void.class) }, attributes = {
|
name = "RegisterDescriptor",
|
||||||
@TargetAttributeType(name = TargetRegister.CONTAINER_ATTRIBUTE_NAME, type = DbgModelTargetRegisterContainerImpl.class),
|
elements = {
|
||||||
|
@TargetElementType(type = Void.class) },
|
||||||
|
attributes = {
|
||||||
|
@TargetAttributeType(
|
||||||
|
name = TargetRegister.CONTAINER_ATTRIBUTE_NAME,
|
||||||
|
type = DbgModelTargetRegisterContainerImpl.class),
|
||||||
@TargetAttributeType(type = Void.class) })
|
@TargetAttributeType(type = Void.class) })
|
||||||
public class DbgModelTargetRegisterImpl extends DbgModelTargetObjectImpl
|
public class DbgModelTargetRegisterImpl extends DbgModelTargetObjectImpl
|
||||||
implements DbgModelTargetRegister {
|
implements DbgModelTargetRegister {
|
||||||
|
|||||||
+10
-8
@@ -27,6 +27,7 @@ import ghidra.dbg.target.TargetObject;
|
|||||||
import ghidra.dbg.target.schema.*;
|
import ghidra.dbg.target.schema.*;
|
||||||
import ghidra.dbg.util.PathUtils;
|
import ghidra.dbg.util.PathUtils;
|
||||||
import ghidra.program.model.address.Address;
|
import ghidra.program.model.address.Address;
|
||||||
|
import ghidra.program.model.address.AddressSpace;
|
||||||
|
|
||||||
@TargetObjectSchemaInfo(
|
@TargetObjectSchemaInfo(
|
||||||
name = "StackFrame",
|
name = "StackFrame",
|
||||||
@@ -41,16 +42,16 @@ import ghidra.program.model.address.Address;
|
|||||||
type = String.class),
|
type = String.class),
|
||||||
@TargetAttributeType(
|
@TargetAttributeType(
|
||||||
name = DbgModelTargetStackFrame.INST_OFFSET_ATTRIBUTE_NAME,
|
name = DbgModelTargetStackFrame.INST_OFFSET_ATTRIBUTE_NAME,
|
||||||
type = String.class),
|
type = Address.class),
|
||||||
@TargetAttributeType(
|
@TargetAttributeType(
|
||||||
name = DbgModelTargetStackFrame.FRAME_OFFSET_ATTRIBUTE_NAME,
|
name = DbgModelTargetStackFrame.FRAME_OFFSET_ATTRIBUTE_NAME,
|
||||||
type = String.class),
|
type = Address.class),
|
||||||
@TargetAttributeType(
|
@TargetAttributeType(
|
||||||
name = DbgModelTargetStackFrame.RETURN_OFFSET_ATTRIBUTE_NAME,
|
name = DbgModelTargetStackFrame.RETURN_OFFSET_ATTRIBUTE_NAME,
|
||||||
type = String.class),
|
type = Address.class),
|
||||||
@TargetAttributeType(
|
@TargetAttributeType(
|
||||||
name = DbgModelTargetStackFrame.STACK_OFFSET_ATTRIBUTE_NAME,
|
name = DbgModelTargetStackFrame.STACK_OFFSET_ATTRIBUTE_NAME,
|
||||||
type = String.class),
|
type = Address.class),
|
||||||
@TargetAttributeType(
|
@TargetAttributeType(
|
||||||
name = DbgModelTargetStackFrame.VIRTUAL_ATTRIBUTE_NAME,
|
name = DbgModelTargetStackFrame.VIRTUAL_ATTRIBUTE_NAME,
|
||||||
type = Boolean.class),
|
type = Boolean.class),
|
||||||
@@ -141,15 +142,16 @@ public class DbgModelTargetStackFrameImpl extends DbgModelTargetObjectImpl
|
|||||||
// TODO: module? "from"
|
// TODO: module? "from"
|
||||||
this.frame = frame;
|
this.frame = frame;
|
||||||
|
|
||||||
|
AddressSpace space = getModel().getAddressSpace("ram");
|
||||||
changeAttributes(List.of(), List.of(), Map.of( //
|
changeAttributes(List.of(), List.of(), Map.of( //
|
||||||
PC_ATTRIBUTE_NAME, pc, //
|
PC_ATTRIBUTE_NAME, pc, //
|
||||||
DISPLAY_ATTRIBUTE_NAME, display = computeDisplay(frame), //
|
DISPLAY_ATTRIBUTE_NAME, display = computeDisplay(frame), //
|
||||||
FUNC_ATTRIBUTE_NAME, func, //
|
FUNC_ATTRIBUTE_NAME, func, //
|
||||||
FUNC_TABLE_ENTRY_ATTRIBUTE_NAME, Long.toHexString(funcTableEntry), //
|
FUNC_TABLE_ENTRY_ATTRIBUTE_NAME, Long.toHexString(funcTableEntry), //
|
||||||
INST_OFFSET_ATTRIBUTE_NAME, Long.toHexString(lval), //
|
INST_OFFSET_ATTRIBUTE_NAME, space.getAddress(lval), //
|
||||||
FRAME_OFFSET_ATTRIBUTE_NAME, Long.toHexString(frameOffset), //
|
FRAME_OFFSET_ATTRIBUTE_NAME, space.getAddress(frameOffset), //
|
||||||
RETURN_OFFSET_ATTRIBUTE_NAME, Long.toHexString(returnOffset), //
|
RETURN_OFFSET_ATTRIBUTE_NAME, space.getAddress(returnOffset), //
|
||||||
STACK_OFFSET_ATTRIBUTE_NAME, Long.toHexString(stackOffset), //
|
STACK_OFFSET_ATTRIBUTE_NAME, space.getAddress(stackOffset), //
|
||||||
VIRTUAL_ATTRIBUTE_NAME, virtual //
|
VIRTUAL_ATTRIBUTE_NAME, virtual //
|
||||||
), "Refreshed");
|
), "Refreshed");
|
||||||
changeAttributes(List.of(), List.of(), Map.of( //
|
changeAttributes(List.of(), List.of(), Map.of( //
|
||||||
|
|||||||
+2
-1
@@ -104,7 +104,8 @@ public class GdbModelTargetStackFrame extends DefaultTargetObject<TargetObject,
|
|||||||
), Map.of( //
|
), Map.of( //
|
||||||
PC_ATTRIBUTE_NAME, pc, //
|
PC_ATTRIBUTE_NAME, pc, //
|
||||||
FUNC_ATTRIBUTE_NAME, func, //
|
FUNC_ATTRIBUTE_NAME, func, //
|
||||||
DISPLAY_ATTRIBUTE_NAME, display = computeDisplay(frame) //
|
DISPLAY_ATTRIBUTE_NAME, display = computeDisplay(frame), //
|
||||||
|
VALUE_ATTRIBUTE_NAME, pc //
|
||||||
), "Refreshed");
|
), "Refreshed");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+14
-10
@@ -31,6 +31,7 @@ import ghidra.dbg.target.schema.*;
|
|||||||
import ghidra.dbg.target.schema.TargetObjectSchema.ResyncMode;
|
import ghidra.dbg.target.schema.TargetObjectSchema.ResyncMode;
|
||||||
import ghidra.dbg.util.PathUtils;
|
import ghidra.dbg.util.PathUtils;
|
||||||
import ghidra.program.model.address.Address;
|
import ghidra.program.model.address.Address;
|
||||||
|
import ghidra.program.model.address.AddressSpace;
|
||||||
|
|
||||||
@TargetObjectSchemaInfo(
|
@TargetObjectSchemaInfo(
|
||||||
name = "StackFrame",
|
name = "StackFrame",
|
||||||
@@ -50,19 +51,19 @@ import ghidra.program.model.address.Address;
|
|||||||
type = String.class),
|
type = String.class),
|
||||||
@TargetAttributeType(
|
@TargetAttributeType(
|
||||||
name = LldbModelTargetStackFrame.INST_OFFSET_ATTRIBUTE_NAME,
|
name = LldbModelTargetStackFrame.INST_OFFSET_ATTRIBUTE_NAME,
|
||||||
type = String.class),
|
type = Address.class),
|
||||||
@TargetAttributeType(
|
@TargetAttributeType(
|
||||||
name = LldbModelTargetStackFrame.FRAME_OFFSET_ATTRIBUTE_NAME,
|
name = LldbModelTargetStackFrame.FRAME_OFFSET_ATTRIBUTE_NAME,
|
||||||
type = String.class),
|
type = Address.class),
|
||||||
@TargetAttributeType(
|
@TargetAttributeType(
|
||||||
name = LldbModelTargetStackFrame.RETURN_OFFSET_ATTRIBUTE_NAME,
|
name = LldbModelTargetStackFrame.RETURN_OFFSET_ATTRIBUTE_NAME,
|
||||||
type = String.class),
|
type = Address.class),
|
||||||
@TargetAttributeType(
|
@TargetAttributeType(
|
||||||
name = LldbModelTargetStackFrame.CALL_FRAME_OFFSET_ATTRIBUTE_NAME,
|
name = LldbModelTargetStackFrame.CALL_FRAME_OFFSET_ATTRIBUTE_NAME,
|
||||||
type = String.class),
|
type = Address.class),
|
||||||
@TargetAttributeType(
|
@TargetAttributeType(
|
||||||
name = LldbModelTargetStackFrame.STACK_OFFSET_ATTRIBUTE_NAME,
|
name = LldbModelTargetStackFrame.STACK_OFFSET_ATTRIBUTE_NAME,
|
||||||
type = String.class),
|
type = Address.class),
|
||||||
@TargetAttributeType(type = Void.class) })
|
@TargetAttributeType(type = Void.class) })
|
||||||
public class LldbModelTargetStackFrameImpl extends LldbModelTargetObjectImpl
|
public class LldbModelTargetStackFrameImpl extends LldbModelTargetObjectImpl
|
||||||
implements LldbModelTargetStackFrame {
|
implements LldbModelTargetStackFrame {
|
||||||
@@ -116,6 +117,7 @@ public class LldbModelTargetStackFrameImpl extends LldbModelTargetObjectImpl
|
|||||||
getManager().addEventsListener(this);
|
getManager().addEventsListener(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public String getDescription(int level) {
|
public String getDescription(int level) {
|
||||||
SBStream stream = new SBStream();
|
SBStream stream = new SBStream();
|
||||||
SBFrame frame = (SBFrame) getModelObject();
|
SBFrame frame = (SBFrame) getModelObject();
|
||||||
@@ -127,7 +129,8 @@ public class LldbModelTargetStackFrameImpl extends LldbModelTargetObjectImpl
|
|||||||
if (frame.GetFunction() == null) {
|
if (frame.GetFunction() == null) {
|
||||||
return String.format("#%d 0x%s", DebugClient.getId(frame), frame.GetPC().toString(16));
|
return String.format("#%d 0x%s", DebugClient.getId(frame), frame.GetPC().toString(16));
|
||||||
}
|
}
|
||||||
return String.format("#%d 0x%s in %s ()", DebugClient.getId(frame), frame.GetPC().toString(16),
|
return String.format("#%d 0x%s in %s ()", DebugClient.getId(frame),
|
||||||
|
frame.GetPC().toString(16),
|
||||||
frame.GetDisplayFunctionName());
|
frame.GetDisplayFunctionName());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -163,14 +166,15 @@ public class LldbModelTargetStackFrameImpl extends LldbModelTargetObjectImpl
|
|||||||
this.stackOffset = frame.GetSP().longValue();
|
this.stackOffset = frame.GetSP().longValue();
|
||||||
this.callFrameOffset = frame.GetCFA().longValue();
|
this.callFrameOffset = frame.GetCFA().longValue();
|
||||||
|
|
||||||
|
AddressSpace space = getModel().getAddressSpace("ram");
|
||||||
changeAttributes(List.of(), List.of(), Map.of( //
|
changeAttributes(List.of(), List.of(), Map.of( //
|
||||||
PC_ATTRIBUTE_NAME, pc, //
|
PC_ATTRIBUTE_NAME, pc, //
|
||||||
DISPLAY_ATTRIBUTE_NAME, display = getDescription(0), //computeDisplay(frame), //
|
DISPLAY_ATTRIBUTE_NAME, display = getDescription(0), //computeDisplay(frame), //
|
||||||
FUNC_ATTRIBUTE_NAME, func, //
|
FUNC_ATTRIBUTE_NAME, func, //
|
||||||
INST_OFFSET_ATTRIBUTE_NAME, Long.toHexString(lval), //
|
INST_OFFSET_ATTRIBUTE_NAME, space.getAddress(lval), //
|
||||||
FRAME_OFFSET_ATTRIBUTE_NAME, Long.toHexString(frameOffset), //
|
FRAME_OFFSET_ATTRIBUTE_NAME, space.getAddress(frameOffset), //
|
||||||
STACK_OFFSET_ATTRIBUTE_NAME, Long.toHexString(stackOffset), //
|
STACK_OFFSET_ATTRIBUTE_NAME, space.getAddress(stackOffset), //
|
||||||
CALL_FRAME_OFFSET_ATTRIBUTE_NAME, Long.toHexString(callFrameOffset) //
|
CALL_FRAME_OFFSET_ATTRIBUTE_NAME, space.getAddress(callFrameOffset) //
|
||||||
), "Refreshed");
|
), "Refreshed");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+3
@@ -60,6 +60,7 @@ public class LldbModelTargetStackFrameRegisterImpl
|
|||||||
), "Initialized");
|
), "Initialized");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public String getDescription(int level) {
|
public String getDescription(int level) {
|
||||||
SBStream stream = new SBStream();
|
SBStream stream = new SBStream();
|
||||||
SBValue val = (SBValue) getModelObject();
|
SBValue val = (SBValue) getModelObject();
|
||||||
@@ -89,6 +90,7 @@ public class LldbModelTargetStackFrameRegisterImpl
|
|||||||
return (SBValue) getModelObject();
|
return (SBValue) getModelObject();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public byte[] getBytes() {
|
public byte[] getBytes() {
|
||||||
String oldValue = value;
|
String oldValue = value;
|
||||||
value = getValue();
|
value = getValue();
|
||||||
@@ -115,6 +117,7 @@ public class LldbModelTargetStackFrameRegisterImpl
|
|||||||
return bytes;
|
return bytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public String getDisplay() {
|
public String getDisplay() {
|
||||||
return getValue() == null ? getName() : getName() + " : " + getValue();
|
return getValue() == null ? getName() : getName() + " : " + getValue();
|
||||||
}
|
}
|
||||||
|
|||||||
+90
-2
@@ -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,15 @@ 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) {
|
||||||
|
navigateToSelectedObject(t, null);
|
||||||
|
}
|
||||||
|
return AsyncUtils.NIL;
|
||||||
|
}, "Couldn't navigate");
|
||||||
|
}
|
||||||
|
|
||||||
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 +1864,68 @@ public class DebuggerObjectsProvider extends ComponentProviderAdapter
|
|||||||
return listener.queue.in;
|
return listener.queue.in;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void navigateToSelectedObject(TargetObject object, Object value) {
|
||||||
|
if (listingService == null || listingService == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (value == null) {
|
||||||
|
value =
|
||||||
|
object.getCachedAttribute(TargetBreakpointLocation.ADDRESS_ATTRIBUTE_NAME);
|
||||||
|
}
|
||||||
|
if (value == null) {
|
||||||
|
value = object.getCachedAttribute(TargetObject.PREFIX_INVISIBLE + "range");
|
||||||
|
}
|
||||||
|
if (value == null) {
|
||||||
|
value = object.getCachedAttribute(TargetObject.VALUE_ATTRIBUTE_NAME);
|
||||||
|
}
|
||||||
|
if (value == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Address addr = null;
|
||||||
|
if (value instanceof Address) {
|
||||||
|
addr = (Address) value;
|
||||||
|
}
|
||||||
|
else if (value instanceof AddressRangeImpl) {
|
||||||
|
AddressRangeImpl range = (AddressRangeImpl) value;
|
||||||
|
addr = range.getMinAddress();
|
||||||
|
}
|
||||||
|
else if (value instanceof Long) {
|
||||||
|
Long lval = (Long) value;
|
||||||
|
addr = object.getModel().getAddress("ram", lval);
|
||||||
|
}
|
||||||
|
else if (value instanceof String) {
|
||||||
|
String sval = (String) value;
|
||||||
|
addr = stringToAddress(object, addr, sval);
|
||||||
|
}
|
||||||
|
if (addr != null) {
|
||||||
|
TraceRecorder recorder = modelService.getRecorderForSuccessor(object);
|
||||||
|
if (recorder == null) {
|
||||||
|
recorder = modelService.getRecorder(currentTrace);
|
||||||
|
if (recorder == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-36
@@ -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,31 +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 (modelService != null) {
|
|
||||||
TraceRecorder recorder =
|
|
||||||
modelService.getRecorderForSuccessor(container.getTargetObject());
|
|
||||||
DebuggerMemoryMapper memoryMapper = recorder.getMemoryMapper();
|
|
||||||
Address traceAddr = memoryMapper.targetToTrace(addr);
|
|
||||||
listingService.goTo(traceAddr, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-38
@@ -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,10 @@ 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) {
|
||||||
|
container.getProvider().navigateToSelectedObject(selectedObject, null);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -407,31 +400,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 (modelService != null && addr != null) {
|
|
||||||
TraceRecorder recorder = modelService.getRecorderForSuccessor(selectedObject);
|
|
||||||
DebuggerMemoryMapper memoryMapper = recorder.getMemoryMapper();
|
|
||||||
Address traceAddr = memoryMapper.targetToTrace(addr);
|
|
||||||
listingService.goTo(traceAddr, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user