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 ff1c20b779..3b590a8135 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 @@ -108,6 +108,19 @@ meaning may vary among platforms. While there may be some nuances to the register value, the value recorded in the stack should indicate the next instruction to be executed. +
  • Track Program Counter (by stack) - navigates this listing to the current program counter + as recorded from the debugger's stack trace. This option is not recommended for regular use, + especially for emulation, since the emulator does not provide stack trace records. It is + recommended for debugger connection developers to verify the stack records are being property + interpreted by the GUI.
  • + +
  • Track Program Counter (by register) - navigates this listing to the current program + counter as recorded from the registers. While suitable for regular use, the default "Track + Program Counter" option is recommended, since the stack may record the program counter in + some cases where the registers do not. For example, when unwinding a stack frame, the + debugger may report the frame's program counter without reporting the frame's registers. This + option may be desired if/when stack frames are recorded incorrectly.
  • +
  • Track Stack Pointer - navigates this listing to the current stack pointer. Again, platforms may vary in how they define the stack pointer.
  • 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 80ca50538b..d71d5643d3 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 @@ -83,13 +83,26 @@ diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/DebuggerResources.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/DebuggerResources.java index 35b922f138..ea344a108f 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/DebuggerResources.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/DebuggerResources.java @@ -859,11 +859,15 @@ public interface DebuggerResources { String HELP_ANCHOR = "track_location"; String NAME_PC = "Track Program Counter"; + String NAME_PC_BY_REGISTER = "Track Program Counter (by Register)"; + String NAME_PC_BY_STACK = "Track Program Counter (by Stack)"; String NAME_SP = "Track Stack Pointer"; String NAME_NONE = "Do Not Track"; // TODO: Separate icons for Program Counter and Stack Pointer Icon ICON_PC = ICON_REGISTER_MARKER; + Icon ICON_PC_BY_REGISTER = ICON_REGISTER_MARKER; + Icon ICON_PC_BY_STACK = ICON_REGISTER_MARKER; Icon ICON_SP = ICON_REGISTER_MARKER; // TODO: Consider sync_disabled icon Icon ICON_NONE = ICON_DELETE; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/DebuggerTrackLocationAction.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/DebuggerTrackLocationAction.java index 845db0061d..41c7cc2a92 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/DebuggerTrackLocationAction.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/DebuggerTrackLocationAction.java @@ -25,6 +25,7 @@ public interface DebuggerTrackLocationAction extends TrackLocationAction { static MultiStateActionBuilder builder(Plugin owner) { MultiStateActionBuilder builder = TrackLocationAction.builder(owner); builder.toolBarGroup(owner.getName()); + builder.useCheckboxForIcons(true); for (LocationTrackingSpec spec : LocationTrackingSpec.allSpecs().values()) { builder.addState(spec.getMenuName(), spec.getMenuIcon(), spec); } 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 f023da0417..9cdf3a2412 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 @@ -251,8 +251,8 @@ public class DebuggerTrackLocationTrait { return null; } // NB: view's snap may be forked for emulation - Address address = spec.computeTraceAddress(tool, cur, current.getView().getSnap()); - return address == null ? null : new ProgramLocation(current.getView(), address); + Address address = spec.computeTraceAddress(tool, cur); + return address == null ? null : new ProgramLocation(cur.getView(), address); } protected void doTrack() { 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 b23a7b40ea..c228b3f6ab 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 @@ -29,21 +29,26 @@ import ghidra.framework.plugintool.AutoConfigState.ConfigFieldCodec; import ghidra.framework.plugintool.PluginTool; import ghidra.program.model.address.Address; import ghidra.trace.model.TraceAddressSnapRange; +import ghidra.trace.model.guest.TracePlatform; +import ghidra.trace.model.memory.TraceMemorySpace; import ghidra.trace.model.stack.TraceStack; import ghidra.trace.util.TraceAddressSpace; import ghidra.util.classfinder.ClassSearcher; import ghidra.util.classfinder.ExtensionPoint; /** - * A "specification" for automatic navigation of the dynamic listing + * A specification for automatic navigation of the dynamic listing * *

    - * TODO: Some of these should be configurable, and permit multiple instances, so that common - * configurations can be saved. The most obvious use case would be a SLEIGH expression. A user may - * want 3 different common expressions readily available in the drop-down list. + * TODO: Some of these should be configurable and permit multiple instances so that common + * configurations can be saved. The most obvious use case would be a Sleigh expression. A user may + * want 3 different common expressions readily available in the drop-down list. It might make sense + * to generate a tracking specification from each Watch. */ public interface LocationTrackingSpec extends ExtensionPoint { - class Private { + enum Private { + INSTANCE; + private final Map specsByName = new TreeMap<>(); private final ChangeListener classListener = this::classesChanged; @@ -57,7 +62,7 @@ public interface LocationTrackingSpec extends ExtensionPoint { } } - Private PRIVATE = new Private(); + Private PRIVATE = Private.INSTANCE; public static class TrackingSpecConfigFieldCodec implements ConfigFieldCodec { @@ -74,13 +79,32 @@ public interface LocationTrackingSpec extends ExtensionPoint { } } + /** + * Check if the given trace-space and range refer to memory or the current frame + * + *

    + * If the space models memory, the thread and frame are not considered, in case, e.g., the + * tracked register is memory-mapped. If the space models registers, the thread and frame are + * considered and must match those given in the coordinates. Whatever the case, the span must + * include the snap of the coordinates. Otherwise, the change is not considered current. + * + * @param space the trace-space, giving thread, frame, and address space + * @param range the address range and time span of the change + * @param current the current coordinates + * @return true if the change affects the tracked address for the given coordinates + */ static boolean changeIsCurrent(TraceAddressSpace space, TraceAddressSnapRange range, DebuggerCoordinates current) { - if (space == null || space.getThread() != current.getThread()) { + if (space == null) { return false; } - if (space.getFrameLevel() != current.getFrame()) { - return false; + if (!space.getAddressSpace().isMemorySpace()) { + TraceMemorySpace memSpace = current.getTrace() + .getMemoryManager() + .getMemoryRegisterSpace(current.getThread(), current.getFrame(), false); + if (memSpace == null || memSpace.getAddressSpace() != space.getAddressSpace()) { + return false; + } } if (!range.getLifespan().contains(current.getSnap())) { return false; @@ -88,22 +112,54 @@ public interface LocationTrackingSpec extends ExtensionPoint { return true; } + /** + * Get the specification for the given configuration name + * + * @param name the name + * @return the spec, or null + */ static LocationTrackingSpec fromConfigName(String name) { synchronized (PRIVATE) { return PRIVATE.specsByName.get(name); } } + /** + * Get a copy of all the known specifications + * + * @return the specifications by configuration name + */ static Map allSpecs() { synchronized (PRIVATE) { - return Map.copyOf(PRIVATE.specsByName); + return new TreeMap<>(PRIVATE.specsByName); } } + /** + * Get the configuration name + * + *

    + * This is the value stored in configuration files to identify this specification + * + * @return the configuration name + */ String getConfigName(); + /** + * A human-readable name for this specification + * + *

    + * This is the text displayed in menus + * + * @return the menu name + */ String getMenuName(); + /** + * Get the icon for this specification + * + * @return the icon + */ Icon getMenuIcon(); /** @@ -120,15 +176,16 @@ public interface LocationTrackingSpec extends ExtensionPoint { *

    * If the coordinates indicate emulation, i.e., the schedule is non-empty, the trace manager * will already have performed the emulation and stored the results in a "scratch" snap. In - * general, the location should be computed using that snap (@code emuSnap) rather than the one - * indicated in {@code coordinates}. + * general, the location should be computed using that snap, i.e., + * {@link DebuggerCoordinates#getViewSnap()} rather than {@link DebuggerCoordinates#getSnap()}. + * 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 coordinates the trace, thread, snap, etc., of the tool - * @param emuSnap the "scratch" snap storing emulated state * @return the address to navigate to */ - Address computeTraceAddress(PluginTool tool, DebuggerCoordinates coordinates, long emuSnap); + Address computeTraceAddress(PluginTool tool, DebuggerCoordinates coordinates); // TODO: Is there a way to generalize these so that other dependencies need not // have their own bespoke methods? 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 f0df0c5f50..e013e2a62c 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 @@ -49,8 +49,7 @@ public class NoneLocationTrackingSpec implements LocationTrackingSpec { } @Override - public Address computeTraceAddress(PluginTool tool, DebuggerCoordinates coordinates, - long emuSnap) { + public Address computeTraceAddress(PluginTool tool, DebuggerCoordinates coordinates) { return null; } 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 new file mode 100644 index 0000000000..400e0b7f01 --- /dev/null +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/PCByRegisterLocationTrackingSpec.java @@ -0,0 +1,57 @@ +/* ### + * IP: GHIDRA + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ghidra.app.plugin.core.debug.gui.action; + +import javax.swing.Icon; + +import ghidra.app.plugin.core.debug.DebuggerCoordinates; +import ghidra.app.plugin.core.debug.gui.DebuggerResources.TrackLocationAction; +import ghidra.program.model.address.AddressSpace; +import ghidra.program.model.lang.Register; +import ghidra.trace.model.guest.TracePlatform; + +public class PCByRegisterLocationTrackingSpec implements RegisterLocationTrackingSpec { + public static final String CONFIG_NAME = "TRACK_PC_BY_REGISTER"; + + @Override + public String getConfigName() { + return CONFIG_NAME; + } + + @Override + public String getMenuName() { + return TrackLocationAction.NAME_PC_BY_REGISTER; + } + + @Override + public Icon getMenuIcon() { + return TrackLocationAction.ICON_PC_BY_REGISTER; + } + + @Override + public Register computeRegister(DebuggerCoordinates coordinates) { + TracePlatform platform = coordinates.getPlatform(); + if (platform == null) { + return null; + } + return platform.getLanguage().getProgramCounter(); + } + + @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 new file mode 100644 index 0000000000..ad69988204 --- /dev/null +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/PCByStackLocationTrackingSpec.java @@ -0,0 +1,96 @@ +/* ### + * IP: GHIDRA + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ghidra.app.plugin.core.debug.gui.action; + +import javax.swing.Icon; + +import ghidra.app.plugin.core.debug.DebuggerCoordinates; +import ghidra.app.plugin.core.debug.gui.DebuggerResources.TrackLocationAction; +import ghidra.framework.plugintool.PluginTool; +import ghidra.program.model.address.Address; +import ghidra.trace.model.Trace; +import ghidra.trace.model.TraceAddressSnapRange; +import ghidra.trace.model.stack.TraceStack; +import ghidra.trace.model.stack.TraceStackFrame; +import ghidra.trace.model.thread.TraceThread; +import ghidra.trace.util.TraceAddressSpace; + +public class PCByStackLocationTrackingSpec implements LocationTrackingSpec { + public static final String CONFIG_NAME = "TRACK_PC_BY_STACK"; + + @Override + public String getConfigName() { + return CONFIG_NAME; + } + + @Override + public String getMenuName() { + return TrackLocationAction.NAME_PC_BY_STACK; + } + + @Override + public Icon getMenuIcon() { + return TrackLocationAction.ICON_PC_BY_STACK; + } + + @Override + public String computeTitle(DebuggerCoordinates coordinates) { + return "Stack's PC"; + } + + @Override + public Address computeTraceAddress(PluginTool tool, DebuggerCoordinates coordinates) { + Trace trace = coordinates.getTrace(); + TraceThread thread = coordinates.getThread(); + long snap = coordinates.getSnap(); + TraceStack stack = trace.getStackManager().getLatestStack(thread, snap); + if (stack == null) { + return null; + } + int level = coordinates.getFrame(); + TraceStackFrame frame = stack.getFrame(level, false); + if (frame == null) { + return null; + } + return frame.getProgramCounter(snap); + } + + // Note it does no good to override affectByRegChange. It must do what we'd avoid anyway. + @Override + public boolean affectedByStackChange(TraceStack stack, DebuggerCoordinates coordinates) { + if (stack.getThread() != coordinates.getThread()) { + return false; + } + if (!coordinates.getTime().isSnapOnly()) { + return false; + } + // TODO: Would be nice to have stack lifespan... + // TODO: It does in objects mode. Leave until old code is removed. + TraceStack curStack = coordinates.getTrace() + .getStackManager() + .getLatestStack(stack.getThread(), coordinates.getSnap()); + if (stack != curStack) { + return false; + } + return true; + } + + @Override + public boolean affectedByRegisterChange(TraceAddressSpace space, TraceAddressSnapRange range, + DebuggerCoordinates coordinates) { + return false; + } +} 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 0da99ed8b0..783ac0bd2b 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 @@ -21,16 +21,18 @@ import ghidra.app.plugin.core.debug.DebuggerCoordinates; import ghidra.app.plugin.core.debug.gui.DebuggerResources.TrackLocationAction; import ghidra.framework.plugintool.PluginTool; import ghidra.program.model.address.Address; -import ghidra.program.model.address.AddressSpace; -import ghidra.program.model.lang.Register; -import ghidra.trace.model.Trace; +import ghidra.trace.model.TraceAddressSnapRange; import ghidra.trace.model.stack.TraceStack; -import ghidra.trace.model.stack.TraceStackFrame; -import ghidra.trace.model.thread.TraceThread; +import ghidra.trace.util.TraceAddressSpace; -public class PCLocationTrackingSpec implements RegisterLocationTrackingSpec { +public class PCLocationTrackingSpec implements LocationTrackingSpec { public static final String CONFIG_NAME = "TRACK_PC"; + private static final PCByRegisterLocationTrackingSpec BY_REG = + new PCByRegisterLocationTrackingSpec(); + private static final PCByStackLocationTrackingSpec BY_STACK = + new PCByStackLocationTrackingSpec(); + @Override public String getConfigName() { return CONFIG_NAME; @@ -47,63 +49,30 @@ public class PCLocationTrackingSpec implements RegisterLocationTrackingSpec { } @Override - public Register computeRegister(DebuggerCoordinates coordinates) { - Trace trace = coordinates.getTrace(); - if (trace == null) { - return null; - } - return trace.getBaseLanguage().getProgramCounter(); + public String computeTitle(DebuggerCoordinates coordinates) { + return "Auto PC"; } @Override - public AddressSpace computeDefaultAddressSpace(DebuggerCoordinates coordinates) { - return coordinates.getTrace().getBaseLanguage().getDefaultSpace(); - } - - public Address computePCViaStack(DebuggerCoordinates coordinates) { - Trace trace = coordinates.getTrace(); - TraceThread thread = coordinates.getThread(); - long snap = coordinates.getSnap(); - TraceStack stack = trace.getStackManager().getLatestStack(thread, snap); - if (stack == null) { - return null; - } - int level = coordinates.getFrame(); - TraceStackFrame frame = stack.getFrame(level, false); - if (frame == null) { - return null; - } - return frame.getProgramCounter(snap); - } - - @Override - public Address computeTraceAddress(PluginTool tool, DebuggerCoordinates coordinates, - long emuSnap) { + public Address computeTraceAddress(PluginTool tool, DebuggerCoordinates coordinates) { if (coordinates.getTime().isSnapOnly()) { - Address pc = computePCViaStack(coordinates); + Address pc = BY_STACK.computeTraceAddress(tool, coordinates); if (pc != null) { return pc; } } - return RegisterLocationTrackingSpec.super.computeTraceAddress(tool, coordinates, emuSnap); + return BY_REG.computeTraceAddress(tool, coordinates); } // Note it does no good to override affectByRegChange. It must do what we'd avoid anyway. @Override public boolean affectedByStackChange(TraceStack stack, DebuggerCoordinates coordinates) { - if (stack.getThread() != coordinates.getThread()) { - return false; - } - if (!coordinates.getTime().isSnapOnly()) { - return false; - } - // TODO: Would be nice to have stack lifespan... - TraceStack curStack = coordinates.getTrace() - .getStackManager() - .getLatestStack(stack.getThread(), coordinates.getSnap()); - if (stack != curStack) { - return false; - } - return true; + return BY_STACK.affectedByStackChange(stack, coordinates); + } + + @Override + public boolean affectedByRegisterChange(TraceAddressSpace space, TraceAddressSnapRange range, + DebuggerCoordinates coordinates) { + return BY_REG.affectedByRegisterChange(space, range, coordinates); } } 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 cbb00c1a1e..6583f9f2cd 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 @@ -22,12 +22,12 @@ import ghidra.program.model.lang.Register; import ghidra.program.model.lang.RegisterValue; import ghidra.trace.model.Trace; import ghidra.trace.model.TraceAddressSnapRange; +import ghidra.trace.model.guest.TracePlatform; import ghidra.trace.model.memory.TraceMemorySpace; import ghidra.trace.model.memory.TraceMemoryState; import ghidra.trace.model.stack.TraceStack; import ghidra.trace.model.thread.TraceThread; import ghidra.trace.util.TraceAddressSpace; -import ghidra.trace.util.TraceRegisterUtils; // TODO: Use this, or allow arbitrary expressions public interface RegisterLocationTrackingSpec extends LocationTrackingSpec { @@ -45,10 +45,11 @@ public interface RegisterLocationTrackingSpec extends LocationTrackingSpec { } @Override - default Address computeTraceAddress(PluginTool tool, DebuggerCoordinates coordinates, - long emuSnap) { + default Address computeTraceAddress(PluginTool tool, DebuggerCoordinates coordinates) { Trace trace = coordinates.getTrace(); + TracePlatform platform = coordinates.getPlatform(); TraceThread thread = coordinates.getThread(); + long viewSnap = coordinates.getViewSnap(); long snap = coordinates.getSnap(); int frame = coordinates.getFrame(); Register reg = computeRegister(coordinates); @@ -64,19 +65,19 @@ public interface RegisterLocationTrackingSpec extends LocationTrackingSpec { return null; } RegisterValue value; - if (regs.getState(emuSnap, reg) == TraceMemoryState.KNOWN) { - value = regs.getValue(emuSnap, reg); + if (regs.getState(platform, viewSnap, reg) == TraceMemoryState.KNOWN) { + value = regs.getValue(platform, viewSnap, reg); } else { - value = regs.getValue(snap, reg); + value = regs.getValue(platform, snap, reg); } if (value == null) { return null; } // TODO: Action to select the address space // Could use code unit, but that can't specify space, yet, either.... - return computeDefaultAddressSpace(coordinates) - .getAddress(value.getUnsignedValue().longValue(), true); + return platform.mapGuestToHost(computeDefaultAddressSpace(coordinates) + .getAddress(value.getUnsignedValue().longValue(), true)); } @Override @@ -89,7 +90,9 @@ public interface RegisterLocationTrackingSpec extends LocationTrackingSpec { if (register == null) { return false; } - AddressRange regRng = TraceRegisterUtils.rangeForRegister(register); + AddressSpace as = space.getAddressSpace(); + AddressRange regRng = coordinates.getPlatform() + .getConventionalRegisterRange(as.isRegisterSpace() ? as : null, register); return range.getRange().intersects(regRng); } 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 922db2fbf3..b38dd679cd 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 @@ -21,7 +21,7 @@ import ghidra.app.plugin.core.debug.DebuggerCoordinates; import ghidra.app.plugin.core.debug.gui.DebuggerResources.TrackLocationAction; import ghidra.program.model.address.AddressSpace; import ghidra.program.model.lang.Register; -import ghidra.trace.model.Trace; +import ghidra.trace.model.guest.TracePlatform; public class SPLocationTrackingSpec implements RegisterLocationTrackingSpec { public static final String CONFIG_NAME = "TRACK_SP"; @@ -43,11 +43,11 @@ public class SPLocationTrackingSpec implements RegisterLocationTrackingSpec { @Override public Register computeRegister(DebuggerCoordinates coordinates) { - Trace trace = coordinates.getTrace(); - if (trace == null) { + TracePlatform platform = coordinates.getPlatform(); + if (platform == null) { return null; } - return trace.getBaseCompilerSpec().getStackPointer(); + return platform.getCompilerSpec().getStackPointer(); } @Override 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 319a161c3e..2d3a956328 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 @@ -201,6 +201,7 @@ public class DebuggerListingProvider extends CodeViewerProvider { @Override protected void specChanged(LocationTrackingSpec spec) { + updateTitle(); trackingSpecChangeListeners.fire.locationTrackingSpecChanged(spec); } @@ -1057,6 +1058,7 @@ public class DebuggerListingProvider extends CodeViewerProvider { trackingTrait.goToCoordinates(coordinates); readsMemTrait.goToCoordinates(coordinates); locationLabel.goToCoordinates(coordinates); + updateTitle(); contextChanged(); } 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 67d6db2267..0abc918c85 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 @@ -101,6 +101,11 @@ public class DebuggerMemoryBytesProvider extends ProgramByteViewerComponentProvi protected void locationTracked() { doGoToTracked(); } + + @Override + protected void specChanged(LocationTrackingSpec spec) { + updateTitle(); + } } protected class ForMemoryBytesReadsMemoryTrait extends DebuggerReadsMemoryTrait { @@ -324,6 +329,7 @@ public class DebuggerMemoryBytesProvider extends ProgramByteViewerComponentProvi trackingTrait.goToCoordinates(coordinates); readsMemTrait.goToCoordinates(coordinates); locationLabel.goToCoordinates(coordinates); + updateTitle(); contextChanged(); }