Merge remote-tracking branch 'origin/GP-5896_ghidra_red_StackView--SQUASHED'

This commit is contained in:
Ryan Kurtz
2026-06-10 10:47:32 -04:00
3 changed files with 71 additions and 9 deletions

View File

@@ -4,9 +4,9 @@
* 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.
@@ -15,16 +15,16 @@
*/
package ghidra.app.plugin.core.debug.gui.memory;
import ghidra.app.plugin.core.byteviewer.ByteViewerActionContext;
import ghidra.app.plugin.core.byteviewer.ProgramByteViewerComponentProvider;
import ghidra.app.plugin.core.byteviewer.*;
import ghidra.app.plugin.core.debug.gui.action.DebuggerProgramLocationActionContext;
import ghidra.trace.model.program.TraceProgramView;
public class DebuggerMemoryBytesActionContext extends ByteViewerActionContext
implements DebuggerProgramLocationActionContext {
public DebuggerMemoryBytesActionContext(ProgramByteViewerComponentProvider provider) {
super(provider);
public DebuggerMemoryBytesActionContext(ProgramByteViewerComponentProvider provider,
ByteViewerComponent currentComponent) {
super(provider, currentComponent);
}
@Override

View File

@@ -16,15 +16,17 @@
package ghidra.app.plugin.core.debug.gui.memory;
import java.util.List;
import java.util.Set;
import java.util.function.Consumer;
import java.util.stream.Collectors;
import org.jdom2.Element;
import docking.ActionContext;
import docking.action.DockingAction;
import ghidra.app.plugin.PluginCategoryNames;
import ghidra.app.plugin.core.byteviewer.AbstractByteViewerPlugin;
import ghidra.app.plugin.core.byteviewer.ByteViewerComponentProvider;
import ghidra.app.plugin.core.byteviewer.*;
import ghidra.app.plugin.core.debug.gui.action.SPLocationTrackingSpec;
import ghidra.app.plugin.core.debug.DebuggerPluginPackage;
import ghidra.app.plugin.core.debug.event.*;
import ghidra.app.plugin.core.debug.gui.DebuggerResources.NewMemoryAction;
@@ -73,6 +75,7 @@ public class DebuggerMemoryBytesPlugin
private static final String PREFIX_DISCONNECTED_PROVIDER = "disconnectedProvider";
protected DockingAction actionNewMemory;
private DockingAction actionNewStackView;
@AutoServiceConsumed
private ProgramManager programManager;
@@ -99,6 +102,12 @@ public class DebuggerMemoryBytesPlugin
.enabled(true)
.onAction(c -> connectedProvider.cloneWindow())
.buildAndInstall(tool);
actionNewStackView = NewMemoryAction.builder(this)
.enabled(true)
.menuPath("Window", DebuggerPluginPackage.NAME, "New Stack View")
.onAction(this::newStackViewActivated)
.buildAndInstall(tool);
}
public DebuggerMemoryBytesProvider createViewerIfMissing(LocationTrackingSpec spec,
@@ -277,4 +286,26 @@ public class DebuggerMemoryBytesPlugin
int disconnectedCount = saveState.getInt(KEY_DISCONNECTED_COUNT, 0);
ensureProviders(disconnectedCount, true, saveState);
}
private void newStackViewActivated(ActionContext c) {
DebuggerMemoryBytesProvider provider = createNewDisconnectedProvider();
provider.setTrackingSpec(SPLocationTrackingSpec.INSTANCE);
provider.setFollowsCurrentThread(true);
ByteViewerConfigOptions options = new ByteViewerConfigOptions();
options.setHexGroupSize(1);
String hexColumn = "Hex";
int bytesPerLine = 8;
if (current != DebuggerCoordinates.NOWHERE) {
int pointerSize = current.getTrace().getProgramView().getMinAddress().getPointerSize();
hexColumn = switch (pointerSize) {
case 2 -> "Hex Short";
case 4 -> "Hex Integer";
case 8 -> "Hex Long";
default -> "Hex";
};
bytesPerLine = pointerSize;
}
options.setBytesPerLine(bytesPerLine);
provider.updateConfigOptions(options, Set.of(hexColumn, "Chars"));
}
}

View File

@@ -28,6 +28,7 @@ import java.util.concurrent.*;
import javax.swing.*;
import docking.action.builder.ActionBuilder;
import org.apache.commons.lang3.StringUtils;
import docking.ActionContext;
@@ -237,6 +238,7 @@ public class DebuggerMemoryBytesProvider extends ProgramByteViewerComponentProvi
protected MultiStateDockingAction<AutoReadMemorySpec> actionAutoReadMemory;
protected DockingAction actionRefreshSelectedMemory;
protected MultiStateDockingAction<LocationTrackingSpec> actionTrackLocation;
protected DockingAction actionConvertToStackView;
protected ForMemoryBytesGoToTrait goToTrait;
protected ForMemoryBytesTrackingTrait trackingTrait;
@@ -500,7 +502,7 @@ public class DebuggerMemoryBytesProvider extends ProgramByteViewerComponentProvi
@Override
protected ByteViewerActionContext newByteViewerActionContext() {
return new DebuggerMemoryBytesActionContext(this);
return new DebuggerMemoryBytesActionContext(this, panel.getCurrentComponent());
}
@Override
@@ -529,6 +531,15 @@ public class DebuggerMemoryBytesProvider extends ProgramByteViewerComponentProvi
.onAction(
ctx -> doSetFollowsCurrentThread(actionFollowsCurrentThread.isSelected()))
.buildAndInstallLocal(this);
actionConvertToStackView =
new ActionBuilder("Convert To Stack View", plugin.getName()).description(
"Convert current byte viewer into a stack view")
.enabled(true)
.menuPath("Convert To Stack View")
.menuGroup("aa")
.onAction(this::convertToStackViewActivated)
.buildAndInstallLocal(this);
}
actionGoTo = goToTrait.installAction();
@@ -812,4 +823,24 @@ public class DebuggerMemoryBytesProvider extends ProgramByteViewerComponentProvi
CompletableFuture<?> getLastAutoRead() {
return readsMemTrait.getLastRead();
}
private void convertToStackViewActivated(ActionContext c) {
setTrackingSpec(SPLocationTrackingSpec.INSTANCE);
ByteViewerConfigOptions options = new ByteViewerConfigOptions();
options.setHexGroupSize(1);
String hexColumn = "Hex";
int bytesPerLine = 8;
if (current != DebuggerCoordinates.NOWHERE) {
int pointerSize = current.getTrace().getProgramView().getMinAddress().getPointerSize();
hexColumn = switch (pointerSize) {
case 2 -> "Hex Short";
case 4 -> "Hex Integer";
case 8 -> "Hex Long";
default -> "Hex";
};
bytesPerLine = pointerSize;
}
options.setBytesPerLine(bytesPerLine);
updateConfigOptions(options, Set.of(hexColumn, "Chars"));
}
}