From 270fb014009ab89dbc935523e04983ff1dce0161 Mon Sep 17 00:00:00 2001 From: Dan <46821332+nsadeveloper789@users.noreply.github.com> Date: Thu, 22 Feb 2024 12:19:25 -0500 Subject: [PATCH] GP-4236: Implement new columns: PC, Func, Mod, SP. Remove: Created, Destroyed --- .../debug/api/action/LocationTracker.java | 12 +- .../api/action/LocationTrackingSpec.java | 2 +- .../gui/action/NoneLocationTrackingSpec.java | 6 +- .../action/PCByStackLocationTrackingSpec.java | 13 +- .../gui/action/PCLocationTrackingSpec.java | 12 +- .../action/RegisterLocationTrackingSpec.java | 9 +- .../gui/action/WatchLocationTrackingSpec.java | 15 +-- .../TraceValueObjectPropertyColumn.java | 5 + .../core/debug/gui/modules/ModuleRow.java | 14 +-- .../debug/gui/stack/DebuggerStackPanel.java | 7 +- .../gui/stack/DebuggerStackProvider.java | 42 +------ .../core/debug/gui/stack/StackFrameRow.java | 6 +- .../thread/DebuggerLegacyThreadsPanel.java | 38 +++--- .../gui/thread/DebuggerThreadsPanel.java | 115 ++++++++++++------ .../core/debug/gui/thread/ThreadRow.java | 34 ++++++ .../data/AbstractPcodeDebuggerAccess.java | 13 +- .../data/DefaultPcodeDebuggerAccess.java | 16 +-- .../DefaultPcodeDebuggerMemoryAccess.java | 16 +-- .../DefaultPcodeDebuggerPropertyAccess.java | 2 +- .../DefaultPcodeDebuggerRegistersAccess.java | 14 +-- .../data/InternalPcodeDebuggerDataAccess.java | 4 +- .../modules/DebuggerStaticMappingUtils.java | 58 ++++++++- .../ghidra/pcode/exec/DebuggerPcodeUtils.java | 45 +++---- .../DefaultEnumeratedColumnTableModel.java | 22 +++- 24 files changed, 320 insertions(+), 200 deletions(-) diff --git a/Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/action/LocationTracker.java b/Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/action/LocationTracker.java index c2edb03ef5..beab2ae89f 100644 --- a/Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/action/LocationTracker.java +++ b/Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/action/LocationTracker.java @@ -15,10 +15,8 @@ */ package ghidra.debug.api.action; -import java.util.concurrent.CompletableFuture; - import ghidra.debug.api.tracemgr.DebuggerCoordinates; -import ghidra.framework.plugintool.PluginTool; +import ghidra.framework.plugintool.ServiceProvider; import ghidra.program.model.address.Address; import ghidra.program.util.ProgramLocation; import ghidra.trace.model.TraceAddressSnapRange; @@ -47,21 +45,21 @@ public interface LocationTracker { * The address returned must be in the host platform's language, i.e., please use * {@link TracePlatform#mapGuestToHost(Address)}. * - * @param tool the tool containing the provider + * @param provider the service provider (usually the tool) * @param coordinates the trace, thread, snap, etc., of the tool * @return the address to navigate to */ - Address computeTraceAddress(PluginTool tool, DebuggerCoordinates coordinates); + Address computeTraceAddress(ServiceProvider provider, DebuggerCoordinates coordinates); /** * Get the suggested input if the user activates "Go To" while this tracker is active * - * @param tool the tool containing the provider + * @param provider the service provider (usually the tool) * @param coordinates the user's current coordinates * @param location the user's current location * @return the suggested address or Sleigh expression */ - GoToInput getDefaultGoToInput(PluginTool tool, DebuggerCoordinates coordinates, + GoToInput getDefaultGoToInput(ServiceProvider provider, DebuggerCoordinates coordinates, ProgramLocation location); // TODO: Is there a way to generalize these so that other dependencies need not diff --git a/Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/action/LocationTrackingSpec.java b/Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/action/LocationTrackingSpec.java index 1fc5f593a3..2bf2bbd5c5 100644 --- a/Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/action/LocationTrackingSpec.java +++ b/Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/action/LocationTrackingSpec.java @@ -119,7 +119,7 @@ public interface LocationTrackingSpec { /** * Compute a title prefix to indicate this tracking specification * - * @param thread the provider's current thread + * @param coordinates the current coordinates * @return a prefix, or {@code null} to use a default */ String computeTitle(DebuggerCoordinates coordinates); diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/NoneLocationTrackingSpec.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/NoneLocationTrackingSpec.java index 30f5927a6e..af74c7b581 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/NoneLocationTrackingSpec.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/NoneLocationTrackingSpec.java @@ -20,7 +20,7 @@ import javax.swing.Icon; import ghidra.app.plugin.core.debug.gui.DebuggerResources.TrackLocationAction; import ghidra.debug.api.action.*; import ghidra.debug.api.tracemgr.DebuggerCoordinates; -import ghidra.framework.plugintool.PluginTool; +import ghidra.framework.plugintool.ServiceProvider; import ghidra.program.model.address.Address; import ghidra.program.util.ProgramLocation; import ghidra.trace.model.TraceAddressSnapRange; @@ -63,12 +63,12 @@ public enum NoneLocationTrackingSpec implements LocationTrackingSpec, LocationTr } @Override - public Address computeTraceAddress(PluginTool tool, DebuggerCoordinates coordinates) { + public Address computeTraceAddress(ServiceProvider provider, DebuggerCoordinates coordinates) { return null; } @Override - public GoToInput getDefaultGoToInput(PluginTool tool, DebuggerCoordinates coordinates, + public GoToInput getDefaultGoToInput(ServiceProvider provider, DebuggerCoordinates coordinates, ProgramLocation location) { if (location == null) { return GoToInput.fromString("00000000"); diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/PCByStackLocationTrackingSpec.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/PCByStackLocationTrackingSpec.java index 900ecf4d2e..2e39041d0b 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/PCByStackLocationTrackingSpec.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/PCByStackLocationTrackingSpec.java @@ -20,7 +20,7 @@ import javax.swing.Icon; import ghidra.app.plugin.core.debug.gui.DebuggerResources.TrackLocationAction; import ghidra.debug.api.action.*; import ghidra.debug.api.tracemgr.DebuggerCoordinates; -import ghidra.framework.plugintool.PluginTool; +import ghidra.framework.plugintool.ServiceProvider; import ghidra.program.model.address.Address; import ghidra.program.util.ProgramLocation; import ghidra.trace.model.Trace; @@ -66,9 +66,12 @@ public enum PCByStackLocationTrackingSpec implements LocationTrackingSpec, Locat } @Override - public Address computeTraceAddress(PluginTool tool, DebuggerCoordinates coordinates) { + public Address computeTraceAddress(ServiceProvider provider, DebuggerCoordinates coordinates) { Trace trace = coordinates.getTrace(); TraceThread thread = coordinates.getThread(); + if (thread == null) { + return null; + } long snap = coordinates.getSnap(); TraceStack stack = trace.getStackManager().getLatestStack(thread, snap); if (stack == null) { @@ -83,11 +86,11 @@ public enum PCByStackLocationTrackingSpec implements LocationTrackingSpec, Locat } @Override - public GoToInput getDefaultGoToInput(PluginTool tool, DebuggerCoordinates coordinates, + public GoToInput getDefaultGoToInput(ServiceProvider provider, DebuggerCoordinates coordinates, ProgramLocation location) { - Address address = computeTraceAddress(tool, coordinates); + Address address = computeTraceAddress(provider, coordinates); if (address == null) { - return NoneLocationTrackingSpec.INSTANCE.getDefaultGoToInput(tool, coordinates, + return NoneLocationTrackingSpec.INSTANCE.getDefaultGoToInput(provider, coordinates, location); } return GoToInput.fromAddress(address); diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/PCLocationTrackingSpec.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/PCLocationTrackingSpec.java index f6aec39a48..aeb1f39368 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/PCLocationTrackingSpec.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/PCLocationTrackingSpec.java @@ -20,7 +20,7 @@ import javax.swing.Icon; import ghidra.app.plugin.core.debug.gui.DebuggerResources.TrackLocationAction; import ghidra.debug.api.action.*; import ghidra.debug.api.tracemgr.DebuggerCoordinates; -import ghidra.framework.plugintool.PluginTool; +import ghidra.framework.plugintool.ServiceProvider; import ghidra.program.model.address.Address; import ghidra.program.util.ProgramLocation; import ghidra.trace.model.TraceAddressSnapRange; @@ -68,20 +68,20 @@ public enum PCLocationTrackingSpec implements LocationTrackingSpec, LocationTrac } @Override - public Address computeTraceAddress(PluginTool tool, DebuggerCoordinates coordinates) { + public Address computeTraceAddress(ServiceProvider provider, DebuggerCoordinates coordinates) { if (coordinates.getTime().isSnapOnly()) { - Address pc = BY_STACK.computeTraceAddress(tool, coordinates); + Address pc = BY_STACK.computeTraceAddress(provider, coordinates); if (pc != null) { return pc; } } - return BY_REG.computeTraceAddress(tool, coordinates); + return BY_REG.computeTraceAddress(provider, coordinates); } @Override - public GoToInput getDefaultGoToInput(PluginTool tool, DebuggerCoordinates coordinates, + public GoToInput getDefaultGoToInput(ServiceProvider provider, DebuggerCoordinates coordinates, ProgramLocation location) { - return BY_REG.getDefaultGoToInput(tool, coordinates, location); + return BY_REG.getDefaultGoToInput(provider, coordinates, location); } // Note it does no good to override affectByRegChange. It must do what we'd avoid anyway. diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/RegisterLocationTrackingSpec.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/RegisterLocationTrackingSpec.java index 8cf970320a..3ac0d6b524 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/RegisterLocationTrackingSpec.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/RegisterLocationTrackingSpec.java @@ -17,7 +17,7 @@ package ghidra.app.plugin.core.debug.gui.action; import ghidra.debug.api.action.*; import ghidra.debug.api.tracemgr.DebuggerCoordinates; -import ghidra.framework.plugintool.PluginTool; +import ghidra.framework.plugintool.ServiceProvider; import ghidra.program.model.address.*; import ghidra.program.model.lang.Register; import ghidra.program.model.lang.RegisterValue; @@ -51,10 +51,13 @@ public interface RegisterLocationTrackingSpec extends LocationTrackingSpec, Loca } @Override - default Address computeTraceAddress(PluginTool tool, DebuggerCoordinates coordinates) { + default Address computeTraceAddress(ServiceProvider provider, DebuggerCoordinates coordinates) { Trace trace = coordinates.getTrace(); TracePlatform platform = coordinates.getPlatform(); TraceThread thread = coordinates.getThread(); + if (thread == null) { + return null; + } long viewSnap = coordinates.getViewSnap(); long snap = coordinates.getSnap(); int frame = coordinates.getFrame(); @@ -88,7 +91,7 @@ public interface RegisterLocationTrackingSpec extends LocationTrackingSpec, Loca } @Override - default GoToInput getDefaultGoToInput(PluginTool tool, DebuggerCoordinates coordinates, + default GoToInput getDefaultGoToInput(ServiceProvider provider, DebuggerCoordinates coordinates, ProgramLocation location) { Register register = computeRegister(coordinates); return GoToInput.offsetOnly(register.getName()); diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/WatchLocationTrackingSpec.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/WatchLocationTrackingSpec.java index 11537b05d5..8b951adc31 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/WatchLocationTrackingSpec.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/WatchLocationTrackingSpec.java @@ -24,7 +24,7 @@ import ghidra.app.plugin.core.debug.gui.DebuggerResources.TrackLocationAction; import ghidra.debug.api.action.*; import ghidra.debug.api.tracemgr.DebuggerCoordinates; import ghidra.debug.api.watch.WatchRow; -import ghidra.framework.plugintool.PluginTool; +import ghidra.framework.plugintool.ServiceProvider; import ghidra.pcode.exec.*; import ghidra.pcode.exec.DebuggerPcodeUtils.WatchValue; import ghidra.pcode.exec.SleighUtils.AddressOf; @@ -117,11 +117,12 @@ public class WatchLocationTrackingSpec implements LocationTrackingSpec { private PcodeExpression compiled; @Override - public Address computeTraceAddress(PluginTool tool, DebuggerCoordinates coordinates) { + public Address computeTraceAddress(ServiceProvider provider, + DebuggerCoordinates coordinates) { if (!Objects.equals(current, coordinates) || exec == null) { current = coordinates; exec = current.getPlatform() == null ? null - : DebuggerPcodeUtils.buildWatchExecutor(tool, coordinates); + : DebuggerPcodeUtils.buildWatchExecutor(provider, coordinates); } else { exec.getState().clear(); @@ -129,20 +130,20 @@ public class WatchLocationTrackingSpec implements LocationTrackingSpec { if (current.getTrace() == null) { return null; } - compiled = DebuggerPcodeUtils.compileExpression(tool, current, expression); + compiled = DebuggerPcodeUtils.compileExpression(provider, current, expression); WatchValue value = compiled.evaluate(exec); return value == null ? null : value.address(); } @Override - public GoToInput getDefaultGoToInput(PluginTool tool, DebuggerCoordinates coordinates, - ProgramLocation location) { + public GoToInput getDefaultGoToInput(ServiceProvider provider, + DebuggerCoordinates coordinates, ProgramLocation location) { TracePlatform platform = current.getPlatform(); String defaultSpace = platform == null ? "ram" : platform.getLanguage().getDefaultSpace().getName(); AddressOf addrOf = SleighUtils.recoverAddressOf(defaultSpace, expression); if (addrOf == null) { - return NoneLocationTrackingSpec.INSTANCE.getDefaultGoToInput(tool, coordinates, + return NoneLocationTrackingSpec.INSTANCE.getDefaultGoToInput(provider, coordinates, location); } return new GoToInput(addrOf.space(), diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/model/columns/TraceValueObjectPropertyColumn.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/model/columns/TraceValueObjectPropertyColumn.java index df6cb302bb..c84d1d8feb 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/model/columns/TraceValueObjectPropertyColumn.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/model/columns/TraceValueObjectPropertyColumn.java @@ -54,6 +54,11 @@ public abstract class TraceValueObjectPropertyColumn super.getTableCellRendererComponent(data); @SuppressWarnings("unchecked") ValueProperty p = (ValueProperty) data.getValue(); + if (p == null) { + setText(""); + setToolTipText(""); + return this; + } setText(p.getHtmlDisplay()); setToolTipText(p.getToolTip()); setForeground(getForegroundFor(data.getTable(), p.isModified(), data.isSelected())); diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/modules/ModuleRow.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/modules/ModuleRow.java index 91c6597818..255225af54 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/modules/ModuleRow.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/modules/ModuleRow.java @@ -40,20 +40,8 @@ public class ModuleRow { } } - public static String computeShortName(String path) { - int sep = path.lastIndexOf('\\'); - if (sep > 0 && sep < path.length()) { - path = path.substring(sep + 1); - } - sep = path.lastIndexOf('/'); - if (sep > 0 && sep < path.length()) { - path = path.substring(sep + 1); - } - return path; - } - public String getShortName() { - return computeShortName(module.getName()); + return DebuggerStaticMappingUtils.computeModuleShortName(module.getName()); } public String getName() { diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/stack/DebuggerStackPanel.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/stack/DebuggerStackPanel.java index 9ab01273dd..a65e1ab017 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/stack/DebuggerStackPanel.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/stack/DebuggerStackPanel.java @@ -27,6 +27,7 @@ import ghidra.app.plugin.core.debug.gui.model.AbstractQueryTablePanel.CellActiva import ghidra.app.plugin.core.debug.gui.model.ObjectTableModel.ValueRow; import ghidra.app.plugin.core.debug.gui.model.columns.TraceValueKeyColumn; import ghidra.app.plugin.core.debug.gui.model.columns.TraceValueObjectAttributeColumn; +import ghidra.app.plugin.core.debug.service.modules.DebuggerStaticMappingUtils; import ghidra.app.services.DebuggerTraceManagerService; import ghidra.dbg.target.TargetStack; import ghidra.dbg.target.TargetStackFrame; @@ -40,7 +41,6 @@ import ghidra.framework.plugintool.annotation.AutoServiceConsumed; import ghidra.program.model.address.Address; import ghidra.program.model.listing.Function; import ghidra.trace.model.Trace; -import ghidra.trace.model.modules.TraceModule; import ghidra.trace.model.stack.TraceObjectStackFrame; import ghidra.trace.model.target.TraceObject; import ghidra.trace.model.target.TraceObjectValue; @@ -84,7 +84,8 @@ public class DebuggerStackPanel extends AbstractObjectsTableBasedPanel { - NAME("Name", String.class, ThreadRow::getName, ThreadRow::setName, true), - CREATED("Created", Long.class, ThreadRow::getCreationSnap, true), - DESTROYED("Destroyed", String.class, ThreadRow::getDestructionSnap, true), - STATE("State", ThreadState.class, ThreadRow::getState, true), - COMMENT("Comment", String.class, ThreadRow::getComment, ThreadRow::setComment, true), - PLOT("Plot", Lifespan.class, ThreadRow::getLifespan, false); + NAME("Name", String.class, ThreadRow::getName, ThreadRow::setName, true, true), + PC("PC", Address.class, ThreadRow::getProgramCounter, true, true), + FUNCTION("Function", ghidra.program.model.listing.Function.class, ThreadRow::getFunction, // + true, true), + MODULE("Module", String.class, ThreadRow::getModule, true, false), + SP("SP", Address.class, ThreadRow::getStackPointer, true, false), + CREATED("Created", Long.class, ThreadRow::getCreationSnap, true, false), + DESTROYED("Destroyed", String.class, ThreadRow::getDestructionSnap, true, false), + + STATE("State", ThreadState.class, ThreadRow::getState, true, true), + COMMENT("Comment", String.class, ThreadRow::getComment, ThreadRow::setComment, true, false), + PLOT("Plot", Lifespan.class, ThreadRow::getLifespan, false, true); private final String header; private final Function getter; private final BiConsumer setter; private final boolean sortable; + private final boolean visible; private final Class cls; ThreadTableColumns(String header, Class cls, Function getter, - boolean sortable) { - this(header, cls, getter, null, sortable); + boolean sortable, boolean visible) { + this(header, cls, getter, null, sortable, visible); } @SuppressWarnings("unchecked") ThreadTableColumns(String header, Class cls, Function getter, - BiConsumer setter, boolean sortable) { + BiConsumer setter, boolean sortable, boolean visible) { this.header = header; this.cls = cls; this.getter = getter; this.setter = (BiConsumer) setter; this.sortable = sortable; + this.visible = visible; } @Override @@ -108,6 +117,11 @@ public class DebuggerLegacyThreadsPanel extends JPanel { return sortable; } + @Override + public boolean isVisible() { + return visible; + } + @Override public void setValueOf(ThreadRow row, Object value) { setter.accept(row, value); @@ -253,22 +267,16 @@ public class DebuggerLegacyThreadsPanel extends JPanel { TableColumnModel columnModel = threadTable.getColumnModel(); TableColumn colName = columnModel.getColumn(ThreadTableColumns.NAME.ordinal()); - colName.setPreferredWidth(100); colName.setCellRenderer(boldCurrentRenderer); TableColumn colCreated = columnModel.getColumn(ThreadTableColumns.CREATED.ordinal()); - colCreated.setPreferredWidth(10); colCreated.setCellRenderer(boldCurrentRenderer); TableColumn colDestroyed = columnModel.getColumn(ThreadTableColumns.DESTROYED.ordinal()); - colDestroyed.setPreferredWidth(10); colDestroyed.setCellRenderer(boldCurrentRenderer); TableColumn colState = columnModel.getColumn(ThreadTableColumns.STATE.ordinal()); - colState.setPreferredWidth(20); colState.setCellRenderer(boldCurrentRenderer); TableColumn colComment = columnModel.getColumn(ThreadTableColumns.COMMENT.ordinal()); - colComment.setPreferredWidth(100); colComment.setCellRenderer(boldCurrentRenderer); TableColumn colPlot = columnModel.getColumn(ThreadTableColumns.PLOT.ordinal()); - colPlot.setPreferredWidth(200); colPlot.setCellRenderer(spanRenderer); colPlot.setHeaderRenderer(headerRenderer); diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/thread/DebuggerThreadsPanel.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/thread/DebuggerThreadsPanel.java index d8f159b0d4..c213ebb09f 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/thread/DebuggerThreadsPanel.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/thread/DebuggerThreadsPanel.java @@ -20,12 +20,16 @@ import java.util.List; import javax.swing.JTable; import javax.swing.event.ListSelectionEvent; +import docking.widgets.table.AbstractDynamicTableColumn; import docking.widgets.table.RangeCursorTableHeaderRenderer.SeekListener; import docking.widgets.table.TableColumnDescriptor; import docking.widgets.table.threaded.ThreadedTableModelListener; +import ghidra.app.plugin.core.debug.gui.action.PCLocationTrackingSpec; +import ghidra.app.plugin.core.debug.gui.action.SPLocationTrackingSpec; import ghidra.app.plugin.core.debug.gui.model.*; import ghidra.app.plugin.core.debug.gui.model.ObjectTableModel.*; import ghidra.app.plugin.core.debug.gui.model.columns.*; +import ghidra.app.plugin.core.debug.service.modules.DebuggerStaticMappingUtils; import ghidra.app.services.DebuggerTraceManagerService; import ghidra.dbg.target.*; import ghidra.dbg.target.schema.TargetObjectSchema; @@ -34,10 +38,10 @@ import ghidra.docking.settings.Settings; import ghidra.framework.plugintool.Plugin; import ghidra.framework.plugintool.ServiceProvider; import ghidra.framework.plugintool.annotation.AutoServiceConsumed; -import ghidra.trace.model.Lifespan; +import ghidra.program.model.address.Address; +import ghidra.program.model.listing.Function; import ghidra.trace.model.Trace; import ghidra.trace.model.target.TraceObject; -import ghidra.trace.model.target.TraceObjectValue; import ghidra.trace.model.thread.TraceObjectThread; public class DebuggerThreadsPanel extends AbstractObjectsTableBasedPanel { @@ -67,53 +71,92 @@ public class DebuggerThreadsPanel extends AbstractObjectsTableBasedPanel { - public AbstractThreadLifeBoundColumn() { - super(Long.class); + private Address computeProgramCounter(DebuggerCoordinates coords) { + // TODO: Cheating a bit. Also, can user configure whether by stack or regs? + return PCLocationTrackingSpec.INSTANCE.computeTraceAddress(provider.getTool(), + coords); + } + + private class ThreadPcColumn extends TraceValueObjectPropertyColumn
{ + public ThreadPcColumn() { + super(Address.class); } - abstract Long fromLifespan(Lifespan lifespan); - @Override - public ValueProperty getProperty(ValueRow row) { - return new ValueDerivedProperty<>(row, Long.class) { + public ValueProperty
getProperty(ValueRow row) { + TraceObject obj = row.getValue().getChild(); + DebuggerCoordinates coords = provider.current.object(obj); + return new ValueAddressProperty(row) { @Override - public Long getValue() { - // De-duplication may not select parent value at current snap - TraceObjectValue curVal = - row.getValue().getChild().getCanonicalParent(row.currentSnap()); - if (curVal == null) { - // Thread is not actually alive a current snap - return null; - } - return fromLifespan(curVal.getLifespan()); + public Address getValue() { + return computeProgramCounter(coords); } }; } - } - private static class ThreadCreatedColumn extends AbstractThreadLifeBoundColumn { @Override public String getColumnName() { - return "Created"; - } - - @Override - Long fromLifespan(Lifespan lifespan) { - return lifespan.minIsFinite() ? lifespan.lmin() : null; + return "PC"; } } - private static class ThreadDestroyedColumn extends AbstractThreadLifeBoundColumn { + private class ThreadFunctionColumn + extends AbstractDynamicTableColumn { @Override public String getColumnName() { - return "Destroyed"; + return "Function"; } @Override - Long fromLifespan(Lifespan lifespan) { - return lifespan.maxIsFinite() ? lifespan.lmax() : null; + public Function getValue(ValueRow rowObject, Settings settings, Trace data, + ServiceProvider serviceProvider) throws IllegalArgumentException { + DebuggerCoordinates coords = provider.current.object(rowObject.currentObject()); + Address pc = computeProgramCounter(coords); + if (pc == null) { + return null; + } + return DebuggerStaticMappingUtils.getFunction(pc, coords, serviceProvider); + } + } + + private class ThreadModuleColumn extends AbstractDynamicTableColumn { + @Override + public String getColumnName() { + return "Module"; + } + + @Override + public String getValue(ValueRow rowObject, Settings settings, Trace data, + ServiceProvider serviceProvider) throws IllegalArgumentException { + DebuggerCoordinates coords = provider.current.object(rowObject.currentObject()); + Address pc = computeProgramCounter(coords); + if (pc == null) { + return null; + } + return DebuggerStaticMappingUtils.getModuleName(pc, coords); + } + } + + private class ThreadSpColumn extends TraceValueObjectPropertyColumn
{ + public ThreadSpColumn() { + super(Address.class); + } + + @Override + public ValueProperty
getProperty(ValueRow row) { + DebuggerCoordinates coords = provider.current.object(row.currentObject()); + return new ValueAddressProperty(row) { + @Override + public Address getValue() { + return SPLocationTrackingSpec.INSTANCE.computeTraceAddress(provider.getTool(), + coords); + } + }; + } + + @Override + public String getColumnName() { + return "SP"; } } @@ -144,7 +187,7 @@ public class DebuggerThreadsPanel extends AbstractObjectsTableBasedPanel descriptor = new TableColumnDescriptor<>(); descriptor.addHiddenColumn(new ThreadPathColumn()); descriptor.addVisibleColumn(new ThreadNameColumn(), 1, true); - descriptor.addVisibleColumn(new ThreadCreatedColumn()); - descriptor.addVisibleColumn(new ThreadDestroyedColumn()); + descriptor.addVisibleColumn(new ThreadPcColumn()); + descriptor.addVisibleColumn(new ThreadFunctionColumn()); + descriptor.addHiddenColumn(new ThreadModuleColumn()); + descriptor.addHiddenColumn(new ThreadSpColumn()); descriptor.addVisibleColumn(new ThreadStateColumn()); - descriptor.addVisibleColumn(new ThreadCommentColumn()); + descriptor.addHiddenColumn(new ThreadCommentColumn()); descriptor.addVisibleColumn(new ThreadPlotColumn()); return descriptor; } diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/thread/ThreadRow.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/thread/ThreadRow.java index c98cc7f61c..dc1c0bc01a 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/thread/ThreadRow.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/thread/ThreadRow.java @@ -16,8 +16,14 @@ package ghidra.app.plugin.core.debug.gui.thread; import db.Transaction; +import ghidra.app.plugin.core.debug.gui.action.PCLocationTrackingSpec; +import ghidra.app.plugin.core.debug.gui.action.SPLocationTrackingSpec; +import ghidra.app.plugin.core.debug.service.modules.DebuggerStaticMappingUtils; import ghidra.dbg.target.TargetExecutionStateful.TargetExecutionState; import ghidra.debug.api.target.Target; +import ghidra.debug.api.tracemgr.DebuggerCoordinates; +import ghidra.program.model.address.Address; +import ghidra.program.model.listing.Function; import ghidra.trace.model.Lifespan; import ghidra.trace.model.Trace; import ghidra.trace.model.thread.TraceThread; @@ -50,6 +56,34 @@ public class ThreadRow { return thread.getName(); } + private Address computeProgramCounter(DebuggerCoordinates coords) { + // TODO: Cheating a bit. Also, can user configure whether by stack or regs? + return PCLocationTrackingSpec.INSTANCE.computeTraceAddress(provider.getTool(), + coords); + } + + public Address getProgramCounter() { + DebuggerCoordinates coords = provider.current.thread(thread); + return computeProgramCounter(coords); + } + + public Function getFunction() { + DebuggerCoordinates coords = provider.current.thread(thread); + Address pc = computeProgramCounter(coords); + return DebuggerStaticMappingUtils.getFunction(pc, coords, provider.getTool()); + } + + public String getModule() { + DebuggerCoordinates coords = provider.current.thread(thread); + Address pc = computeProgramCounter(coords); + return DebuggerStaticMappingUtils.getModuleName(pc, coords); + } + + public Address getStackPointer() { + DebuggerCoordinates coords = provider.current.thread(thread); + return SPLocationTrackingSpec.INSTANCE.computeTraceAddress(provider.getTool(), coords); + } + public long getCreationSnap() { return thread.getCreationSnap(); } diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/emulation/data/AbstractPcodeDebuggerAccess.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/emulation/data/AbstractPcodeDebuggerAccess.java index f7419800c3..fe3b25cf38 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/emulation/data/AbstractPcodeDebuggerAccess.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/emulation/data/AbstractPcodeDebuggerAccess.java @@ -17,7 +17,7 @@ package ghidra.app.plugin.core.debug.service.emulation.data; import ghidra.debug.api.emulation.*; import ghidra.debug.api.target.Target; -import ghidra.framework.plugintool.PluginTool; +import ghidra.framework.plugintool.ServiceProvider; import ghidra.pcode.exec.trace.data.AbstractPcodeTraceAccess; import ghidra.trace.model.guest.TracePlatform; @@ -31,21 +31,22 @@ public abstract class AbstractPcodeDebuggerAccess implements PcodeDebuggerAccess { - protected final PluginTool tool; + protected final ServiceProvider provider; protected final Target target; /** * Construct a shim * - * @param tool the tool controlling the session - * @param recorder the target's recorder + * @param provider the service provider (usually the tool) + * @param target the target * @param platform the associated platform, having the same trace as the recorder * @param snap the associated snap */ - public AbstractPcodeDebuggerAccess(PluginTool tool, Target target, TracePlatform platform, + public AbstractPcodeDebuggerAccess(ServiceProvider provider, Target target, + TracePlatform platform, long snap) { super(platform, snap); - this.tool = tool; + this.provider = provider; this.target = target; } } diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/emulation/data/DefaultPcodeDebuggerAccess.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/emulation/data/DefaultPcodeDebuggerAccess.java index ef089738fe..ea0a0ed29f 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/emulation/data/DefaultPcodeDebuggerAccess.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/emulation/data/DefaultPcodeDebuggerAccess.java @@ -16,7 +16,7 @@ package ghidra.app.plugin.core.debug.service.emulation.data; import ghidra.debug.api.target.Target; -import ghidra.framework.plugintool.PluginTool; +import ghidra.framework.plugintool.ServiceProvider; import ghidra.trace.model.guest.TracePlatform; import ghidra.trace.model.thread.TraceThread; @@ -30,25 +30,25 @@ public class DefaultPcodeDebuggerAccess extends /** * Construct a shim * - * @param tool the tool controlling the session + * @param provider the service provider (usually the tool) * @param target the target * @param platform the associated platform, having the same trace as the recorder * @param snap the associated snap */ - public DefaultPcodeDebuggerAccess(PluginTool tool, Target target, TracePlatform platform, - long snap) { - super(tool, target, platform, snap); + public DefaultPcodeDebuggerAccess(ServiceProvider provider, Target target, + TracePlatform platform, long snap) { + super(provider, target, platform, snap); } @Override protected DefaultPcodeDebuggerMemoryAccess newDataForSharedState() { - return new DefaultPcodeDebuggerMemoryAccess(tool, target, platform, snap, viewport); + return new DefaultPcodeDebuggerMemoryAccess(provider, target, platform, snap, viewport); } @Override protected DefaultPcodeDebuggerRegistersAccess newDataForLocalState(TraceThread thread, int frame) { - return new DefaultPcodeDebuggerRegistersAccess(tool, target, platform, snap, thread, frame, - viewport); + return new DefaultPcodeDebuggerRegistersAccess(provider, target, platform, snap, thread, + frame, viewport); } } diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/emulation/data/DefaultPcodeDebuggerMemoryAccess.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/emulation/data/DefaultPcodeDebuggerMemoryAccess.java index 081fe760ce..73fb0d9dd9 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/emulation/data/DefaultPcodeDebuggerMemoryAccess.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/emulation/data/DefaultPcodeDebuggerMemoryAccess.java @@ -23,7 +23,7 @@ import ghidra.app.services.DebuggerStaticMappingService; import ghidra.app.services.DebuggerStaticMappingService.MappedAddressRange; import ghidra.debug.api.emulation.PcodeDebuggerMemoryAccess; import ghidra.debug.api.target.Target; -import ghidra.framework.plugintool.PluginTool; +import ghidra.framework.plugintool.ServiceProvider; import ghidra.generic.util.datastruct.SemisparseByteArray; import ghidra.pcode.exec.trace.data.DefaultPcodeTraceMemoryAccess; import ghidra.pcode.exec.trace.data.PcodeTracePropertyAccess; @@ -42,22 +42,22 @@ import ghidra.util.task.TaskMonitor; public class DefaultPcodeDebuggerMemoryAccess extends DefaultPcodeTraceMemoryAccess implements PcodeDebuggerMemoryAccess, InternalPcodeDebuggerDataAccess { - protected final PluginTool tool; + protected final ServiceProvider provider; protected final Target target; /** * Construct a shim * - * @param tool the tool controlling the session + * @param provider the service provider (usually the tool) * @param target the target * @param platform the associated platform, having the same trace as the recorder * @param snap the associated snap * @param viewport the viewport, set to the same snapshot */ - protected DefaultPcodeDebuggerMemoryAccess(PluginTool tool, Target target, + protected DefaultPcodeDebuggerMemoryAccess(ServiceProvider provider, Target target, TracePlatform platform, long snap, TraceTimeViewport viewport) { super(platform, snap, viewport); - this.tool = Objects.requireNonNull(tool); + this.provider = Objects.requireNonNull(provider); this.target = target; } @@ -67,8 +67,8 @@ public class DefaultPcodeDebuggerMemoryAccess extends DefaultPcodeTraceMemoryAcc } @Override - public PluginTool getTool() { - return tool; + public ServiceProvider getServiceProvider() { + return provider; } @Override @@ -97,7 +97,7 @@ public class DefaultPcodeDebuggerMemoryAccess extends DefaultPcodeTraceMemoryAcc public boolean readFromStaticImages(SemisparseByteArray bytes, AddressSetView guestView) { // TODO: Expand to block? DON'T OVERWRITE KNOWN! DebuggerStaticMappingService mappingService = - tool.getService(DebuggerStaticMappingService.class); + provider.getService(DebuggerStaticMappingService.class); if (mappingService == null) { return false; } diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/emulation/data/DefaultPcodeDebuggerPropertyAccess.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/emulation/data/DefaultPcodeDebuggerPropertyAccess.java index 358ca581fe..23fc7f0c5d 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/emulation/data/DefaultPcodeDebuggerPropertyAccess.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/emulation/data/DefaultPcodeDebuggerPropertyAccess.java @@ -53,7 +53,7 @@ public class DefaultPcodeDebuggerPropertyAccess @Override protected T whenNull(Address hostAddress) { DebuggerStaticMappingService mappingService = - data.getTool().getService(DebuggerStaticMappingService.class); + data.getServiceProvider().getService(DebuggerStaticMappingService.class); if (mappingService == null) { return super.whenNull(hostAddress); } diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/emulation/data/DefaultPcodeDebuggerRegistersAccess.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/emulation/data/DefaultPcodeDebuggerRegistersAccess.java index c68e03e2e4..f001093d03 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/emulation/data/DefaultPcodeDebuggerRegistersAccess.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/emulation/data/DefaultPcodeDebuggerRegistersAccess.java @@ -19,7 +19,7 @@ import java.util.concurrent.CompletableFuture; import ghidra.debug.api.emulation.PcodeDebuggerRegistersAccess; import ghidra.debug.api.target.Target; -import ghidra.framework.plugintool.PluginTool; +import ghidra.framework.plugintool.ServiceProvider; import ghidra.pcode.exec.trace.data.DefaultPcodeTraceRegistersAccess; import ghidra.program.model.address.Address; import ghidra.program.model.address.AddressSetView; @@ -33,13 +33,13 @@ import ghidra.trace.model.thread.TraceThread; public class DefaultPcodeDebuggerRegistersAccess extends DefaultPcodeTraceRegistersAccess implements PcodeDebuggerRegistersAccess, InternalPcodeDebuggerDataAccess { - protected final PluginTool tool; + protected final ServiceProvider provider; protected final Target target; /** * Construct a shim * - * @param tool the tool controlling the session + * @param provider the service provider (usually the tool) * @param target the target * @param platform the associated platform, having the same trace as the recorder * @param snap the associated snap @@ -47,11 +47,11 @@ public class DefaultPcodeDebuggerRegistersAccess extends DefaultPcodeTraceRegist * @param frame the associated frame, or 0 if not applicable * @param viewport the viewport, set to the same snapshot */ - protected DefaultPcodeDebuggerRegistersAccess(PluginTool tool, Target target, + protected DefaultPcodeDebuggerRegistersAccess(ServiceProvider provider, Target target, TracePlatform platform, long snap, TraceThread thread, int frame, TraceTimeViewport viewport) { super(platform, snap, thread, frame, viewport); - this.tool = tool; + this.provider = provider; this.target = target; } @@ -61,8 +61,8 @@ public class DefaultPcodeDebuggerRegistersAccess extends DefaultPcodeTraceRegist } @Override - public PluginTool getTool() { - return tool; + public ServiceProvider getServiceProvider() { + return provider; } @Override diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/emulation/data/InternalPcodeDebuggerDataAccess.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/emulation/data/InternalPcodeDebuggerDataAccess.java index 1fca7979a7..1bfdd51bcd 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/emulation/data/InternalPcodeDebuggerDataAccess.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/emulation/data/InternalPcodeDebuggerDataAccess.java @@ -16,14 +16,14 @@ package ghidra.app.plugin.core.debug.service.emulation.data; import ghidra.debug.api.target.Target; -import ghidra.framework.plugintool.PluginTool; +import ghidra.framework.plugintool.ServiceProvider; import ghidra.lifecycle.Internal; import ghidra.pcode.exec.trace.data.InternalPcodeTraceDataAccess; import ghidra.trace.model.TraceTimeViewport; @Internal public interface InternalPcodeDebuggerDataAccess extends InternalPcodeTraceDataAccess { - PluginTool getTool(); + ServiceProvider getServiceProvider(); Target getTarget(); diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/modules/DebuggerStaticMappingUtils.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/modules/DebuggerStaticMappingUtils.java index 1f0c5e9871..849dcad950 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/modules/DebuggerStaticMappingUtils.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/modules/DebuggerStaticMappingUtils.java @@ -20,18 +20,21 @@ import java.util.*; import java.util.stream.Collectors; import ghidra.app.plugin.core.debug.utils.ProgramURLUtils; +import ghidra.app.services.DebuggerStaticMappingService; import ghidra.debug.api.modules.MapEntry; +import ghidra.debug.api.tracemgr.DebuggerCoordinates; import ghidra.framework.model.DomainFile; import ghidra.framework.model.ProjectData; +import ghidra.framework.plugintool.ServiceProvider; import ghidra.program.model.address.*; -import ghidra.program.model.listing.Library; -import ghidra.program.model.listing.Program; +import ghidra.program.model.listing.*; import ghidra.program.model.mem.MemoryBlock; import ghidra.program.model.symbol.ExternalManager; import ghidra.program.util.ProgramLocation; import ghidra.trace.model.*; import ghidra.trace.model.modules.*; import ghidra.trace.model.program.TraceProgramView; +import ghidra.trace.model.thread.TraceThread; import ghidra.util.ComparatorMath; import ghidra.util.Msg; @@ -301,4 +304,55 @@ public enum DebuggerStaticMappingUtils { } return names.stream().collect(Collectors.joining(",")); } + + public static Function getFunction(Address pc, DebuggerCoordinates coordinates, + ServiceProvider serviceProvider) { + if (pc == null) { + return null; + } + DebuggerStaticMappingService mappingService = + serviceProvider.getService(DebuggerStaticMappingService.class); + if (mappingService == null) { + return null; + } + TraceThread curThread = coordinates.getThread(); + if (curThread == null) { + return null; + } + TraceLocation dloc = new DefaultTraceLocation(curThread.getTrace(), + curThread, Lifespan.at(coordinates.getSnap()), pc); + ProgramLocation sloc = mappingService.getOpenMappedLocation(dloc); + if (sloc == null) { + return null; + } + return sloc.getProgram().getFunctionManager().getFunctionContaining(sloc.getAddress()); + } + + public static String computeModuleShortName(String path) { + int sep = path.lastIndexOf('\\'); + if (sep > 0 && sep < path.length()) { + path = path.substring(sep + 1); + } + sep = path.lastIndexOf('/'); + if (sep > 0 && sep < path.length()) { + path = path.substring(sep + 1); + } + return path; + } + + public static String getModuleName(Address pc, DebuggerCoordinates coordinates) { + if (pc == null) { + return null; + } + Trace trace = coordinates.getTrace(); + if (trace == null) { + return null; + } + for (TraceModule module : trace.getModuleManager() + .getModulesAt(coordinates.getSnap(), pc)) { + // Just take the first + return computeModuleShortName(module.getName()); + } + return null; + } } diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/pcode/exec/DebuggerPcodeUtils.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/pcode/exec/DebuggerPcodeUtils.java index 17354f42f8..df4a3beb00 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/pcode/exec/DebuggerPcodeUtils.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/pcode/exec/DebuggerPcodeUtils.java @@ -26,7 +26,7 @@ import ghidra.app.plugin.processors.sleigh.SleighException; import ghidra.app.plugin.processors.sleigh.SleighLanguage; import ghidra.app.services.DebuggerStaticMappingService; import ghidra.debug.api.tracemgr.DebuggerCoordinates; -import ghidra.framework.plugintool.PluginTool; +import ghidra.framework.plugintool.ServiceProvider; import ghidra.pcode.emu.ThreadPcodeExecutorState; import ghidra.pcode.exec.PcodeArithmetic.Purpose; import ghidra.pcode.exec.PcodeExecutorStatePiece.Reason; @@ -73,12 +73,12 @@ public enum DebuggerPcodeUtils { /** * Construct a parser bound to the given coordinates * - * @param tool the tool for the mapping service + * @param provider the service provider (usually the tool) * @param coordinates the current coordinates for context */ - public LabelBoundPcodeParser(PluginTool tool, DebuggerCoordinates coordinates) { + public LabelBoundPcodeParser(ServiceProvider provider, DebuggerCoordinates coordinates) { super((SleighLanguage) coordinates.getPlatform().getLanguage()); - this.mappings = tool.getService(DebuggerStaticMappingService.class); + this.mappings = provider.getService(DebuggerStaticMappingService.class); this.coordinates = coordinates; } @@ -194,15 +194,17 @@ public enum DebuggerPcodeUtils { * substituted for their offsets. If a label moves, the program should be recompiled in order to * update those substitutions. * - * @param tool the tool for context + * @param provider the service provider (usually the tool) * @param coordinates the coordinates for the trace (and programs) from which labels can be * resolved * @see SleighProgramCompiler#compileProgram(PcodeParser, SleighLanguage, String, String, * PcodeUseropLibrary) */ - public static PcodeProgram compileProgram(PluginTool tool, DebuggerCoordinates coordinates, + public static PcodeProgram compileProgram(ServiceProvider provider, + DebuggerCoordinates coordinates, String sourceName, String source, PcodeUseropLibrary library) { - return SleighProgramCompiler.compileProgram(new LabelBoundPcodeParser(tool, coordinates), + return SleighProgramCompiler.compileProgram( + new LabelBoundPcodeParser(provider, coordinates), (SleighLanguage) coordinates.getPlatform().getLanguage(), sourceName, source, library); } @@ -211,13 +213,14 @@ public enum DebuggerPcodeUtils { * *

* This has the same limitations as - * {@link #compileProgram(PluginTool, DebuggerCoordinates, String, String, PcodeUseropLibrary)} + * {@link #compileProgram(ServiceProvider, DebuggerCoordinates, String, String, PcodeUseropLibrary)} * * @see SleighProgramCompiler#compileExpression(PcodeParser, SleighLanguage, String) */ - public static PcodeExpression compileExpression(PluginTool tool, + public static PcodeExpression compileExpression(ServiceProvider provider, DebuggerCoordinates coordinates, String source) { - return SleighProgramCompiler.compileExpression(new LabelBoundPcodeParser(tool, coordinates), + return SleighProgramCompiler.compileExpression( + new LabelBoundPcodeParser(provider, coordinates), (SleighLanguage) coordinates.getPlatform().getLanguage(), source); } @@ -228,11 +231,11 @@ public enum DebuggerPcodeUtils { * If a thread is included, the executor state will have access to both the memory and registers * in the context of that thread. Otherwise, only memory access is permitted. * - * @param tool the plugin tool + * @param provider the service provider (usually the tool) * @param coordinates the coordinates * @return the state */ - public static PcodeExecutorState executorStateForCoordinates(PluginTool tool, + public static PcodeExecutorState executorStateForCoordinates(ServiceProvider provider, DebuggerCoordinates coordinates) { Trace trace = coordinates.getTrace(); if (trace == null) { @@ -244,7 +247,7 @@ public enum DebuggerPcodeUtils { throw new IllegalArgumentException( "Given trace or platform does not use a Sleigh language"); } - DefaultPcodeDebuggerAccess access = new DefaultPcodeDebuggerAccess(tool, + DefaultPcodeDebuggerAccess access = new DefaultPcodeDebuggerAccess(provider, coordinates.getTarget(), platform, coordinates.getViewSnap()); PcodeExecutorState shared = new RWTargetMemoryPcodeExecutorState(access.getDataForSharedState(), Mode.RW); @@ -270,13 +273,13 @@ public enum DebuggerPcodeUtils { * If a thread is included, the executor will have access to both the memory and registers in * the context of that thread. Otherwise, only memory access is permitted. * - * @param tool the plugin tool. TODO: This shouldn't be required + * @param provider the service provider (usually the tool) * @param coordinates the coordinates * @return the executor */ - public static PcodeExecutor executorForCoordinates(PluginTool tool, + public static PcodeExecutor executorForCoordinates(ServiceProvider provider, DebuggerCoordinates coordinates) { - PcodeExecutorState state = executorStateForCoordinates(tool, coordinates); + PcodeExecutorState state = executorStateForCoordinates(provider, coordinates); SleighLanguage slang = (SleighLanguage) state.getLanguage(); return new PcodeExecutor<>(slang, BytesPcodeArithmetic.forLanguage(slang), state, @@ -695,12 +698,12 @@ public enum DebuggerPcodeUtils { } } - public static WatchValuePcodeExecutorState buildWatchState(PluginTool tool, + public static WatchValuePcodeExecutorState buildWatchState(ServiceProvider provider, DebuggerCoordinates coordinates) { PcodeTraceDataAccess data = new DefaultPcodeTraceAccess(coordinates.getPlatform(), coordinates.getViewSnap(), coordinates.getSnap()) .getDataForThreadState(coordinates.getThread(), coordinates.getFrame()); - PcodeExecutorState bytesState = executorStateForCoordinates(tool, coordinates); + PcodeExecutorState bytesState = executorStateForCoordinates(provider, coordinates); return new WatchValuePcodeExecutorState(new WatchValuePcodeExecutorStatePiece( bytesState, new TraceMemoryStatePcodeExecutorStatePiece(data), @@ -717,18 +720,18 @@ public enum DebuggerPcodeUtils { * machine state, if applicable. Use the executor in a background thread to avoid locking the * GUI. * - * @param tool this plugin tool + * @param provider the service provider (usually the tool) * @param coordinates the coordinates providing context for the evaluation * @return an executor for evaluating the watch */ - public static PcodeExecutor buildWatchExecutor(PluginTool tool, + public static PcodeExecutor buildWatchExecutor(ServiceProvider provider, DebuggerCoordinates coordinates) { TracePlatform platform = coordinates.getPlatform(); Language language = platform.getLanguage(); if (!(language instanceof SleighLanguage slang)) { throw new IllegalArgumentException("Watch expressions require a Sleigh language"); } - WatchValuePcodeExecutorState state = buildWatchState(tool, coordinates); + WatchValuePcodeExecutorState state = buildWatchState(provider, coordinates); return new PcodeExecutor<>(slang, state.getArithmetic(), state, Reason.INSPECT); } } diff --git a/Ghidra/Debug/ProposedUtils/src/main/java/docking/widgets/table/DefaultEnumeratedColumnTableModel.java b/Ghidra/Debug/ProposedUtils/src/main/java/docking/widgets/table/DefaultEnumeratedColumnTableModel.java index 61ec02f703..9f060184ea 100644 --- a/Ghidra/Debug/ProposedUtils/src/main/java/docking/widgets/table/DefaultEnumeratedColumnTableModel.java +++ b/Ghidra/Debug/ProposedUtils/src/main/java/docking/widgets/table/DefaultEnumeratedColumnTableModel.java @@ -100,6 +100,15 @@ public class DefaultEnumeratedColumnTableModel & EnumeratedTab return true; } + /** + * Check if this column should be visible by default + * + * @return true if visible + */ + default public boolean isVisible() { + return true; + } + /** * Get the default sort direction for this column * @@ -217,10 +226,15 @@ public class DefaultEnumeratedColumnTableModel & EnumeratedTab if (cols != null) { // Smells List defaultOrder = defaultSortOrder(); for (C col : cols) { - descriptor.addVisibleColumn( - new EnumeratedDynamicTableColumn(col), - defaultOrder.indexOf(col), // -1 means not found, not sorted - col.defaultSortDirection().isAscending()); + EnumeratedDynamicTableColumn ecol = new EnumeratedDynamicTableColumn(col); + if (col.isVisible()) { + descriptor.addVisibleColumn(ecol, + defaultOrder.indexOf(col), // -1 means not found, not sorted + col.defaultSortDirection().isAscending()); + } + else { + descriptor.addHiddenColumn(ecol); + } } } return descriptor;