diff --git a/Ghidra/Debug/Debugger-agent-dbgeng/src/main/java/agent/dbgeng/model/impl/DbgModelTargetRegisterContainerImpl.java b/Ghidra/Debug/Debugger-agent-dbgeng/src/main/java/agent/dbgeng/model/impl/DbgModelTargetRegisterContainerImpl.java index f74a37d1b1..122334b94f 100644 --- a/Ghidra/Debug/Debugger-agent-dbgeng/src/main/java/agent/dbgeng/model/impl/DbgModelTargetRegisterContainerImpl.java +++ b/Ghidra/Debug/Debugger-agent-dbgeng/src/main/java/agent/dbgeng/model/impl/DbgModelTargetRegisterContainerImpl.java @@ -170,6 +170,7 @@ public class DbgModelTargetRegisterContainerImpl extends DbgModelTargetObjectImp })); } + @Override public Map getCachedRegisters() { return values; } diff --git a/Ghidra/Debug/Debugger-agent-dbgeng/src/main/java/agent/dbgeng/model/impl/DbgModelTargetRegisterImpl.java b/Ghidra/Debug/Debugger-agent-dbgeng/src/main/java/agent/dbgeng/model/impl/DbgModelTargetRegisterImpl.java index f131e301ce..5a1a16b772 100644 --- a/Ghidra/Debug/Debugger-agent-dbgeng/src/main/java/agent/dbgeng/model/impl/DbgModelTargetRegisterImpl.java +++ b/Ghidra/Debug/Debugger-agent-dbgeng/src/main/java/agent/dbgeng/model/impl/DbgModelTargetRegisterImpl.java @@ -25,9 +25,14 @@ import ghidra.dbg.target.TargetRegister; import ghidra.dbg.target.schema.*; import ghidra.dbg.util.PathUtils; -@TargetObjectSchemaInfo(name = "RegisterDescriptor", elements = { - @TargetElementType(type = Void.class) }, attributes = { - @TargetAttributeType(name = TargetRegister.CONTAINER_ATTRIBUTE_NAME, type = DbgModelTargetRegisterContainerImpl.class), +@TargetObjectSchemaInfo( + name = "RegisterDescriptor", + elements = { + @TargetElementType(type = Void.class) }, + attributes = { + @TargetAttributeType( + name = TargetRegister.CONTAINER_ATTRIBUTE_NAME, + type = DbgModelTargetRegisterContainerImpl.class), @TargetAttributeType(type = Void.class) }) public class DbgModelTargetRegisterImpl extends DbgModelTargetObjectImpl implements DbgModelTargetRegister { diff --git a/Ghidra/Debug/Debugger-agent-dbgeng/src/main/java/agent/dbgeng/model/impl/DbgModelTargetStackFrameImpl.java b/Ghidra/Debug/Debugger-agent-dbgeng/src/main/java/agent/dbgeng/model/impl/DbgModelTargetStackFrameImpl.java index 49da5d6a28..0c189c45bd 100644 --- a/Ghidra/Debug/Debugger-agent-dbgeng/src/main/java/agent/dbgeng/model/impl/DbgModelTargetStackFrameImpl.java +++ b/Ghidra/Debug/Debugger-agent-dbgeng/src/main/java/agent/dbgeng/model/impl/DbgModelTargetStackFrameImpl.java @@ -27,6 +27,7 @@ import ghidra.dbg.target.TargetObject; import ghidra.dbg.target.schema.*; import ghidra.dbg.util.PathUtils; import ghidra.program.model.address.Address; +import ghidra.program.model.address.AddressSpace; @TargetObjectSchemaInfo( name = "StackFrame", @@ -41,16 +42,16 @@ import ghidra.program.model.address.Address; type = String.class), @TargetAttributeType( name = DbgModelTargetStackFrame.INST_OFFSET_ATTRIBUTE_NAME, - type = String.class), + type = Address.class), @TargetAttributeType( name = DbgModelTargetStackFrame.FRAME_OFFSET_ATTRIBUTE_NAME, - type = String.class), + type = Address.class), @TargetAttributeType( name = DbgModelTargetStackFrame.RETURN_OFFSET_ATTRIBUTE_NAME, - type = String.class), + type = Address.class), @TargetAttributeType( name = DbgModelTargetStackFrame.STACK_OFFSET_ATTRIBUTE_NAME, - type = String.class), + type = Address.class), @TargetAttributeType( name = DbgModelTargetStackFrame.VIRTUAL_ATTRIBUTE_NAME, type = Boolean.class), @@ -141,15 +142,16 @@ public class DbgModelTargetStackFrameImpl extends DbgModelTargetObjectImpl // TODO: module? "from" this.frame = frame; + AddressSpace space = getModel().getAddressSpace("ram"); changeAttributes(List.of(), List.of(), Map.of( // PC_ATTRIBUTE_NAME, pc, // DISPLAY_ATTRIBUTE_NAME, display = computeDisplay(frame), // FUNC_ATTRIBUTE_NAME, func, // FUNC_TABLE_ENTRY_ATTRIBUTE_NAME, Long.toHexString(funcTableEntry), // - INST_OFFSET_ATTRIBUTE_NAME, Long.toHexString(lval), // - FRAME_OFFSET_ATTRIBUTE_NAME, Long.toHexString(frameOffset), // - RETURN_OFFSET_ATTRIBUTE_NAME, Long.toHexString(returnOffset), // - STACK_OFFSET_ATTRIBUTE_NAME, Long.toHexString(stackOffset), // + INST_OFFSET_ATTRIBUTE_NAME, space.getAddress(lval), // + FRAME_OFFSET_ATTRIBUTE_NAME, space.getAddress(frameOffset), // + RETURN_OFFSET_ATTRIBUTE_NAME, space.getAddress(returnOffset), // + STACK_OFFSET_ATTRIBUTE_NAME, space.getAddress(stackOffset), // VIRTUAL_ATTRIBUTE_NAME, virtual // ), "Refreshed"); changeAttributes(List.of(), List.of(), Map.of( // diff --git a/Ghidra/Debug/Debugger-agent-gdb/src/main/java/agent/gdb/model/impl/GdbModelTargetStackFrame.java b/Ghidra/Debug/Debugger-agent-gdb/src/main/java/agent/gdb/model/impl/GdbModelTargetStackFrame.java index fd4ec70d47..c5e854a54d 100644 --- a/Ghidra/Debug/Debugger-agent-gdb/src/main/java/agent/gdb/model/impl/GdbModelTargetStackFrame.java +++ b/Ghidra/Debug/Debugger-agent-gdb/src/main/java/agent/gdb/model/impl/GdbModelTargetStackFrame.java @@ -104,7 +104,8 @@ public class GdbModelTargetStackFrame extends DefaultTargetObject 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); displayAsTableAction = new DisplayAsTableAction(tool, plugin.getName(), this); @@ -1545,6 +1560,15 @@ public class DebuggerObjectsProvider extends ComponentProviderAdapter }, "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) { performAction(context, false, TargetInterpreter.class, interpreter -> { getPlugin().showConsole(interpreter); @@ -1840,4 +1864,68 @@ public class DebuggerObjectsProvider extends ComponentProviderAdapter 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; + } } diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/objects/components/ObjectTable.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/objects/components/ObjectTable.java index d47cb32cd6..0090f348c6 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/objects/components/ObjectTable.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/objects/components/ObjectTable.java @@ -27,11 +27,7 @@ import docking.widgets.table.AbstractSortedTableModel; import docking.widgets.table.EnumeratedColumnTableModel; import ghidra.app.plugin.core.debug.gui.objects.DebuggerObjectsProvider; 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.program.model.address.Address; -import ghidra.program.model.address.AddressRangeImpl; import ghidra.util.Swing; import ghidra.util.table.GhidraTable; import resources.ResourceManager; @@ -45,8 +41,6 @@ public class ObjectTable implements ObjectPane { private AbstractSortedTableModel model; private GhidraTable table; private JScrollPane component; - private DebuggerListingService listingService; - private DebuggerModelService modelService; public ObjectTable(ObjectContainer container, Class clazz, AbstractSortedTableModel model) { @@ -55,8 +49,6 @@ public class ObjectTable implements ObjectPane { this.container = container; this.clazz = clazz; this.model = model; - this.listingService = container.getProvider().getListingService(); - this.modelService = container.getProvider().getModelService(); table.getSelectionModel().addListSelectionListener(new ListSelectionListener() { @Override @@ -72,7 +64,11 @@ public class ObjectTable implements ObjectPane { @Override public void mouseClicked(MouseEvent e) { 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 implements ObjectPane { 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); - } - } - } - } diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/objects/components/ObjectTree.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/objects/components/ObjectTree.java index f0043d763d..ea33a88a76 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/objects/components/ObjectTree.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/objects/components/ObjectTree.java @@ -35,15 +35,11 @@ import docking.widgets.tree.support.GTreeSelectionEvent.EventOrigin; import docking.widgets.tree.support.GTreeSelectionListener; import ghidra.app.plugin.core.debug.gui.objects.DebuggerObjectsProvider; 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.TypeSpec; import ghidra.dbg.DebugModelConventions; import ghidra.dbg.target.TargetAccessConditioned; import ghidra.dbg.target.TargetObject; -import ghidra.program.model.address.Address; -import ghidra.program.model.address.AddressRangeImpl; import ghidra.util.*; import ghidra.util.task.SwingUpdateManager; import resources.ResourceManager; @@ -63,17 +59,11 @@ public class ObjectTree implements ObjectPane { private SwingUpdateManager restoreTreeStateManager = new SwingUpdateManager(this::restoreTreeState); - private DebuggerListingService listingService; - private DebuggerModelService modelService; - public ObjectTree(ObjectContainer container) { this.root = new ObjectNode(this, null, container); addToMap(null, container, root); this.tree = new GTree(root); - this.listingService = container.getProvider().getListingService(); - this.modelService = container.getProvider().getModelService(); - tree.addGTreeSelectionListener(new GTreeSelectionListener() { @Override public void valueChanged(GTreeSelectionEvent e) { @@ -165,7 +155,10 @@ public class ObjectTree implements ObjectPane { @Override public void mouseClicked(MouseEvent e) { 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())); } - 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); - } - } - } }