diff --git a/Ghidra/Debug/Debugger/src/main/help/help/topics/DebuggerListingPlugin/DebuggerListingPlugin.html b/Ghidra/Debug/Debugger/src/main/help/help/topics/DebuggerListingPlugin/DebuggerListingPlugin.html
index 0001e848c2..032f904f74 100644
--- a/Ghidra/Debug/Debugger/src/main/help/help/topics/DebuggerListingPlugin/DebuggerListingPlugin.html
+++ b/Ghidra/Debug/Debugger/src/main/help/help/topics/DebuggerListingPlugin/DebuggerListingPlugin.html
@@ -94,10 +94,12 @@
This action is always available on all dynamic listings. It configures automatic navigation
for the dynamic listing. When location tracking is enabled, the listing is automatically
- navigated to an address computed from the trace's or target's machine state. The address (and
- its corresponding static address) are also highlighted in green. The computed address is
- affected by the tool's current "coordinates," that is the selected thread, frame, and point in
- time. The options are pluggable, but currently consist of:
+ navigated to an address computed from the trace's or target's machine state. The address is
+ displayed in the top right of the viewer. That address and its corresponding static address are
+ also highlighted in green in the listing. If the address cannot be located in the listing, the
+ address is displayed in red. The computed address is affected by the tool's current
+ "coordinates," that is the selected thread, frame, and point in time. The options are
+ pluggable, but currently consist of:
- Do Not Track - disables automatic navigation.
diff --git a/Ghidra/Debug/Debugger/src/main/help/help/topics/DebuggerListingPlugin/images/DebuggerListingPlugin.png b/Ghidra/Debug/Debugger/src/main/help/help/topics/DebuggerListingPlugin/images/DebuggerListingPlugin.png
index 69777a726d..ebe1c9b18e 100644
Binary files a/Ghidra/Debug/Debugger/src/main/help/help/topics/DebuggerListingPlugin/images/DebuggerListingPlugin.png and b/Ghidra/Debug/Debugger/src/main/help/help/topics/DebuggerListingPlugin/images/DebuggerListingPlugin.png differ
diff --git a/Ghidra/Debug/Debugger/src/main/help/help/topics/DebuggerMemoryBytesPlugin/DebuggerMemoryBytesPlugin.html b/Ghidra/Debug/Debugger/src/main/help/help/topics/DebuggerMemoryBytesPlugin/DebuggerMemoryBytesPlugin.html
index 078934cb04..47b1687768 100644
--- a/Ghidra/Debug/Debugger/src/main/help/help/topics/DebuggerMemoryBytesPlugin/DebuggerMemoryBytesPlugin.html
+++ b/Ghidra/Debug/Debugger/src/main/help/help/topics/DebuggerMemoryBytesPlugin/DebuggerMemoryBytesPlugin.html
@@ -44,7 +44,7 @@
failed, the first address in the failed range is displayed with a pink background. Otherwise,
up-to-date contents are displayed with the default background color.
- The dynamic listing supports editing memory. SeeThe dynamic bytes viewer supports editing memory. See Control and Machine State.
Such edits are performed as usual: Toggling edits and typing into the editor, or by pasting
byte strings. These edits may be directed toward a live target, the trace, or the emulator.
diff --git a/Ghidra/Debug/Debugger/src/main/help/help/topics/DebuggerMemoryBytesPlugin/images/DebuggerMemoryBytesPlugin.png b/Ghidra/Debug/Debugger/src/main/help/help/topics/DebuggerMemoryBytesPlugin/images/DebuggerMemoryBytesPlugin.png
index 2ec3857509..feebf9768f 100644
Binary files a/Ghidra/Debug/Debugger/src/main/help/help/topics/DebuggerMemoryBytesPlugin/images/DebuggerMemoryBytesPlugin.png and b/Ghidra/Debug/Debugger/src/main/help/help/topics/DebuggerMemoryBytesPlugin/images/DebuggerMemoryBytesPlugin.png differ
diff --git a/Ghidra/Debug/Debugger/src/main/help/help/topics/DebuggerObjectsPlugin/DebuggerObjectsPlugin.html b/Ghidra/Debug/Debugger/src/main/help/help/topics/DebuggerObjectsPlugin/DebuggerObjectsPlugin.html
index 253f121d12..d546f4c211 100644
--- a/Ghidra/Debug/Debugger/src/main/help/help/topics/DebuggerObjectsPlugin/DebuggerObjectsPlugin.html
+++ b/Ghidra/Debug/Debugger/src/main/help/help/topics/DebuggerObjectsPlugin/DebuggerObjectsPlugin.html
@@ -349,7 +349,8 @@
- Set the default value for the timeout used when expanding a node, i.e. populating its children.
+ Set the default value for the timeout used when expanding a node, i.e. populating its
+ children.
Color Options
diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/DebuggerTrackLocationTrait.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/DebuggerTrackLocationTrait.java
index 3d6d97e3f8..e9fcef819f 100644
--- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/DebuggerTrackLocationTrait.java
+++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/DebuggerTrackLocationTrait.java
@@ -258,6 +258,13 @@ public class DebuggerTrackLocationTrait {
});
}
+ public String computeLabelText() {
+ if (spec == null || trackedLocation == null) {
+ return "";
+ }
+ return spec.getLocationLabel() + " = " + trackedLocation.getByteAddress();
+ }
+
protected void doTrack() {
computeTrackedLocation().thenAccept(loc -> {
trackedLocation = loc;
diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/LocationTrackingSpec.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/LocationTrackingSpec.java
index 53ca90bd58..7ca22a96c5 100644
--- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/LocationTrackingSpec.java
+++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/LocationTrackingSpec.java
@@ -121,6 +121,13 @@ public interface LocationTrackingSpec {
*/
String computeTitle(DebuggerCoordinates coordinates);
+ /**
+ * Get the name used in the location tracking label
+ *
+ * @return the label
+ */
+ String getLocationLabel();
+
/**
* Get (or create) the actual location tracking logic
*
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 c7392f0c00..f41121d0e8 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
@@ -53,6 +53,11 @@ public enum NoneLocationTrackingSpec implements LocationTrackingSpec, LocationTr
return null;
}
+ @Override
+ public String getLocationLabel() {
+ return null;
+ }
+
@Override
public LocationTracker getTracker() {
return this;
diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/PCByRegisterLocationTrackingSpec.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/PCByRegisterLocationTrackingSpec.java
index 7bbe7cf764..9aaa48aef3 100644
--- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/PCByRegisterLocationTrackingSpec.java
+++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/PCByRegisterLocationTrackingSpec.java
@@ -52,6 +52,11 @@ public enum PCByRegisterLocationTrackingSpec implements RegisterLocationTracking
return platform.getLanguage().getProgramCounter();
}
+ @Override
+ public String getLocationLabel() {
+ return "pc";
+ }
+
@Override
public AddressSpace computeDefaultAddressSpace(DebuggerCoordinates coordinates) {
return coordinates.getPlatform().getLanguage().getDefaultSpace();
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 f05acdb08b..996552df13 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
@@ -55,6 +55,11 @@ public enum PCByStackLocationTrackingSpec implements LocationTrackingSpec, Locat
return "Stack's PC";
}
+ @Override
+ public String getLocationLabel() {
+ return "pc";
+ }
+
@Override
public LocationTracker getTracker() {
return this;
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 87084b6863..c2b69303cb 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
@@ -57,6 +57,11 @@ public enum PCLocationTrackingSpec implements LocationTrackingSpec, LocationTrac
return "Auto PC";
}
+ @Override
+ public String getLocationLabel() {
+ return "pc";
+ }
+
@Override
public LocationTracker getTracker() {
return this;
diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/SPLocationTrackingSpec.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/SPLocationTrackingSpec.java
index 8d8680adec..80eddf48eb 100644
--- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/SPLocationTrackingSpec.java
+++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/SPLocationTrackingSpec.java
@@ -43,6 +43,11 @@ public enum SPLocationTrackingSpec implements RegisterLocationTrackingSpec {
return TrackLocationAction.ICON_SP;
}
+ @Override
+ public String getLocationLabel() {
+ return "sp";
+ }
+
@Override
public Register computeRegister(DebuggerCoordinates coordinates) {
TracePlatform platform = coordinates.getPlatform();
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 e9ae639cdb..527b200a63 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
@@ -95,6 +95,11 @@ public class WatchLocationTrackingSpec implements LocationTrackingSpec {
return "&(" + expression + ")";
}
+ @Override
+ public String getLocationLabel() {
+ return "&watch";
+ }
+
/**
* The tracking logic for a watch (Sleigh expression)
*/
diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/listing/DebuggerListingProvider.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/listing/DebuggerListingProvider.java
index 4e28d97e85..3298f8c256 100644
--- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/listing/DebuggerListingProvider.java
+++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/listing/DebuggerListingProvider.java
@@ -17,12 +17,17 @@ package ghidra.app.plugin.core.debug.gui.listing;
import static ghidra.app.plugin.core.debug.gui.DebuggerResources.ICON_REGISTER_MARKER;
+import java.awt.BorderLayout;
import java.awt.Color;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
import java.lang.invoke.MethodHandles;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
@@ -36,6 +41,7 @@ import docking.action.ToggleDockingAction;
import docking.menu.MultiStateDockingAction;
import docking.widgets.EventTrigger;
import docking.widgets.fieldpanel.support.ViewerPosition;
+import generic.theme.GThemeDefaults.Colors;
import ghidra.app.nav.ListingPanelContainer;
import ghidra.app.plugin.core.codebrowser.CodeViewerProvider;
import ghidra.app.plugin.core.codebrowser.MarkerServiceBackgroundColorModel;
@@ -193,6 +199,8 @@ public class DebuggerListingProvider extends CodeViewerProvider {
@Override
protected void specChanged(LocationTrackingSpec spec) {
updateTitle();
+ trackingLabel.setText("");
+ trackingLabel.setForeground(Colors.FOREGROUND);
trackingSpecChangeListeners.fire.locationTrackingSpecChanged(spec);
}
@@ -270,6 +278,7 @@ public class DebuggerListingProvider extends CodeViewerProvider {
new ListenerSet<>(LocationTrackingSpecChangeListener.class);
protected final DebuggerLocationLabel locationLabel = new DebuggerLocationLabel();
+ protected final JLabel trackingLabel = new JLabel();
protected final MultiBlendedListingBackgroundColorModel colorModel;
protected final MarkerSetChangeListener markerChangeListener = new MarkerSetChangeListener();
@@ -316,7 +325,10 @@ public class DebuggerListingProvider extends CodeViewerProvider {
addDisplayListener(readsMemTrait.getDisplayListener());
- this.setNorthComponent(locationLabel);
+ JPanel northPanel = new JPanel(new BorderLayout());
+ northPanel.add(locationLabel, BorderLayout.WEST);
+ northPanel.add(trackingLabel, BorderLayout.EAST);
+ this.setNorthComponent(northPanel);
if (isConnected) {
setTitle(DebuggerResources.TITLE_PROVIDER_LISTING);
}
@@ -325,6 +337,15 @@ public class DebuggerListingProvider extends CodeViewerProvider {
}
updateTitle(); // Actually, the subtitle
setHelpLocation(DebuggerResources.HELP_PROVIDER_LISTING);
+
+ trackingLabel.addMouseListener(new MouseAdapter() {
+ @Override
+ public void mouseClicked(MouseEvent e) {
+ if (e.getClickCount() == 2 && e.getButton() == MouseEvent.BUTTON1) {
+ doGoToTracked();
+ }
+ }
+ });
}
@Override
@@ -1020,6 +1041,16 @@ public class DebuggerListingProvider extends CodeViewerProvider {
return trackedStatic;
}
+ protected void goToAndUpdateTrackingLabel(TraceProgramView curView, ProgramLocation loc) {
+ trackingLabel.setText(trackingTrait.computeLabelText());
+ if (goTo(curView, loc)) {
+ trackingLabel.setForeground(Colors.FOREGROUND);
+ }
+ else {
+ trackingLabel.setForeground(Colors.ERROR);
+ }
+ }
+
protected void doGoToTracked() {
ProgramLocation loc = trackingTrait.getTrackedLocation();
ProgramLocation trackedStatic = doMarkTrackedLocation();
@@ -1029,13 +1060,13 @@ public class DebuggerListingProvider extends CodeViewerProvider {
TraceProgramView curView = current.getView();
if (!syncTrait.isAutoSyncCursorWithStaticListing() || trackedStatic == null) {
Swing.runIfSwingOrRunLater(() -> {
- goTo(curView, loc);
+ goToAndUpdateTrackingLabel(curView, loc);
doCheckCurrentModuleMissing();
});
}
else {
Swing.runIfSwingOrRunLater(() -> {
- goTo(curView, loc);
+ goToAndUpdateTrackingLabel(curView, loc);
doCheckCurrentModuleMissing();
plugin.fireStaticLocationEvent(trackedStatic);
});
@@ -1080,6 +1111,10 @@ public class DebuggerListingProvider extends CodeViewerProvider {
public void coordinatesActivated(DebuggerCoordinates coordinates) {
DebuggerCoordinates adjusted = adjustCoordinates(coordinates);
goToCoordinates(adjusted);
+ if (adjusted.getTrace() == null) {
+ trackingLabel.setText("");
+ trackingLabel.setForeground(Colors.FOREGROUND);
+ }
}
public void traceClosed(Trace trace) {
diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/memory/DebuggerMemoryBytesProvider.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/memory/DebuggerMemoryBytesProvider.java
index 9e7c882ba6..4774bb093a 100644
--- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/memory/DebuggerMemoryBytesProvider.java
+++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/memory/DebuggerMemoryBytesProvider.java
@@ -16,16 +16,22 @@
package ghidra.app.plugin.core.debug.gui.memory;
import java.awt.BorderLayout;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
import java.lang.invoke.MethodHandles;
import java.math.BigInteger;
import java.util.*;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+
import org.apache.commons.lang3.StringUtils;
import docking.action.DockingAction;
import docking.action.ToggleDockingAction;
import docking.menu.MultiStateDockingAction;
import docking.widgets.fieldpanel.support.ViewerPosition;
+import generic.theme.GThemeDefaults.Colors;
import ghidra.app.plugin.core.byteviewer.*;
import ghidra.app.plugin.core.debug.DebuggerCoordinates;
import ghidra.app.plugin.core.debug.gui.DebuggerLocationLabel;
@@ -121,6 +127,8 @@ public class DebuggerMemoryBytesProvider extends ProgramByteViewerComponentProvi
@Override
protected void specChanged(LocationTrackingSpec spec) {
updateTitle();
+ trackingLabel.setText("");
+ trackingLabel.setForeground(Colors.FOREGROUND);
}
}
@@ -165,6 +173,7 @@ public class DebuggerMemoryBytesProvider extends ProgramByteViewerComponentProvi
protected ForMemoryBytesReadsMemoryTrait readsMemTrait;
protected final DebuggerLocationLabel locationLabel = new DebuggerLocationLabel();
+ protected final JLabel trackingLabel = new JLabel();
@AutoConfigStateField
protected boolean followsCurrentThread = true;
@@ -191,7 +200,11 @@ public class DebuggerMemoryBytesProvider extends ProgramByteViewerComponentProvi
autoServiceWiring = AutoService.wireServicesConsumed(plugin, this);
createActions();
addDisplayListener(readsMemTrait.getDisplayListener());
- decorationComponent.add(locationLabel, BorderLayout.NORTH);
+
+ JPanel northPanel = new JPanel(new BorderLayout());
+ northPanel.add(locationLabel, BorderLayout.WEST);
+ northPanel.add(trackingLabel, BorderLayout.EAST);
+ decorationComponent.add(northPanel, BorderLayout.NORTH);
goToTrait.goToCoordinates(current);
trackingTrait.goToCoordinates(current);
@@ -199,6 +212,15 @@ public class DebuggerMemoryBytesProvider extends ProgramByteViewerComponentProvi
locationLabel.goToCoordinates(current);
setHelpLocation(DebuggerResources.HELP_PROVIDER_MEMORY_BYTES);
+
+ trackingLabel.addMouseListener(new MouseAdapter() {
+ @Override
+ public void mouseClicked(MouseEvent e) {
+ if (e.getClickCount() == 2 && e.getButton() == MouseEvent.BUTTON1) {
+ doGoToTracked();
+ }
+ }
+ });
}
@Override
@@ -347,9 +369,17 @@ public class DebuggerMemoryBytesProvider extends ProgramByteViewerComponentProvi
@Override
public boolean goTo(Program gotoProgram, ProgramLocation location) {
- boolean result = super.goTo(gotoProgram, location);
- locationLabel.goToAddress(location == null ? null : location.getAddress());
- return result;
+ if (location == null) {
+ return false;
+ }
+ if (blockSet.getByteBlockInfo(location.getAddress()) == null) {
+ return false;
+ }
+ if (!super.goTo(gotoProgram, location)) {
+ return false;
+ }
+ locationLabel.goToAddress(location.getAddress());
+ return true;
}
protected void removeOldListeners() {
@@ -394,6 +424,10 @@ public class DebuggerMemoryBytesProvider extends ProgramByteViewerComponentProvi
public void coordinatesActivated(DebuggerCoordinates coordinates) {
DebuggerCoordinates adjusted = adjustCoordinates(coordinates);
goToCoordinates(adjusted);
+ if (adjusted.getTrace() == null) {
+ trackingLabel.setText("");
+ trackingLabel.setForeground(Colors.FOREGROUND);
+ }
}
public void traceClosed(Trace trace) {
@@ -434,6 +468,16 @@ public class DebuggerMemoryBytesProvider extends ProgramByteViewerComponentProvi
return readsMemTrait.getAutoSpec();
}
+ protected void goToAndUpdateTrackingLabel(TraceProgramView curView, ProgramLocation loc) {
+ trackingLabel.setText(trackingTrait.computeLabelText());
+ if (goTo(curView, loc)) {
+ trackingLabel.setForeground(Colors.FOREGROUND);
+ }
+ else {
+ trackingLabel.setForeground(Colors.ERROR);
+ }
+ }
+
protected void doGoToTracked() {
if (editModeAction.isSelected()) {
return;
@@ -444,7 +488,7 @@ public class DebuggerMemoryBytesProvider extends ProgramByteViewerComponentProvi
}
TraceProgramView curView = current.getView();
Swing.runIfSwingOrRunLater(() -> {
- goTo(curView, loc);
+ goToAndUpdateTrackingLabel(curView, loc);
});
}
diff --git a/Ghidra/Features/ByteViewer/src/main/java/ghidra/app/plugin/core/byteviewer/ProgramByteBlockSet.java b/Ghidra/Features/ByteViewer/src/main/java/ghidra/app/plugin/core/byteviewer/ProgramByteBlockSet.java
index 7d98e04de0..51c713fa9d 100644
--- a/Ghidra/Features/ByteViewer/src/main/java/ghidra/app/plugin/core/byteviewer/ProgramByteBlockSet.java
+++ b/Ghidra/Features/ByteViewer/src/main/java/ghidra/app/plugin/core/byteviewer/ProgramByteBlockSet.java
@@ -220,7 +220,7 @@ public class ProgramByteBlockSet implements ByteBlockSet {
/**
* Given an address, get the byte block info.
*/
- protected ByteBlockInfo getByteBlockInfo(Address address) {
+ public ByteBlockInfo getByteBlockInfo(Address address) {
if (!program.getMemory().contains(address)) {
// this block set is out of date...eventually a new