Merge remote-tracking branch 'origin/GP-2978_Dan_renameStateEditingService--SQUASHED'

This commit is contained in:
Ryan Kurtz 2023-01-31 08:00:12 -05:00
commit a7eea63ff1
43 changed files with 589 additions and 555 deletions

View file

@ -169,11 +169,11 @@ icon.debugger.diff = table_relationship.png
icon.debugger.diff.previous = up.png icon.debugger.diff.previous = up.png
icon.debugger.diff.next = down.png icon.debugger.diff.next = down.png
icon.debugger.edit.mode.ro.target = record.png icon.debugger.control.mode.ro.target = record.png
icon.debugger.edit.mode.rw.target = write-target.png icon.debugger.control.mode.rw.target = write-target.png
icon.debugger.edit.mode.ro.trace = video-x-generic16.png icon.debugger.control.mode.ro.trace = video-x-generic16.png
icon.debugger.edit.mode.rw.trace = write-trace.png icon.debugger.control.mode.rw.trace = write-trace.png
icon.debugger.edit.mode.rw.emulator = write-emulator.png icon.debugger.control.mode.rw.emulator = write-emulator.png
icon.debugger.marker.register = register-marker.png icon.debugger.marker.register = register-marker.png
icon.debugger.marker.event = icon.debugger.marker.register icon.debugger.marker.event = icon.debugger.marker.register

View file

@ -716,7 +716,7 @@ public class DebuggerBreakpointMarkerPlugin extends Plugin
@AutoServiceConsumed @AutoServiceConsumed
private DebuggerConsoleService consoleService; private DebuggerConsoleService consoleService;
@AutoServiceConsumed @AutoServiceConsumed
private DebuggerStateEditingService editingService; private DebuggerControlService controlService;
// @AutoServiceConsumed via method // @AutoServiceConsumed via method
DecompilerMarginService decompilerMarginService; DecompilerMarginService decompilerMarginService;
@SuppressWarnings("unused") @SuppressWarnings("unused")
@ -859,8 +859,8 @@ public class DebuggerBreakpointMarkerPlugin extends Plugin
} }
protected Set<TraceBreakpointKind> getSupportedKindsFromTrace(Trace trace) { protected Set<TraceBreakpointKind> getSupportedKindsFromTrace(Trace trace) {
StateEditingMode mode = editingService == null ? StateEditingMode.DEFAULT ControlMode mode = controlService == null ? ControlMode.DEFAULT
: editingService.getCurrentMode(trace); : controlService.getCurrentMode(trace);
if (mode.useEmulatedBreakpoints()) { if (mode.useEmulatedBreakpoints()) {
return EnumSet.allOf(TraceBreakpointKind.class); return EnumSet.allOf(TraceBreakpointKind.class);
} }

View file

@ -37,7 +37,7 @@ import ghidra.app.plugin.core.debug.DebuggerPluginPackage;
import ghidra.app.plugin.core.debug.gui.DebuggerResources; import ghidra.app.plugin.core.debug.gui.DebuggerResources;
import ghidra.app.plugin.core.debug.gui.DebuggerResources.*; import ghidra.app.plugin.core.debug.gui.DebuggerResources.*;
import ghidra.app.services.*; import ghidra.app.services.*;
import ghidra.app.services.DebuggerStateEditingService.StateEditingModeChangeListener; import ghidra.app.services.DebuggerControlService.ControlModeChangeListener;
import ghidra.app.services.LogicalBreakpoint.State; import ghidra.app.services.LogicalBreakpoint.State;
import ghidra.framework.model.DomainObject; import ghidra.framework.model.DomainObject;
import ghidra.framework.plugintool.*; import ghidra.framework.plugintool.*;
@ -57,7 +57,7 @@ import ghidra.util.table.GhidraTable;
import ghidra.util.table.GhidraTableFilterPanel; import ghidra.util.table.GhidraTableFilterPanel;
public class DebuggerBreakpointsProvider extends ComponentProviderAdapter public class DebuggerBreakpointsProvider extends ComponentProviderAdapter
implements LogicalBreakpointsChangeListener, StateEditingModeChangeListener { implements LogicalBreakpointsChangeListener, ControlModeChangeListener {
protected enum LogicalBreakpointTableColumns protected enum LogicalBreakpointTableColumns
implements EnumeratedTableColumn<LogicalBreakpointTableColumns, LogicalBreakpointRow> { implements EnumeratedTableColumn<LogicalBreakpointTableColumns, LogicalBreakpointRow> {
@ -672,7 +672,7 @@ public class DebuggerBreakpointsProvider extends ComponentProviderAdapter
@AutoServiceConsumed @AutoServiceConsumed
private DebuggerConsoleService consoleService; private DebuggerConsoleService consoleService;
// @AutoServiceConsumed via method // @AutoServiceConsumed via method
private DebuggerStateEditingService editingService; private DebuggerControlService controlService;
@AutoServiceConsumed @AutoServiceConsumed
private GoToService goToService; private GoToService goToService;
@SuppressWarnings("unused") @SuppressWarnings("unused")
@ -784,18 +784,18 @@ public class DebuggerBreakpointsProvider extends ComponentProviderAdapter
} }
@AutoServiceConsumed @AutoServiceConsumed
private void setEditingService(DebuggerStateEditingService editingService) { private void setControlService(DebuggerControlService editingService) {
if (this.editingService != null) { if (this.controlService != null) {
this.editingService.removeModeChangeListener(this); this.controlService.removeModeChangeListener(this);
} }
this.editingService = editingService; this.controlService = editingService;
if (this.editingService != null) { if (this.controlService != null) {
this.editingService.addModeChangeListener(this); this.controlService.addModeChangeListener(this);
} }
} }
@Override @Override
public void modeChanged(Trace trace, StateEditingMode mode) { public void modeChanged(Trace trace, ControlMode mode) {
Swing.runIfSwingOrRunLater(() -> { Swing.runIfSwingOrRunLater(() -> {
reloadBreakpointLocations(trace); reloadBreakpointLocations(trace);
contextChanged(); contextChanged();
@ -860,9 +860,9 @@ public class DebuggerBreakpointsProvider extends ComponentProviderAdapter
} }
private void loadBreakpointLocations(Trace trace) { private void loadBreakpointLocations(Trace trace) {
StateEditingMode mode = editingService == null ControlMode mode = controlService == null
? StateEditingMode.DEFAULT ? ControlMode.DEFAULT
: editingService.getCurrentMode(trace); : controlService.getCurrentMode(trace);
DebuggerCoordinates currentFor = traceManager.getCurrentFor(trace); DebuggerCoordinates currentFor = traceManager.getCurrentFor(trace);
TraceRecorder recorder = currentFor.getRecorder(); TraceRecorder recorder = currentFor.getRecorder();
if (!mode.useEmulatedBreakpoints() && recorder == null) { if (!mode.useEmulatedBreakpoints() && recorder == null) {
@ -1197,7 +1197,7 @@ public class DebuggerBreakpointsProvider extends ComponentProviderAdapter
} }
private boolean isAllInvolvedTracesUsingEmulatedBreakpoints(ActionContext ctx) { private boolean isAllInvolvedTracesUsingEmulatedBreakpoints(ActionContext ctx) {
if (editingService == null) { if (controlService == null) {
return false; return false;
} }
Set<Trace> traces = new HashSet<>(); Set<Trace> traces = new HashSet<>();
@ -1223,7 +1223,7 @@ public class DebuggerBreakpointsProvider extends ComponentProviderAdapter
return false; return false;
} }
for (Trace trace : traces) { for (Trace trace : traces) {
if (!editingService.getCurrentMode(trace).useEmulatedBreakpoints()) { if (!controlService.getCurrentMode(trace).useEmulatedBreakpoints()) {
return false; return false;
} }
} }

View file

@ -21,16 +21,15 @@ import java.util.concurrent.CompletableFuture;
import java.util.function.BiPredicate; import java.util.function.BiPredicate;
import java.util.function.Function; import java.util.function.Function;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.stream.Stream;
import javax.swing.Icon; import javax.swing.Icon;
import javax.swing.KeyStroke; import javax.swing.KeyStroke;
import docking.ActionContext; import docking.ActionContext;
import docking.DockingContextListener; import docking.DockingContextListener;
import docking.action.DockingAction; import docking.action.*;
import docking.action.DockingActionIf; import docking.action.builder.AbstractActionBuilder;
import docking.action.builder.*; import docking.action.builder.ActionBuilder;
import docking.menu.ActionState; import docking.menu.ActionState;
import docking.menu.MultiStateDockingAction; import docking.menu.MultiStateDockingAction;
import docking.widgets.EventTrigger; import docking.widgets.EventTrigger;
@ -40,9 +39,9 @@ import ghidra.app.plugin.core.debug.event.*;
import ghidra.app.plugin.core.debug.gui.DebuggerResources; import ghidra.app.plugin.core.debug.gui.DebuggerResources;
import ghidra.app.plugin.core.debug.service.emulation.DebuggerPcodeMachine; import ghidra.app.plugin.core.debug.service.emulation.DebuggerPcodeMachine;
import ghidra.app.services.*; import ghidra.app.services.*;
import ghidra.app.services.DebuggerControlService.ControlModeChangeListener;
import ghidra.app.services.DebuggerEmulationService.CachedEmulator; import ghidra.app.services.DebuggerEmulationService.CachedEmulator;
import ghidra.app.services.DebuggerEmulationService.EmulatorStateListener; import ghidra.app.services.DebuggerEmulationService.EmulatorStateListener;
import ghidra.app.services.DebuggerStateEditingService.StateEditingModeChangeListener;
import ghidra.app.services.DebuggerTraceManagerService.ActivationCause; import ghidra.app.services.DebuggerTraceManagerService.ActivationCause;
import ghidra.async.AsyncUtils; import ghidra.async.AsyncUtils;
import ghidra.dbg.DebuggerObjectModel; import ghidra.dbg.DebuggerObjectModel;
@ -71,7 +70,7 @@ import ghidra.util.*;
ModelObjectFocusedPluginEvent.class, ModelObjectFocusedPluginEvent.class,
}, },
servicesRequired = { servicesRequired = {
DebuggerStateEditingService.class, DebuggerControlService.class,
DebuggerTraceManagerService.class, DebuggerTraceManagerService.class,
}) })
public class DebuggerControlPlugin extends AbstractDebuggerPlugin public class DebuggerControlPlugin extends AbstractDebuggerPlugin
@ -210,22 +209,37 @@ public class DebuggerControlPlugin extends AbstractDebuggerPlugin
String GROUP = DebuggerResources.GROUP_CONTROL; String GROUP = DebuggerResources.GROUP_CONTROL;
} }
interface ControlModeAction { protected class ControlModeAction extends MultiStateDockingAction<ControlMode> {
String NAME = "Control Mode"; public static final String NAME = "Control Mode";
String DESCRIPTION = "Choose what to control and edit in dynamic views"; public static final String DESCRIPTION = "Choose what to control and edit in dynamic views";
String GROUP = DebuggerResources.GROUP_CONTROL; public static final String GROUP = DebuggerResources.GROUP_CONTROL;
String HELP_ANCHOR = "control_mode"; public static final String HELP_ANCHOR = "control_mode";
static MultiStateActionBuilder<StateEditingMode> builder(Plugin owner) { public ControlModeAction() {
String ownerName = owner.getName(); super(NAME, DebuggerControlPlugin.this.getName());
return new MultiStateActionBuilder<StateEditingMode>(NAME, ownerName) setDescription(DESCRIPTION);
.description(DESCRIPTION) setToolBarData(new ToolBarData(DebuggerResources.ICON_BLANK, GROUP, ""));
.toolBarIcon(DebuggerResources.ICON_BLANK) // Docs say required setHelpLocation(new HelpLocation(getOwner(), HELP_ANCHOR));
.toolBarGroup(GROUP, "") setActionStates(ControlMode.ALL.stream()
.helpLocation(new HelpLocation(ownerName, HELP_ANCHOR)) .map(m -> new ActionState<>(m.name, m.icon, m))
.addStates(Stream.of(StateEditingMode.values()) .collect(Collectors.toList()));
.map(m -> new ActionState<>(m.name, m.icon, m)) setEnabled(false);
.collect(Collectors.toList())); }
@Override
public boolean isEnabledForContext(ActionContext context) {
return current.getTrace() != null;
}
@Override
protected boolean isStateEnabled(ActionState<ControlMode> state) {
return state.getUserData().isSelectable(current);
}
@Override
public void actionStateChanged(ActionState<ControlMode> newActionState,
EventTrigger trigger) {
activateControlMode(newActionState, trigger);
} }
} }
@ -546,7 +560,7 @@ public class DebuggerControlPlugin extends AbstractDebuggerPlugin
} }
}; };
private final StateEditingModeChangeListener listenerForModeChanges = this::modeChanged; private final ControlModeChangeListener listenerForModeChanges = this::modeChanged;
private final EmulatorStateListener listenerForEmuStateChanges = new EmulatorStateListener() { private final EmulatorStateListener listenerForEmuStateChanges = new EmulatorStateListener() {
@Override @Override
public void running(CachedEmulator emu) { public void running(CachedEmulator emu) {
@ -561,7 +575,7 @@ public class DebuggerControlPlugin extends AbstractDebuggerPlugin
protected DebuggerCoordinates current = DebuggerCoordinates.NOWHERE; protected DebuggerCoordinates current = DebuggerCoordinates.NOWHERE;
protected MultiStateDockingAction<StateEditingMode> actionEditMode; protected MultiStateDockingAction<ControlMode> actionControlMode;
DockingAction actionTargetResume; DockingAction actionTargetResume;
DockingAction actionTargetInterrupt; DockingAction actionTargetInterrupt;
@ -592,7 +606,7 @@ public class DebuggerControlPlugin extends AbstractDebuggerPlugin
@AutoServiceConsumed @AutoServiceConsumed
private DebuggerTraceManagerService traceManager; private DebuggerTraceManagerService traceManager;
// @AutoServiceConsumed // via method // @AutoServiceConsumed // via method
private DebuggerStateEditingService editingService; private DebuggerControlService controlService;
// @AutoServiceConsumed // via method // @AutoServiceConsumed // via method
private DebuggerEmulationService emulationService; private DebuggerEmulationService emulationService;
@ -604,7 +618,7 @@ public class DebuggerControlPlugin extends AbstractDebuggerPlugin
createActions(); createActions();
} }
protected Set<DockingAction> getActionSet(StateEditingMode mode) { protected Set<DockingAction> getActionSet(ControlMode mode) {
switch (mode) { switch (mode) {
case RO_TARGET: case RO_TARGET:
case RW_TARGET: case RW_TARGET:
@ -623,7 +637,7 @@ public class DebuggerControlPlugin extends AbstractDebuggerPlugin
return getActionSet(computeCurrentEditingMode()); return getActionSet(computeCurrentEditingMode());
} }
protected void updateActionsEnabled(StateEditingMode mode) { protected void updateActionsEnabled(ControlMode mode) {
for (DockingAction action : getActionSet(mode)) { for (DockingAction action : getActionSet(mode)) {
action.setEnabled(action.isEnabledForContext(context)); action.setEnabled(action.isEnabledForContext(context));
} }
@ -640,11 +654,8 @@ public class DebuggerControlPlugin extends AbstractDebuggerPlugin
} }
protected void createActions() { protected void createActions() {
actionEditMode = ControlModeAction.builder(this) actionControlMode = new ControlModeAction();
.enabled(false) tool.addAction(actionControlMode);
.enabledWhen(c -> current.getTrace() != null)
.onActionStateChanged(this::activateEditMode)
.buildAndInstall(tool);
actionTargetResume = TargetResumeAction.builder(this) actionTargetResume = TargetResumeAction.builder(this)
.enabledWhenTarget(this::isActionTargetResumeEnabled) .enabledWhenTarget(this::isActionTargetResumeEnabled)
@ -720,19 +731,19 @@ public class DebuggerControlPlugin extends AbstractDebuggerPlugin
updateActions(); updateActions();
} }
protected void activateEditMode(ActionState<StateEditingMode> state, EventTrigger trigger) { protected void activateControlMode(ActionState<ControlMode> state, EventTrigger trigger) {
if (current.getTrace() == null) { if (current.getTrace() == null) {
return; return;
} }
if (editingService == null) { if (controlService == null) {
return; return;
} }
editingService.setCurrentMode(current.getTrace(), state.getUserData()); controlService.setCurrentMode(current.getTrace(), state.getUserData());
// TODO: Limit selectable modes? // TODO: Limit selectable modes?
// No sense showing Write Target, if the trace can never be live, again.... // No sense showing Write Target, if the trace can never be live, again....
} }
private void modeChanged(Trace trace, StateEditingMode mode) { private void modeChanged(Trace trace, ControlMode mode) {
Swing.runIfSwingOrRunLater(() -> { Swing.runIfSwingOrRunLater(() -> {
if (current.getTrace() == trace) { if (current.getTrace() == trace) {
updateActions(); updateActions();
@ -971,16 +982,14 @@ public class DebuggerControlPlugin extends AbstractDebuggerPlugin
updateActions(); updateActions();
} }
private StateEditingMode computeCurrentEditingMode() { private ControlMode computeCurrentEditingMode() {
// TODO: We're sort of piggy-backing our mode onto that of the editing service. if (controlService == null) {
// Seems we should have our own? return ControlMode.DEFAULT;
if (editingService == null) {
return StateEditingMode.DEFAULT;
} }
if (current.getTrace() == null) { if (current.getTrace() == null) {
return StateEditingMode.DEFAULT; return ControlMode.DEFAULT;
} }
return editingService.getCurrentMode(current.getTrace()); return controlService.getCurrentMode(current.getTrace());
} }
private void hideActions(Collection<? extends DockingActionIf> actions) { private void hideActions(Collection<? extends DockingActionIf> actions) {
@ -1009,8 +1018,8 @@ public class DebuggerControlPlugin extends AbstractDebuggerPlugin
} }
private void updateActions() { private void updateActions() {
StateEditingMode mode = computeCurrentEditingMode(); ControlMode mode = computeCurrentEditingMode();
actionEditMode.setCurrentActionStateByUserData(mode); actionControlMode.setCurrentActionStateByUserData(mode);
Set<DockingAction> actions = getActionSet(mode); Set<DockingAction> actions = getActionSet(mode);
for (Set<DockingAction> set : actionSets) { for (Set<DockingAction> set : actionSets) {
@ -1033,19 +1042,19 @@ public class DebuggerControlPlugin extends AbstractDebuggerPlugin
} }
@AutoServiceConsumed @AutoServiceConsumed
protected void setEditingService(DebuggerStateEditingService editingService) { private void setControlService(DebuggerControlService editingService) {
if (this.editingService != null) { if (this.controlService != null) {
this.editingService.removeModeChangeListener(listenerForModeChanges); this.controlService.removeModeChangeListener(listenerForModeChanges);
} }
this.editingService = editingService; this.controlService = editingService;
if (this.editingService != null) { if (this.controlService != null) {
this.editingService.addModeChangeListener(listenerForModeChanges); this.controlService.addModeChangeListener(listenerForModeChanges);
} }
updateActions(); updateActions();
} }
@AutoServiceConsumed @AutoServiceConsumed
protected void setEmulationService(DebuggerEmulationService emulationService) { private void setEmulationService(DebuggerEmulationService emulationService) {
if (this.emulationService != null) { if (this.emulationService != null) {
this.emulationService.removeStateListener(listenerForEmuStateChanges); this.emulationService.removeStateListener(listenerForEmuStateChanges);
} }

View file

@ -228,7 +228,7 @@ public class DebuggerListingProvider extends CodeViewerProvider {
@AutoServiceConsumed @AutoServiceConsumed
private DebuggerConsoleService consoleService; private DebuggerConsoleService consoleService;
@AutoServiceConsumed @AutoServiceConsumed
private DebuggerStateEditingService editingService; private DebuggerControlService controlService;
@AutoServiceConsumed @AutoServiceConsumed
private ProgramManager programManager; private ProgramManager programManager;
@AutoServiceConsumed @AutoServiceConsumed
@ -362,14 +362,14 @@ public class DebuggerListingProvider extends CodeViewerProvider {
@Override @Override
public boolean isReadOnly() { public boolean isReadOnly() {
if (editingService == null) { if (controlService == null) {
return true; return true;
} }
Trace trace = current.getTrace(); Trace trace = current.getTrace();
if (trace == null) { if (trace == null) {
return true; return true;
} }
StateEditingMode mode = editingService.getCurrentMode(trace); ControlMode mode = controlService.getCurrentMode(trace);
return !mode.canEdit(current); return !mode.canEdit(current);
} }

View file

@ -46,7 +46,7 @@ import ghidra.app.plugin.core.debug.gui.DebuggerProvider;
import ghidra.app.plugin.core.debug.gui.DebuggerResources; import ghidra.app.plugin.core.debug.gui.DebuggerResources;
import ghidra.app.plugin.core.debug.mapping.DebuggerRegisterMapper; import ghidra.app.plugin.core.debug.mapping.DebuggerRegisterMapper;
import ghidra.app.services.*; import ghidra.app.services.*;
import ghidra.app.services.DebuggerStateEditingService.StateEditor; import ghidra.app.services.DebuggerControlService.StateEditor;
import ghidra.async.AsyncLazyValue; import ghidra.async.AsyncLazyValue;
import ghidra.async.AsyncUtils; import ghidra.async.AsyncUtils;
import ghidra.base.widgets.table.DataTypeTableCellEditor; import ghidra.base.widgets.table.DataTypeTableCellEditor;
@ -476,7 +476,7 @@ public class DebuggerRegistersProvider extends ComponentProviderAdapter
@AutoServiceConsumed @AutoServiceConsumed
private DebuggerListingService listingService; private DebuggerListingService listingService;
@AutoServiceConsumed @AutoServiceConsumed
private DebuggerStateEditingService editingService; private DebuggerControlService controlService;
@AutoServiceConsumed @AutoServiceConsumed
private MarkerService markerService; // TODO: Mark address types (separate plugin?) private MarkerService markerService; // TODO: Mark address types (separate plugin?)
@SuppressWarnings("unused") @SuppressWarnings("unused")
@ -845,10 +845,10 @@ public class DebuggerRegistersProvider extends ComponentProviderAdapter
if (!isEditsEnabled()) { if (!isEditsEnabled()) {
return false; return false;
} }
if (editingService == null) { if (controlService == null) {
return false; return false;
} }
StateEditor editor = editingService.createStateEditor(current); StateEditor editor = controlService.createStateEditor(current);
return editor.isRegisterEditable(register); return editor.isRegisterEditable(register);
} }
@ -866,11 +866,11 @@ public class DebuggerRegistersProvider extends ComponentProviderAdapter
} }
void writeRegisterValue(RegisterValue rv) { void writeRegisterValue(RegisterValue rv) {
if (editingService == null) { if (controlService == null) {
Msg.showError(this, getComponent(), "Edit Register", "No editing service."); Msg.showError(this, getComponent(), "Edit Register", "No control service.");
return; return;
} }
StateEditor editor = editingService.createStateEditor(current); StateEditor editor = controlService.createStateEditor(current);
if (!editor.isRegisterEditable(rv.getRegister())) { if (!editor.isRegisterEditable(rv.getRegister())) {
Msg.showError(this, getComponent(), "Edit Register", Msg.showError(this, getComponent(), "Edit Register",
"Neither the register nor any parent can be edited."); "Neither the register nor any parent can be edited.");

View file

@ -19,7 +19,7 @@ import java.math.BigInteger;
import java.util.Objects; import java.util.Objects;
import ghidra.app.plugin.core.debug.DebuggerCoordinates; import ghidra.app.plugin.core.debug.DebuggerCoordinates;
import ghidra.app.services.DebuggerStateEditingService; import ghidra.app.services.DebuggerControlService;
import ghidra.program.model.data.DataType; import ghidra.program.model.data.DataType;
import ghidra.program.model.lang.Language; import ghidra.program.model.lang.Language;
import ghidra.program.model.lang.Register; import ghidra.program.model.lang.Register;
@ -105,8 +105,8 @@ public class RegisterRow {
* Attempt to set the register's value * Attempt to set the register's value
* *
* <p> * <p>
* The edit will be directed according to the tool's current edit mode. See * The edit will be directed according to the tool's current control mode. See
* {@link DebuggerStateEditingService#getCurrentMode(Trace)} * {@link DebuggerControlService#getCurrentMode(Trace)}
* *
* @param value the value * @param value the value
*/ */

View file

@ -339,7 +339,7 @@ public class DebuggerWatchesProvider extends ComponentProviderAdapter
@AutoServiceConsumed @AutoServiceConsumed
private DebuggerTraceManagerService traceManager; // For goto time (emu mods) private DebuggerTraceManagerService traceManager; // For goto time (emu mods)
@AutoServiceConsumed @AutoServiceConsumed
protected DebuggerStateEditingService editingService; protected DebuggerControlService controlService;
@AutoServiceConsumed @AutoServiceConsumed
DebuggerStaticMappingService mappingService; DebuggerStaticMappingService mappingService;
@SuppressWarnings("unused") @SuppressWarnings("unused")

View file

@ -22,8 +22,8 @@ import java.util.concurrent.CompletableFuture;
import ghidra.app.plugin.core.debug.DebuggerCoordinates; import ghidra.app.plugin.core.debug.DebuggerCoordinates;
import ghidra.app.plugin.processors.sleigh.SleighLanguage; import ghidra.app.plugin.processors.sleigh.SleighLanguage;
import ghidra.app.services.DataTypeManagerService; import ghidra.app.services.DataTypeManagerService;
import ghidra.app.services.DebuggerStateEditingService; import ghidra.app.services.DebuggerControlService;
import ghidra.app.services.DebuggerStateEditingService.StateEditor; import ghidra.app.services.DebuggerControlService.StateEditor;
import ghidra.async.AsyncUtils; import ghidra.async.AsyncUtils;
import ghidra.docking.settings.Settings; import ghidra.docking.settings.Settings;
import ghidra.docking.settings.SettingsImpl; import ghidra.docking.settings.SettingsImpl;
@ -346,11 +346,11 @@ public class WatchRow {
if (address == null) { if (address == null) {
return false; return false;
} }
DebuggerStateEditingService editingService = provider.editingService; DebuggerControlService controlService = provider.controlService;
if (editingService == null) { if (controlService == null) {
return false; return false;
} }
StateEditor editor = editingService.createStateEditor(provider.current); StateEditor editor = controlService.createStateEditor(provider.current);
return editor.isVariableEditable(address, getValueLength()); return editor.isVariableEditable(address, getValueLength());
} }
@ -397,11 +397,11 @@ public class WatchRow {
System.arraycopy(bytes, 0, fillOld, 0, bytes.length); System.arraycopy(bytes, 0, fillOld, 0, bytes.length);
bytes = fillOld; bytes = fillOld;
} }
DebuggerStateEditingService editingService = provider.editingService; DebuggerControlService controlService = provider.controlService;
if (editingService == null) { if (controlService == null) {
throw new AssertionError("No editing service"); throw new AssertionError("No control service");
} }
StateEditor editor = editingService.createStateEditor(provider.current); StateEditor editor = controlService.createStateEditor(provider.current);
editor.setVariable(address, bytes).exceptionally(ex -> { editor.setVariable(address, bytes).exceptionally(ex -> {
Msg.showError(this, null, "Write Failed", Msg.showError(this, null, "Write Failed",
"Could not modify watch value (on target)", ex); "Could not modify watch value (on target)", ex);

View file

@ -31,7 +31,7 @@ import ghidra.app.plugin.core.debug.DebuggerCoordinates;
import ghidra.app.plugin.core.debug.DebuggerPluginPackage; import ghidra.app.plugin.core.debug.DebuggerPluginPackage;
import ghidra.app.plugin.core.debug.event.*; import ghidra.app.plugin.core.debug.event.*;
import ghidra.app.services.*; import ghidra.app.services.*;
import ghidra.app.services.DebuggerStateEditingService.StateEditingModeChangeListener; import ghidra.app.services.DebuggerControlService.ControlModeChangeListener;
import ghidra.app.services.LogicalBreakpoint.State; import ghidra.app.services.LogicalBreakpoint.State;
import ghidra.async.SwingExecutorService; import ghidra.async.SwingExecutorService;
import ghidra.dbg.target.TargetBreakpointLocation; import ghidra.dbg.target.TargetBreakpointLocation;
@ -187,9 +187,9 @@ public class DebuggerLogicalBreakpointServicePlugin extends Plugin
} }
} }
protected class TrackModesListener implements StateEditingModeChangeListener { protected class TrackModesListener implements ControlModeChangeListener {
@Override @Override
public void modeChanged(Trace trace, StateEditingMode mode) { public void modeChanged(Trace trace, ControlMode mode) {
processChange(c -> evtModeChanged(c, trace), "modeChanged"); processChange(c -> evtModeChanged(c, trace), "modeChanged");
} }
} }
@ -516,7 +516,7 @@ public class DebuggerLogicalBreakpointServicePlugin extends Plugin
* snap has changed to where it's no longer present, because the mapping to static space * snap has changed to where it's no longer present, because the mapping to static space
* has changed or become invalid, or because it has no live breakpoint in target mode. * has changed or become invalid, or because it has no live breakpoint in target mode.
*/ */
StateEditingMode mode = getMode(trace); ControlMode mode = getMode(trace);
for (Set<LogicalBreakpointInternal> set : List for (Set<LogicalBreakpointInternal> set : List
.copyOf(breakpointsByAddress.values())) { .copyOf(breakpointsByAddress.values())) {
for (LogicalBreakpointInternal lb : Set.copyOf(set)) { for (LogicalBreakpointInternal lb : Set.copyOf(set)) {
@ -547,7 +547,7 @@ public class DebuggerLogicalBreakpointServicePlugin extends Plugin
} }
protected void trackTraceBreakpoints(AddCollector a) { protected void trackTraceBreakpoints(AddCollector a) {
StateEditingMode mode = getMode(trace); ControlMode mode = getMode(trace);
if (!mode.useEmulatedBreakpoints() && recorder == null) { if (!mode.useEmulatedBreakpoints() && recorder == null) {
return; return;
} }
@ -560,7 +560,7 @@ public class DebuggerLogicalBreakpointServicePlugin extends Plugin
} }
protected void trackTraceBreakpoints(AddCollector a, protected void trackTraceBreakpoints(AddCollector a,
Collection<TraceBreakpoint> breakpoints, StateEditingMode mode) { Collection<TraceBreakpoint> breakpoints, ControlMode mode) {
for (TraceBreakpoint tb : breakpoints) { for (TraceBreakpoint tb : breakpoints) {
try { try {
trackTraceBreakpoint(a, tb, mode, false); trackTraceBreakpoint(a, tb, mode, false);
@ -587,7 +587,7 @@ public class DebuggerLogicalBreakpointServicePlugin extends Plugin
} }
protected void trackTraceBreakpoint(AddCollector a, TraceBreakpoint tb, protected void trackTraceBreakpoint(AddCollector a, TraceBreakpoint tb,
StateEditingMode mode, boolean forceUpdate) ControlMode mode, boolean forceUpdate)
throws TrackedTooSoonException { throws TrackedTooSoonException {
if (!mode.useEmulatedBreakpoints() && if (!mode.useEmulatedBreakpoints() &&
(recorder == null || recorder.getTargetBreakpoint(tb) == null)) { (recorder == null || recorder.getTargetBreakpoint(tb) == null)) {
@ -803,7 +803,7 @@ public class DebuggerLogicalBreakpointServicePlugin extends Plugin
// @AutoServiceConsumed via method // @AutoServiceConsumed via method
private DebuggerStaticMappingService mappingService; private DebuggerStaticMappingService mappingService;
// @AutoServiceConsumed via method // @AutoServiceConsumed via method
private DebuggerStateEditingService editingService; private DebuggerControlService controlService;
@SuppressWarnings("unused") @SuppressWarnings("unused")
private final AutoService.Wiring autoServiceWiring; private final AutoService.Wiring autoServiceWiring;
@ -921,13 +921,13 @@ public class DebuggerLogicalBreakpointServicePlugin extends Plugin
} }
@AutoServiceConsumed @AutoServiceConsumed
public void setEditingService(DebuggerStateEditingService editingService) { private void setControlService(DebuggerControlService editingService) {
if (this.editingService != null) { if (this.controlService != null) {
this.editingService.removeModeChangeListener(modeListener); this.controlService.removeModeChangeListener(modeListener);
} }
this.editingService = editingService; this.controlService = editingService;
if (this.editingService != null) { if (this.controlService != null) {
this.editingService.addModeChangeListener(modeListener); this.controlService.addModeChangeListener(modeListener);
} }
} }
@ -1248,16 +1248,16 @@ public class DebuggerLogicalBreakpointServicePlugin extends Plugin
}, (actions, lbi) -> lbi.planDelete(actions, trace)); }, (actions, lbi) -> lbi.planDelete(actions, trace));
} }
private StateEditingMode getMode(Trace trace) { private ControlMode getMode(Trace trace) {
return editingService == null return controlService == null
? StateEditingMode.DEFAULT ? ControlMode.DEFAULT
: editingService.getCurrentMode(trace); : controlService.getCurrentMode(trace);
} }
private void planActOnLoc(BreakpointActionSet actions, TraceBreakpoint tb, private void planActOnLoc(BreakpointActionSet actions, TraceBreakpoint tb,
BiConsumer<BreakpointActionSet, TargetBreakpointLocation> targetLocConsumer, BiConsumer<BreakpointActionSet, TargetBreakpointLocation> targetLocConsumer,
BiConsumer<BreakpointActionSet, TraceBreakpoint> emuLocConsumer) { BiConsumer<BreakpointActionSet, TraceBreakpoint> emuLocConsumer) {
StateEditingMode mode = getMode(tb.getTrace()); ControlMode mode = getMode(tb.getTrace());
if (mode.useEmulatedBreakpoints()) { if (mode.useEmulatedBreakpoints()) {
planActOnLocEmu(actions, tb, emuLocConsumer); planActOnLocEmu(actions, tb, emuLocConsumer);
} }

View file

@ -78,9 +78,9 @@ class TraceBreakpointSet {
this.recorder = recorder; this.recorder = recorder;
} }
private StateEditingMode getStateEditingMode() { private ControlMode getControlMode() {
DebuggerStateEditingService service = tool.getService(DebuggerStateEditingService.class); DebuggerControlService service = tool.getService(DebuggerControlService.class);
return service == null ? StateEditingMode.DEFAULT : service.getCurrentMode(trace); return service == null ? ControlMode.DEFAULT : service.getCurrentMode(trace);
} }
private long getSnap() { private long getSnap() {
@ -139,7 +139,7 @@ class TraceBreakpointSet {
*/ */
public TraceMode computeMode() { public TraceMode computeMode() {
TraceMode mode = TraceMode.NONE; TraceMode mode = TraceMode.NONE;
if (getStateEditingMode().useEmulatedBreakpoints()) { if (getControlMode().useEmulatedBreakpoints()) {
for (IDHashed<TraceBreakpoint> bpt : breakpoints) { for (IDHashed<TraceBreakpoint> bpt : breakpoints) {
mode = mode.combine(computeEmuMode(bpt.obj)); mode = mode.combine(computeEmuMode(bpt.obj));
if (mode == TraceMode.MISSING) { if (mode == TraceMode.MISSING) {
@ -169,7 +169,7 @@ class TraceBreakpointSet {
* @return the mode * @return the mode
*/ */
public TraceMode computeMode(TraceBreakpoint bpt) { public TraceMode computeMode(TraceBreakpoint bpt) {
return getStateEditingMode().useEmulatedBreakpoints() return getControlMode().useEmulatedBreakpoints()
? computeEmuMode(bpt) ? computeEmuMode(bpt)
: computeTargetMode(bpt); : computeTargetMode(bpt);
} }
@ -318,7 +318,7 @@ class TraceBreakpointSet {
Collection<TraceBreakpointKind> kinds) { Collection<TraceBreakpointKind> kinds) {
long snap = getSnap(); long snap = getSnap();
if (breakpoints.isEmpty()) { if (breakpoints.isEmpty()) {
if (recorder == null || getStateEditingMode().useEmulatedBreakpoints()) { if (recorder == null || getControlMode().useEmulatedBreakpoints()) {
planPlaceEmu(actions, snap, length, kinds); planPlaceEmu(actions, snap, length, kinds);
} }
else { else {
@ -326,7 +326,7 @@ class TraceBreakpointSet {
} }
} }
else { else {
if (recorder == null || getStateEditingMode().useEmulatedBreakpoints()) { if (recorder == null || getControlMode().useEmulatedBreakpoints()) {
planEnableEmu(actions); planEnableEmu(actions);
} }
else { else {
@ -384,7 +384,7 @@ class TraceBreakpointSet {
*/ */
public void planDisable(BreakpointActionSet actions, long length, public void planDisable(BreakpointActionSet actions, long length,
Collection<TraceBreakpointKind> kinds) { Collection<TraceBreakpointKind> kinds) {
if (getStateEditingMode().useEmulatedBreakpoints()) { if (getControlMode().useEmulatedBreakpoints()) {
planDisableEmu(actions); planDisableEmu(actions);
} }
else { else {
@ -427,7 +427,7 @@ class TraceBreakpointSet {
*/ */
public void planDelete(BreakpointActionSet actions, long length, public void planDelete(BreakpointActionSet actions, long length,
Set<TraceBreakpointKind> kinds) { Set<TraceBreakpointKind> kinds) {
if (getStateEditingMode().useEmulatedBreakpoints()) { if (getControlMode().useEmulatedBreakpoints()) {
planDeleteEmu(actions); planDeleteEmu(actions);
} }
else { else {

View file

@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package ghidra.app.plugin.core.debug.service.editing; package ghidra.app.plugin.core.debug.service.control;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.util.*; import java.util.*;
@ -36,8 +36,8 @@ import ghidra.trace.model.program.TraceProgramViewMemory;
import ghidra.util.datastruct.ListenerSet; import ghidra.util.datastruct.ListenerSet;
@PluginInfo( @PluginInfo(
shortDescription = "Debugger machine-state editing service plugin", shortDescription = "Debugger control and machine-state editing service plugin",
description = "Centralizes machine-state editing across the tool", description = "Centralizes control and machine-state editing across the tool",
category = PluginCategoryNames.DEBUGGER, category = PluginCategoryNames.DEBUGGER,
packageName = DebuggerPluginPackage.NAME, packageName = DebuggerPluginPackage.NAME,
status = PluginStatus.RELEASED, status = PluginStatus.RELEASED,
@ -51,10 +51,10 @@ import ghidra.util.datastruct.ListenerSet;
DebuggerEmulationService.class, DebuggerEmulationService.class,
}, },
servicesProvided = { servicesProvided = {
DebuggerStateEditingService.class, DebuggerControlService.class,
}) })
public class DebuggerStateEditingServicePlugin extends AbstractDebuggerPlugin public class DebuggerControlServicePlugin extends AbstractDebuggerPlugin
implements DebuggerStateEditingService { implements DebuggerControlService {
protected abstract class AbstractStateEditor implements StateEditor { protected abstract class AbstractStateEditor implements StateEditor {
@Override @Override
@ -80,8 +80,8 @@ public class DebuggerStateEditingServicePlugin extends AbstractDebuggerPlugin
} }
@Override @Override
public DebuggerStateEditingService getService() { public DebuggerControlService getService() {
return DebuggerStateEditingServicePlugin.this; return DebuggerControlServicePlugin.this;
} }
@Override @Override
@ -98,8 +98,8 @@ public class DebuggerStateEditingServicePlugin extends AbstractDebuggerPlugin
} }
@Override @Override
public DebuggerStateEditingService getService() { public DebuggerControlService getService() {
return DebuggerStateEditingServicePlugin.this; return DebuggerControlServicePlugin.this;
} }
@Override @Override
@ -121,8 +121,8 @@ public class DebuggerStateEditingServicePlugin extends AbstractDebuggerPlugin
} }
@Override @Override
public DebuggerStateEditingService getService() { public DebuggerControlService getService() {
return DebuggerStateEditingServicePlugin.this; return DebuggerControlServicePlugin.this;
} }
@Override @Override
@ -204,29 +204,27 @@ public class DebuggerStateEditingServicePlugin extends AbstractDebuggerPlugin
protected final ListenerForEditorInstallation listenerForEditorInstallation = protected final ListenerForEditorInstallation listenerForEditorInstallation =
new ListenerForEditorInstallation(); new ListenerForEditorInstallation();
public DebuggerStateEditingServicePlugin(PluginTool tool) { public DebuggerControlServicePlugin(PluginTool tool) {
super(tool); super(tool);
} }
private final Map<Trace, StateEditingMode> currentModes = new HashMap<>(); private final Map<Trace, ControlMode> currentModes = new HashMap<>();
private final ListenerSet<StateEditingModeChangeListener> listeners = private final ListenerSet<ControlModeChangeListener> listeners =
new ListenerSet<>(StateEditingModeChangeListener.class); new ListenerSet<>(ControlModeChangeListener.class);
@Override @Override
public StateEditingMode getCurrentMode(Trace trace) { public ControlMode getCurrentMode(Trace trace) {
synchronized (currentModes) { synchronized (currentModes) {
return currentModes.getOrDefault(Objects.requireNonNull(trace), return currentModes.getOrDefault(Objects.requireNonNull(trace), ControlMode.DEFAULT);
StateEditingMode.DEFAULT);
} }
} }
@Override @Override
public void setCurrentMode(Trace trace, StateEditingMode newMode) { public void setCurrentMode(Trace trace, ControlMode newMode) {
StateEditingMode oldMode; ControlMode oldMode;
synchronized (currentModes) { synchronized (currentModes) {
oldMode = oldMode = currentModes.getOrDefault(Objects.requireNonNull(trace), ControlMode.DEFAULT);
currentModes.getOrDefault(Objects.requireNonNull(trace), StateEditingMode.DEFAULT);
if (newMode != oldMode) { if (newMode != oldMode) {
currentModes.put(trace, newMode); currentModes.put(trace, newMode);
} }
@ -238,12 +236,12 @@ public class DebuggerStateEditingServicePlugin extends AbstractDebuggerPlugin
} }
@Override @Override
public void addModeChangeListener(StateEditingModeChangeListener listener) { public void addModeChangeListener(ControlModeChangeListener listener) {
listeners.add(listener); listeners.add(listener);
} }
@Override @Override
public void removeModeChangeListener(StateEditingModeChangeListener listener) { public void removeModeChangeListener(ControlModeChangeListener listener) {
listeners.remove(listener); listeners.remove(listener);
} }
@ -270,10 +268,10 @@ public class DebuggerStateEditingServicePlugin extends AbstractDebuggerPlugin
if (trace == null) { if (trace == null) {
return; return;
} }
StateEditingMode oldMode; ControlMode oldMode;
StateEditingMode newMode; ControlMode newMode;
synchronized (currentModes) { synchronized (currentModes) {
oldMode = currentModes.getOrDefault(trace, StateEditingMode.DEFAULT); oldMode = currentModes.getOrDefault(trace, ControlMode.DEFAULT);
newMode = oldMode.modeOnChange(coordinates); newMode = oldMode.modeOnChange(coordinates);
if (newMode != oldMode) { if (newMode != oldMode) {
currentModes.put(trace, newMode); currentModes.put(trace, newMode);

View file

@ -267,7 +267,7 @@ public class DebuggerEmulationServicePlugin extends Plugin implements DebuggerEm
@AutoServiceConsumed @AutoServiceConsumed
private DebuggerStaticMappingService staticMappings; private DebuggerStaticMappingService staticMappings;
@AutoServiceConsumed @AutoServiceConsumed
private DebuggerStateEditingService editingService; private DebuggerControlService controlService;
@SuppressWarnings("unused") @SuppressWarnings("unused")
private AutoService.Wiring autoServiceWiring; private AutoService.Wiring autoServiceWiring;
@ -367,8 +367,8 @@ public class DebuggerEmulationServicePlugin extends Plugin implements DebuggerEm
trace = ProgramEmulationUtils.launchEmulationTrace(program, ctx.getAddress(), this); trace = ProgramEmulationUtils.launchEmulationTrace(program, ctx.getAddress(), this);
traceManager.openTrace(trace); traceManager.openTrace(trace);
traceManager.activateTrace(trace); traceManager.activateTrace(trace);
if (editingService != null) { if (controlService != null) {
editingService.setCurrentMode(trace, StateEditingMode.RW_EMULATOR); controlService.setCurrentMode(trace, ControlMode.RW_EMULATOR);
} }
} }
catch (IOException e) { catch (IOException e) {

View file

@ -32,7 +32,7 @@ import ghidra.app.plugin.core.debug.event.*;
import ghidra.app.plugin.core.debug.gui.DebuggerResources.*; import ghidra.app.plugin.core.debug.gui.DebuggerResources.*;
import ghidra.app.plugin.core.debug.mapping.DebuggerPlatformMapper; import ghidra.app.plugin.core.debug.mapping.DebuggerPlatformMapper;
import ghidra.app.services.*; import ghidra.app.services.*;
import ghidra.app.services.DebuggerStateEditingService.StateEditingModeChangeListener; import ghidra.app.services.DebuggerControlService.ControlModeChangeListener;
import ghidra.async.*; import ghidra.async.*;
import ghidra.async.AsyncConfigFieldCodec.BooleanAsyncConfigFieldCodec; import ghidra.async.AsyncConfigFieldCodec.BooleanAsyncConfigFieldCodec;
import ghidra.dbg.target.*; import ghidra.dbg.target.*;
@ -234,9 +234,9 @@ public class DebuggerTraceManagerServicePlugin extends Plugin
} }
} }
class ForFollowPresentListener implements StateEditingModeChangeListener { class ForFollowPresentListener implements ControlModeChangeListener {
@Override @Override
public void modeChanged(Trace trace, StateEditingMode mode) { public void modeChanged(Trace trace, ControlMode mode) {
if (trace != current.getTrace() || !mode.followsPresent()) { if (trace != current.getTrace() || !mode.followsPresent()) {
return; return;
} }
@ -278,7 +278,7 @@ public class DebuggerTraceManagerServicePlugin extends Plugin
@AutoServiceConsumed @AutoServiceConsumed
private DebuggerPlatformService platformService; private DebuggerPlatformService platformService;
// @AutoServiceConsumed via method // @AutoServiceConsumed via method
private DebuggerStateEditingService editingService; private DebuggerControlService controlService;
@SuppressWarnings("unused") @SuppressWarnings("unused")
private final AutoService.Wiring autoServiceWiring; private final AutoService.Wiring autoServiceWiring;
@ -474,13 +474,13 @@ public class DebuggerTraceManagerServicePlugin extends Plugin
} }
@AutoServiceConsumed @AutoServiceConsumed
private void setEditingService(DebuggerStateEditingService editingService) { private void setControlService(DebuggerControlService editingService) {
if (this.editingService != null) { if (this.controlService != null) {
this.editingService.removeModeChangeListener(forFollowPresentListener); this.controlService.removeModeChangeListener(forFollowPresentListener);
} }
this.editingService = editingService; this.controlService = editingService;
if (this.editingService != null) { if (this.controlService != null) {
this.editingService.addModeChangeListener(forFollowPresentListener); this.controlService.addModeChangeListener(forFollowPresentListener);
} }
} }
@ -622,9 +622,9 @@ public class DebuggerTraceManagerServicePlugin extends Plugin
} }
private boolean isFollowsPresent(Trace trace) { private boolean isFollowsPresent(Trace trace) {
StateEditingMode mode = editingService == null ControlMode mode = controlService == null
? StateEditingMode.DEFAULT ? ControlMode.DEFAULT
: editingService.getCurrentMode(trace); : controlService.getCurrentMode(trace);
return mode.followsPresent(); return mode.followsPresent();
} }

View file

@ -23,7 +23,7 @@ import java.util.concurrent.CompletableFuture;
import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.ArrayUtils;
import ghidra.app.plugin.core.debug.DebuggerCoordinates; import ghidra.app.plugin.core.debug.DebuggerCoordinates;
import ghidra.app.services.DebuggerStateEditingService.StateEditor; import ghidra.app.services.DebuggerControlService.StateEditor;
import ghidra.app.services.DebuggerStaticMappingService; import ghidra.app.services.DebuggerStaticMappingService;
import ghidra.async.AsyncFence; import ghidra.async.AsyncFence;
import ghidra.framework.plugintool.PluginTool; import ghidra.framework.plugintool.PluginTool;

View file

@ -21,7 +21,7 @@ import java.util.concurrent.CompletableFuture;
import ghidra.app.plugin.core.bookmark.BookmarkNavigator; import ghidra.app.plugin.core.bookmark.BookmarkNavigator;
import ghidra.app.plugin.core.debug.DebuggerCoordinates; import ghidra.app.plugin.core.debug.DebuggerCoordinates;
import ghidra.app.services.DebuggerStateEditingService.StateEditor; import ghidra.app.services.DebuggerControlService.StateEditor;
import ghidra.app.services.DebuggerStaticMappingService; import ghidra.app.services.DebuggerStaticMappingService;
import ghidra.framework.plugintool.PluginTool; import ghidra.framework.plugintool.PluginTool;
import ghidra.pcode.exec.BytesPcodeArithmetic; import ghidra.pcode.exec.BytesPcodeArithmetic;

View file

@ -20,7 +20,7 @@ import java.util.*;
import java.util.Map.Entry; import java.util.Map.Entry;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
import ghidra.app.services.DebuggerStateEditingService.StateEditor; import ghidra.app.services.DebuggerControlService.StateEditor;
import ghidra.async.AsyncFence; import ghidra.async.AsyncFence;
import ghidra.pcode.eval.ArithmeticVarnodeEvaluator; import ghidra.pcode.eval.ArithmeticVarnodeEvaluator;
import ghidra.pcode.exec.PcodeArithmetic; import ghidra.pcode.exec.PcodeArithmetic;

View file

@ -20,7 +20,7 @@ import java.util.concurrent.CompletableFuture;
import ghidra.app.decompiler.ClangLine; import ghidra.app.decompiler.ClangLine;
import ghidra.app.plugin.core.debug.gui.stack.vars.VariableValueUtils; import ghidra.app.plugin.core.debug.gui.stack.vars.VariableValueUtils;
import ghidra.app.services.DebuggerStateEditingService.StateEditor; import ghidra.app.services.DebuggerControlService.StateEditor;
import ghidra.program.model.address.Address; import ghidra.program.model.address.Address;
import ghidra.program.model.address.AddressSetView; import ghidra.program.model.address.AddressSetView;
import ghidra.program.model.lang.Register; import ghidra.program.model.lang.Register;

View file

@ -16,6 +16,7 @@
package ghidra.app.services; package ghidra.app.services;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.util.List;
import java.util.Objects; import java.util.Objects;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
@ -47,12 +48,13 @@ import ghidra.util.task.TaskMonitor;
/** /**
* The control / state editing modes * The control / state editing modes
*/ */
public enum StateEditingMode { public enum ControlMode {
/** /**
* Control actions, breakpoint commands are directed to the target, but state edits are * Control actions, breakpoint commands are directed to the target, but state edits are
* rejected. * rejected.
*/ */
RO_TARGET("Control Target w/ Edits Disabled", new GIcon("icon.debugger.edit.mode.ro.target")) { RO_TARGET("Control Target w/ Edits Disabled", new GIcon(
"icon.debugger.control.mode.ro.target")) {
@Override @Override
public boolean followsPresent() { public boolean followsPresent() {
return true; return true;
@ -86,14 +88,14 @@ public enum StateEditingMode {
} }
@Override @Override
public StateEditingMode getAlternative(DebuggerCoordinates coordinates) { public ControlMode getAlternative(DebuggerCoordinates coordinates) {
return RO_TRACE; return RO_TRACE;
} }
}, },
/** /**
* Control actions, breakpoint commands, and state edits are all directed to the target. * Control actions, breakpoint commands, and state edits are all directed to the target.
*/ */
RW_TARGET("Control Target", new GIcon("icon.debugger.edit.mode.rw.target")) { RW_TARGET("Control Target", new GIcon("icon.debugger.control.mode.rw.target")) {
@Override @Override
public boolean followsPresent() { public boolean followsPresent() {
return true; return true;
@ -142,7 +144,7 @@ public enum StateEditingMode {
} }
@Override @Override
public StateEditingMode getAlternative(DebuggerCoordinates coordinates) { public ControlMode getAlternative(DebuggerCoordinates coordinates) {
return RW_EMULATOR; return RW_EMULATOR;
} }
}, },
@ -150,7 +152,7 @@ public enum StateEditingMode {
* Control actions activate trace snapshots, breakpoint commands are directed to the emulator, * Control actions activate trace snapshots, breakpoint commands are directed to the emulator,
* and state edits are rejected. * and state edits are rejected.
*/ */
RO_TRACE("Control Trace w/ Edits Disabled", new GIcon("icon.debugger.edit.mode.ro.trace")) { RO_TRACE("Control Trace w/ Edits Disabled", new GIcon("icon.debugger.control.mode.ro.trace")) {
@Override @Override
public boolean followsPresent() { public boolean followsPresent() {
return false; return false;
@ -182,7 +184,7 @@ public enum StateEditingMode {
* Control actions activate trace snapshots, breakpoint commands are directed to the emulator, * Control actions activate trace snapshots, breakpoint commands are directed to the emulator,
* and state edits modify the current trace snapshot. * and state edits modify the current trace snapshot.
*/ */
RW_TRACE("Control Trace", new GIcon("icon.debugger.edit.mode.rw.trace")) { RW_TRACE("Control Trace", new GIcon("icon.debugger.control.mode.rw.trace")) {
@Override @Override
public boolean followsPresent() { public boolean followsPresent() {
return false; return false;
@ -249,7 +251,7 @@ public enum StateEditingMode {
* Edits are accomplished by appending patch steps to the current schedule and activating that * Edits are accomplished by appending patch steps to the current schedule and activating that
* schedule. * schedule.
*/ */
RW_EMULATOR("Control Emulator", new GIcon("icon.debugger.edit.mode.rw.emulator")) { RW_EMULATOR("Control Emulator", new GIcon("icon.debugger.control.mode.rw.emulator")) {
@Override @Override
public boolean followsPresent() { public boolean followsPresent() {
return false; return false;
@ -328,12 +330,13 @@ public enum StateEditingMode {
} }
}; };
public static final StateEditingMode DEFAULT = RO_TARGET; public static final List<ControlMode> ALL = List.of(values());
public static final ControlMode DEFAULT = RO_TARGET;
public final String name; public final String name;
public final Icon icon; public final Icon icon;
private StateEditingMode(String name, Icon icon) { private ControlMode(String name, Icon icon) {
this.name = name; this.name = name;
this.icon = icon; this.icon = icon;
} }
@ -408,7 +411,7 @@ public enum StateEditingMode {
* @param coordinates the new coordinates * @param coordinates the new coordinates
* @return the new mode * @return the new mode
*/ */
public StateEditingMode getAlternative(DebuggerCoordinates coordinates) { public ControlMode getAlternative(DebuggerCoordinates coordinates) {
throw new AssertionError("INTERNAL: Non-selectable mode must provide alternative"); throw new AssertionError("INTERNAL: Non-selectable mode must provide alternative");
} }
@ -422,7 +425,7 @@ public enum StateEditingMode {
* @param coordinates the new coordinates * @param coordinates the new coordinates
* @return the mode * @return the mode
*/ */
public StateEditingMode modeOnChange(DebuggerCoordinates coordinates) { public ControlMode modeOnChange(DebuggerCoordinates coordinates) {
if (isSelectable(coordinates)) { if (isSelectable(coordinates)) {
return this; return this;
} }

View file

@ -18,7 +18,7 @@ package ghidra.app.services;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
import ghidra.app.plugin.core.debug.DebuggerCoordinates; import ghidra.app.plugin.core.debug.DebuggerCoordinates;
import ghidra.app.plugin.core.debug.service.editing.DebuggerStateEditingServicePlugin; import ghidra.app.plugin.core.debug.service.control.DebuggerControlServicePlugin;
import ghidra.framework.plugintool.ServiceInfo; import ghidra.framework.plugintool.ServiceInfo;
import ghidra.pcode.utils.Utils; import ghidra.pcode.utils.Utils;
import ghidra.program.model.address.Address; import ghidra.program.model.address.Address;
@ -28,11 +28,11 @@ import ghidra.trace.model.Trace;
import ghidra.trace.model.program.TraceProgramView; import ghidra.trace.model.program.TraceProgramView;
@ServiceInfo( @ServiceInfo(
defaultProvider = DebuggerStateEditingServicePlugin.class, defaultProvider = DebuggerControlServicePlugin.class,
description = "Centralized service for modifying machine states") description = "Centralized service for modifying machine states")
public interface DebuggerStateEditingService { public interface DebuggerControlService {
interface StateEditor { interface StateEditor {
DebuggerStateEditingService getService(); DebuggerControlService getService();
DebuggerCoordinates getCoordinates(); DebuggerCoordinates getCoordinates();
@ -55,17 +55,17 @@ public interface DebuggerStateEditingService {
interface StateEditingMemoryHandler extends StateEditor, LiveMemoryHandler { interface StateEditingMemoryHandler extends StateEditor, LiveMemoryHandler {
} }
interface StateEditingModeChangeListener { interface ControlModeChangeListener {
void modeChanged(Trace trace, StateEditingMode mode); void modeChanged(Trace trace, ControlMode mode);
} }
StateEditingMode getCurrentMode(Trace trace); ControlMode getCurrentMode(Trace trace);
void setCurrentMode(Trace trace, StateEditingMode mode); void setCurrentMode(Trace trace, ControlMode mode);
void addModeChangeListener(StateEditingModeChangeListener listener); void addModeChangeListener(ControlModeChangeListener listener);
void removeModeChangeListener(StateEditingModeChangeListener listener); void removeModeChangeListener(ControlModeChangeListener listener);
StateEditor createStateEditor(DebuggerCoordinates coordinates); StateEditor createStateEditor(DebuggerCoordinates coordinates);

View file

@ -30,7 +30,7 @@ import ghidra.app.plugin.core.debug.service.model.launch.DebuggerProgramLaunchOf
import ghidra.app.script.GhidraScript; import ghidra.app.script.GhidraScript;
import ghidra.app.script.GhidraState; import ghidra.app.script.GhidraState;
import ghidra.app.services.*; import ghidra.app.services.*;
import ghidra.app.services.DebuggerStateEditingService.StateEditor; import ghidra.app.services.DebuggerControlService.StateEditor;
import ghidra.dbg.AnnotatedDebuggerAttributeListener; import ghidra.dbg.AnnotatedDebuggerAttributeListener;
import ghidra.dbg.DebuggerObjectModel; import ghidra.dbg.DebuggerObjectModel;
import ghidra.dbg.target.*; import ghidra.dbg.target.*;
@ -1182,40 +1182,40 @@ public interface FlatDebuggerAPI {
} }
/** /**
* Get the state editing service * Get the control service
* *
* @return the service * @return the service
*/ */
default DebuggerStateEditingService getEditingService() { default DebuggerControlService getControlService() {
return requireService(DebuggerStateEditingService.class); return requireService(DebuggerControlService.class);
} }
/** /**
* Set the editing mode of the given trace * Set the control mode of the given trace
* *
* @param trace the trace * @param trace the trace
* @param mode the mode * @param mode the mode
*/ */
default void setEditingMode(Trace trace, StateEditingMode mode) { default void setControlMode(Trace trace, ControlMode mode) {
requireService(DebuggerStateEditingService.class).setCurrentMode(trace, mode); requireService(DebuggerControlService.class).setCurrentMode(trace, mode);
} }
/** /**
* Set the editing mode of the current trace * Set the control mode of the current trace
* *
* @param mode the mode * @param mode the mode
*/ */
default void setEditingMode(StateEditingMode mode) { default void setControlMode(ControlMode mode) {
setEditingMode(requireCurrentTrace(), mode); setControlMode(requireCurrentTrace(), mode);
} }
/** /**
* Create a state editor for the given context, adhering to its current editing mode * Create a state editor for the given context, adhering to its current control mode
* *
* @return the editor * @return the editor
*/ */
default StateEditor createStateEditor(DebuggerCoordinates coordinates) { default StateEditor createStateEditor(DebuggerCoordinates coordinates) {
return getEditingService().createStateEditor(coordinates); return getControlService().createStateEditor(coordinates);
} }
/** /**
@ -1226,7 +1226,7 @@ public interface FlatDebuggerAPI {
* @return the editor * @return the editor
*/ */
default StateEditor createStateEditor(Trace trace, long snap) { default StateEditor createStateEditor(Trace trace, long snap) {
return getEditingService().createStateEditor(getTraceManager() return getControlService().createStateEditor(getTraceManager()
.resolveTrace(trace) .resolveTrace(trace)
.snap(snap)); .snap(snap));
} }
@ -1240,14 +1240,14 @@ public interface FlatDebuggerAPI {
* @return the editor * @return the editor
*/ */
default StateEditor createStateEditor(TraceThread thread, int frame, long snap) { default StateEditor createStateEditor(TraceThread thread, int frame, long snap) {
return getEditingService().createStateEditor(getTraceManager() return getControlService().createStateEditor(getTraceManager()
.resolveThread(thread) .resolveThread(thread)
.snap(snap) .snap(snap)
.frame(frame)); .frame(frame));
} }
/** /**
* Create a state editor for the current context, adhering to the current editing mode * Create a state editor for the current context, adhering to the current control mode
* *
* @return the editor * @return the editor
*/ */
@ -1260,7 +1260,7 @@ public interface FlatDebuggerAPI {
* *
* <p> * <p>
* The success or failure of this method depends on a few factors. First is the user-selected * The success or failure of this method depends on a few factors. First is the user-selected
* editing mode for the trace. See {@link #setEditingMode(StateEditingMode)}. In read-only mode, * control mode for the trace. See {@link #setControlMode(ControlMode)}. In read-only mode,
* this will always fail. When editing traces, a write almost always succeeds. Exceptions would * this will always fail. When editing traces, a write almost always succeeds. Exceptions would
* probably indicate I/O errors. When editing via emulation, a write should almost always * probably indicate I/O errors. When editing via emulation, a write should almost always
* succeed. Second, when editing the target, the state of the target matters. If the trace has * succeed. Second, when editing the target, the state of the target matters. If the trace has
@ -1288,7 +1288,7 @@ public interface FlatDebuggerAPI {
} }
/** /**
* Patch memory of the given target, according to its current editing mode * Patch memory of the given target, according to its current control mode
* *
* <p> * <p>
* If you intend to apply several patches, consider using {@link #createStateEditor(Trace,long)} * If you intend to apply several patches, consider using {@link #createStateEditor(Trace,long)}
@ -1305,7 +1305,7 @@ public interface FlatDebuggerAPI {
} }
/** /**
* Patch memory of the current target, according to the current editing mode * Patch memory of the current target, according to the current control mode
* *
* <p> * <p>
* If you intend to apply several patches, consider using {@link #createStateEditor()} and * If you intend to apply several patches, consider using {@link #createStateEditor()} and
@ -1324,7 +1324,7 @@ public interface FlatDebuggerAPI {
* *
* <p> * <p>
* The success or failure of this methods depends on a few factors. First is the user-selected * The success or failure of this methods depends on a few factors. First is the user-selected
* editing mode for the trace. See {@link #setEditingMode(StateEditingMode)}. In read-only mode, * control mode for the trace. See {@link #setControlMode(ControlMode)}. In read-only mode,
* this will always fail. When editing traces, a write almost always succeeds. Exceptions would * this will always fail. When editing traces, a write almost always succeeds. Exceptions would
* probably indicate I/O errors. When editing via emulation, a write should only fail if the * probably indicate I/O errors. When editing via emulation, a write should only fail if the
* register is not accessible to Sleigh, e.g., the context register. Second, when editing the * register is not accessible to Sleigh, e.g., the context register. Second, when editing the
@ -1351,7 +1351,7 @@ public interface FlatDebuggerAPI {
} }
/** /**
* Patch a register of the given context, according to its current editing mode * Patch a register of the given context, according to its current control mode
* *
* <p> * <p>
* If you intend to apply several patches, consider using * If you intend to apply several patches, consider using
@ -1369,7 +1369,7 @@ public interface FlatDebuggerAPI {
} }
/** /**
* Patch a register of the given context, according to its current editing mode * Patch a register of the given context, according to its current control mode
* *
* @see #writeRegister(TraceThread, int, long, RegisterValue) * @see #writeRegister(TraceThread, int, long, RegisterValue)
* @throws IllegalArgumentException if the register name is invalid * @throws IllegalArgumentException if the register name is invalid
@ -1381,7 +1381,7 @@ public interface FlatDebuggerAPI {
} }
/** /**
* Patch a register of the current thread, according to the current editing mode * Patch a register of the current thread, according to the current control mode
* *
* <p> * <p>
* If you intend to apply several patches, consider using {@link #createStateEditor()} and * If you intend to apply several patches, consider using {@link #createStateEditor()} and
@ -1396,7 +1396,7 @@ public interface FlatDebuggerAPI {
} }
/** /**
* Patch a register of the current thread, according to the current editing mode * Patch a register of the current thread, according to the current control mode
* *
* @see #writeRegister(RegisterValue) * @see #writeRegister(RegisterValue)
* @throws IllegalArgumentException if the register name is invalid * @throws IllegalArgumentException if the register name is invalid

View file

@ -28,7 +28,7 @@ import ghidra.app.plugin.core.debug.DebuggerCoordinates;
import ghidra.app.plugin.core.debug.gui.action.SPLocationTrackingSpec; import ghidra.app.plugin.core.debug.gui.action.SPLocationTrackingSpec;
import ghidra.app.plugin.core.debug.gui.listing.DebuggerListingPlugin; import ghidra.app.plugin.core.debug.gui.listing.DebuggerListingPlugin;
import ghidra.app.plugin.core.debug.gui.listing.DebuggerListingProvider; import ghidra.app.plugin.core.debug.gui.listing.DebuggerListingProvider;
import ghidra.app.plugin.core.debug.service.editing.DebuggerStateEditingServicePlugin; import ghidra.app.plugin.core.debug.service.control.DebuggerControlServicePlugin;
import ghidra.app.plugin.core.debug.service.emulation.DebuggerEmulationServicePlugin; import ghidra.app.plugin.core.debug.service.emulation.DebuggerEmulationServicePlugin;
import ghidra.app.plugin.core.debug.service.emulation.ProgramEmulationUtils; import ghidra.app.plugin.core.debug.service.emulation.ProgramEmulationUtils;
import ghidra.app.plugin.core.debug.service.modules.DebuggerStaticMappingServicePlugin; import ghidra.app.plugin.core.debug.service.modules.DebuggerStaticMappingServicePlugin;
@ -38,7 +38,7 @@ import ghidra.app.plugin.core.debug.stack.*;
import ghidra.app.plugin.core.progmgr.ProgramManagerPlugin; import ghidra.app.plugin.core.progmgr.ProgramManagerPlugin;
import ghidra.app.services.*; import ghidra.app.services.*;
import ghidra.app.services.DebuggerEmulationService.EmulationResult; import ghidra.app.services.DebuggerEmulationService.EmulationResult;
import ghidra.app.services.DebuggerStateEditingService.StateEditor; import ghidra.app.services.DebuggerControlService.StateEditor;
import ghidra.async.AsyncTestUtils; import ghidra.async.AsyncTestUtils;
import ghidra.framework.model.DomainFolder; import ghidra.framework.model.DomainFolder;
import ghidra.framework.model.DomainObject; import ghidra.framework.model.DomainObject;
@ -278,8 +278,7 @@ public class DebuggerStackPluginScreenShots extends GhidraScreenShotGenerator
public void testCaptureDebuggerStackUnwindInListing() throws Throwable { public void testCaptureDebuggerStackUnwindInListing() throws Throwable {
addPlugin(tool, DebuggerListingPlugin.class); addPlugin(tool, DebuggerListingPlugin.class);
DebuggerStateEditingService editingService = DebuggerControlService controlService = addPlugin(tool, DebuggerControlServicePlugin.class);
addPlugin(tool, DebuggerStateEditingServicePlugin.class);
DebuggerEmulationService emuService = addPlugin(tool, DebuggerEmulationServicePlugin.class); DebuggerEmulationService emuService = addPlugin(tool, DebuggerEmulationServicePlugin.class);
Function function = createFibonacciProgramX86_32(); Function function = createFibonacciProgramX86_32();
@ -296,8 +295,8 @@ public class DebuggerStackPluginScreenShots extends GhidraScreenShotGenerator
traceManager.activateThread(thread); traceManager.activateThread(thread);
waitForSwing(); waitForSwing();
editingService.setCurrentMode(tb.trace, StateEditingMode.RW_TRACE); controlService.setCurrentMode(tb.trace, ControlMode.RW_TRACE);
StateEditor editor = editingService.createStateEditor(tb.trace); StateEditor editor = controlService.createStateEditor(tb.trace);
DebuggerCoordinates atSetup = traceManager.getCurrent(); DebuggerCoordinates atSetup = traceManager.getCurrent();
StackUnwinder unwinder = new StackUnwinder(tool, atSetup.getPlatform()); StackUnwinder unwinder = new StackUnwinder(tool, atSetup.getPlatform());
@ -331,7 +330,7 @@ public class DebuggerStackPluginScreenShots extends GhidraScreenShotGenerator
waitForComponentProvider(DebuggerListingProvider.class); waitForComponentProvider(DebuggerListingProvider.class);
listingProvider.setTrackingSpec(SPLocationTrackingSpec.INSTANCE); listingProvider.setTrackingSpec(SPLocationTrackingSpec.INSTANCE);
waitForSwing(); waitForSwing();
captureIsolatedProvider(listingProvider, 800, 600); captureIsolatedProvider(listingProvider, 800, 600);
} }
} }

View file

@ -34,7 +34,7 @@ import ghidra.app.plugin.core.codebrowser.CodeViewerProvider;
import ghidra.app.plugin.core.debug.DebuggerCoordinates; import ghidra.app.plugin.core.debug.DebuggerCoordinates;
import ghidra.app.plugin.core.debug.gui.listing.DebuggerListingPlugin; import ghidra.app.plugin.core.debug.gui.listing.DebuggerListingPlugin;
import ghidra.app.plugin.core.debug.gui.listing.DebuggerListingProvider; import ghidra.app.plugin.core.debug.gui.listing.DebuggerListingProvider;
import ghidra.app.plugin.core.debug.service.editing.DebuggerStateEditingServicePlugin; import ghidra.app.plugin.core.debug.service.control.DebuggerControlServicePlugin;
import ghidra.app.plugin.core.debug.service.emulation.DebuggerEmulationServicePlugin; import ghidra.app.plugin.core.debug.service.emulation.DebuggerEmulationServicePlugin;
import ghidra.app.plugin.core.debug.service.emulation.ProgramEmulationUtils; import ghidra.app.plugin.core.debug.service.emulation.ProgramEmulationUtils;
import ghidra.app.plugin.core.debug.service.modules.DebuggerStaticMappingServicePlugin; import ghidra.app.plugin.core.debug.service.modules.DebuggerStaticMappingServicePlugin;
@ -45,7 +45,7 @@ import ghidra.app.plugin.core.decompile.DecompilerProvider;
import ghidra.app.plugin.core.progmgr.ProgramManagerPlugin; import ghidra.app.plugin.core.progmgr.ProgramManagerPlugin;
import ghidra.app.services.*; import ghidra.app.services.*;
import ghidra.app.services.DebuggerEmulationService.EmulationResult; import ghidra.app.services.DebuggerEmulationService.EmulationResult;
import ghidra.app.services.DebuggerStateEditingService.StateEditor; import ghidra.app.services.DebuggerControlService.StateEditor;
import ghidra.app.util.viewer.listingpanel.ListingPanel; import ghidra.app.util.viewer.listingpanel.ListingPanel;
import ghidra.async.AsyncTestUtils; import ghidra.async.AsyncTestUtils;
import ghidra.framework.model.DomainFolder; import ghidra.framework.model.DomainFolder;
@ -227,8 +227,7 @@ public class VariableValueHoverPluginScreenShots extends GhidraScreenShotGenerat
addPlugin(tool, DebuggerListingPlugin.class); addPlugin(tool, DebuggerListingPlugin.class);
addPlugin(tool, VariableValueHoverPlugin.class); addPlugin(tool, VariableValueHoverPlugin.class);
DebuggerStateEditingService editingService = DebuggerControlService controlService = addPlugin(tool, DebuggerControlServicePlugin.class);
addPlugin(tool, DebuggerStateEditingServicePlugin.class);
DebuggerEmulationService emuService = addPlugin(tool, DebuggerEmulationServicePlugin.class); DebuggerEmulationService emuService = addPlugin(tool, DebuggerEmulationServicePlugin.class);
Function function = createFibonacciProgramX86_32(); Function function = createFibonacciProgramX86_32();
@ -258,8 +257,8 @@ public class VariableValueHoverPluginScreenShots extends GhidraScreenShotGenerat
} }
waitForDomainObject(tb.trace); waitForDomainObject(tb.trace);
editingService.setCurrentMode(tb.trace, StateEditingMode.RW_TRACE); controlService.setCurrentMode(tb.trace, ControlMode.RW_TRACE);
StateEditor editor = editingService.createStateEditor(tb.trace); StateEditor editor = controlService.createStateEditor(tb.trace);
DebuggerCoordinates atSetup = traceManager.getCurrent(); DebuggerCoordinates atSetup = traceManager.getCurrent();
StackUnwinder unwinder = new StackUnwinder(tool, atSetup.getPlatform()); StackUnwinder unwinder = new StackUnwinder(tool, atSetup.getPlatform());

View file

@ -34,7 +34,7 @@ import ghidra.app.plugin.core.assembler.AssemblerPluginTestHelper;
import ghidra.app.plugin.core.debug.gui.AbstractGhidraHeadedDebuggerGUITest; import ghidra.app.plugin.core.debug.gui.AbstractGhidraHeadedDebuggerGUITest;
import ghidra.app.plugin.core.debug.gui.listing.DebuggerListingPlugin; import ghidra.app.plugin.core.debug.gui.listing.DebuggerListingPlugin;
import ghidra.app.plugin.core.debug.gui.listing.DebuggerListingProvider; import ghidra.app.plugin.core.debug.gui.listing.DebuggerListingProvider;
import ghidra.app.plugin.core.debug.service.editing.DebuggerStateEditingServicePlugin; import ghidra.app.plugin.core.debug.service.control.DebuggerControlServicePlugin;
import ghidra.app.plugin.core.debug.service.platform.DebuggerPlatformServicePlugin; import ghidra.app.plugin.core.debug.service.platform.DebuggerPlatformServicePlugin;
import ghidra.app.plugin.core.debug.service.workflow.DebuggerWorkflowServiceProxyPlugin; import ghidra.app.plugin.core.debug.service.workflow.DebuggerWorkflowServiceProxyPlugin;
import ghidra.app.plugin.core.debug.workflow.DisassembleAtPcDebuggerBot; import ghidra.app.plugin.core.debug.workflow.DisassembleAtPcDebuggerBot;
@ -405,12 +405,11 @@ public class DebuggerDisassemblyTest extends AbstractGhidraHeadedDebuggerGUITest
@Test @Test
public void testCurrentAssembleActionHostArm() throws Throwable { public void testCurrentAssembleActionHostArm() throws Throwable {
// Assemble actions will think read-only otherwise // Assemble actions will think read-only otherwise
DebuggerStateEditingService editingService = DebuggerControlService controlService = addPlugin(tool, DebuggerControlServicePlugin.class);
addPlugin(tool, DebuggerStateEditingServicePlugin.class);
createLegacyTrace("ARM:LE:32:v8", 0x00400000, () -> tb.buf(0x00, 0x00, 0x00, 0x00)); createLegacyTrace("ARM:LE:32:v8", 0x00400000, () -> tb.buf(0x00, 0x00, 0x00, 0x00));
Address start = tb.addr(0x00400000); Address start = tb.addr(0x00400000);
editingService.setCurrentMode(tb.trace, StateEditingMode.RW_TRACE); controlService.setCurrentMode(tb.trace, ControlMode.RW_TRACE);
// Ensure the mapper is added to the trace // Ensure the mapper is added to the trace
assertNotNull(platformService.getMapper(tb.trace, null, 0)); assertNotNull(platformService.getMapper(tb.trace, null, 0));
@ -437,13 +436,12 @@ public class DebuggerDisassemblyTest extends AbstractGhidraHeadedDebuggerGUITest
@Test @Test
public void testCurrentAssembleActionHostThumb() throws Throwable { public void testCurrentAssembleActionHostThumb() throws Throwable {
// Assemble actions will think read-only otherwise // Assemble actions will think read-only otherwise
DebuggerStateEditingService editingService = DebuggerControlService controlService = addPlugin(tool, DebuggerControlServicePlugin.class);
addPlugin(tool, DebuggerStateEditingServicePlugin.class);
// Don't cheat here and choose v8T! // Don't cheat here and choose v8T!
createLegacyTrace("ARM:LE:32:v8", 0x00400000, () -> tb.buf(0x00, 0x00)); createLegacyTrace("ARM:LE:32:v8", 0x00400000, () -> tb.buf(0x00, 0x00));
Address start = tb.addr(0x00400000); Address start = tb.addr(0x00400000);
editingService.setCurrentMode(tb.trace, StateEditingMode.RW_TRACE); controlService.setCurrentMode(tb.trace, ControlMode.RW_TRACE);
// Ensure the mapper is added to the trace // Ensure the mapper is added to the trace
assertNotNull(platformService.getMapper(tb.trace, null, 0)); assertNotNull(platformService.getMapper(tb.trace, null, 0));
@ -474,13 +472,12 @@ public class DebuggerDisassemblyTest extends AbstractGhidraHeadedDebuggerGUITest
@Test @Test
public void testCurrentAssembleActionGuestArm() throws Throwable { public void testCurrentAssembleActionGuestArm() throws Throwable {
// Assemble actions will think read-only otherwise // Assemble actions will think read-only otherwise
DebuggerStateEditingService editingService = DebuggerControlService controlService = addPlugin(tool, DebuggerControlServicePlugin.class);
addPlugin(tool, DebuggerStateEditingServicePlugin.class);
TraceObjectThread thread = TraceObjectThread thread =
createPolyglotTrace("armv8le", 0x00400000, () -> tb.buf(0x00, 0x00, 0x00, 0x00)); createPolyglotTrace("armv8le", 0x00400000, () -> tb.buf(0x00, 0x00, 0x00, 0x00));
Address start = tb.addr(0x00400000); Address start = tb.addr(0x00400000);
editingService.setCurrentMode(tb.trace, StateEditingMode.RW_TRACE); controlService.setCurrentMode(tb.trace, ControlMode.RW_TRACE);
// Ensure the mapper is added to the trace // Ensure the mapper is added to the trace
assertNotNull(platformService.getMapper(tb.trace, thread.getObject(), 0)); assertNotNull(platformService.getMapper(tb.trace, thread.getObject(), 0));
@ -509,13 +506,12 @@ public class DebuggerDisassemblyTest extends AbstractGhidraHeadedDebuggerGUITest
@Test @Test
public void testCurrentAssembleActionGuestThumb() throws Throwable { public void testCurrentAssembleActionGuestThumb() throws Throwable {
// Assemble actions will think read-only otherwise // Assemble actions will think read-only otherwise
DebuggerStateEditingService editingService = DebuggerControlService controlService = addPlugin(tool, DebuggerControlServicePlugin.class);
addPlugin(tool, DebuggerStateEditingServicePlugin.class);
TraceObjectThread thread = TraceObjectThread thread =
createPolyglotTrace("armv8le", 0x00400000, () -> tb.buf(0x00, 0x00)); createPolyglotTrace("armv8le", 0x00400000, () -> tb.buf(0x00, 0x00));
Address start = tb.addr(0x00400000); Address start = tb.addr(0x00400000);
editingService.setCurrentMode(tb.trace, StateEditingMode.RW_TRACE); controlService.setCurrentMode(tb.trace, ControlMode.RW_TRACE);
// Ensure the mapper is added to the trace // Ensure the mapper is added to the trace
assertNotNull(platformService.getMapper(tb.trace, thread.getObject(), 0)); assertNotNull(platformService.getMapper(tb.trace, thread.getObject(), 0));
@ -567,12 +563,11 @@ public class DebuggerDisassemblyTest extends AbstractGhidraHeadedDebuggerGUITest
@Test @Test
public void testFixedAssembleActionsHostArm() throws Throwable { public void testFixedAssembleActionsHostArm() throws Throwable {
// Assemble actions will think read-only otherwise // Assemble actions will think read-only otherwise
DebuggerStateEditingService editingService = DebuggerControlService controlService = addPlugin(tool, DebuggerControlServicePlugin.class);
addPlugin(tool, DebuggerStateEditingServicePlugin.class);
createLegacyTrace("ARM:LE:32:v8", 0x00400000, () -> tb.buf()); createLegacyTrace("ARM:LE:32:v8", 0x00400000, () -> tb.buf());
Address start = tb.addr(0x00400000); Address start = tb.addr(0x00400000);
editingService.setCurrentMode(tb.trace, StateEditingMode.RW_TRACE); controlService.setCurrentMode(tb.trace, ControlMode.RW_TRACE);
// Ensure the mapper is added to the trace // Ensure the mapper is added to the trace
assertNotNull(platformService.getMapper(tb.trace, null, 0)); assertNotNull(platformService.getMapper(tb.trace, null, 0));
@ -587,12 +582,11 @@ public class DebuggerDisassemblyTest extends AbstractGhidraHeadedDebuggerGUITest
@Test @Test
public void testFixedAssembleActionsGuestArm() throws Throwable { public void testFixedAssembleActionsGuestArm() throws Throwable {
// Assemble actions will think read-only otherwise // Assemble actions will think read-only otherwise
DebuggerStateEditingService editingService = DebuggerControlService controlService = addPlugin(tool, DebuggerControlServicePlugin.class);
addPlugin(tool, DebuggerStateEditingServicePlugin.class);
TraceObjectThread thread = createPolyglotTrace("armv8le", 0x00400000, () -> tb.buf()); TraceObjectThread thread = createPolyglotTrace("armv8le", 0x00400000, () -> tb.buf());
Address start = tb.addr(0x00400000); Address start = tb.addr(0x00400000);
editingService.setCurrentMode(tb.trace, StateEditingMode.RW_TRACE); controlService.setCurrentMode(tb.trace, ControlMode.RW_TRACE);
// Ensure the mapper is added to the trace // Ensure the mapper is added to the trace
assertNotNull(platformService.getMapper(tb.trace, thread.getObject(), 0)); assertNotNull(platformService.getMapper(tb.trace, thread.getObject(), 0));
@ -607,12 +601,11 @@ public class DebuggerDisassemblyTest extends AbstractGhidraHeadedDebuggerGUITest
@Test @Test
public void testFixedAssembleActionsGuestThumb() throws Throwable { public void testFixedAssembleActionsGuestThumb() throws Throwable {
// Assemble actions will think read-only otherwise // Assemble actions will think read-only otherwise
DebuggerStateEditingService editingService = DebuggerControlService controlService = addPlugin(tool, DebuggerControlServicePlugin.class);
addPlugin(tool, DebuggerStateEditingServicePlugin.class);
TraceObjectThread thread = createPolyglotTrace("armv8le", 0x00400000, () -> tb.buf()); TraceObjectThread thread = createPolyglotTrace("armv8le", 0x00400000, () -> tb.buf());
Address start = tb.addr(0x00400000); Address start = tb.addr(0x00400000);
editingService.setCurrentMode(tb.trace, StateEditingMode.RW_TRACE); controlService.setCurrentMode(tb.trace, ControlMode.RW_TRACE);
// Ensure the mapper is added to the trace // Ensure the mapper is added to the trace
assertNotNull(platformService.getMapper(tb.trace, thread.getObject(), 0)); assertNotNull(platformService.getMapper(tb.trace, thread.getObject(), 0));

View file

@ -34,7 +34,7 @@ import ghidra.app.plugin.core.debug.gui.AbstractGhidraHeadedDebuggerGUITest;
import ghidra.app.plugin.core.debug.gui.DebuggerResources.*; import ghidra.app.plugin.core.debug.gui.DebuggerResources.*;
import ghidra.app.plugin.core.debug.gui.breakpoint.DebuggerBreakpointsProvider.LogicalBreakpointTableModel; import ghidra.app.plugin.core.debug.gui.breakpoint.DebuggerBreakpointsProvider.LogicalBreakpointTableModel;
import ghidra.app.plugin.core.debug.gui.console.DebuggerConsolePlugin; import ghidra.app.plugin.core.debug.gui.console.DebuggerConsolePlugin;
import ghidra.app.plugin.core.debug.service.editing.DebuggerStateEditingServicePlugin; import ghidra.app.plugin.core.debug.service.control.DebuggerControlServicePlugin;
import ghidra.app.plugin.core.debug.service.emulation.ProgramEmulationUtils; import ghidra.app.plugin.core.debug.service.emulation.ProgramEmulationUtils;
import ghidra.app.plugin.core.debug.service.modules.DebuggerStaticMappingUtils; import ghidra.app.plugin.core.debug.service.modules.DebuggerStaticMappingUtils;
import ghidra.app.services.*; import ghidra.app.services.*;
@ -689,7 +689,7 @@ public class DebuggerBreakpointsProviderTest extends AbstractGhidraHeadedDebugge
@Test @Test
public void testEmuBreakpointState() throws Throwable { public void testEmuBreakpointState() throws Throwable {
addPlugin(tool, DebuggerStateEditingServicePlugin.class); addPlugin(tool, DebuggerControlServicePlugin.class);
createProgram(); createProgram();
intoProject(program); intoProject(program);
@ -733,8 +733,8 @@ public class DebuggerBreakpointsProviderTest extends AbstractGhidraHeadedDebugge
@Test @Test
public void testTablesAndStatesWhenhModeChanges() throws Throwable { public void testTablesAndStatesWhenhModeChanges() throws Throwable {
DebuggerStateEditingService editingService = DebuggerControlService controlService =
addPlugin(tool, DebuggerStateEditingServicePlugin.class); addPlugin(tool, DebuggerControlServicePlugin.class);
createTestModel(); createTestModel();
mb.createTestProcessesAndThreads(); mb.createTestProcessesAndThreads();
@ -764,7 +764,7 @@ public class DebuggerBreakpointsProviderTest extends AbstractGhidraHeadedDebugge
return newRow; return newRow;
}); });
editingService.setCurrentMode(trace, StateEditingMode.RW_EMULATOR); controlService.setCurrentMode(trace, ControlMode.RW_EMULATOR);
lbRow1.setEnabled(true); lbRow1.setEnabled(true);
TraceBreakpoint emuBpt = waitForValue( TraceBreakpoint emuBpt = waitForValue(
() -> Unique.assertAtMostOne(trace.getBreakpointManager().getAllBreakpoints())); () -> Unique.assertAtMostOne(trace.getBreakpointManager().getAllBreakpoints()));
@ -781,12 +781,12 @@ public class DebuggerBreakpointsProviderTest extends AbstractGhidraHeadedDebugge
}); });
for (int i = 0; i < 3; i++) { for (int i = 0; i < 3; i++) {
editingService.setCurrentMode(trace, StateEditingMode.RO_TARGET); controlService.setCurrentMode(trace, ControlMode.RO_TARGET);
waitOn(breakpointService.changesSettled()); waitOn(breakpointService.changesSettled());
waitForSwing(); waitForSwing();
assertEquals(0, breakpointsProvider.locationTableModel.getModelData().size()); assertEquals(0, breakpointsProvider.locationTableModel.getModelData().size());
editingService.setCurrentMode(trace, StateEditingMode.RW_EMULATOR); controlService.setCurrentMode(trace, ControlMode.RW_EMULATOR);
waitOn(breakpointService.changesSettled()); waitOn(breakpointService.changesSettled());
waitForSwing(); waitForSwing();
assertEquals(1, breakpointsProvider.locationTableModel.getModelData().size()); assertEquals(1, breakpointsProvider.locationTableModel.getModelData().size());

View file

@ -43,7 +43,7 @@ import ghidra.app.plugin.core.debug.gui.AbstractGhidraHeadedDebuggerGUITest;
import ghidra.app.plugin.core.debug.gui.listing.DebuggerListingPlugin; import ghidra.app.plugin.core.debug.gui.listing.DebuggerListingPlugin;
import ghidra.app.plugin.core.debug.mapping.DebuggerTargetTraceMapper; import ghidra.app.plugin.core.debug.mapping.DebuggerTargetTraceMapper;
import ghidra.app.plugin.core.debug.mapping.ObjectBasedDebuggerTargetTraceMapper; import ghidra.app.plugin.core.debug.mapping.ObjectBasedDebuggerTargetTraceMapper;
import ghidra.app.plugin.core.debug.service.editing.DebuggerStateEditingServicePlugin; import ghidra.app.plugin.core.debug.service.control.DebuggerControlServicePlugin;
import ghidra.app.plugin.core.debug.service.emulation.DebuggerEmulationServicePlugin; import ghidra.app.plugin.core.debug.service.emulation.DebuggerEmulationServicePlugin;
import ghidra.app.services.*; import ghidra.app.services.*;
import ghidra.app.services.DebuggerEmulationService.CachedEmulator; import ghidra.app.services.DebuggerEmulationService.CachedEmulator;
@ -71,15 +71,14 @@ import ghidra.util.database.UndoableTransaction;
* Tests for target control and state editing * Tests for target control and state editing
* *
* <p> * <p>
* In these and other machine-state-editing integration tests, we use * In these and other control service integration tests, we use {@link ControlMode#RW_EMULATOR} as a
* {@link StateEditingMode#RW_EMULATOR} as a stand-in for any mode. We also use * stand-in for any mode. We also use {@link ControlMode#RO_TARGET} just to verify the mode is
* {@link StateEditingMode#RO_TARGET} just to verify the mode is heeded. Other modes may be tested * heeded. Other modes may be tested if bugs crop up in various combinations.
* if bugs crop up in various combinations.
*/ */
public class DebuggerControlPluginTest extends AbstractGhidraHeadedDebuggerGUITest { public class DebuggerControlPluginTest extends AbstractGhidraHeadedDebuggerGUITest {
DebuggerListingPlugin listingPlugin; DebuggerListingPlugin listingPlugin;
DebuggerStateEditingService editingService; DebuggerControlService controlService;
DebuggerEmulationService emulationService; DebuggerEmulationService emulationService;
DebuggerControlPlugin controlPlugin; DebuggerControlPlugin controlPlugin;
@ -88,7 +87,7 @@ public class DebuggerControlPluginTest extends AbstractGhidraHeadedDebuggerGUITe
@Before @Before
public void setUpControlTest() throws Exception { public void setUpControlTest() throws Exception {
listingPlugin = addPlugin(tool, DebuggerListingPlugin.class); listingPlugin = addPlugin(tool, DebuggerListingPlugin.class);
editingService = addPlugin(tool, DebuggerStateEditingServicePlugin.class); controlService = addPlugin(tool, DebuggerControlServicePlugin.class);
emulationService = addPlugin(tool, DebuggerEmulationServicePlugin.class); emulationService = addPlugin(tool, DebuggerEmulationServicePlugin.class);
controlPlugin = addPlugin(tool, DebuggerControlPlugin.class); controlPlugin = addPlugin(tool, DebuggerControlPlugin.class);
@ -293,7 +292,7 @@ public class DebuggerControlPluginTest extends AbstractGhidraHeadedDebuggerGUITe
@Test @Test
public void testEmulateResumeAction() throws Throwable { public void testEmulateResumeAction() throws Throwable {
TraceThread thread = createToyLoopTrace(); TraceThread thread = createToyLoopTrace();
editingService.setCurrentMode(tb.trace, StateEditingMode.RW_EMULATOR); controlService.setCurrentMode(tb.trace, ControlMode.RW_EMULATOR);
traceManager.activateThread(thread); traceManager.activateThread(thread);
waitForSwing(); waitForSwing();
@ -310,7 +309,7 @@ public class DebuggerControlPluginTest extends AbstractGhidraHeadedDebuggerGUITe
@Test @Test
public void testEmulateInterruptAction() throws Throwable { public void testEmulateInterruptAction() throws Throwable {
TraceThread thread = createToyLoopTrace(); TraceThread thread = createToyLoopTrace();
editingService.setCurrentMode(tb.trace, StateEditingMode.RW_EMULATOR); controlService.setCurrentMode(tb.trace, ControlMode.RW_EMULATOR);
traceManager.activateThread(thread); traceManager.activateThread(thread);
waitForSwing(); waitForSwing();
@ -332,7 +331,7 @@ public class DebuggerControlPluginTest extends AbstractGhidraHeadedDebuggerGUITe
@Test @Test
public void testEmulateStepBackAction() throws Throwable { public void testEmulateStepBackAction() throws Throwable {
TraceThread thread = createToyLoopTrace(); TraceThread thread = createToyLoopTrace();
editingService.setCurrentMode(tb.trace, StateEditingMode.RW_EMULATOR); controlService.setCurrentMode(tb.trace, ControlMode.RW_EMULATOR);
traceManager.activateThread(thread); traceManager.activateThread(thread);
waitForSwing(); waitForSwing();
@ -351,7 +350,7 @@ public class DebuggerControlPluginTest extends AbstractGhidraHeadedDebuggerGUITe
@Test @Test
public void testEmulateStepIntoAction() throws Throwable { public void testEmulateStepIntoAction() throws Throwable {
TraceThread thread = createToyLoopTrace(); TraceThread thread = createToyLoopTrace();
editingService.setCurrentMode(tb.trace, StateEditingMode.RW_EMULATOR); controlService.setCurrentMode(tb.trace, ControlMode.RW_EMULATOR);
traceManager.activateThread(thread); traceManager.activateThread(thread);
waitForSwing(); waitForSwing();
@ -364,7 +363,7 @@ public class DebuggerControlPluginTest extends AbstractGhidraHeadedDebuggerGUITe
@Test @Test
public void testEmulateSkipOverAction() throws Throwable { public void testEmulateSkipOverAction() throws Throwable {
TraceThread thread = createToyLoopTrace(); TraceThread thread = createToyLoopTrace();
editingService.setCurrentMode(tb.trace, StateEditingMode.RW_EMULATOR); controlService.setCurrentMode(tb.trace, ControlMode.RW_EMULATOR);
traceManager.activateThread(thread); traceManager.activateThread(thread);
waitForSwing(); waitForSwing();
@ -385,7 +384,7 @@ public class DebuggerControlPluginTest extends AbstractGhidraHeadedDebuggerGUITe
@Test @Test
public void testTraceSnapBackwardAction() throws Throwable { public void testTraceSnapBackwardAction() throws Throwable {
create2SnapTrace(); create2SnapTrace();
editingService.setCurrentMode(tb.trace, StateEditingMode.RW_TRACE); controlService.setCurrentMode(tb.trace, ControlMode.RW_TRACE);
traceManager.activateTrace(tb.trace); traceManager.activateTrace(tb.trace);
waitForSwing(); waitForSwing();
@ -402,7 +401,7 @@ public class DebuggerControlPluginTest extends AbstractGhidraHeadedDebuggerGUITe
@Test @Test
public void testTraceSnapForwardAction() throws Throwable { public void testTraceSnapForwardAction() throws Throwable {
create2SnapTrace(); create2SnapTrace();
editingService.setCurrentMode(tb.trace, StateEditingMode.RW_TRACE); controlService.setCurrentMode(tb.trace, ControlMode.RW_TRACE);
traceManager.activateTrace(tb.trace); traceManager.activateTrace(tb.trace);
waitForSwing(); waitForSwing();
@ -418,7 +417,7 @@ public class DebuggerControlPluginTest extends AbstractGhidraHeadedDebuggerGUITe
DebuggerDisassemblerPlugin disassemblerPlugin = DebuggerDisassemblerPlugin disassemblerPlugin =
addPlugin(tool, DebuggerDisassemblerPlugin.class); addPlugin(tool, DebuggerDisassemblerPlugin.class);
assertFalse(controlPlugin.actionEditMode.isEnabled()); assertFalse(controlPlugin.actionControlMode.isEnabled());
createAndOpenTrace(); createAndOpenTrace();
TraceVariableSnapProgramView view = tb.trace.getProgramView(); TraceVariableSnapProgramView view = tb.trace.getProgramView();
@ -440,17 +439,17 @@ public class DebuggerControlPluginTest extends AbstractGhidraHeadedDebuggerGUITe
() -> listingProvider.goTo(view, new ProgramLocation(view, tb.addr(0x00400123)))); () -> listingProvider.goTo(view, new ProgramLocation(view, tb.addr(0x00400123))));
waitForSwing(); waitForSwing();
assertTrue(controlPlugin.actionEditMode.isEnabled()); assertTrue(controlPlugin.actionControlMode.isEnabled());
runSwing(() -> controlPlugin.actionEditMode runSwing(() -> controlPlugin.actionControlMode
.setCurrentActionStateByUserData(StateEditingMode.RO_TARGET)); .setCurrentActionStateByUserData(ControlMode.RO_TARGET));
assertEquals(StateEditingMode.RO_TARGET, editingService.getCurrentMode(tb.trace)); assertEquals(ControlMode.RO_TARGET, controlService.getCurrentMode(tb.trace));
assertFalse( assertFalse(
helper.patchInstructionAction.isAddToPopup(listingProvider.getActionContext(null))); helper.patchInstructionAction.isAddToPopup(listingProvider.getActionContext(null)));
runSwing(() -> controlPlugin.actionEditMode runSwing(() -> controlPlugin.actionControlMode
.setCurrentActionStateByUserData(StateEditingMode.RW_EMULATOR)); .setCurrentActionStateByUserData(ControlMode.RW_EMULATOR));
assertEquals(StateEditingMode.RW_EMULATOR, editingService.getCurrentMode(tb.trace)); assertEquals(ControlMode.RW_EMULATOR, controlService.getCurrentMode(tb.trace));
assertTrue( assertTrue(
helper.patchInstructionAction.isAddToPopup(listingProvider.getActionContext(null))); helper.patchInstructionAction.isAddToPopup(listingProvider.getActionContext(null)));
@ -469,7 +468,7 @@ public class DebuggerControlPluginTest extends AbstractGhidraHeadedDebuggerGUITe
public void testPatchDataActionInDynamicListingEmu() throws Throwable { public void testPatchDataActionInDynamicListingEmu() throws Throwable {
AssemblerPlugin assemblerPlugin = addPlugin(tool, AssemblerPlugin.class); AssemblerPlugin assemblerPlugin = addPlugin(tool, AssemblerPlugin.class);
assertFalse(controlPlugin.actionEditMode.isEnabled()); assertFalse(controlPlugin.actionControlMode.isEnabled());
createAndOpenTrace(); createAndOpenTrace();
TraceVariableSnapProgramView view = tb.trace.getProgramView(); TraceVariableSnapProgramView view = tb.trace.getProgramView();
@ -490,16 +489,16 @@ public class DebuggerControlPluginTest extends AbstractGhidraHeadedDebuggerGUITe
traceManager.activateTrace(tb.trace); traceManager.activateTrace(tb.trace);
waitForSwing(); waitForSwing();
assertTrue(controlPlugin.actionEditMode.isEnabled()); assertTrue(controlPlugin.actionControlMode.isEnabled());
runSwing(() -> controlPlugin.actionEditMode runSwing(() -> controlPlugin.actionControlMode
.setCurrentActionStateByUserData(StateEditingMode.RO_TARGET)); .setCurrentActionStateByUserData(ControlMode.RO_TARGET));
assertEquals(StateEditingMode.RO_TARGET, editingService.getCurrentMode(tb.trace)); assertEquals(ControlMode.RO_TARGET, controlService.getCurrentMode(tb.trace));
assertFalse(helper.patchDataAction.isAddToPopup(listingProvider.getActionContext(null))); assertFalse(helper.patchDataAction.isAddToPopup(listingProvider.getActionContext(null)));
runSwing(() -> controlPlugin.actionEditMode runSwing(() -> controlPlugin.actionControlMode
.setCurrentActionStateByUserData(StateEditingMode.RW_EMULATOR)); .setCurrentActionStateByUserData(ControlMode.RW_EMULATOR));
assertEquals(StateEditingMode.RW_EMULATOR, editingService.getCurrentMode(tb.trace)); assertEquals(ControlMode.RW_EMULATOR, controlService.getCurrentMode(tb.trace));
goTo(listingProvider.getListingPanel(), new ProgramLocation(view, tb.addr(0x00400123))); goTo(listingProvider.getListingPanel(), new ProgramLocation(view, tb.addr(0x00400123)));
assertTrue(helper.patchDataAction.isAddToPopup(listingProvider.getActionContext(null))); assertTrue(helper.patchDataAction.isAddToPopup(listingProvider.getActionContext(null)));
@ -525,7 +524,7 @@ public class DebuggerControlPluginTest extends AbstractGhidraHeadedDebuggerGUITe
CodeViewerProvider listingProvider = listingPlugin.getProvider(); CodeViewerProvider listingProvider = listingPlugin.getProvider();
DockingActionIf pasteAction = getLocalAction(listingProvider, "Paste"); DockingActionIf pasteAction = getLocalAction(listingProvider, "Paste");
assertFalse(controlPlugin.actionEditMode.isEnabled()); assertFalse(controlPlugin.actionControlMode.isEnabled());
createAndOpenTrace(); createAndOpenTrace();
TraceVariableSnapProgramView view = tb.trace.getProgramView(); TraceVariableSnapProgramView view = tb.trace.getProgramView();
@ -541,18 +540,18 @@ public class DebuggerControlPluginTest extends AbstractGhidraHeadedDebuggerGUITe
ActionContext ctx; ActionContext ctx;
assertTrue(controlPlugin.actionEditMode.isEnabled()); assertTrue(controlPlugin.actionControlMode.isEnabled());
runSwing(() -> controlPlugin.actionEditMode runSwing(() -> controlPlugin.actionControlMode
.setCurrentActionStateByUserData(StateEditingMode.RO_TARGET)); .setCurrentActionStateByUserData(ControlMode.RO_TARGET));
assertEquals(StateEditingMode.RO_TARGET, editingService.getCurrentMode(tb.trace)); assertEquals(ControlMode.RO_TARGET, controlService.getCurrentMode(tb.trace));
ctx = listingProvider.getActionContext(null); ctx = listingProvider.getActionContext(null);
assertTrue(pasteAction.isAddToPopup(ctx)); assertTrue(pasteAction.isAddToPopup(ctx));
assertFalse(pasteAction.isEnabledForContext(ctx)); assertFalse(pasteAction.isEnabledForContext(ctx));
runSwing(() -> controlPlugin.actionEditMode runSwing(() -> controlPlugin.actionControlMode
.setCurrentActionStateByUserData(StateEditingMode.RW_EMULATOR)); .setCurrentActionStateByUserData(ControlMode.RW_EMULATOR));
assertEquals(StateEditingMode.RW_EMULATOR, editingService.getCurrentMode(tb.trace)); assertEquals(ControlMode.RW_EMULATOR, controlService.getCurrentMode(tb.trace));
goTo(listingPlugin.getListingPanel(), new ProgramLocation(view, tb.addr(0x00400123))); goTo(listingPlugin.getListingPanel(), new ProgramLocation(view, tb.addr(0x00400123)));
ctx = listingProvider.getActionContext(null); ctx = listingProvider.getActionContext(null);

View file

@ -48,7 +48,7 @@ import ghidra.app.plugin.core.debug.gui.DebuggerResources;
import ghidra.app.plugin.core.debug.gui.DebuggerResources.FollowsCurrentThreadAction; import ghidra.app.plugin.core.debug.gui.DebuggerResources.FollowsCurrentThreadAction;
import ghidra.app.plugin.core.debug.gui.action.*; import ghidra.app.plugin.core.debug.gui.action.*;
import ghidra.app.plugin.core.debug.gui.listing.DebuggerListingPlugin; import ghidra.app.plugin.core.debug.gui.listing.DebuggerListingPlugin;
import ghidra.app.plugin.core.debug.service.editing.DebuggerStateEditingServicePlugin; import ghidra.app.plugin.core.debug.service.control.DebuggerControlServicePlugin;
import ghidra.app.services.*; import ghidra.app.services.*;
import ghidra.async.SwingExecutorService; import ghidra.async.SwingExecutorService;
import ghidra.program.model.address.*; import ghidra.program.model.address.*;
@ -74,7 +74,7 @@ public class DebuggerMemoryBytesProviderTest extends AbstractGhidraHeadedDebugge
protected DebuggerMemoryBytesPlugin memBytesPlugin; protected DebuggerMemoryBytesPlugin memBytesPlugin;
protected DebuggerMemoryBytesProvider memBytesProvider; protected DebuggerMemoryBytesProvider memBytesProvider;
protected DebuggerStateEditingService editingService; protected DebuggerControlService editingService;
@Before @Before
public void setUpMemoryBytesProviderTest() throws Exception { public void setUpMemoryBytesProviderTest() throws Exception {
@ -82,7 +82,7 @@ public class DebuggerMemoryBytesProviderTest extends AbstractGhidraHeadedDebugge
memBytesProvider = waitForComponentProvider(DebuggerMemoryBytesProvider.class); memBytesProvider = waitForComponentProvider(DebuggerMemoryBytesProvider.class);
memBytesProvider.setVisible(true); memBytesProvider.setVisible(true);
editingService = addPlugin(tool, DebuggerStateEditingServicePlugin.class); editingService = addPlugin(tool, DebuggerControlServicePlugin.class);
} }
protected void goToDyn(Address address) { protected void goToDyn(Address address) {
@ -1100,7 +1100,7 @@ public class DebuggerMemoryBytesProviderTest extends AbstractGhidraHeadedDebugge
createTargetTraceMapper(mb.testProcess1)); createTargetTraceMapper(mb.testProcess1));
Trace trace = recorder.getTrace(); Trace trace = recorder.getTrace();
editingService.setCurrentMode(trace, StateEditingMode.RW_TARGET); editingService.setCurrentMode(trace, ControlMode.RW_TARGET);
DockingActionIf actionEdit = getAction(memBytesPlugin, "Enable/Disable Byteviewer Editing"); DockingActionIf actionEdit = getAction(memBytesPlugin, "Enable/Disable Byteviewer Editing");
mb.testProcess1.addRegion("exe:.text", mb.rng(0x55550000, 0x5555ffff), "rx"); mb.testProcess1.addRegion("exe:.text", mb.rng(0x55550000, 0x5555ffff), "rx");
@ -1132,7 +1132,7 @@ public class DebuggerMemoryBytesProviderTest extends AbstractGhidraHeadedDebugge
createTargetTraceMapper(mb.testProcess1)); createTargetTraceMapper(mb.testProcess1));
Trace trace = recorder.getTrace(); Trace trace = recorder.getTrace();
editingService.setCurrentMode(trace, StateEditingMode.RW_TRACE); editingService.setCurrentMode(trace, ControlMode.RW_TRACE);
DockingActionIf actionEdit = getAction(memBytesPlugin, "Enable/Disable Byteviewer Editing"); DockingActionIf actionEdit = getAction(memBytesPlugin, "Enable/Disable Byteviewer Editing");
mb.testProcess1.addRegion("exe:.text", mb.rng(0x55550000, 0x5555ffff), "rx"); mb.testProcess1.addRegion("exe:.text", mb.rng(0x55550000, 0x5555ffff), "rx");
@ -1179,7 +1179,7 @@ public class DebuggerMemoryBytesProviderTest extends AbstractGhidraHeadedDebugge
createTargetTraceMapper(mb.testProcess1)); createTargetTraceMapper(mb.testProcess1));
Trace trace = recorder.getTrace(); Trace trace = recorder.getTrace();
editingService.setCurrentMode(trace, StateEditingMode.RW_TARGET); editingService.setCurrentMode(trace, ControlMode.RW_TARGET);
mb.testProcess1.addRegion("exe:.text", mb.rng(0x55550000, 0x5555ffff), "rx"); mb.testProcess1.addRegion("exe:.text", mb.rng(0x55550000, 0x5555ffff), "rx");
waitFor(() -> !trace.getMemoryManager().getAllRegions().isEmpty()); waitFor(() -> !trace.getMemoryManager().getAllRegions().isEmpty());

View file

@ -28,7 +28,7 @@ import generic.test.category.NightlyCategory;
import ghidra.app.plugin.core.debug.gui.listing.DebuggerListingPlugin; import ghidra.app.plugin.core.debug.gui.listing.DebuggerListingPlugin;
import ghidra.app.plugin.core.debug.mapping.DebuggerTargetTraceMapper; import ghidra.app.plugin.core.debug.mapping.DebuggerTargetTraceMapper;
import ghidra.app.plugin.core.debug.mapping.ObjectBasedDebuggerTargetTraceMapper; import ghidra.app.plugin.core.debug.mapping.ObjectBasedDebuggerTargetTraceMapper;
import ghidra.app.plugin.core.debug.service.editing.DebuggerStateEditingServicePlugin; import ghidra.app.plugin.core.debug.service.control.DebuggerControlServicePlugin;
import ghidra.app.plugin.core.debug.service.model.DebuggerModelServicePlugin; import ghidra.app.plugin.core.debug.service.model.DebuggerModelServicePlugin;
import ghidra.app.services.TraceRecorder; import ghidra.app.services.TraceRecorder;
import ghidra.dbg.target.TargetObject; import ghidra.dbg.target.TargetObject;
@ -66,7 +66,7 @@ public class DebuggerRegistersProviderGuestTest extends DebuggerRegistersProvide
registersPlugin = addPlugin(tool, DebuggerRegistersPlugin.class); registersPlugin = addPlugin(tool, DebuggerRegistersPlugin.class);
registersProvider = waitForComponentProvider(DebuggerRegistersProvider.class); registersProvider = waitForComponentProvider(DebuggerRegistersProvider.class);
listingPlugin = addPlugin(tool, DebuggerListingPlugin.class); listingPlugin = addPlugin(tool, DebuggerListingPlugin.class);
editingService = addPlugin(tool, DebuggerStateEditingServicePlugin.class); editingService = addPlugin(tool, DebuggerControlServicePlugin.class);
createTrace(); createTrace();
createToyPlatform(); createToyPlatform();

View file

@ -32,7 +32,7 @@ import ghidra.app.plugin.core.debug.gui.action.NoneLocationTrackingSpec;
import ghidra.app.plugin.core.debug.gui.listing.DebuggerListingPlugin; import ghidra.app.plugin.core.debug.gui.listing.DebuggerListingPlugin;
import ghidra.app.plugin.core.debug.gui.register.DebuggerRegistersProvider.RegisterDataSettingsDialog; import ghidra.app.plugin.core.debug.gui.register.DebuggerRegistersProvider.RegisterDataSettingsDialog;
import ghidra.app.plugin.core.debug.gui.register.DebuggerRegistersProvider.RegisterTableColumns; import ghidra.app.plugin.core.debug.gui.register.DebuggerRegistersProvider.RegisterTableColumns;
import ghidra.app.plugin.core.debug.service.editing.DebuggerStateEditingServicePlugin; import ghidra.app.plugin.core.debug.service.control.DebuggerControlServicePlugin;
import ghidra.app.services.*; import ghidra.app.services.*;
import ghidra.docking.settings.FormatSettingsDefinition; import ghidra.docking.settings.FormatSettingsDefinition;
import ghidra.docking.settings.Settings; import ghidra.docking.settings.Settings;
@ -57,7 +57,7 @@ public class DebuggerRegistersProviderTest extends AbstractGhidraHeadedDebuggerG
protected DebuggerRegistersPlugin registersPlugin; protected DebuggerRegistersPlugin registersPlugin;
protected DebuggerRegistersProvider registersProvider; protected DebuggerRegistersProvider registersProvider;
protected DebuggerListingPlugin listingPlugin; protected DebuggerListingPlugin listingPlugin;
protected DebuggerStateEditingService editingService; protected DebuggerControlService editingService;
protected Register r0; protected Register r0;
protected Register pc; protected Register pc;
@ -78,7 +78,7 @@ public class DebuggerRegistersProviderTest extends AbstractGhidraHeadedDebuggerG
registersPlugin = addPlugin(tool, DebuggerRegistersPlugin.class); registersPlugin = addPlugin(tool, DebuggerRegistersPlugin.class);
registersProvider = waitForComponentProvider(DebuggerRegistersProvider.class); registersProvider = waitForComponentProvider(DebuggerRegistersProvider.class);
listingPlugin = addPlugin(tool, DebuggerListingPlugin.class); listingPlugin = addPlugin(tool, DebuggerListingPlugin.class);
editingService = addPlugin(tool, DebuggerStateEditingServicePlugin.class); editingService = addPlugin(tool, DebuggerControlServicePlugin.class);
createTrace(); createTrace();
r0 = tb.language.getRegister("r0"); r0 = tb.language.getRegister("r0");
@ -383,7 +383,7 @@ public class DebuggerRegistersProviderTest extends AbstractGhidraHeadedDebuggerG
activateThread(thread); activateThread(thread);
waitForSwing(); waitForSwing();
editingService.setCurrentMode(tb.trace, StateEditingMode.RW_EMULATOR); editingService.setCurrentMode(tb.trace, ControlMode.RW_EMULATOR);
assertTrue(registersProvider.actionEnableEdits.isEnabled()); assertTrue(registersProvider.actionEnableEdits.isEnabled());
performAction(registersProvider.actionEnableEdits); performAction(registersProvider.actionEnableEdits);
@ -421,7 +421,7 @@ public class DebuggerRegistersProviderTest extends AbstractGhidraHeadedDebuggerG
activateThread(thread); activateThread(thread);
waitForSwing(); waitForSwing();
editingService.setCurrentMode(tb.trace, StateEditingMode.RW_EMULATOR); editingService.setCurrentMode(tb.trace, ControlMode.RW_EMULATOR);
assertTrue(registersProvider.actionEnableEdits.isEnabled()); assertTrue(registersProvider.actionEnableEdits.isEnabled());
performAction(registersProvider.actionEnableEdits); performAction(registersProvider.actionEnableEdits);

View file

@ -32,7 +32,7 @@ import ghidra.app.plugin.core.debug.gui.listing.DebuggerListingPlugin;
import ghidra.app.plugin.core.debug.gui.listing.DebuggerListingProvider; import ghidra.app.plugin.core.debug.gui.listing.DebuggerListingProvider;
import ghidra.app.plugin.core.debug.gui.register.*; import ghidra.app.plugin.core.debug.gui.register.*;
import ghidra.app.plugin.core.debug.gui.watch.DebuggerWatchesProvider.WatchDataSettingsDialog; import ghidra.app.plugin.core.debug.gui.watch.DebuggerWatchesProvider.WatchDataSettingsDialog;
import ghidra.app.plugin.core.debug.service.editing.DebuggerStateEditingServicePlugin; import ghidra.app.plugin.core.debug.service.control.DebuggerControlServicePlugin;
import ghidra.app.plugin.core.debug.service.modules.DebuggerStaticMappingServicePlugin; import ghidra.app.plugin.core.debug.service.modules.DebuggerStaticMappingServicePlugin;
import ghidra.app.services.*; import ghidra.app.services.*;
import ghidra.dbg.model.TestTargetRegisterBankInThread; import ghidra.dbg.model.TestTargetRegisterBankInThread;
@ -71,7 +71,7 @@ public class DebuggerWatchesProviderTest extends AbstractGhidraHeadedDebuggerGUI
protected DebuggerListingProvider listingProvider; protected DebuggerListingProvider listingProvider;
protected DebuggerStaticMappingServicePlugin mappingService; protected DebuggerStaticMappingServicePlugin mappingService;
protected CodeViewerProvider codeViewerProvider; protected CodeViewerProvider codeViewerProvider;
protected DebuggerStateEditingService editingService; protected DebuggerControlService editingService;
protected Register r0; protected Register r0;
protected Register r1; protected Register r1;
@ -91,7 +91,7 @@ public class DebuggerWatchesProviderTest extends AbstractGhidraHeadedDebuggerGUI
listingPlugin = addPlugin(tool, DebuggerListingPlugin.class); listingPlugin = addPlugin(tool, DebuggerListingPlugin.class);
listingProvider = waitForComponentProvider(DebuggerListingProvider.class); listingProvider = waitForComponentProvider(DebuggerListingProvider.class);
mappingService = addPlugin(tool, DebuggerStaticMappingServicePlugin.class); mappingService = addPlugin(tool, DebuggerStaticMappingServicePlugin.class);
editingService = addPlugin(tool, DebuggerStateEditingServicePlugin.class); editingService = addPlugin(tool, DebuggerControlServicePlugin.class);
createTrace(); createTrace();
r0 = tb.language.getRegister("r0"); r0 = tb.language.getRegister("r0");
@ -350,7 +350,7 @@ public class DebuggerWatchesProviderTest extends AbstractGhidraHeadedDebuggerGUI
assertFalse(row.isRawValueEditable()); assertFalse(row.isRawValueEditable());
traceManager.openTrace(tb.trace); traceManager.openTrace(tb.trace);
traceManager.activateThread(thread); traceManager.activateThread(thread);
editingService.setCurrentMode(tb.trace, StateEditingMode.RW_EMULATOR); editingService.setCurrentMode(tb.trace, ControlMode.RW_EMULATOR);
waitForWatches(); waitForWatches();
assertNoErr(row); assertNoErr(row);
@ -384,7 +384,7 @@ public class DebuggerWatchesProviderTest extends AbstractGhidraHeadedDebuggerGUI
traceManager.openTrace(tb.trace); traceManager.openTrace(tb.trace);
traceManager.activateThread(thread); traceManager.activateThread(thread);
editingService.setCurrentMode(tb.trace, StateEditingMode.RW_EMULATOR); editingService.setCurrentMode(tb.trace, ControlMode.RW_EMULATOR);
waitForWatches(); waitForWatches();
performAction(watchesProvider.actionEnableEdits); performAction(watchesProvider.actionEnableEdits);
@ -547,7 +547,7 @@ public class DebuggerWatchesProviderTest extends AbstractGhidraHeadedDebuggerGUI
traceManager.openTrace(trace); traceManager.openTrace(trace);
traceManager.activateThread(thread); traceManager.activateThread(thread);
editingService.setCurrentMode(trace, StateEditingMode.RW_TARGET); editingService.setCurrentMode(trace, ControlMode.RW_TARGET);
waitForSwing(); waitForSwing();
performAction(watchesProvider.actionAdd); performAction(watchesProvider.actionAdd);

View file

@ -25,7 +25,7 @@ import org.junit.*;
import generic.Unique; import generic.Unique;
import ghidra.app.plugin.core.debug.gui.AbstractGhidraHeadedDebuggerGUITest; import ghidra.app.plugin.core.debug.gui.AbstractGhidraHeadedDebuggerGUITest;
import ghidra.app.plugin.core.debug.service.editing.DebuggerStateEditingServicePlugin; import ghidra.app.plugin.core.debug.service.control.DebuggerControlServicePlugin;
import ghidra.app.plugin.core.debug.service.modules.DebuggerStaticMappingUtils; import ghidra.app.plugin.core.debug.service.modules.DebuggerStaticMappingUtils;
import ghidra.app.services.*; import ghidra.app.services.*;
import ghidra.app.services.LogicalBreakpoint.State; import ghidra.app.services.LogicalBreakpoint.State;
@ -1619,15 +1619,15 @@ public class DebuggerLogicalBreakpointServiceTest extends AbstractGhidraHeadedDe
@Test @Test
public void testAddTraceBreakpointSetSleighThenMapThenSaveToProgramCopiesSleigh() public void testAddTraceBreakpointSetSleighThenMapThenSaveToProgramCopiesSleigh()
throws Throwable { throws Throwable {
DebuggerStateEditingService editingService = DebuggerControlService editingService =
addPlugin(tool, DebuggerStateEditingServicePlugin.class); addPlugin(tool, DebuggerControlServicePlugin.class);
// TODO: What if already mapped? // TODO: What if already mapped?
// Not sure I care about tb.setEmuSleigh() out of band // Not sure I care about tb.setEmuSleigh() out of band
createTrace(); createTrace();
traceManager.openTrace(tb.trace); traceManager.openTrace(tb.trace);
editingService.setCurrentMode(tb.trace, StateEditingMode.RW_EMULATOR); editingService.setCurrentMode(tb.trace, ControlMode.RW_EMULATOR);
createProgramFromTrace(); createProgramFromTrace();
intoProject(program); intoProject(program);
programManager.openProgram(program); programManager.openProgram(program);

View file

@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package ghidra.app.plugin.core.debug.service.editing; package ghidra.app.plugin.core.debug.service.control;
import java.io.IOException; import java.io.IOException;
import java.util.Set; import java.util.Set;
@ -30,7 +30,7 @@ import ghidra.trace.model.guest.TraceGuestPlatform;
import ghidra.trace.model.guest.TracePlatform; import ghidra.trace.model.guest.TracePlatform;
import ghidra.util.database.UndoableTransaction; import ghidra.util.database.UndoableTransaction;
public class DebuggerStateEditingServiceGuestTest extends DebuggerStateEditingServiceTest { public class DebuggerControlServiceGuestTest extends DebuggerControlServiceTest {
protected TraceGuestPlatform platform; protected TraceGuestPlatform platform;
public void createToyPlatform() { public void createToyPlatform() {

View file

@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package ghidra.app.plugin.core.debug.service.editing; package ghidra.app.plugin.core.debug.service.control;
import static org.junit.Assert.*; import static org.junit.Assert.*;
@ -26,8 +26,9 @@ import org.junit.Test;
import ghidra.app.plugin.assembler.*; import ghidra.app.plugin.assembler.*;
import ghidra.app.plugin.core.debug.DebuggerCoordinates; import ghidra.app.plugin.core.debug.DebuggerCoordinates;
import ghidra.app.plugin.core.debug.gui.AbstractGhidraHeadedDebuggerGUITest; import ghidra.app.plugin.core.debug.gui.AbstractGhidraHeadedDebuggerGUITest;
import ghidra.app.plugin.core.debug.service.control.DebuggerControlServicePlugin;
import ghidra.app.services.*; import ghidra.app.services.*;
import ghidra.app.services.DebuggerStateEditingService.StateEditor; import ghidra.app.services.DebuggerControlService.StateEditor;
import ghidra.async.AsyncUtils.TemperamentalRunnable; import ghidra.async.AsyncUtils.TemperamentalRunnable;
import ghidra.dbg.target.TargetRegisterBank; import ghidra.dbg.target.TargetRegisterBank;
import ghidra.program.model.lang.*; import ghidra.program.model.lang.*;
@ -39,8 +40,8 @@ import ghidra.trace.model.thread.TraceThread;
import ghidra.trace.model.time.schedule.TraceSchedule; import ghidra.trace.model.time.schedule.TraceSchedule;
import ghidra.util.database.UndoableTransaction; import ghidra.util.database.UndoableTransaction;
public class DebuggerStateEditingServiceTest extends AbstractGhidraHeadedDebuggerGUITest { public class DebuggerControlServiceTest extends AbstractGhidraHeadedDebuggerGUITest {
protected DebuggerStateEditingService editingService; protected DebuggerControlService editingService;
protected Register r0; protected Register r0;
protected Register r0h; protected Register r0h;
@ -84,7 +85,7 @@ public class DebuggerStateEditingServiceTest extends AbstractGhidraHeadedDebugge
@Before @Before
public void setUpEditorTest() throws Exception { public void setUpEditorTest() throws Exception {
editingService = addPlugin(tool, DebuggerStateEditingServicePlugin.class); editingService = addPlugin(tool, DebuggerControlServicePlugin.class);
Language toy = getToyBE64Language(); Language toy = getToyBE64Language();
r0 = toy.getRegister("r0"); r0 = toy.getRegister("r0");
r0h = toy.getRegister("r0h"); r0h = toy.getRegister("r0h");
@ -104,7 +105,7 @@ public class DebuggerStateEditingServiceTest extends AbstractGhidraHeadedDebugge
createAndOpenTrace(); createAndOpenTrace();
activateTrace(); activateTrace();
editingService.setCurrentMode(tb.trace, StateEditingMode.RW_EMULATOR); editingService.setCurrentMode(tb.trace, ControlMode.RW_EMULATOR);
StateEditor editor = createStateEditor(); StateEditor editor = createStateEditor();
assertFalse(editor.isVariableEditable(tb.addr(0x00400000), 4)); assertFalse(editor.isVariableEditable(tb.addr(0x00400000), 4));
@ -116,7 +117,7 @@ public class DebuggerStateEditingServiceTest extends AbstractGhidraHeadedDebugge
@Test @Test
public void testWriteEmuRegisterNoThreadErr() throws Throwable { public void testWriteEmuRegisterNoThreadErr() throws Throwable {
createAndOpenTrace(); createAndOpenTrace();
editingService.setCurrentMode(tb.trace, StateEditingMode.RW_EMULATOR); editingService.setCurrentMode(tb.trace, ControlMode.RW_EMULATOR);
activateTrace(); activateTrace();
waitForSwing(); waitForSwing();
@ -131,7 +132,7 @@ public class DebuggerStateEditingServiceTest extends AbstractGhidraHeadedDebugge
@Test @Test
public void testWriteEmuMemory() throws Throwable { public void testWriteEmuMemory() throws Throwable {
createAndOpenTrace(); createAndOpenTrace();
editingService.setCurrentMode(tb.trace, StateEditingMode.RW_EMULATOR); editingService.setCurrentMode(tb.trace, ControlMode.RW_EMULATOR);
try (UndoableTransaction tid = tb.startTransaction()) { try (UndoableTransaction tid = tb.startTransaction()) {
// NB. TraceManager should automatically activate the first thread // NB. TraceManager should automatically activate the first thread
@ -157,7 +158,7 @@ public class DebuggerStateEditingServiceTest extends AbstractGhidraHeadedDebugge
@Test @Test
public void testWriteEmuRegister() throws Throwable { public void testWriteEmuRegister() throws Throwable {
createAndOpenTrace(); createAndOpenTrace();
editingService.setCurrentMode(tb.trace, StateEditingMode.RW_EMULATOR); editingService.setCurrentMode(tb.trace, ControlMode.RW_EMULATOR);
TraceThread thread; TraceThread thread;
try (UndoableTransaction tid = tb.startTransaction()) { try (UndoableTransaction tid = tb.startTransaction()) {
@ -186,7 +187,7 @@ public class DebuggerStateEditingServiceTest extends AbstractGhidraHeadedDebugge
@Test @Test
public void testWriteEmuMemoryAfterStep() throws Throwable { public void testWriteEmuMemoryAfterStep() throws Throwable {
createAndOpenTrace(); createAndOpenTrace();
editingService.setCurrentMode(tb.trace, StateEditingMode.RW_TRACE); editingService.setCurrentMode(tb.trace, ControlMode.RW_TRACE);
try (UndoableTransaction tid = tb.startTransaction()) { try (UndoableTransaction tid = tb.startTransaction()) {
// NB. TraceManager should automatically activate the first thread // NB. TraceManager should automatically activate the first thread
@ -199,7 +200,7 @@ public class DebuggerStateEditingServiceTest extends AbstractGhidraHeadedDebugge
tb.exec(getPlatform(), 0, thread, 0, "pc = 0x00400000;"); tb.exec(getPlatform(), 0, thread, 0, "pc = 0x00400000;");
} }
activateTrace(); activateTrace();
editingService.setCurrentMode(tb.trace, StateEditingMode.RW_EMULATOR); editingService.setCurrentMode(tb.trace, ControlMode.RW_EMULATOR);
waitForSwing(); waitForSwing();
TraceSchedule step1 = TraceSchedule.parse("0:t0-1"); TraceSchedule step1 = TraceSchedule.parse("0:t0-1");
@ -224,7 +225,7 @@ public class DebuggerStateEditingServiceTest extends AbstractGhidraHeadedDebugge
@Test @Test
public void testWriteEmuRegisterAfterStep() throws Throwable { public void testWriteEmuRegisterAfterStep() throws Throwable {
createAndOpenTrace(); createAndOpenTrace();
editingService.setCurrentMode(tb.trace, StateEditingMode.RW_TRACE); editingService.setCurrentMode(tb.trace, ControlMode.RW_TRACE);
TraceThread thread; TraceThread thread;
try (UndoableTransaction tid = tb.startTransaction()) { try (UndoableTransaction tid = tb.startTransaction()) {
@ -238,7 +239,7 @@ public class DebuggerStateEditingServiceTest extends AbstractGhidraHeadedDebugge
tb.exec(getPlatform(), 0, thread, 0, "pc = 0x00400000;"); tb.exec(getPlatform(), 0, thread, 0, "pc = 0x00400000;");
} }
activateTrace(); activateTrace();
editingService.setCurrentMode(tb.trace, StateEditingMode.RW_EMULATOR); editingService.setCurrentMode(tb.trace, ControlMode.RW_EMULATOR);
waitForSwing(); waitForSwing();
TraceSchedule step1 = TraceSchedule.parse("0:t0-1"); TraceSchedule step1 = TraceSchedule.parse("0:t0-1");
@ -264,7 +265,7 @@ public class DebuggerStateEditingServiceTest extends AbstractGhidraHeadedDebugge
@Test @Test
public void testWriteEmuMemoryTwice() throws Throwable { public void testWriteEmuMemoryTwice() throws Throwable {
createAndOpenTrace(); createAndOpenTrace();
editingService.setCurrentMode(tb.trace, StateEditingMode.RW_EMULATOR); editingService.setCurrentMode(tb.trace, ControlMode.RW_EMULATOR);
try (UndoableTransaction tid = tb.startTransaction()) { try (UndoableTransaction tid = tb.startTransaction()) {
// NB. TraceManager should automatically activate the first thread // NB. TraceManager should automatically activate the first thread
@ -293,7 +294,7 @@ public class DebuggerStateEditingServiceTest extends AbstractGhidraHeadedDebugge
@Test @Test
public void testWriteEmuRegisterTwice() throws Throwable { public void testWriteEmuRegisterTwice() throws Throwable {
createAndOpenTrace(); createAndOpenTrace();
editingService.setCurrentMode(tb.trace, StateEditingMode.RW_EMULATOR); editingService.setCurrentMode(tb.trace, ControlMode.RW_EMULATOR);
TraceThread thread; TraceThread thread;
try (UndoableTransaction tid = tb.startTransaction()) { try (UndoableTransaction tid = tb.startTransaction()) {
@ -324,7 +325,7 @@ public class DebuggerStateEditingServiceTest extends AbstractGhidraHeadedDebugge
public void testWriteTraceMemory() throws Throwable { public void testWriteTraceMemory() throws Throwable {
// NB. Definitely no thread required // NB. Definitely no thread required
createAndOpenTrace(); createAndOpenTrace();
editingService.setCurrentMode(tb.trace, StateEditingMode.RW_TRACE); editingService.setCurrentMode(tb.trace, ControlMode.RW_TRACE);
activateTrace(); activateTrace();
waitForSwing(); waitForSwing();
@ -347,7 +348,7 @@ public class DebuggerStateEditingServiceTest extends AbstractGhidraHeadedDebugge
public void testWriteTraceRegisterNoThreadErr() throws Throwable { public void testWriteTraceRegisterNoThreadErr() throws Throwable {
// NB. Definitely no thread required // NB. Definitely no thread required
createAndOpenTrace(); createAndOpenTrace();
editingService.setCurrentMode(tb.trace, StateEditingMode.RW_TRACE); editingService.setCurrentMode(tb.trace, ControlMode.RW_TRACE);
activateTrace(); activateTrace();
waitForSwing(); waitForSwing();
@ -363,7 +364,7 @@ public class DebuggerStateEditingServiceTest extends AbstractGhidraHeadedDebugge
public void testWriteTraceRegister() throws Throwable { public void testWriteTraceRegister() throws Throwable {
// NB. Definitely no thread required // NB. Definitely no thread required
createAndOpenTrace(); createAndOpenTrace();
editingService.setCurrentMode(tb.trace, StateEditingMode.RW_TRACE); editingService.setCurrentMode(tb.trace, ControlMode.RW_TRACE);
TraceThread thread; TraceThread thread;
try (UndoableTransaction tid = tb.startTransaction()) { try (UndoableTransaction tid = tb.startTransaction()) {
@ -396,7 +397,7 @@ public class DebuggerStateEditingServiceTest extends AbstractGhidraHeadedDebugge
activateTrace(); activateTrace();
traceManager.activateThread(recorder.getTraceThread(mb.testThread1)); traceManager.activateThread(recorder.getTraceThread(mb.testThread1));
waitForSwing(); waitForSwing();
editingService.setCurrentMode(recorder.getTrace(), StateEditingMode.RW_TARGET); editingService.setCurrentMode(recorder.getTrace(), ControlMode.RW_TARGET);
StateEditor editor = createStateEditor(); StateEditor editor = createStateEditor();
assertTrue(editor.isVariableEditable(tb.addr(0x00400000), 4)); assertTrue(editor.isVariableEditable(tb.addr(0x00400000), 4));
@ -416,7 +417,7 @@ public class DebuggerStateEditingServiceTest extends AbstractGhidraHeadedDebugge
waitForSwing(); waitForSwing();
traceManager.activateThread(recorder.getTraceThread(mb.testThread1)); traceManager.activateThread(recorder.getTraceThread(mb.testThread1));
waitForSwing(); waitForSwing();
editingService.setCurrentMode(recorder.getTrace(), StateEditingMode.RW_TARGET); editingService.setCurrentMode(recorder.getTrace(), ControlMode.RW_TARGET);
StateEditor editor = createStateEditor(); StateEditor editor = createStateEditor();
assertTrue(editor.isRegisterEditable(r0)); assertTrue(editor.isRegisterEditable(r0));
@ -435,7 +436,7 @@ public class DebuggerStateEditingServiceTest extends AbstractGhidraHeadedDebugge
TraceThread thread = waitForValue(() -> recorder.getTraceThread(mb.testThread1)); TraceThread thread = waitForValue(() -> recorder.getTraceThread(mb.testThread1));
traceManager.activateThread(thread); traceManager.activateThread(thread);
waitForSwing(); waitForSwing();
editingService.setCurrentMode(recorder.getTrace(), StateEditingMode.RW_TARGET); editingService.setCurrentMode(recorder.getTrace(), ControlMode.RW_TARGET);
StateEditor editor = createStateEditor(); StateEditor editor = createStateEditor();
waitForPass(() -> assertTrue(editor.isRegisterEditable(r0))); waitForPass(() -> assertTrue(editor.isRegisterEditable(r0)));
@ -461,15 +462,15 @@ public class DebuggerStateEditingServiceTest extends AbstractGhidraHeadedDebugge
traceManager.activateThread(recorder.getTraceThread(mb.testThread1)); traceManager.activateThread(recorder.getTraceThread(mb.testThread1));
waitForSwing(); waitForSwing();
editingService.setCurrentMode(tb.trace, StateEditingMode.RW_TARGET); editingService.setCurrentMode(tb.trace, ControlMode.RW_TARGET);
waitForSwing(); waitForSwing();
assertEquals(recorder.getSnap(), traceManager.getCurrentSnap()); assertEquals(recorder.getSnap(), traceManager.getCurrentSnap());
traceManager.activateSnap(traceManager.getCurrentSnap() - 1); traceManager.activateSnap(traceManager.getCurrentSnap() - 1);
waitForSwing(); waitForSwing();
assertEquals(StateEditingMode.RW_EMULATOR, editingService.getCurrentMode(tb.trace)); assertEquals(ControlMode.RW_EMULATOR, editingService.getCurrentMode(tb.trace));
editingService.setCurrentMode(tb.trace, StateEditingMode.RW_TARGET); editingService.setCurrentMode(tb.trace, ControlMode.RW_TARGET);
waitForSwing(); waitForSwing();
assertEquals(recorder.getSnap(), traceManager.getCurrentSnap()); assertEquals(recorder.getSnap(), traceManager.getCurrentSnap());
} }
@ -479,7 +480,7 @@ public class DebuggerStateEditingServiceTest extends AbstractGhidraHeadedDebugge
createAndOpenTrace(); createAndOpenTrace();
activateTrace(); activateTrace();
waitForSwing(); waitForSwing();
editingService.setCurrentMode(tb.trace, StateEditingMode.RW_TARGET); editingService.setCurrentMode(tb.trace, ControlMode.RW_TARGET);
waitForSwing(); waitForSwing();
StateEditor editor = createStateEditor(); StateEditor editor = createStateEditor();
@ -494,7 +495,7 @@ public class DebuggerStateEditingServiceTest extends AbstractGhidraHeadedDebugge
createAndOpenTrace(); createAndOpenTrace();
activateTrace(); activateTrace();
waitForSwing(); waitForSwing();
editingService.setCurrentMode(tb.trace, StateEditingMode.RW_TARGET); editingService.setCurrentMode(tb.trace, ControlMode.RW_TARGET);
waitForSwing(); waitForSwing();
StateEditor editor = createStateEditor(); StateEditor editor = createStateEditor();
@ -508,7 +509,7 @@ public class DebuggerStateEditingServiceTest extends AbstractGhidraHeadedDebugge
public void testWriteReadOnlyMemoryErr() throws Throwable { public void testWriteReadOnlyMemoryErr() throws Throwable {
createAndOpenTrace(); createAndOpenTrace();
activateTrace(); activateTrace();
editingService.setCurrentMode(tb.trace, StateEditingMode.RO_TARGET); editingService.setCurrentMode(tb.trace, ControlMode.RO_TARGET);
StateEditor editor = createStateEditor(); StateEditor editor = createStateEditor();
assertFalse(editor.isVariableEditable(tb.addr(0x00400000), 4)); assertFalse(editor.isVariableEditable(tb.addr(0x00400000), 4));
@ -521,7 +522,7 @@ public class DebuggerStateEditingServiceTest extends AbstractGhidraHeadedDebugge
public void testWriteReadOnlyRegisterErr() throws Throwable { public void testWriteReadOnlyRegisterErr() throws Throwable {
createAndOpenTrace(); createAndOpenTrace();
activateTrace(); activateTrace();
editingService.setCurrentMode(tb.trace, StateEditingMode.RO_TARGET); editingService.setCurrentMode(tb.trace, ControlMode.RO_TARGET);
StateEditor editor = createStateEditor(); StateEditor editor = createStateEditor();
assertFalse(editor.isRegisterEditable(r0)); assertFalse(editor.isRegisterEditable(r0));

View file

@ -26,7 +26,7 @@ import org.junit.experimental.categories.Category;
import generic.test.category.NightlyCategory; import generic.test.category.NightlyCategory;
import ghidra.app.plugin.core.debug.DebuggerCoordinates; import ghidra.app.plugin.core.debug.DebuggerCoordinates;
import ghidra.app.plugin.core.debug.gui.AbstractGhidraHeadedDebuggerGUITest; import ghidra.app.plugin.core.debug.gui.AbstractGhidraHeadedDebuggerGUITest;
import ghidra.app.plugin.core.debug.service.editing.DebuggerStateEditingServicePlugin; import ghidra.app.plugin.core.debug.service.control.DebuggerControlServicePlugin;
import ghidra.app.services.*; import ghidra.app.services.*;
import ghidra.dbg.model.TestTargetStack; import ghidra.dbg.model.TestTargetStack;
import ghidra.dbg.model.TestTargetStackFrameHasRegisterBank; import ghidra.dbg.model.TestTargetStackFrameHasRegisterBank;
@ -47,12 +47,12 @@ import ghidra.util.database.UndoableTransaction;
@Category(NightlyCategory.class) // this may actually be an @PortSensitive test @Category(NightlyCategory.class) // this may actually be an @PortSensitive test
public class DebuggerTraceManagerServiceTest extends AbstractGhidraHeadedDebuggerGUITest { public class DebuggerTraceManagerServiceTest extends AbstractGhidraHeadedDebuggerGUITest {
protected DebuggerStateEditingService editingService; protected DebuggerControlService editingService;
@Before @Before
public void setUpTraceManagerTest() throws Exception { public void setUpTraceManagerTest() throws Exception {
addPlugin(tool, DebuggerStateEditingServicePlugin.class); addPlugin(tool, DebuggerControlServicePlugin.class);
editingService = tool.getService(DebuggerStateEditingService.class); editingService = tool.getService(DebuggerControlService.class);
} }
@Test @Test
@ -359,7 +359,7 @@ public class DebuggerTraceManagerServiceTest extends AbstractGhidraHeadedDebugge
traceManager.activateTrace(trace); traceManager.activateTrace(trace);
waitForSwing(); waitForSwing();
assertEquals(StateEditingMode.RO_TARGET, editingService.getCurrentMode(trace)); assertEquals(ControlMode.RO_TARGET, editingService.getCurrentMode(trace));
long initSnap = recorder.getSnap(); long initSnap = recorder.getSnap();
assertEquals(initSnap, traceManager.getCurrentSnap()); assertEquals(initSnap, traceManager.getCurrentSnap());
@ -369,7 +369,7 @@ public class DebuggerTraceManagerServiceTest extends AbstractGhidraHeadedDebugge
assertEquals(initSnap + 1, recorder.getSnap()); assertEquals(initSnap + 1, recorder.getSnap());
assertEquals(initSnap + 1, traceManager.getCurrentSnap()); assertEquals(initSnap + 1, traceManager.getCurrentSnap());
editingService.setCurrentMode(trace, StateEditingMode.RO_TRACE); editingService.setCurrentMode(trace, ControlMode.RO_TRACE);
recorder.forceSnapshot(); recorder.forceSnapshot();
waitForSwing(); waitForSwing();
@ -377,7 +377,7 @@ public class DebuggerTraceManagerServiceTest extends AbstractGhidraHeadedDebugge
assertEquals(initSnap + 2, recorder.getSnap()); assertEquals(initSnap + 2, recorder.getSnap());
assertEquals(initSnap + 1, traceManager.getCurrentSnap()); assertEquals(initSnap + 1, traceManager.getCurrentSnap());
editingService.setCurrentMode(trace, StateEditingMode.RO_TARGET); editingService.setCurrentMode(trace, ControlMode.RO_TARGET);
waitForSwing(); waitForSwing();
assertEquals(initSnap + 2, recorder.getSnap()); assertEquals(initSnap + 2, recorder.getSnap());

View file

@ -40,7 +40,7 @@ import ghidra.app.plugin.core.debug.gui.AbstractGhidraHeadedDebuggerGUITest;
import ghidra.app.plugin.core.debug.gui.listing.DebuggerListingPlugin; import ghidra.app.plugin.core.debug.gui.listing.DebuggerListingPlugin;
import ghidra.app.plugin.core.debug.gui.stack.vars.*; import ghidra.app.plugin.core.debug.gui.stack.vars.*;
import ghidra.app.plugin.core.debug.gui.stack.vars.VariableValueRow.*; import ghidra.app.plugin.core.debug.gui.stack.vars.VariableValueRow.*;
import ghidra.app.plugin.core.debug.service.editing.DebuggerStateEditingServicePlugin; import ghidra.app.plugin.core.debug.service.control.DebuggerControlServicePlugin;
import ghidra.app.plugin.core.debug.service.emulation.DebuggerEmulationServicePlugin; import ghidra.app.plugin.core.debug.service.emulation.DebuggerEmulationServicePlugin;
import ghidra.app.plugin.core.debug.service.emulation.ProgramEmulationUtils; import ghidra.app.plugin.core.debug.service.emulation.ProgramEmulationUtils;
import ghidra.app.plugin.core.debug.stack.StackUnwindWarning.*; import ghidra.app.plugin.core.debug.stack.StackUnwindWarning.*;
@ -49,7 +49,7 @@ import ghidra.app.plugin.core.decompile.DecompilerProvider;
import ghidra.app.plugin.core.disassembler.DisassemblerPlugin; import ghidra.app.plugin.core.disassembler.DisassemblerPlugin;
import ghidra.app.services.*; import ghidra.app.services.*;
import ghidra.app.services.DebuggerEmulationService.EmulationResult; import ghidra.app.services.DebuggerEmulationService.EmulationResult;
import ghidra.app.services.DebuggerStateEditingService.StateEditor; import ghidra.app.services.DebuggerControlService.StateEditor;
import ghidra.app.util.viewer.field.FieldFactory; import ghidra.app.util.viewer.field.FieldFactory;
import ghidra.app.util.viewer.field.ListingField; import ghidra.app.util.viewer.field.ListingField;
import ghidra.app.util.viewer.listingpanel.ListingPanel; import ghidra.app.util.viewer.listingpanel.ListingPanel;
@ -119,7 +119,7 @@ public class StackUnwinderTest extends AbstractGhidraHeadedDebuggerGUITest {
ListingPanel staticListing; ListingPanel staticListing;
DebuggerListingPlugin listingPlugin; DebuggerListingPlugin listingPlugin;
ListingPanel dynamicListing; ListingPanel dynamicListing;
DebuggerStateEditingService editingService; DebuggerControlService editingService;
DebuggerEmulationService emuService; DebuggerEmulationService emuService;
DecompilerProvider decompilerProvider; DecompilerProvider decompilerProvider;
DecompilerPanel decompilerPanel; DecompilerPanel decompilerPanel;
@ -675,8 +675,8 @@ public class StackUnwinderTest extends AbstractGhidraHeadedDebuggerGUITest {
addPlugin(tool, DebuggerListingPlugin.class); addPlugin(tool, DebuggerListingPlugin.class);
addPlugin(tool, DisassemblerPlugin.class); addPlugin(tool, DisassemblerPlugin.class);
addPlugin(tool, DecompilePlugin.class); addPlugin(tool, DecompilePlugin.class);
DebuggerStateEditingService editingService = DebuggerControlService editingService =
addPlugin(tool, DebuggerStateEditingServicePlugin.class); addPlugin(tool, DebuggerControlServicePlugin.class);
DebuggerEmulationService emuService = addPlugin(tool, DebuggerEmulationServicePlugin.class); DebuggerEmulationService emuService = addPlugin(tool, DebuggerEmulationServicePlugin.class);
Function function = createSumSquaresProgramX86_32(); Function function = createSumSquaresProgramX86_32();
@ -691,7 +691,7 @@ public class StackUnwinderTest extends AbstractGhidraHeadedDebuggerGUITest {
traceManager.activateThread(thread); traceManager.activateThread(thread);
waitForSwing(); waitForSwing();
editingService.setCurrentMode(tb.trace, StateEditingMode.RW_TRACE); editingService.setCurrentMode(tb.trace, ControlMode.RW_TRACE);
StateEditor editor = editingService.createStateEditor(tb.trace); StateEditor editor = editingService.createStateEditor(tb.trace);
DebuggerCoordinates atSetup = traceManager.getCurrent(); DebuggerCoordinates atSetup = traceManager.getCurrent();
@ -735,8 +735,8 @@ public class StackUnwinderTest extends AbstractGhidraHeadedDebuggerGUITest {
addPlugin(tool, DebuggerListingPlugin.class); addPlugin(tool, DebuggerListingPlugin.class);
addPlugin(tool, DisassemblerPlugin.class); addPlugin(tool, DisassemblerPlugin.class);
addPlugin(tool, DecompilePlugin.class); addPlugin(tool, DecompilePlugin.class);
DebuggerStateEditingService editingService = DebuggerControlService editingService =
addPlugin(tool, DebuggerStateEditingServicePlugin.class); addPlugin(tool, DebuggerControlServicePlugin.class);
DebuggerEmulationService emuService = addPlugin(tool, DebuggerEmulationServicePlugin.class); DebuggerEmulationService emuService = addPlugin(tool, DebuggerEmulationServicePlugin.class);
Function function = createFibonacciProgramX86_32(); Function function = createFibonacciProgramX86_32();
@ -751,7 +751,7 @@ public class StackUnwinderTest extends AbstractGhidraHeadedDebuggerGUITest {
traceManager.activateThread(thread); traceManager.activateThread(thread);
waitForSwing(); waitForSwing();
editingService.setCurrentMode(tb.trace, StateEditingMode.RW_TRACE); editingService.setCurrentMode(tb.trace, ControlMode.RW_TRACE);
StateEditor editor = editingService.createStateEditor(tb.trace); StateEditor editor = editingService.createStateEditor(tb.trace);
DebuggerCoordinates atSetup = traceManager.getCurrent(); DebuggerCoordinates atSetup = traceManager.getCurrent();
@ -872,7 +872,7 @@ public class StackUnwinderTest extends AbstractGhidraHeadedDebuggerGUITest {
dynamicListing = listingPlugin.getProvider().getListingPanel(); dynamicListing = listingPlugin.getProvider().getListingPanel();
addPlugin(tool, DisassemblerPlugin.class); addPlugin(tool, DisassemblerPlugin.class);
addPlugin(tool, DecompilePlugin.class); addPlugin(tool, DecompilePlugin.class);
editingService = addPlugin(tool, DebuggerStateEditingServicePlugin.class); editingService = addPlugin(tool, DebuggerControlServicePlugin.class);
emuService = addPlugin(tool, DebuggerEmulationServicePlugin.class); emuService = addPlugin(tool, DebuggerEmulationServicePlugin.class);
decompilerProvider = waitForComponentProvider(DecompilerProvider.class); decompilerProvider = waitForComponentProvider(DecompilerProvider.class);
@ -894,7 +894,7 @@ public class StackUnwinderTest extends AbstractGhidraHeadedDebuggerGUITest {
traceManager.activateThread(thread); traceManager.activateThread(thread);
waitForSwing(); waitForSwing();
editingService.setCurrentMode(tb.trace, StateEditingMode.RW_TRACE); editingService.setCurrentMode(tb.trace, ControlMode.RW_TRACE);
StateEditor editor = editingService.createStateEditor(tb.trace); StateEditor editor = editingService.createStateEditor(tb.trace);
DebuggerCoordinates atSetup = traceManager.getCurrent(); DebuggerCoordinates atSetup = traceManager.getCurrent();
@ -944,7 +944,7 @@ public class StackUnwinderTest extends AbstractGhidraHeadedDebuggerGUITest {
traceManager.activateThread(thread); traceManager.activateThread(thread);
waitForSwing(); waitForSwing();
editingService.setCurrentMode(tb.trace, StateEditingMode.RW_TRACE); editingService.setCurrentMode(tb.trace, ControlMode.RW_TRACE);
StateEditor editor = editingService.createStateEditor(tb.trace); StateEditor editor = editingService.createStateEditor(tb.trace);
// Move stack where it shows in UI. Not required, but nice for debugging. // Move stack where it shows in UI. Not required, but nice for debugging.
Register sp = program.getCompilerSpec().getStackPointer(); Register sp = program.getCompilerSpec().getStackPointer();
@ -988,7 +988,7 @@ public class StackUnwinderTest extends AbstractGhidraHeadedDebuggerGUITest {
traceManager.activateThread(thread); traceManager.activateThread(thread);
waitForSwing(); waitForSwing();
editingService.setCurrentMode(tb.trace, StateEditingMode.RW_TRACE); editingService.setCurrentMode(tb.trace, ControlMode.RW_TRACE);
StateEditor editor = editingService.createStateEditor(tb.trace); StateEditor editor = editingService.createStateEditor(tb.trace);
// Move stack where it shows in UI. Not required, but nice for debugging. // Move stack where it shows in UI. Not required, but nice for debugging.
Register sp = program.getCompilerSpec().getStackPointer(); Register sp = program.getCompilerSpec().getStackPointer();
@ -1032,7 +1032,7 @@ public class StackUnwinderTest extends AbstractGhidraHeadedDebuggerGUITest {
traceManager.activateThread(thread); traceManager.activateThread(thread);
waitForSwing(); waitForSwing();
editingService.setCurrentMode(tb.trace, StateEditingMode.RW_TRACE); editingService.setCurrentMode(tb.trace, ControlMode.RW_TRACE);
StateEditor editor = editingService.createStateEditor(tb.trace); StateEditor editor = editingService.createStateEditor(tb.trace);
// Move stack where it shows in UI. Not required, but nice for debugging. // Move stack where it shows in UI. Not required, but nice for debugging.
Register sp = program.getCompilerSpec().getStackPointer(); Register sp = program.getCompilerSpec().getStackPointer();

View file

@ -36,7 +36,7 @@ import ghidra.app.plugin.core.debug.DebuggerCoordinates;
import ghidra.app.plugin.core.debug.gui.AbstractGhidraHeadedDebuggerGUITest; import ghidra.app.plugin.core.debug.gui.AbstractGhidraHeadedDebuggerGUITest;
import ghidra.app.plugin.core.debug.gui.listing.DebuggerListingPlugin; import ghidra.app.plugin.core.debug.gui.listing.DebuggerListingPlugin;
import ghidra.app.plugin.core.debug.service.breakpoint.DebuggerLogicalBreakpointServicePlugin; import ghidra.app.plugin.core.debug.service.breakpoint.DebuggerLogicalBreakpointServicePlugin;
import ghidra.app.plugin.core.debug.service.editing.DebuggerStateEditingServicePlugin; import ghidra.app.plugin.core.debug.service.control.DebuggerControlServicePlugin;
import ghidra.app.plugin.core.debug.service.emulation.DebuggerEmulationServicePlugin; import ghidra.app.plugin.core.debug.service.emulation.DebuggerEmulationServicePlugin;
import ghidra.app.plugin.core.debug.service.model.TestDebuggerProgramLaunchOpinion.TestDebuggerProgramLaunchOffer; import ghidra.app.plugin.core.debug.service.model.TestDebuggerProgramLaunchOpinion.TestDebuggerProgramLaunchOffer;
import ghidra.app.plugin.core.debug.service.model.launch.AbstractDebuggerProgramLaunchOffer; import ghidra.app.plugin.core.debug.service.model.launch.AbstractDebuggerProgramLaunchOffer;
@ -129,7 +129,7 @@ public class FlatDebuggerAPITest extends AbstractGhidraHeadedDebuggerGUITest {
protected DebuggerStaticMappingService mappingService; protected DebuggerStaticMappingService mappingService;
protected DebuggerEmulationService emulationService; protected DebuggerEmulationService emulationService;
protected DebuggerListingService listingService; protected DebuggerListingService listingService;
protected DebuggerStateEditingService editingService; protected DebuggerControlService editingService;
protected FlatDebuggerAPI flat; protected FlatDebuggerAPI flat;
@Before @Before
@ -138,7 +138,7 @@ public class FlatDebuggerAPITest extends AbstractGhidraHeadedDebuggerGUITest {
mappingService = tool.getService(DebuggerStaticMappingService.class); mappingService = tool.getService(DebuggerStaticMappingService.class);
emulationService = addPlugin(tool, DebuggerEmulationServicePlugin.class); emulationService = addPlugin(tool, DebuggerEmulationServicePlugin.class);
listingService = addPlugin(tool, DebuggerListingPlugin.class); listingService = addPlugin(tool, DebuggerListingPlugin.class);
editingService = addPlugin(tool, DebuggerStateEditingServicePlugin.class); editingService = addPlugin(tool, DebuggerControlServicePlugin.class);
flat = new TestFlatAPI(); flat = new TestFlatAPI();
} }
@ -689,7 +689,7 @@ public class FlatDebuggerAPITest extends AbstractGhidraHeadedDebuggerGUITest {
@Test @Test
public void testWriteMemoryGivenContext() throws Throwable { public void testWriteMemoryGivenContext() throws Throwable {
createTraceWithBinText(); createTraceWithBinText();
editingService.setCurrentMode(tb.trace, StateEditingMode.RW_TRACE); editingService.setCurrentMode(tb.trace, ControlMode.RW_TRACE);
assertTrue(flat.writeMemory(tb.trace, 0, tb.addr(0x00400123), tb.arr(3, 2, 1))); assertTrue(flat.writeMemory(tb.trace, 0, tb.addr(0x00400123), tb.arr(3, 2, 1)));
ByteBuffer buf = ByteBuffer.allocate(3); ByteBuffer buf = ByteBuffer.allocate(3);
@ -700,7 +700,7 @@ public class FlatDebuggerAPITest extends AbstractGhidraHeadedDebuggerGUITest {
@Test @Test
public void testWriteMemoryCurrentContext() throws Throwable { public void testWriteMemoryCurrentContext() throws Throwable {
createTraceWithBinText(); createTraceWithBinText();
editingService.setCurrentMode(tb.trace, StateEditingMode.RW_TRACE); editingService.setCurrentMode(tb.trace, ControlMode.RW_TRACE);
assertTrue(flat.writeMemory(tb.addr(0x00400123), tb.arr(3, 2, 1))); assertTrue(flat.writeMemory(tb.addr(0x00400123), tb.arr(3, 2, 1)));
ByteBuffer buf = ByteBuffer.allocate(3); ByteBuffer buf = ByteBuffer.allocate(3);
@ -711,7 +711,7 @@ public class FlatDebuggerAPITest extends AbstractGhidraHeadedDebuggerGUITest {
@Test @Test
public void testWriteRegisterGivenContext() throws Throwable { public void testWriteRegisterGivenContext() throws Throwable {
TraceThread thread = createTraceWithThreadAndStack(true); TraceThread thread = createTraceWithThreadAndStack(true);
editingService.setCurrentMode(tb.trace, StateEditingMode.RW_TRACE); editingService.setCurrentMode(tb.trace, ControlMode.RW_TRACE);
traceManager.activateThread(thread); traceManager.activateThread(thread);
waitForSwing(); waitForSwing();
@ -727,7 +727,7 @@ public class FlatDebuggerAPITest extends AbstractGhidraHeadedDebuggerGUITest {
@Test @Test
public void testWriteRegisterCurrentContext() throws Throwable { public void testWriteRegisterCurrentContext() throws Throwable {
TraceThread thread = createTraceWithThreadAndStack(true); TraceThread thread = createTraceWithThreadAndStack(true);
editingService.setCurrentMode(tb.trace, StateEditingMode.RW_TRACE); editingService.setCurrentMode(tb.trace, ControlMode.RW_TRACE);
traceManager.activateThread(thread); traceManager.activateThread(thread);
waitForSwing(); waitForSwing();

View file

@ -22,9 +22,9 @@ import javax.swing.Icon;
import docking.ActionContext; import docking.ActionContext;
import docking.action.*; import docking.action.*;
import docking.menu.HorizontalRuleAction;
import docking.menu.MultiActionDockingAction; import docking.menu.MultiActionDockingAction;
import ghidra.app.util.datatype.DataTypeUrl; import ghidra.app.util.datatype.DataTypeUrl;
import ghidra.base.actions.HorizontalRuleAction;
import ghidra.program.model.data.DataType; import ghidra.program.model.data.DataType;
import ghidra.program.model.data.DataTypeManager; import ghidra.program.model.data.DataTypeManager;
import ghidra.util.HelpLocation; import ghidra.util.HelpLocation;

View file

@ -24,6 +24,7 @@ import javax.swing.Icon;
import docking.ActionContext; import docking.ActionContext;
import docking.action.*; import docking.action.*;
import docking.menu.HorizontalRuleAction;
import docking.menu.MultiActionDockingAction; import docking.menu.MultiActionDockingAction;
import docking.tool.ToolConstants; import docking.tool.ToolConstants;
import generic.theme.GIcon; import generic.theme.GIcon;
@ -37,7 +38,6 @@ import ghidra.app.services.GoToService;
import ghidra.app.services.NavigationHistoryService; import ghidra.app.services.NavigationHistoryService;
import ghidra.app.util.HelpTopics; import ghidra.app.util.HelpTopics;
import ghidra.app.util.viewer.field.BrowserCodeUnitFormat; import ghidra.app.util.viewer.field.BrowserCodeUnitFormat;
import ghidra.base.actions.HorizontalRuleAction;
import ghidra.framework.model.DomainFile; import ghidra.framework.model.DomainFile;
import ghidra.framework.plugintool.*; import ghidra.framework.plugintool.*;
import ghidra.framework.plugintool.util.PluginStatus; import ghidra.framework.plugintool.util.PluginStatus;

View file

@ -1,69 +0,0 @@
/* ###
* 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.base.actions;
import docking.ActionContext;
import docking.action.DockingAction;
import docking.action.MenuData;
import generic.theme.GThemeDefaults.Colors.Palette;
import ghidra.util.HTMLUtilities;
/**
* An action that can be added to a menu in order to separate menu items into groups
*/
public class HorizontalRuleAction extends DockingAction {
private static int idCount = 0;
/**
* Constructor
*
* @param owner the action owner
* @param topName the name that will appear above the separator bar
* @param bottomName the name that will appear below the separator bar
*/
public HorizontalRuleAction(String owner, String topName, String bottomName) {
super("HorizontalRuleAction: " + ++idCount, owner, false);
setEnabled(false);
markHelpUnnecessary();
// The menu name is both names, one over the other, in a small, light grayish font.
setMenuBarData(new MenuData(new String[] { "<HTML><CENTER><FONT SIZE=2 COLOR=\"" +
Palette.SILVER + "\">" +
fixupFirstAmp(
HTMLUtilities.escapeHTML(topName) + "<BR>" + HTMLUtilities.escapeHTML(bottomName)) +
"</FONT></CENTER>" }));
// the description is meant to be used for the tooltip and is larger
String padding = "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;";
setDescription("<HTML><CENTER><B>" + padding + HTMLUtilities.escapeHTML(topName) + padding +
"<B><HR><B>" + padding + HTMLUtilities.escapeHTML(bottomName) + padding +
"</B></CENTER>");
}
private String fixupFirstAmp(String text) {
// add an extra & to replace the one that the MenuData will eat
int index = text.indexOf('&');
return index < 0 ? text : text.substring(0, index) + "&" + text.substring(index);
}
@Override
public void actionPerformed(ActionContext context) {
// this does't actually do anything
}
}

View file

@ -15,6 +15,7 @@
*/ */
package docking.action; package docking.action;
import java.awt.Component;
import java.beans.PropertyChangeListener; import java.beans.PropertyChangeListener;
import java.util.Set; import java.util.Set;
@ -281,6 +282,21 @@ public interface DockingActionIf extends HelpDescriptor {
*/ */
public JMenuItem createMenuItem(boolean isPopup); public JMenuItem createMenuItem(boolean isPopup);
/**
* Returns a component to represent this action in the menu.
* <p>
* Typically, this is the menu item that triggers the action. However, some actions may wish to
* use components other than menu items. For example, they may produce component for helping to
* organize the menu visually.
* @param isPopup true if the action should use its Popup MenuData, else it uses the MenuBar
* MenuData.
* @return the component
* @see #createMenuItem(boolean)
*/
public default Component createMenuComponent(boolean isPopup) {
return createMenuItem(isPopup);
}
/** /**
* Determines whether this action should be added to a window (either the main window or a * Determines whether this action should be added to a window (either the main window or a
* secondary detached window). By default, this method will return true for the main window * secondary detached window). By default, this method will return true for the main window

View file

@ -0,0 +1,173 @@
/* ###
* 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 docking.menu;
import java.awt.Dimension;
import java.awt.Graphics;
import javax.swing.*;
import org.apache.commons.lang3.StringUtils;
import docking.ActionContext;
import docking.DockingUtils;
import docking.action.DockingAction;
import docking.action.MenuData;
import docking.widgets.label.GDHtmlLabel;
import generic.theme.GThemeDefaults.Colors.Palette;
import ghidra.util.HTMLUtilities;
/**
* An action that can be added to a menu in order to separate menu items into groups
*/
public class HorizontalRuleAction extends DockingAction {
private static final String PADDING = "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;";
private static int idCount = 0;
/**
* Constructor
*
* @param owner the action owner
* @param topName the name that will appear above the separator bar
* @param bottomName the name that will appear below the separator bar
*/
public HorizontalRuleAction(String owner, String topName, String bottomName) {
super("HorizontalRuleAction: " + ++idCount, owner, false);
setEnabled(false);
markHelpUnnecessary();
MenuData menuData = new MenuData(new String[] { "" });
// The menu name is both names, one over the other, in a small, light grayish font.
String topHtml = HTMLUtilities.escapeHTML(topName);
String bottomHtml = HTMLUtilities.escapeHTML(bottomName);
menuData.setMenuItemNamePlain(String.format("""
<HTML><CENTER><FONT SIZE=2 COLOR="%s">%s<BR>%s</FONT></CENTER>
""", Palette.SILVER, topHtml, bottomHtml));
setMenuBarData(menuData);
// the description is meant to be used for the tooltip and is larger
setDescription(String.format("""
<HTML><CENTER><B>%s</B><HR><B>%s</B></CENTER>
""", PADDING + topHtml + PADDING, PADDING + bottomHtml + PADDING));
}
@Override
public void actionPerformed(ActionContext context) {
// this does't actually do anything
}
@Override
public JSeparator createMenuComponent(boolean isPopup) {
String[] menuPath = getMenuBarData().getMenuPath();
String name = menuPath[menuPath.length - 1];
String description = getDescription();
return new LabeledSeparator(name, description);
}
private static class LabeledSeparator extends JSeparator {
private final int EMTPY_SEPARATOR_HEIGHT = 10;
private final int TEXT_SEPARATOR_HEIGHT = 32;
private JLabel renderer = new GDHtmlLabel();
private int separatorHeight = EMTPY_SEPARATOR_HEIGHT;
private LabeledSeparator(String name, String description) {
setBorder(BorderFactory.createEmptyBorder(20, 0, 20, 0));
renderer.setText(name);
DockingUtils.setTransparent(renderer);
renderer.setHorizontalAlignment(SwingConstants.CENTER);
renderer.setVisible(true);
if (!StringUtils.isBlank(name)) {
separatorHeight = TEXT_SEPARATOR_HEIGHT;
}
// IF WE CHOOSE TO SHOW TOOLTIPS (and below too)...
// setToolTipText( description );
}
@Override
protected void paintComponent(Graphics g) {
Dimension d = getSize();
// some edge padding, for classiness
int pad = 10;
int center = separatorHeight >> 1;
int x = 0 + pad;
int y = center;
int w = d.width - pad;
g.setColor(getForeground());
g.drawLine(x, y, w, y);
// drop-shadow
g.setColor(getBackground());
g.drawLine(x, (y + 1), w, (y + 1));
// now add our custom text
renderer.setSize(getSize());
renderer.paint(g);
}
@Override
public Dimension getPreferredSize() {
// assume horizontal
return new Dimension(0, separatorHeight);
}
@Override
public Dimension getMinimumSize() {
return new Dimension(0, separatorHeight);
}
//
// USE THE CODE BELOW IF WE WANT TOOLTIPS
//
// @Override
// public String getToolTipText( MouseEvent event ) {
// // We only want to show the tooltip when the user is over the label. Since the label
// // is not on the screen, we cannot ask it if the mouse location is within its bounds.
// Dimension labelSize = renderer.getPreferredSize();
// if ( labelSize.height == 0 && labelSize.width == 0 ) {
// return null;
// }
//
// Dimension mySize = getSize();
// int centerX = mySize.width >> 1;
//
// int labelMidPoint = labelSize.width >> 1;
// int labelStartX = centerX - labelMidPoint;
// int labelEndX = centerX + labelMidPoint;
//
// Point mousePoint = event.getPoint();
// boolean insideLabel = (mousePoint.x >= labelStartX) && (mousePoint.x <= labelEndX);
// if ( !insideLabel ) {
// return null;
// }
// return getToolTipText();
// }
//
// @Override
// public Point getToolTipLocation( MouseEvent event ) {
// Rectangle bounds = getBounds();
// bounds.x += bounds.width;
// bounds.y = 0;
// return bounds.getLocation();
// }
}
}

View file

@ -146,6 +146,16 @@ public abstract class MultiStateDockingAction<T> extends DockingAction {
actionStates.addAll(newStates); actionStates.addAll(newStates);
} }
/**
* Check if the given state can be selected
*
* @param state the state to check
* @return true (the default) if selectable, false to disable
*/
protected boolean isStateEnabled(ActionState<T> state) {
return true;
}
protected List<DockingActionIf> getStateActions() { protected List<DockingActionIf> getStateActions() {
updateStates(); updateStates();
List<DockingActionIf> actions = new ArrayList<>(actionStates.size()); List<DockingActionIf> actions = new ArrayList<>(actionStates.size());
@ -154,6 +164,8 @@ public abstract class MultiStateDockingAction<T> extends DockingAction {
DockingActionIf a = useCheckboxForIcons DockingActionIf a = useCheckboxForIcons
? new ActionStateToggleAction(actionState, isSelected) ? new ActionStateToggleAction(actionState, isSelected)
: new ActionStateAction(actionState, isSelected); : new ActionStateAction(actionState, isSelected);
boolean isEnabled = isStateEnabled(actionState);
a.setEnabled(isEnabled);
actions.add(a); actions.add(a);
} }
return actions; return actions;

View file

@ -24,12 +24,9 @@ import javax.swing.*;
import javax.swing.border.Border; import javax.swing.border.Border;
import javax.swing.event.*; import javax.swing.event.*;
import org.apache.commons.lang3.StringUtils;
import docking.*; import docking.*;
import docking.action.*; import docking.action.*;
import docking.widgets.EmptyBorderButton; import docking.widgets.EmptyBorderButton;
import docking.widgets.label.GDHtmlLabel;
import generic.theme.GThemeDefaults.Colors; import generic.theme.GThemeDefaults.Colors;
import ghidra.util.Swing; import ghidra.util.Swing;
import resources.ResourceManager; import resources.ResourceManager;
@ -150,8 +147,9 @@ public class MultipleActionDockingToolbarButton extends EmptyBorderButton {
return manager.getActiveComponentProvider(); return manager.getActiveComponentProvider();
} }
/** /**
* Show a popup containing all the actions below the button * Show a popup containing all the actions below the button
*
* @return the popup menu that was shown * @return the popup menu that was shown
*/ */
JPopupMenu showPopup() { JPopupMenu showPopup() {
@ -181,19 +179,13 @@ public class MultipleActionDockingToolbarButton extends EmptyBorderButton {
List<DockingActionIf> actionList = multipleAction.getActionList(getActionContext()); List<DockingActionIf> actionList = multipleAction.getActionList(getActionContext());
for (DockingActionIf dockingAction : actionList) { for (DockingActionIf dockingAction : actionList) {
String[] menuPath = dockingAction.getMenuBarData().getMenuPath(); Component component = dockingAction.createMenuComponent(false);
String name = menuPath[menuPath.length - 1]; if (!(component instanceof JMenuItem item)) {
// not an actual item, e.g., a separator as in HorizontalRuleAction
// this is a special signal to say we should insert a separator and not a real menu item menu.add(component);
if (!dockingAction.isEnabled()) {
String description = dockingAction.getDescription();
JSeparator separator = new ProgramNameSeparator(name, description);
menu.add(separator);
continue; continue;
} }
JMenuItem item = dockingAction.createMenuItem(false);
// a custom Ghidra UI that handles alignment issues and allows for tabulating presentation // a custom Ghidra UI that handles alignment issues and allows for tabulating presentation
item.setUI((DockingMenuItemUI) DockingMenuItemUI.createUI(item)); item.setUI((DockingMenuItemUI) DockingMenuItemUI.createUI(item));
final DockingActionIf delegateAction = dockingAction; final DockingActionIf delegateAction = dockingAction;
@ -415,95 +407,4 @@ public class MultipleActionDockingToolbarButton extends EmptyBorderButton {
} }
private static class ProgramNameSeparator extends JSeparator {
private final int EMTPY_SEPARATOR_HEIGHT = 10;
private final int TEXT_SEPARATOR_HEIGHT = 32;
private JLabel renderer = new GDHtmlLabel();
private int separatorHeight = EMTPY_SEPARATOR_HEIGHT;
private ProgramNameSeparator(String name, String description) {
setBorder(BorderFactory.createEmptyBorder(20, 0, 20, 0));
renderer.setText(name);
DockingUtils.setTransparent(renderer);
renderer.setHorizontalAlignment(SwingConstants.CENTER);
renderer.setVisible(true);
if (!StringUtils.isBlank(name)) {
separatorHeight = TEXT_SEPARATOR_HEIGHT;
}
// IF WE CHOOSE TO SHOW TOOLTIPS (and below too)...
// setToolTipText( description );
}
@Override
protected void paintComponent(Graphics g) {
Dimension d = getSize();
// some edge padding, for classiness
int pad = 10;
int center = separatorHeight >> 1;
int x = 0 + pad;
int y = center;
int w = d.width - pad;
g.setColor(getForeground());
g.drawLine(x, y, w, y);
// drop-shadow
g.setColor(getBackground());
g.drawLine(x, (y + 1), w, (y + 1));
// now add our custom text
renderer.setSize(getSize());
renderer.paint(g);
}
@Override
public Dimension getPreferredSize() {
// assume horizontal
return new Dimension(0, separatorHeight);
}
@Override
public Dimension getMinimumSize() {
return new Dimension(0, separatorHeight);
}
//
// USE THE CODE BELOW IF WE WANT TOOLTIPS
//
// @Override
// public String getToolTipText( MouseEvent event ) {
// // We only want to show the tooltip when the user is over the label. Since the label
// // is not on the screen, we cannot ask it if the mouse location is within its bounds.
// Dimension labelSize = renderer.getPreferredSize();
// if ( labelSize.height == 0 && labelSize.width == 0 ) {
// return null;
// }
//
// Dimension mySize = getSize();
// int centerX = mySize.width >> 1;
//
// int labelMidPoint = labelSize.width >> 1;
// int labelStartX = centerX - labelMidPoint;
// int labelEndX = centerX + labelMidPoint;
//
// Point mousePoint = event.getPoint();
// boolean insideLabel = (mousePoint.x >= labelStartX) && (mousePoint.x <= labelEndX);
// if ( !insideLabel ) {
// return null;
// }
// return getToolTipText();
// }
//
// @Override
// public Point getToolTipLocation( MouseEvent event ) {
// Rectangle bounds = getBounds();
// bounds.x += bounds.width;
// bounds.y = 0;
// return bounds.getLocation();
// }
}
} }