mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-05 10:49:34 +02:00
Merge remote-tracking branch 'origin/GP-2978_Dan_renameStateEditingService--SQUASHED'
This commit is contained in:
commit
a7eea63ff1
43 changed files with 589 additions and 555 deletions
|
@ -169,11 +169,11 @@ icon.debugger.diff = table_relationship.png
|
|||
icon.debugger.diff.previous = up.png
|
||||
icon.debugger.diff.next = down.png
|
||||
|
||||
icon.debugger.edit.mode.ro.target = record.png
|
||||
icon.debugger.edit.mode.rw.target = write-target.png
|
||||
icon.debugger.edit.mode.ro.trace = video-x-generic16.png
|
||||
icon.debugger.edit.mode.rw.trace = write-trace.png
|
||||
icon.debugger.edit.mode.rw.emulator = write-emulator.png
|
||||
icon.debugger.control.mode.ro.target = record.png
|
||||
icon.debugger.control.mode.rw.target = write-target.png
|
||||
icon.debugger.control.mode.ro.trace = video-x-generic16.png
|
||||
icon.debugger.control.mode.rw.trace = write-trace.png
|
||||
icon.debugger.control.mode.rw.emulator = write-emulator.png
|
||||
|
||||
icon.debugger.marker.register = register-marker.png
|
||||
icon.debugger.marker.event = icon.debugger.marker.register
|
||||
|
|
|
@ -716,7 +716,7 @@ public class DebuggerBreakpointMarkerPlugin extends Plugin
|
|||
@AutoServiceConsumed
|
||||
private DebuggerConsoleService consoleService;
|
||||
@AutoServiceConsumed
|
||||
private DebuggerStateEditingService editingService;
|
||||
private DebuggerControlService controlService;
|
||||
// @AutoServiceConsumed via method
|
||||
DecompilerMarginService decompilerMarginService;
|
||||
@SuppressWarnings("unused")
|
||||
|
@ -859,8 +859,8 @@ public class DebuggerBreakpointMarkerPlugin extends Plugin
|
|||
}
|
||||
|
||||
protected Set<TraceBreakpointKind> getSupportedKindsFromTrace(Trace trace) {
|
||||
StateEditingMode mode = editingService == null ? StateEditingMode.DEFAULT
|
||||
: editingService.getCurrentMode(trace);
|
||||
ControlMode mode = controlService == null ? ControlMode.DEFAULT
|
||||
: controlService.getCurrentMode(trace);
|
||||
if (mode.useEmulatedBreakpoints()) {
|
||||
return EnumSet.allOf(TraceBreakpointKind.class);
|
||||
}
|
||||
|
|
|
@ -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.services.*;
|
||||
import ghidra.app.services.DebuggerStateEditingService.StateEditingModeChangeListener;
|
||||
import ghidra.app.services.DebuggerControlService.ControlModeChangeListener;
|
||||
import ghidra.app.services.LogicalBreakpoint.State;
|
||||
import ghidra.framework.model.DomainObject;
|
||||
import ghidra.framework.plugintool.*;
|
||||
|
@ -57,7 +57,7 @@ import ghidra.util.table.GhidraTable;
|
|||
import ghidra.util.table.GhidraTableFilterPanel;
|
||||
|
||||
public class DebuggerBreakpointsProvider extends ComponentProviderAdapter
|
||||
implements LogicalBreakpointsChangeListener, StateEditingModeChangeListener {
|
||||
implements LogicalBreakpointsChangeListener, ControlModeChangeListener {
|
||||
|
||||
protected enum LogicalBreakpointTableColumns
|
||||
implements EnumeratedTableColumn<LogicalBreakpointTableColumns, LogicalBreakpointRow> {
|
||||
|
@ -672,7 +672,7 @@ public class DebuggerBreakpointsProvider extends ComponentProviderAdapter
|
|||
@AutoServiceConsumed
|
||||
private DebuggerConsoleService consoleService;
|
||||
// @AutoServiceConsumed via method
|
||||
private DebuggerStateEditingService editingService;
|
||||
private DebuggerControlService controlService;
|
||||
@AutoServiceConsumed
|
||||
private GoToService goToService;
|
||||
@SuppressWarnings("unused")
|
||||
|
@ -784,18 +784,18 @@ public class DebuggerBreakpointsProvider extends ComponentProviderAdapter
|
|||
}
|
||||
|
||||
@AutoServiceConsumed
|
||||
private void setEditingService(DebuggerStateEditingService editingService) {
|
||||
if (this.editingService != null) {
|
||||
this.editingService.removeModeChangeListener(this);
|
||||
private void setControlService(DebuggerControlService editingService) {
|
||||
if (this.controlService != null) {
|
||||
this.controlService.removeModeChangeListener(this);
|
||||
}
|
||||
this.editingService = editingService;
|
||||
if (this.editingService != null) {
|
||||
this.editingService.addModeChangeListener(this);
|
||||
this.controlService = editingService;
|
||||
if (this.controlService != null) {
|
||||
this.controlService.addModeChangeListener(this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void modeChanged(Trace trace, StateEditingMode mode) {
|
||||
public void modeChanged(Trace trace, ControlMode mode) {
|
||||
Swing.runIfSwingOrRunLater(() -> {
|
||||
reloadBreakpointLocations(trace);
|
||||
contextChanged();
|
||||
|
@ -860,9 +860,9 @@ public class DebuggerBreakpointsProvider extends ComponentProviderAdapter
|
|||
}
|
||||
|
||||
private void loadBreakpointLocations(Trace trace) {
|
||||
StateEditingMode mode = editingService == null
|
||||
? StateEditingMode.DEFAULT
|
||||
: editingService.getCurrentMode(trace);
|
||||
ControlMode mode = controlService == null
|
||||
? ControlMode.DEFAULT
|
||||
: controlService.getCurrentMode(trace);
|
||||
DebuggerCoordinates currentFor = traceManager.getCurrentFor(trace);
|
||||
TraceRecorder recorder = currentFor.getRecorder();
|
||||
if (!mode.useEmulatedBreakpoints() && recorder == null) {
|
||||
|
@ -1197,7 +1197,7 @@ public class DebuggerBreakpointsProvider extends ComponentProviderAdapter
|
|||
}
|
||||
|
||||
private boolean isAllInvolvedTracesUsingEmulatedBreakpoints(ActionContext ctx) {
|
||||
if (editingService == null) {
|
||||
if (controlService == null) {
|
||||
return false;
|
||||
}
|
||||
Set<Trace> traces = new HashSet<>();
|
||||
|
@ -1223,7 +1223,7 @@ public class DebuggerBreakpointsProvider extends ComponentProviderAdapter
|
|||
return false;
|
||||
}
|
||||
for (Trace trace : traces) {
|
||||
if (!editingService.getCurrentMode(trace).useEmulatedBreakpoints()) {
|
||||
if (!controlService.getCurrentMode(trace).useEmulatedBreakpoints()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,16 +21,15 @@ import java.util.concurrent.CompletableFuture;
|
|||
import java.util.function.BiPredicate;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import javax.swing.Icon;
|
||||
import javax.swing.KeyStroke;
|
||||
|
||||
import docking.ActionContext;
|
||||
import docking.DockingContextListener;
|
||||
import docking.action.DockingAction;
|
||||
import docking.action.DockingActionIf;
|
||||
import docking.action.builder.*;
|
||||
import docking.action.*;
|
||||
import docking.action.builder.AbstractActionBuilder;
|
||||
import docking.action.builder.ActionBuilder;
|
||||
import docking.menu.ActionState;
|
||||
import docking.menu.MultiStateDockingAction;
|
||||
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.service.emulation.DebuggerPcodeMachine;
|
||||
import ghidra.app.services.*;
|
||||
import ghidra.app.services.DebuggerControlService.ControlModeChangeListener;
|
||||
import ghidra.app.services.DebuggerEmulationService.CachedEmulator;
|
||||
import ghidra.app.services.DebuggerEmulationService.EmulatorStateListener;
|
||||
import ghidra.app.services.DebuggerStateEditingService.StateEditingModeChangeListener;
|
||||
import ghidra.app.services.DebuggerTraceManagerService.ActivationCause;
|
||||
import ghidra.async.AsyncUtils;
|
||||
import ghidra.dbg.DebuggerObjectModel;
|
||||
|
@ -71,7 +70,7 @@ import ghidra.util.*;
|
|||
ModelObjectFocusedPluginEvent.class,
|
||||
},
|
||||
servicesRequired = {
|
||||
DebuggerStateEditingService.class,
|
||||
DebuggerControlService.class,
|
||||
DebuggerTraceManagerService.class,
|
||||
})
|
||||
public class DebuggerControlPlugin extends AbstractDebuggerPlugin
|
||||
|
@ -210,22 +209,37 @@ public class DebuggerControlPlugin extends AbstractDebuggerPlugin
|
|||
String GROUP = DebuggerResources.GROUP_CONTROL;
|
||||
}
|
||||
|
||||
interface ControlModeAction {
|
||||
String NAME = "Control Mode";
|
||||
String DESCRIPTION = "Choose what to control and edit in dynamic views";
|
||||
String GROUP = DebuggerResources.GROUP_CONTROL;
|
||||
String HELP_ANCHOR = "control_mode";
|
||||
protected class ControlModeAction extends MultiStateDockingAction<ControlMode> {
|
||||
public static final String NAME = "Control Mode";
|
||||
public static final String DESCRIPTION = "Choose what to control and edit in dynamic views";
|
||||
public static final String GROUP = DebuggerResources.GROUP_CONTROL;
|
||||
public static final String HELP_ANCHOR = "control_mode";
|
||||
|
||||
static MultiStateActionBuilder<StateEditingMode> builder(Plugin owner) {
|
||||
String ownerName = owner.getName();
|
||||
return new MultiStateActionBuilder<StateEditingMode>(NAME, ownerName)
|
||||
.description(DESCRIPTION)
|
||||
.toolBarIcon(DebuggerResources.ICON_BLANK) // Docs say required
|
||||
.toolBarGroup(GROUP, "")
|
||||
.helpLocation(new HelpLocation(ownerName, HELP_ANCHOR))
|
||||
.addStates(Stream.of(StateEditingMode.values())
|
||||
.map(m -> new ActionState<>(m.name, m.icon, m))
|
||||
.collect(Collectors.toList()));
|
||||
public ControlModeAction() {
|
||||
super(NAME, DebuggerControlPlugin.this.getName());
|
||||
setDescription(DESCRIPTION);
|
||||
setToolBarData(new ToolBarData(DebuggerResources.ICON_BLANK, GROUP, ""));
|
||||
setHelpLocation(new HelpLocation(getOwner(), HELP_ANCHOR));
|
||||
setActionStates(ControlMode.ALL.stream()
|
||||
.map(m -> new ActionState<>(m.name, m.icon, m))
|
||||
.collect(Collectors.toList()));
|
||||
setEnabled(false);
|
||||
}
|
||||
|
||||
@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() {
|
||||
@Override
|
||||
public void running(CachedEmulator emu) {
|
||||
|
@ -561,7 +575,7 @@ public class DebuggerControlPlugin extends AbstractDebuggerPlugin
|
|||
|
||||
protected DebuggerCoordinates current = DebuggerCoordinates.NOWHERE;
|
||||
|
||||
protected MultiStateDockingAction<StateEditingMode> actionEditMode;
|
||||
protected MultiStateDockingAction<ControlMode> actionControlMode;
|
||||
|
||||
DockingAction actionTargetResume;
|
||||
DockingAction actionTargetInterrupt;
|
||||
|
@ -592,7 +606,7 @@ public class DebuggerControlPlugin extends AbstractDebuggerPlugin
|
|||
@AutoServiceConsumed
|
||||
private DebuggerTraceManagerService traceManager;
|
||||
// @AutoServiceConsumed // via method
|
||||
private DebuggerStateEditingService editingService;
|
||||
private DebuggerControlService controlService;
|
||||
// @AutoServiceConsumed // via method
|
||||
private DebuggerEmulationService emulationService;
|
||||
|
||||
|
@ -604,7 +618,7 @@ public class DebuggerControlPlugin extends AbstractDebuggerPlugin
|
|||
createActions();
|
||||
}
|
||||
|
||||
protected Set<DockingAction> getActionSet(StateEditingMode mode) {
|
||||
protected Set<DockingAction> getActionSet(ControlMode mode) {
|
||||
switch (mode) {
|
||||
case RO_TARGET:
|
||||
case RW_TARGET:
|
||||
|
@ -623,7 +637,7 @@ public class DebuggerControlPlugin extends AbstractDebuggerPlugin
|
|||
return getActionSet(computeCurrentEditingMode());
|
||||
}
|
||||
|
||||
protected void updateActionsEnabled(StateEditingMode mode) {
|
||||
protected void updateActionsEnabled(ControlMode mode) {
|
||||
for (DockingAction action : getActionSet(mode)) {
|
||||
action.setEnabled(action.isEnabledForContext(context));
|
||||
}
|
||||
|
@ -640,11 +654,8 @@ public class DebuggerControlPlugin extends AbstractDebuggerPlugin
|
|||
}
|
||||
|
||||
protected void createActions() {
|
||||
actionEditMode = ControlModeAction.builder(this)
|
||||
.enabled(false)
|
||||
.enabledWhen(c -> current.getTrace() != null)
|
||||
.onActionStateChanged(this::activateEditMode)
|
||||
.buildAndInstall(tool);
|
||||
actionControlMode = new ControlModeAction();
|
||||
tool.addAction(actionControlMode);
|
||||
|
||||
actionTargetResume = TargetResumeAction.builder(this)
|
||||
.enabledWhenTarget(this::isActionTargetResumeEnabled)
|
||||
|
@ -720,19 +731,19 @@ public class DebuggerControlPlugin extends AbstractDebuggerPlugin
|
|||
updateActions();
|
||||
}
|
||||
|
||||
protected void activateEditMode(ActionState<StateEditingMode> state, EventTrigger trigger) {
|
||||
protected void activateControlMode(ActionState<ControlMode> state, EventTrigger trigger) {
|
||||
if (current.getTrace() == null) {
|
||||
return;
|
||||
}
|
||||
if (editingService == null) {
|
||||
if (controlService == null) {
|
||||
return;
|
||||
}
|
||||
editingService.setCurrentMode(current.getTrace(), state.getUserData());
|
||||
controlService.setCurrentMode(current.getTrace(), state.getUserData());
|
||||
// TODO: Limit selectable modes?
|
||||
// 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(() -> {
|
||||
if (current.getTrace() == trace) {
|
||||
updateActions();
|
||||
|
@ -971,16 +982,14 @@ public class DebuggerControlPlugin extends AbstractDebuggerPlugin
|
|||
updateActions();
|
||||
}
|
||||
|
||||
private StateEditingMode computeCurrentEditingMode() {
|
||||
// TODO: We're sort of piggy-backing our mode onto that of the editing service.
|
||||
// Seems we should have our own?
|
||||
if (editingService == null) {
|
||||
return StateEditingMode.DEFAULT;
|
||||
private ControlMode computeCurrentEditingMode() {
|
||||
if (controlService == null) {
|
||||
return ControlMode.DEFAULT;
|
||||
}
|
||||
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) {
|
||||
|
@ -1009,8 +1018,8 @@ public class DebuggerControlPlugin extends AbstractDebuggerPlugin
|
|||
}
|
||||
|
||||
private void updateActions() {
|
||||
StateEditingMode mode = computeCurrentEditingMode();
|
||||
actionEditMode.setCurrentActionStateByUserData(mode);
|
||||
ControlMode mode = computeCurrentEditingMode();
|
||||
actionControlMode.setCurrentActionStateByUserData(mode);
|
||||
|
||||
Set<DockingAction> actions = getActionSet(mode);
|
||||
for (Set<DockingAction> set : actionSets) {
|
||||
|
@ -1033,19 +1042,19 @@ public class DebuggerControlPlugin extends AbstractDebuggerPlugin
|
|||
}
|
||||
|
||||
@AutoServiceConsumed
|
||||
protected void setEditingService(DebuggerStateEditingService editingService) {
|
||||
if (this.editingService != null) {
|
||||
this.editingService.removeModeChangeListener(listenerForModeChanges);
|
||||
private void setControlService(DebuggerControlService editingService) {
|
||||
if (this.controlService != null) {
|
||||
this.controlService.removeModeChangeListener(listenerForModeChanges);
|
||||
}
|
||||
this.editingService = editingService;
|
||||
if (this.editingService != null) {
|
||||
this.editingService.addModeChangeListener(listenerForModeChanges);
|
||||
this.controlService = editingService;
|
||||
if (this.controlService != null) {
|
||||
this.controlService.addModeChangeListener(listenerForModeChanges);
|
||||
}
|
||||
updateActions();
|
||||
}
|
||||
|
||||
@AutoServiceConsumed
|
||||
protected void setEmulationService(DebuggerEmulationService emulationService) {
|
||||
private void setEmulationService(DebuggerEmulationService emulationService) {
|
||||
if (this.emulationService != null) {
|
||||
this.emulationService.removeStateListener(listenerForEmuStateChanges);
|
||||
}
|
||||
|
|
|
@ -228,7 +228,7 @@ public class DebuggerListingProvider extends CodeViewerProvider {
|
|||
@AutoServiceConsumed
|
||||
private DebuggerConsoleService consoleService;
|
||||
@AutoServiceConsumed
|
||||
private DebuggerStateEditingService editingService;
|
||||
private DebuggerControlService controlService;
|
||||
@AutoServiceConsumed
|
||||
private ProgramManager programManager;
|
||||
@AutoServiceConsumed
|
||||
|
@ -362,14 +362,14 @@ public class DebuggerListingProvider extends CodeViewerProvider {
|
|||
|
||||
@Override
|
||||
public boolean isReadOnly() {
|
||||
if (editingService == null) {
|
||||
if (controlService == null) {
|
||||
return true;
|
||||
}
|
||||
Trace trace = current.getTrace();
|
||||
if (trace == null) {
|
||||
return true;
|
||||
}
|
||||
StateEditingMode mode = editingService.getCurrentMode(trace);
|
||||
ControlMode mode = controlService.getCurrentMode(trace);
|
||||
return !mode.canEdit(current);
|
||||
}
|
||||
|
||||
|
|
|
@ -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.mapping.DebuggerRegisterMapper;
|
||||
import ghidra.app.services.*;
|
||||
import ghidra.app.services.DebuggerStateEditingService.StateEditor;
|
||||
import ghidra.app.services.DebuggerControlService.StateEditor;
|
||||
import ghidra.async.AsyncLazyValue;
|
||||
import ghidra.async.AsyncUtils;
|
||||
import ghidra.base.widgets.table.DataTypeTableCellEditor;
|
||||
|
@ -476,7 +476,7 @@ public class DebuggerRegistersProvider extends ComponentProviderAdapter
|
|||
@AutoServiceConsumed
|
||||
private DebuggerListingService listingService;
|
||||
@AutoServiceConsumed
|
||||
private DebuggerStateEditingService editingService;
|
||||
private DebuggerControlService controlService;
|
||||
@AutoServiceConsumed
|
||||
private MarkerService markerService; // TODO: Mark address types (separate plugin?)
|
||||
@SuppressWarnings("unused")
|
||||
|
@ -845,10 +845,10 @@ public class DebuggerRegistersProvider extends ComponentProviderAdapter
|
|||
if (!isEditsEnabled()) {
|
||||
return false;
|
||||
}
|
||||
if (editingService == null) {
|
||||
if (controlService == null) {
|
||||
return false;
|
||||
}
|
||||
StateEditor editor = editingService.createStateEditor(current);
|
||||
StateEditor editor = controlService.createStateEditor(current);
|
||||
return editor.isRegisterEditable(register);
|
||||
}
|
||||
|
||||
|
@ -866,11 +866,11 @@ public class DebuggerRegistersProvider extends ComponentProviderAdapter
|
|||
}
|
||||
|
||||
void writeRegisterValue(RegisterValue rv) {
|
||||
if (editingService == null) {
|
||||
Msg.showError(this, getComponent(), "Edit Register", "No editing service.");
|
||||
if (controlService == null) {
|
||||
Msg.showError(this, getComponent(), "Edit Register", "No control service.");
|
||||
return;
|
||||
}
|
||||
StateEditor editor = editingService.createStateEditor(current);
|
||||
StateEditor editor = controlService.createStateEditor(current);
|
||||
if (!editor.isRegisterEditable(rv.getRegister())) {
|
||||
Msg.showError(this, getComponent(), "Edit Register",
|
||||
"Neither the register nor any parent can be edited.");
|
||||
|
|
|
@ -19,7 +19,7 @@ import java.math.BigInteger;
|
|||
import java.util.Objects;
|
||||
|
||||
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.lang.Language;
|
||||
import ghidra.program.model.lang.Register;
|
||||
|
@ -105,8 +105,8 @@ public class RegisterRow {
|
|||
* Attempt to set the register's value
|
||||
*
|
||||
* <p>
|
||||
* The edit will be directed according to the tool's current edit mode. See
|
||||
* {@link DebuggerStateEditingService#getCurrentMode(Trace)}
|
||||
* The edit will be directed according to the tool's current control mode. See
|
||||
* {@link DebuggerControlService#getCurrentMode(Trace)}
|
||||
*
|
||||
* @param value the value
|
||||
*/
|
||||
|
|
|
@ -339,7 +339,7 @@ public class DebuggerWatchesProvider extends ComponentProviderAdapter
|
|||
@AutoServiceConsumed
|
||||
private DebuggerTraceManagerService traceManager; // For goto time (emu mods)
|
||||
@AutoServiceConsumed
|
||||
protected DebuggerStateEditingService editingService;
|
||||
protected DebuggerControlService controlService;
|
||||
@AutoServiceConsumed
|
||||
DebuggerStaticMappingService mappingService;
|
||||
@SuppressWarnings("unused")
|
||||
|
|
|
@ -22,8 +22,8 @@ import java.util.concurrent.CompletableFuture;
|
|||
import ghidra.app.plugin.core.debug.DebuggerCoordinates;
|
||||
import ghidra.app.plugin.processors.sleigh.SleighLanguage;
|
||||
import ghidra.app.services.DataTypeManagerService;
|
||||
import ghidra.app.services.DebuggerStateEditingService;
|
||||
import ghidra.app.services.DebuggerStateEditingService.StateEditor;
|
||||
import ghidra.app.services.DebuggerControlService;
|
||||
import ghidra.app.services.DebuggerControlService.StateEditor;
|
||||
import ghidra.async.AsyncUtils;
|
||||
import ghidra.docking.settings.Settings;
|
||||
import ghidra.docking.settings.SettingsImpl;
|
||||
|
@ -346,11 +346,11 @@ public class WatchRow {
|
|||
if (address == null) {
|
||||
return false;
|
||||
}
|
||||
DebuggerStateEditingService editingService = provider.editingService;
|
||||
if (editingService == null) {
|
||||
DebuggerControlService controlService = provider.controlService;
|
||||
if (controlService == null) {
|
||||
return false;
|
||||
}
|
||||
StateEditor editor = editingService.createStateEditor(provider.current);
|
||||
StateEditor editor = controlService.createStateEditor(provider.current);
|
||||
return editor.isVariableEditable(address, getValueLength());
|
||||
}
|
||||
|
||||
|
@ -397,11 +397,11 @@ public class WatchRow {
|
|||
System.arraycopy(bytes, 0, fillOld, 0, bytes.length);
|
||||
bytes = fillOld;
|
||||
}
|
||||
DebuggerStateEditingService editingService = provider.editingService;
|
||||
if (editingService == null) {
|
||||
throw new AssertionError("No editing service");
|
||||
DebuggerControlService controlService = provider.controlService;
|
||||
if (controlService == null) {
|
||||
throw new AssertionError("No control service");
|
||||
}
|
||||
StateEditor editor = editingService.createStateEditor(provider.current);
|
||||
StateEditor editor = controlService.createStateEditor(provider.current);
|
||||
editor.setVariable(address, bytes).exceptionally(ex -> {
|
||||
Msg.showError(this, null, "Write Failed",
|
||||
"Could not modify watch value (on target)", ex);
|
||||
|
|
|
@ -31,7 +31,7 @@ import ghidra.app.plugin.core.debug.DebuggerCoordinates;
|
|||
import ghidra.app.plugin.core.debug.DebuggerPluginPackage;
|
||||
import ghidra.app.plugin.core.debug.event.*;
|
||||
import ghidra.app.services.*;
|
||||
import ghidra.app.services.DebuggerStateEditingService.StateEditingModeChangeListener;
|
||||
import ghidra.app.services.DebuggerControlService.ControlModeChangeListener;
|
||||
import ghidra.app.services.LogicalBreakpoint.State;
|
||||
import ghidra.async.SwingExecutorService;
|
||||
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
|
||||
public void modeChanged(Trace trace, StateEditingMode mode) {
|
||||
public void modeChanged(Trace trace, ControlMode mode) {
|
||||
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
|
||||
* 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
|
||||
.copyOf(breakpointsByAddress.values())) {
|
||||
for (LogicalBreakpointInternal lb : Set.copyOf(set)) {
|
||||
|
@ -547,7 +547,7 @@ public class DebuggerLogicalBreakpointServicePlugin extends Plugin
|
|||
}
|
||||
|
||||
protected void trackTraceBreakpoints(AddCollector a) {
|
||||
StateEditingMode mode = getMode(trace);
|
||||
ControlMode mode = getMode(trace);
|
||||
if (!mode.useEmulatedBreakpoints() && recorder == null) {
|
||||
return;
|
||||
}
|
||||
|
@ -560,7 +560,7 @@ public class DebuggerLogicalBreakpointServicePlugin extends Plugin
|
|||
}
|
||||
|
||||
protected void trackTraceBreakpoints(AddCollector a,
|
||||
Collection<TraceBreakpoint> breakpoints, StateEditingMode mode) {
|
||||
Collection<TraceBreakpoint> breakpoints, ControlMode mode) {
|
||||
for (TraceBreakpoint tb : breakpoints) {
|
||||
try {
|
||||
trackTraceBreakpoint(a, tb, mode, false);
|
||||
|
@ -587,7 +587,7 @@ public class DebuggerLogicalBreakpointServicePlugin extends Plugin
|
|||
}
|
||||
|
||||
protected void trackTraceBreakpoint(AddCollector a, TraceBreakpoint tb,
|
||||
StateEditingMode mode, boolean forceUpdate)
|
||||
ControlMode mode, boolean forceUpdate)
|
||||
throws TrackedTooSoonException {
|
||||
if (!mode.useEmulatedBreakpoints() &&
|
||||
(recorder == null || recorder.getTargetBreakpoint(tb) == null)) {
|
||||
|
@ -803,7 +803,7 @@ public class DebuggerLogicalBreakpointServicePlugin extends Plugin
|
|||
// @AutoServiceConsumed via method
|
||||
private DebuggerStaticMappingService mappingService;
|
||||
// @AutoServiceConsumed via method
|
||||
private DebuggerStateEditingService editingService;
|
||||
private DebuggerControlService controlService;
|
||||
@SuppressWarnings("unused")
|
||||
private final AutoService.Wiring autoServiceWiring;
|
||||
|
||||
|
@ -921,13 +921,13 @@ public class DebuggerLogicalBreakpointServicePlugin extends Plugin
|
|||
}
|
||||
|
||||
@AutoServiceConsumed
|
||||
public void setEditingService(DebuggerStateEditingService editingService) {
|
||||
if (this.editingService != null) {
|
||||
this.editingService.removeModeChangeListener(modeListener);
|
||||
private void setControlService(DebuggerControlService editingService) {
|
||||
if (this.controlService != null) {
|
||||
this.controlService.removeModeChangeListener(modeListener);
|
||||
}
|
||||
this.editingService = editingService;
|
||||
if (this.editingService != null) {
|
||||
this.editingService.addModeChangeListener(modeListener);
|
||||
this.controlService = editingService;
|
||||
if (this.controlService != null) {
|
||||
this.controlService.addModeChangeListener(modeListener);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1248,16 +1248,16 @@ public class DebuggerLogicalBreakpointServicePlugin extends Plugin
|
|||
}, (actions, lbi) -> lbi.planDelete(actions, trace));
|
||||
}
|
||||
|
||||
private StateEditingMode getMode(Trace trace) {
|
||||
return editingService == null
|
||||
? StateEditingMode.DEFAULT
|
||||
: editingService.getCurrentMode(trace);
|
||||
private ControlMode getMode(Trace trace) {
|
||||
return controlService == null
|
||||
? ControlMode.DEFAULT
|
||||
: controlService.getCurrentMode(trace);
|
||||
}
|
||||
|
||||
private void planActOnLoc(BreakpointActionSet actions, TraceBreakpoint tb,
|
||||
BiConsumer<BreakpointActionSet, TargetBreakpointLocation> targetLocConsumer,
|
||||
BiConsumer<BreakpointActionSet, TraceBreakpoint> emuLocConsumer) {
|
||||
StateEditingMode mode = getMode(tb.getTrace());
|
||||
ControlMode mode = getMode(tb.getTrace());
|
||||
if (mode.useEmulatedBreakpoints()) {
|
||||
planActOnLocEmu(actions, tb, emuLocConsumer);
|
||||
}
|
||||
|
|
|
@ -78,9 +78,9 @@ class TraceBreakpointSet {
|
|||
this.recorder = recorder;
|
||||
}
|
||||
|
||||
private StateEditingMode getStateEditingMode() {
|
||||
DebuggerStateEditingService service = tool.getService(DebuggerStateEditingService.class);
|
||||
return service == null ? StateEditingMode.DEFAULT : service.getCurrentMode(trace);
|
||||
private ControlMode getControlMode() {
|
||||
DebuggerControlService service = tool.getService(DebuggerControlService.class);
|
||||
return service == null ? ControlMode.DEFAULT : service.getCurrentMode(trace);
|
||||
}
|
||||
|
||||
private long getSnap() {
|
||||
|
@ -139,7 +139,7 @@ class TraceBreakpointSet {
|
|||
*/
|
||||
public TraceMode computeMode() {
|
||||
TraceMode mode = TraceMode.NONE;
|
||||
if (getStateEditingMode().useEmulatedBreakpoints()) {
|
||||
if (getControlMode().useEmulatedBreakpoints()) {
|
||||
for (IDHashed<TraceBreakpoint> bpt : breakpoints) {
|
||||
mode = mode.combine(computeEmuMode(bpt.obj));
|
||||
if (mode == TraceMode.MISSING) {
|
||||
|
@ -169,7 +169,7 @@ class TraceBreakpointSet {
|
|||
* @return the mode
|
||||
*/
|
||||
public TraceMode computeMode(TraceBreakpoint bpt) {
|
||||
return getStateEditingMode().useEmulatedBreakpoints()
|
||||
return getControlMode().useEmulatedBreakpoints()
|
||||
? computeEmuMode(bpt)
|
||||
: computeTargetMode(bpt);
|
||||
}
|
||||
|
@ -318,7 +318,7 @@ class TraceBreakpointSet {
|
|||
Collection<TraceBreakpointKind> kinds) {
|
||||
long snap = getSnap();
|
||||
if (breakpoints.isEmpty()) {
|
||||
if (recorder == null || getStateEditingMode().useEmulatedBreakpoints()) {
|
||||
if (recorder == null || getControlMode().useEmulatedBreakpoints()) {
|
||||
planPlaceEmu(actions, snap, length, kinds);
|
||||
}
|
||||
else {
|
||||
|
@ -326,7 +326,7 @@ class TraceBreakpointSet {
|
|||
}
|
||||
}
|
||||
else {
|
||||
if (recorder == null || getStateEditingMode().useEmulatedBreakpoints()) {
|
||||
if (recorder == null || getControlMode().useEmulatedBreakpoints()) {
|
||||
planEnableEmu(actions);
|
||||
}
|
||||
else {
|
||||
|
@ -384,7 +384,7 @@ class TraceBreakpointSet {
|
|||
*/
|
||||
public void planDisable(BreakpointActionSet actions, long length,
|
||||
Collection<TraceBreakpointKind> kinds) {
|
||||
if (getStateEditingMode().useEmulatedBreakpoints()) {
|
||||
if (getControlMode().useEmulatedBreakpoints()) {
|
||||
planDisableEmu(actions);
|
||||
}
|
||||
else {
|
||||
|
@ -427,7 +427,7 @@ class TraceBreakpointSet {
|
|||
*/
|
||||
public void planDelete(BreakpointActionSet actions, long length,
|
||||
Set<TraceBreakpointKind> kinds) {
|
||||
if (getStateEditingMode().useEmulatedBreakpoints()) {
|
||||
if (getControlMode().useEmulatedBreakpoints()) {
|
||||
planDeleteEmu(actions);
|
||||
}
|
||||
else {
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* 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.util.*;
|
||||
|
@ -36,8 +36,8 @@ import ghidra.trace.model.program.TraceProgramViewMemory;
|
|||
import ghidra.util.datastruct.ListenerSet;
|
||||
|
||||
@PluginInfo(
|
||||
shortDescription = "Debugger machine-state editing service plugin",
|
||||
description = "Centralizes machine-state editing across the tool",
|
||||
shortDescription = "Debugger control and machine-state editing service plugin",
|
||||
description = "Centralizes control and machine-state editing across the tool",
|
||||
category = PluginCategoryNames.DEBUGGER,
|
||||
packageName = DebuggerPluginPackage.NAME,
|
||||
status = PluginStatus.RELEASED,
|
||||
|
@ -51,10 +51,10 @@ import ghidra.util.datastruct.ListenerSet;
|
|||
DebuggerEmulationService.class,
|
||||
},
|
||||
servicesProvided = {
|
||||
DebuggerStateEditingService.class,
|
||||
DebuggerControlService.class,
|
||||
})
|
||||
public class DebuggerStateEditingServicePlugin extends AbstractDebuggerPlugin
|
||||
implements DebuggerStateEditingService {
|
||||
public class DebuggerControlServicePlugin extends AbstractDebuggerPlugin
|
||||
implements DebuggerControlService {
|
||||
|
||||
protected abstract class AbstractStateEditor implements StateEditor {
|
||||
@Override
|
||||
|
@ -80,8 +80,8 @@ public class DebuggerStateEditingServicePlugin extends AbstractDebuggerPlugin
|
|||
}
|
||||
|
||||
@Override
|
||||
public DebuggerStateEditingService getService() {
|
||||
return DebuggerStateEditingServicePlugin.this;
|
||||
public DebuggerControlService getService() {
|
||||
return DebuggerControlServicePlugin.this;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -98,8 +98,8 @@ public class DebuggerStateEditingServicePlugin extends AbstractDebuggerPlugin
|
|||
}
|
||||
|
||||
@Override
|
||||
public DebuggerStateEditingService getService() {
|
||||
return DebuggerStateEditingServicePlugin.this;
|
||||
public DebuggerControlService getService() {
|
||||
return DebuggerControlServicePlugin.this;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -121,8 +121,8 @@ public class DebuggerStateEditingServicePlugin extends AbstractDebuggerPlugin
|
|||
}
|
||||
|
||||
@Override
|
||||
public DebuggerStateEditingService getService() {
|
||||
return DebuggerStateEditingServicePlugin.this;
|
||||
public DebuggerControlService getService() {
|
||||
return DebuggerControlServicePlugin.this;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -204,29 +204,27 @@ public class DebuggerStateEditingServicePlugin extends AbstractDebuggerPlugin
|
|||
protected final ListenerForEditorInstallation listenerForEditorInstallation =
|
||||
new ListenerForEditorInstallation();
|
||||
|
||||
public DebuggerStateEditingServicePlugin(PluginTool tool) {
|
||||
public DebuggerControlServicePlugin(PluginTool tool) {
|
||||
super(tool);
|
||||
}
|
||||
|
||||
private final Map<Trace, StateEditingMode> currentModes = new HashMap<>();
|
||||
private final Map<Trace, ControlMode> currentModes = new HashMap<>();
|
||||
|
||||
private final ListenerSet<StateEditingModeChangeListener> listeners =
|
||||
new ListenerSet<>(StateEditingModeChangeListener.class);
|
||||
private final ListenerSet<ControlModeChangeListener> listeners =
|
||||
new ListenerSet<>(ControlModeChangeListener.class);
|
||||
|
||||
@Override
|
||||
public StateEditingMode getCurrentMode(Trace trace) {
|
||||
public ControlMode getCurrentMode(Trace trace) {
|
||||
synchronized (currentModes) {
|
||||
return currentModes.getOrDefault(Objects.requireNonNull(trace),
|
||||
StateEditingMode.DEFAULT);
|
||||
return currentModes.getOrDefault(Objects.requireNonNull(trace), ControlMode.DEFAULT);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCurrentMode(Trace trace, StateEditingMode newMode) {
|
||||
StateEditingMode oldMode;
|
||||
public void setCurrentMode(Trace trace, ControlMode newMode) {
|
||||
ControlMode oldMode;
|
||||
synchronized (currentModes) {
|
||||
oldMode =
|
||||
currentModes.getOrDefault(Objects.requireNonNull(trace), StateEditingMode.DEFAULT);
|
||||
oldMode = currentModes.getOrDefault(Objects.requireNonNull(trace), ControlMode.DEFAULT);
|
||||
if (newMode != oldMode) {
|
||||
currentModes.put(trace, newMode);
|
||||
}
|
||||
|
@ -238,12 +236,12 @@ public class DebuggerStateEditingServicePlugin extends AbstractDebuggerPlugin
|
|||
}
|
||||
|
||||
@Override
|
||||
public void addModeChangeListener(StateEditingModeChangeListener listener) {
|
||||
public void addModeChangeListener(ControlModeChangeListener listener) {
|
||||
listeners.add(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeModeChangeListener(StateEditingModeChangeListener listener) {
|
||||
public void removeModeChangeListener(ControlModeChangeListener listener) {
|
||||
listeners.remove(listener);
|
||||
}
|
||||
|
||||
|
@ -270,10 +268,10 @@ public class DebuggerStateEditingServicePlugin extends AbstractDebuggerPlugin
|
|||
if (trace == null) {
|
||||
return;
|
||||
}
|
||||
StateEditingMode oldMode;
|
||||
StateEditingMode newMode;
|
||||
ControlMode oldMode;
|
||||
ControlMode newMode;
|
||||
synchronized (currentModes) {
|
||||
oldMode = currentModes.getOrDefault(trace, StateEditingMode.DEFAULT);
|
||||
oldMode = currentModes.getOrDefault(trace, ControlMode.DEFAULT);
|
||||
newMode = oldMode.modeOnChange(coordinates);
|
||||
if (newMode != oldMode) {
|
||||
currentModes.put(trace, newMode);
|
|
@ -267,7 +267,7 @@ public class DebuggerEmulationServicePlugin extends Plugin implements DebuggerEm
|
|||
@AutoServiceConsumed
|
||||
private DebuggerStaticMappingService staticMappings;
|
||||
@AutoServiceConsumed
|
||||
private DebuggerStateEditingService editingService;
|
||||
private DebuggerControlService controlService;
|
||||
@SuppressWarnings("unused")
|
||||
private AutoService.Wiring autoServiceWiring;
|
||||
|
||||
|
@ -367,8 +367,8 @@ public class DebuggerEmulationServicePlugin extends Plugin implements DebuggerEm
|
|||
trace = ProgramEmulationUtils.launchEmulationTrace(program, ctx.getAddress(), this);
|
||||
traceManager.openTrace(trace);
|
||||
traceManager.activateTrace(trace);
|
||||
if (editingService != null) {
|
||||
editingService.setCurrentMode(trace, StateEditingMode.RW_EMULATOR);
|
||||
if (controlService != null) {
|
||||
controlService.setCurrentMode(trace, ControlMode.RW_EMULATOR);
|
||||
}
|
||||
}
|
||||
catch (IOException e) {
|
||||
|
|
|
@ -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.mapping.DebuggerPlatformMapper;
|
||||
import ghidra.app.services.*;
|
||||
import ghidra.app.services.DebuggerStateEditingService.StateEditingModeChangeListener;
|
||||
import ghidra.app.services.DebuggerControlService.ControlModeChangeListener;
|
||||
import ghidra.async.*;
|
||||
import ghidra.async.AsyncConfigFieldCodec.BooleanAsyncConfigFieldCodec;
|
||||
import ghidra.dbg.target.*;
|
||||
|
@ -234,9 +234,9 @@ public class DebuggerTraceManagerServicePlugin extends Plugin
|
|||
}
|
||||
}
|
||||
|
||||
class ForFollowPresentListener implements StateEditingModeChangeListener {
|
||||
class ForFollowPresentListener implements ControlModeChangeListener {
|
||||
@Override
|
||||
public void modeChanged(Trace trace, StateEditingMode mode) {
|
||||
public void modeChanged(Trace trace, ControlMode mode) {
|
||||
if (trace != current.getTrace() || !mode.followsPresent()) {
|
||||
return;
|
||||
}
|
||||
|
@ -278,7 +278,7 @@ public class DebuggerTraceManagerServicePlugin extends Plugin
|
|||
@AutoServiceConsumed
|
||||
private DebuggerPlatformService platformService;
|
||||
// @AutoServiceConsumed via method
|
||||
private DebuggerStateEditingService editingService;
|
||||
private DebuggerControlService controlService;
|
||||
@SuppressWarnings("unused")
|
||||
private final AutoService.Wiring autoServiceWiring;
|
||||
|
||||
|
@ -474,13 +474,13 @@ public class DebuggerTraceManagerServicePlugin extends Plugin
|
|||
}
|
||||
|
||||
@AutoServiceConsumed
|
||||
private void setEditingService(DebuggerStateEditingService editingService) {
|
||||
if (this.editingService != null) {
|
||||
this.editingService.removeModeChangeListener(forFollowPresentListener);
|
||||
private void setControlService(DebuggerControlService editingService) {
|
||||
if (this.controlService != null) {
|
||||
this.controlService.removeModeChangeListener(forFollowPresentListener);
|
||||
}
|
||||
this.editingService = editingService;
|
||||
if (this.editingService != null) {
|
||||
this.editingService.addModeChangeListener(forFollowPresentListener);
|
||||
this.controlService = editingService;
|
||||
if (this.controlService != null) {
|
||||
this.controlService.addModeChangeListener(forFollowPresentListener);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -622,9 +622,9 @@ public class DebuggerTraceManagerServicePlugin extends Plugin
|
|||
}
|
||||
|
||||
private boolean isFollowsPresent(Trace trace) {
|
||||
StateEditingMode mode = editingService == null
|
||||
? StateEditingMode.DEFAULT
|
||||
: editingService.getCurrentMode(trace);
|
||||
ControlMode mode = controlService == null
|
||||
? ControlMode.DEFAULT
|
||||
: controlService.getCurrentMode(trace);
|
||||
return mode.followsPresent();
|
||||
}
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ import java.util.concurrent.CompletableFuture;
|
|||
import org.apache.commons.lang3.ArrayUtils;
|
||||
|
||||
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.async.AsyncFence;
|
||||
import ghidra.framework.plugintool.PluginTool;
|
||||
|
|
|
@ -21,7 +21,7 @@ import java.util.concurrent.CompletableFuture;
|
|||
|
||||
import ghidra.app.plugin.core.bookmark.BookmarkNavigator;
|
||||
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.framework.plugintool.PluginTool;
|
||||
import ghidra.pcode.exec.BytesPcodeArithmetic;
|
||||
|
|
|
@ -20,7 +20,7 @@ import java.util.*;
|
|||
import java.util.Map.Entry;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
import ghidra.app.services.DebuggerStateEditingService.StateEditor;
|
||||
import ghidra.app.services.DebuggerControlService.StateEditor;
|
||||
import ghidra.async.AsyncFence;
|
||||
import ghidra.pcode.eval.ArithmeticVarnodeEvaluator;
|
||||
import ghidra.pcode.exec.PcodeArithmetic;
|
||||
|
|
|
@ -20,7 +20,7 @@ import java.util.concurrent.CompletableFuture;
|
|||
|
||||
import ghidra.app.decompiler.ClangLine;
|
||||
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.AddressSetView;
|
||||
import ghidra.program.model.lang.Register;
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
package ghidra.app.services;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
|
@ -47,12 +48,13 @@ import ghidra.util.task.TaskMonitor;
|
|||
/**
|
||||
* The control / state editing modes
|
||||
*/
|
||||
public enum StateEditingMode {
|
||||
public enum ControlMode {
|
||||
/**
|
||||
* Control actions, breakpoint commands are directed to the target, but state edits are
|
||||
* 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
|
||||
public boolean followsPresent() {
|
||||
return true;
|
||||
|
@ -86,14 +88,14 @@ public enum StateEditingMode {
|
|||
}
|
||||
|
||||
@Override
|
||||
public StateEditingMode getAlternative(DebuggerCoordinates coordinates) {
|
||||
public ControlMode getAlternative(DebuggerCoordinates coordinates) {
|
||||
return RO_TRACE;
|
||||
}
|
||||
},
|
||||
/**
|
||||
* 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
|
||||
public boolean followsPresent() {
|
||||
return true;
|
||||
|
@ -142,7 +144,7 @@ public enum StateEditingMode {
|
|||
}
|
||||
|
||||
@Override
|
||||
public StateEditingMode getAlternative(DebuggerCoordinates coordinates) {
|
||||
public ControlMode getAlternative(DebuggerCoordinates coordinates) {
|
||||
return RW_EMULATOR;
|
||||
}
|
||||
},
|
||||
|
@ -150,7 +152,7 @@ public enum StateEditingMode {
|
|||
* Control actions activate trace snapshots, breakpoint commands are directed to the emulator,
|
||||
* 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
|
||||
public boolean followsPresent() {
|
||||
return false;
|
||||
|
@ -182,7 +184,7 @@ public enum StateEditingMode {
|
|||
* Control actions activate trace snapshots, breakpoint commands are directed to the emulator,
|
||||
* 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
|
||||
public boolean followsPresent() {
|
||||
return false;
|
||||
|
@ -249,7 +251,7 @@ public enum StateEditingMode {
|
|||
* Edits are accomplished by appending patch steps to the current schedule and activating that
|
||||
* 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
|
||||
public boolean followsPresent() {
|
||||
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 Icon icon;
|
||||
|
||||
private StateEditingMode(String name, Icon icon) {
|
||||
private ControlMode(String name, Icon icon) {
|
||||
this.name = name;
|
||||
this.icon = icon;
|
||||
}
|
||||
|
@ -408,7 +411,7 @@ public enum StateEditingMode {
|
|||
* @param coordinates the new coordinates
|
||||
* @return the new mode
|
||||
*/
|
||||
public StateEditingMode getAlternative(DebuggerCoordinates coordinates) {
|
||||
public ControlMode getAlternative(DebuggerCoordinates coordinates) {
|
||||
throw new AssertionError("INTERNAL: Non-selectable mode must provide alternative");
|
||||
}
|
||||
|
||||
|
@ -422,7 +425,7 @@ public enum StateEditingMode {
|
|||
* @param coordinates the new coordinates
|
||||
* @return the mode
|
||||
*/
|
||||
public StateEditingMode modeOnChange(DebuggerCoordinates coordinates) {
|
||||
public ControlMode modeOnChange(DebuggerCoordinates coordinates) {
|
||||
if (isSelectable(coordinates)) {
|
||||
return this;
|
||||
}
|
|
@ -18,7 +18,7 @@ package ghidra.app.services;
|
|||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
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.pcode.utils.Utils;
|
||||
import ghidra.program.model.address.Address;
|
||||
|
@ -28,11 +28,11 @@ import ghidra.trace.model.Trace;
|
|||
import ghidra.trace.model.program.TraceProgramView;
|
||||
|
||||
@ServiceInfo(
|
||||
defaultProvider = DebuggerStateEditingServicePlugin.class,
|
||||
defaultProvider = DebuggerControlServicePlugin.class,
|
||||
description = "Centralized service for modifying machine states")
|
||||
public interface DebuggerStateEditingService {
|
||||
public interface DebuggerControlService {
|
||||
interface StateEditor {
|
||||
DebuggerStateEditingService getService();
|
||||
DebuggerControlService getService();
|
||||
|
||||
DebuggerCoordinates getCoordinates();
|
||||
|
||||
|
@ -55,17 +55,17 @@ public interface DebuggerStateEditingService {
|
|||
interface StateEditingMemoryHandler extends StateEditor, LiveMemoryHandler {
|
||||
}
|
||||
|
||||
interface StateEditingModeChangeListener {
|
||||
void modeChanged(Trace trace, StateEditingMode mode);
|
||||
interface ControlModeChangeListener {
|
||||
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);
|
||||
|
|
@ -30,7 +30,7 @@ import ghidra.app.plugin.core.debug.service.model.launch.DebuggerProgramLaunchOf
|
|||
import ghidra.app.script.GhidraScript;
|
||||
import ghidra.app.script.GhidraState;
|
||||
import ghidra.app.services.*;
|
||||
import ghidra.app.services.DebuggerStateEditingService.StateEditor;
|
||||
import ghidra.app.services.DebuggerControlService.StateEditor;
|
||||
import ghidra.dbg.AnnotatedDebuggerAttributeListener;
|
||||
import ghidra.dbg.DebuggerObjectModel;
|
||||
import ghidra.dbg.target.*;
|
||||
|
@ -1182,40 +1182,40 @@ public interface FlatDebuggerAPI {
|
|||
}
|
||||
|
||||
/**
|
||||
* Get the state editing service
|
||||
* Get the control service
|
||||
*
|
||||
* @return the service
|
||||
*/
|
||||
default DebuggerStateEditingService getEditingService() {
|
||||
return requireService(DebuggerStateEditingService.class);
|
||||
default DebuggerControlService getControlService() {
|
||||
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 mode the mode
|
||||
*/
|
||||
default void setEditingMode(Trace trace, StateEditingMode mode) {
|
||||
requireService(DebuggerStateEditingService.class).setCurrentMode(trace, mode);
|
||||
default void setControlMode(Trace trace, ControlMode 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
|
||||
*/
|
||||
default void setEditingMode(StateEditingMode mode) {
|
||||
setEditingMode(requireCurrentTrace(), mode);
|
||||
default void setControlMode(ControlMode 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
|
||||
*/
|
||||
default StateEditor createStateEditor(DebuggerCoordinates coordinates) {
|
||||
return getEditingService().createStateEditor(coordinates);
|
||||
return getControlService().createStateEditor(coordinates);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1226,7 +1226,7 @@ public interface FlatDebuggerAPI {
|
|||
* @return the editor
|
||||
*/
|
||||
default StateEditor createStateEditor(Trace trace, long snap) {
|
||||
return getEditingService().createStateEditor(getTraceManager()
|
||||
return getControlService().createStateEditor(getTraceManager()
|
||||
.resolveTrace(trace)
|
||||
.snap(snap));
|
||||
}
|
||||
|
@ -1240,14 +1240,14 @@ public interface FlatDebuggerAPI {
|
|||
* @return the editor
|
||||
*/
|
||||
default StateEditor createStateEditor(TraceThread thread, int frame, long snap) {
|
||||
return getEditingService().createStateEditor(getTraceManager()
|
||||
return getControlService().createStateEditor(getTraceManager()
|
||||
.resolveThread(thread)
|
||||
.snap(snap)
|
||||
.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
|
||||
*/
|
||||
|
@ -1260,7 +1260,7 @@ public interface FlatDebuggerAPI {
|
|||
*
|
||||
* <p>
|
||||
* 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
|
||||
* 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
|
||||
|
@ -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>
|
||||
* 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>
|
||||
* If you intend to apply several patches, consider using {@link #createStateEditor()} and
|
||||
|
@ -1324,7 +1324,7 @@ public interface FlatDebuggerAPI {
|
|||
*
|
||||
* <p>
|
||||
* 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
|
||||
* 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
|
||||
|
@ -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>
|
||||
* 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)
|
||||
* @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>
|
||||
* 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)
|
||||
* @throws IllegalArgumentException if the register name is invalid
|
||||
|
|
|
@ -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.listing.DebuggerListingPlugin;
|
||||
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.ProgramEmulationUtils;
|
||||
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.services.*;
|
||||
import ghidra.app.services.DebuggerEmulationService.EmulationResult;
|
||||
import ghidra.app.services.DebuggerStateEditingService.StateEditor;
|
||||
import ghidra.app.services.DebuggerControlService.StateEditor;
|
||||
import ghidra.async.AsyncTestUtils;
|
||||
import ghidra.framework.model.DomainFolder;
|
||||
import ghidra.framework.model.DomainObject;
|
||||
|
@ -278,8 +278,7 @@ public class DebuggerStackPluginScreenShots extends GhidraScreenShotGenerator
|
|||
public void testCaptureDebuggerStackUnwindInListing() throws Throwable {
|
||||
addPlugin(tool, DebuggerListingPlugin.class);
|
||||
|
||||
DebuggerStateEditingService editingService =
|
||||
addPlugin(tool, DebuggerStateEditingServicePlugin.class);
|
||||
DebuggerControlService controlService = addPlugin(tool, DebuggerControlServicePlugin.class);
|
||||
DebuggerEmulationService emuService = addPlugin(tool, DebuggerEmulationServicePlugin.class);
|
||||
|
||||
Function function = createFibonacciProgramX86_32();
|
||||
|
@ -296,8 +295,8 @@ public class DebuggerStackPluginScreenShots extends GhidraScreenShotGenerator
|
|||
traceManager.activateThread(thread);
|
||||
waitForSwing();
|
||||
|
||||
editingService.setCurrentMode(tb.trace, StateEditingMode.RW_TRACE);
|
||||
StateEditor editor = editingService.createStateEditor(tb.trace);
|
||||
controlService.setCurrentMode(tb.trace, ControlMode.RW_TRACE);
|
||||
StateEditor editor = controlService.createStateEditor(tb.trace);
|
||||
|
||||
DebuggerCoordinates atSetup = traceManager.getCurrent();
|
||||
StackUnwinder unwinder = new StackUnwinder(tool, atSetup.getPlatform());
|
||||
|
|
|
@ -34,7 +34,7 @@ import ghidra.app.plugin.core.codebrowser.CodeViewerProvider;
|
|||
import ghidra.app.plugin.core.debug.DebuggerCoordinates;
|
||||
import ghidra.app.plugin.core.debug.gui.listing.DebuggerListingPlugin;
|
||||
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.ProgramEmulationUtils;
|
||||
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.services.*;
|
||||
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.async.AsyncTestUtils;
|
||||
import ghidra.framework.model.DomainFolder;
|
||||
|
@ -227,8 +227,7 @@ public class VariableValueHoverPluginScreenShots extends GhidraScreenShotGenerat
|
|||
addPlugin(tool, DebuggerListingPlugin.class);
|
||||
addPlugin(tool, VariableValueHoverPlugin.class);
|
||||
|
||||
DebuggerStateEditingService editingService =
|
||||
addPlugin(tool, DebuggerStateEditingServicePlugin.class);
|
||||
DebuggerControlService controlService = addPlugin(tool, DebuggerControlServicePlugin.class);
|
||||
DebuggerEmulationService emuService = addPlugin(tool, DebuggerEmulationServicePlugin.class);
|
||||
|
||||
Function function = createFibonacciProgramX86_32();
|
||||
|
@ -258,8 +257,8 @@ public class VariableValueHoverPluginScreenShots extends GhidraScreenShotGenerat
|
|||
}
|
||||
waitForDomainObject(tb.trace);
|
||||
|
||||
editingService.setCurrentMode(tb.trace, StateEditingMode.RW_TRACE);
|
||||
StateEditor editor = editingService.createStateEditor(tb.trace);
|
||||
controlService.setCurrentMode(tb.trace, ControlMode.RW_TRACE);
|
||||
StateEditor editor = controlService.createStateEditor(tb.trace);
|
||||
|
||||
DebuggerCoordinates atSetup = traceManager.getCurrent();
|
||||
StackUnwinder unwinder = new StackUnwinder(tool, atSetup.getPlatform());
|
||||
|
|
|
@ -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.listing.DebuggerListingPlugin;
|
||||
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.workflow.DebuggerWorkflowServiceProxyPlugin;
|
||||
import ghidra.app.plugin.core.debug.workflow.DisassembleAtPcDebuggerBot;
|
||||
|
@ -405,12 +405,11 @@ public class DebuggerDisassemblyTest extends AbstractGhidraHeadedDebuggerGUITest
|
|||
@Test
|
||||
public void testCurrentAssembleActionHostArm() throws Throwable {
|
||||
// Assemble actions will think read-only otherwise
|
||||
DebuggerStateEditingService editingService =
|
||||
addPlugin(tool, DebuggerStateEditingServicePlugin.class);
|
||||
DebuggerControlService controlService = addPlugin(tool, DebuggerControlServicePlugin.class);
|
||||
|
||||
createLegacyTrace("ARM:LE:32:v8", 0x00400000, () -> tb.buf(0x00, 0x00, 0x00, 0x00));
|
||||
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
|
||||
assertNotNull(platformService.getMapper(tb.trace, null, 0));
|
||||
|
@ -437,13 +436,12 @@ public class DebuggerDisassemblyTest extends AbstractGhidraHeadedDebuggerGUITest
|
|||
@Test
|
||||
public void testCurrentAssembleActionHostThumb() throws Throwable {
|
||||
// Assemble actions will think read-only otherwise
|
||||
DebuggerStateEditingService editingService =
|
||||
addPlugin(tool, DebuggerStateEditingServicePlugin.class);
|
||||
DebuggerControlService controlService = addPlugin(tool, DebuggerControlServicePlugin.class);
|
||||
|
||||
// Don't cheat here and choose v8T!
|
||||
createLegacyTrace("ARM:LE:32:v8", 0x00400000, () -> tb.buf(0x00, 0x00));
|
||||
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
|
||||
assertNotNull(platformService.getMapper(tb.trace, null, 0));
|
||||
|
@ -474,13 +472,12 @@ public class DebuggerDisassemblyTest extends AbstractGhidraHeadedDebuggerGUITest
|
|||
@Test
|
||||
public void testCurrentAssembleActionGuestArm() throws Throwable {
|
||||
// Assemble actions will think read-only otherwise
|
||||
DebuggerStateEditingService editingService =
|
||||
addPlugin(tool, DebuggerStateEditingServicePlugin.class);
|
||||
DebuggerControlService controlService = addPlugin(tool, DebuggerControlServicePlugin.class);
|
||||
|
||||
TraceObjectThread thread =
|
||||
createPolyglotTrace("armv8le", 0x00400000, () -> tb.buf(0x00, 0x00, 0x00, 0x00));
|
||||
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
|
||||
assertNotNull(platformService.getMapper(tb.trace, thread.getObject(), 0));
|
||||
|
@ -509,13 +506,12 @@ public class DebuggerDisassemblyTest extends AbstractGhidraHeadedDebuggerGUITest
|
|||
@Test
|
||||
public void testCurrentAssembleActionGuestThumb() throws Throwable {
|
||||
// Assemble actions will think read-only otherwise
|
||||
DebuggerStateEditingService editingService =
|
||||
addPlugin(tool, DebuggerStateEditingServicePlugin.class);
|
||||
DebuggerControlService controlService = addPlugin(tool, DebuggerControlServicePlugin.class);
|
||||
|
||||
TraceObjectThread thread =
|
||||
createPolyglotTrace("armv8le", 0x00400000, () -> tb.buf(0x00, 0x00));
|
||||
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
|
||||
assertNotNull(platformService.getMapper(tb.trace, thread.getObject(), 0));
|
||||
|
@ -567,12 +563,11 @@ public class DebuggerDisassemblyTest extends AbstractGhidraHeadedDebuggerGUITest
|
|||
@Test
|
||||
public void testFixedAssembleActionsHostArm() throws Throwable {
|
||||
// Assemble actions will think read-only otherwise
|
||||
DebuggerStateEditingService editingService =
|
||||
addPlugin(tool, DebuggerStateEditingServicePlugin.class);
|
||||
DebuggerControlService controlService = addPlugin(tool, DebuggerControlServicePlugin.class);
|
||||
|
||||
createLegacyTrace("ARM:LE:32:v8", 0x00400000, () -> tb.buf());
|
||||
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
|
||||
assertNotNull(platformService.getMapper(tb.trace, null, 0));
|
||||
|
@ -587,12 +582,11 @@ public class DebuggerDisassemblyTest extends AbstractGhidraHeadedDebuggerGUITest
|
|||
@Test
|
||||
public void testFixedAssembleActionsGuestArm() throws Throwable {
|
||||
// Assemble actions will think read-only otherwise
|
||||
DebuggerStateEditingService editingService =
|
||||
addPlugin(tool, DebuggerStateEditingServicePlugin.class);
|
||||
DebuggerControlService controlService = addPlugin(tool, DebuggerControlServicePlugin.class);
|
||||
|
||||
TraceObjectThread thread = createPolyglotTrace("armv8le", 0x00400000, () -> tb.buf());
|
||||
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
|
||||
assertNotNull(platformService.getMapper(tb.trace, thread.getObject(), 0));
|
||||
|
@ -607,12 +601,11 @@ public class DebuggerDisassemblyTest extends AbstractGhidraHeadedDebuggerGUITest
|
|||
@Test
|
||||
public void testFixedAssembleActionsGuestThumb() throws Throwable {
|
||||
// Assemble actions will think read-only otherwise
|
||||
DebuggerStateEditingService editingService =
|
||||
addPlugin(tool, DebuggerStateEditingServicePlugin.class);
|
||||
DebuggerControlService controlService = addPlugin(tool, DebuggerControlServicePlugin.class);
|
||||
|
||||
TraceObjectThread thread = createPolyglotTrace("armv8le", 0x00400000, () -> tb.buf());
|
||||
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
|
||||
assertNotNull(platformService.getMapper(tb.trace, thread.getObject(), 0));
|
||||
|
|
|
@ -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.breakpoint.DebuggerBreakpointsProvider.LogicalBreakpointTableModel;
|
||||
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.modules.DebuggerStaticMappingUtils;
|
||||
import ghidra.app.services.*;
|
||||
|
@ -689,7 +689,7 @@ public class DebuggerBreakpointsProviderTest extends AbstractGhidraHeadedDebugge
|
|||
|
||||
@Test
|
||||
public void testEmuBreakpointState() throws Throwable {
|
||||
addPlugin(tool, DebuggerStateEditingServicePlugin.class);
|
||||
addPlugin(tool, DebuggerControlServicePlugin.class);
|
||||
|
||||
createProgram();
|
||||
intoProject(program);
|
||||
|
@ -733,8 +733,8 @@ public class DebuggerBreakpointsProviderTest extends AbstractGhidraHeadedDebugge
|
|||
|
||||
@Test
|
||||
public void testTablesAndStatesWhenhModeChanges() throws Throwable {
|
||||
DebuggerStateEditingService editingService =
|
||||
addPlugin(tool, DebuggerStateEditingServicePlugin.class);
|
||||
DebuggerControlService controlService =
|
||||
addPlugin(tool, DebuggerControlServicePlugin.class);
|
||||
|
||||
createTestModel();
|
||||
mb.createTestProcessesAndThreads();
|
||||
|
@ -764,7 +764,7 @@ public class DebuggerBreakpointsProviderTest extends AbstractGhidraHeadedDebugge
|
|||
return newRow;
|
||||
});
|
||||
|
||||
editingService.setCurrentMode(trace, StateEditingMode.RW_EMULATOR);
|
||||
controlService.setCurrentMode(trace, ControlMode.RW_EMULATOR);
|
||||
lbRow1.setEnabled(true);
|
||||
TraceBreakpoint emuBpt = waitForValue(
|
||||
() -> Unique.assertAtMostOne(trace.getBreakpointManager().getAllBreakpoints()));
|
||||
|
@ -781,12 +781,12 @@ public class DebuggerBreakpointsProviderTest extends AbstractGhidraHeadedDebugge
|
|||
});
|
||||
|
||||
for (int i = 0; i < 3; i++) {
|
||||
editingService.setCurrentMode(trace, StateEditingMode.RO_TARGET);
|
||||
controlService.setCurrentMode(trace, ControlMode.RO_TARGET);
|
||||
waitOn(breakpointService.changesSettled());
|
||||
waitForSwing();
|
||||
assertEquals(0, breakpointsProvider.locationTableModel.getModelData().size());
|
||||
|
||||
editingService.setCurrentMode(trace, StateEditingMode.RW_EMULATOR);
|
||||
controlService.setCurrentMode(trace, ControlMode.RW_EMULATOR);
|
||||
waitOn(breakpointService.changesSettled());
|
||||
waitForSwing();
|
||||
assertEquals(1, breakpointsProvider.locationTableModel.getModelData().size());
|
||||
|
|
|
@ -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.mapping.DebuggerTargetTraceMapper;
|
||||
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.services.*;
|
||||
import ghidra.app.services.DebuggerEmulationService.CachedEmulator;
|
||||
|
@ -71,15 +71,14 @@ import ghidra.util.database.UndoableTransaction;
|
|||
* Tests for target control and state editing
|
||||
*
|
||||
* <p>
|
||||
* In these and other machine-state-editing integration tests, we use
|
||||
* {@link StateEditingMode#RW_EMULATOR} as a stand-in for any mode. We also use
|
||||
* {@link StateEditingMode#RO_TARGET} just to verify the mode is heeded. Other modes may be tested
|
||||
* if bugs crop up in various combinations.
|
||||
* In these and other control service integration tests, we use {@link ControlMode#RW_EMULATOR} as a
|
||||
* stand-in for any mode. We also use {@link ControlMode#RO_TARGET} just to verify the mode is
|
||||
* heeded. Other modes may be tested if bugs crop up in various combinations.
|
||||
*/
|
||||
public class DebuggerControlPluginTest extends AbstractGhidraHeadedDebuggerGUITest {
|
||||
|
||||
DebuggerListingPlugin listingPlugin;
|
||||
DebuggerStateEditingService editingService;
|
||||
DebuggerControlService controlService;
|
||||
DebuggerEmulationService emulationService;
|
||||
DebuggerControlPlugin controlPlugin;
|
||||
|
||||
|
@ -88,7 +87,7 @@ public class DebuggerControlPluginTest extends AbstractGhidraHeadedDebuggerGUITe
|
|||
@Before
|
||||
public void setUpControlTest() throws Exception {
|
||||
listingPlugin = addPlugin(tool, DebuggerListingPlugin.class);
|
||||
editingService = addPlugin(tool, DebuggerStateEditingServicePlugin.class);
|
||||
controlService = addPlugin(tool, DebuggerControlServicePlugin.class);
|
||||
emulationService = addPlugin(tool, DebuggerEmulationServicePlugin.class);
|
||||
controlPlugin = addPlugin(tool, DebuggerControlPlugin.class);
|
||||
|
||||
|
@ -293,7 +292,7 @@ public class DebuggerControlPluginTest extends AbstractGhidraHeadedDebuggerGUITe
|
|||
@Test
|
||||
public void testEmulateResumeAction() throws Throwable {
|
||||
TraceThread thread = createToyLoopTrace();
|
||||
editingService.setCurrentMode(tb.trace, StateEditingMode.RW_EMULATOR);
|
||||
controlService.setCurrentMode(tb.trace, ControlMode.RW_EMULATOR);
|
||||
|
||||
traceManager.activateThread(thread);
|
||||
waitForSwing();
|
||||
|
@ -310,7 +309,7 @@ public class DebuggerControlPluginTest extends AbstractGhidraHeadedDebuggerGUITe
|
|||
@Test
|
||||
public void testEmulateInterruptAction() throws Throwable {
|
||||
TraceThread thread = createToyLoopTrace();
|
||||
editingService.setCurrentMode(tb.trace, StateEditingMode.RW_EMULATOR);
|
||||
controlService.setCurrentMode(tb.trace, ControlMode.RW_EMULATOR);
|
||||
|
||||
traceManager.activateThread(thread);
|
||||
waitForSwing();
|
||||
|
@ -332,7 +331,7 @@ public class DebuggerControlPluginTest extends AbstractGhidraHeadedDebuggerGUITe
|
|||
@Test
|
||||
public void testEmulateStepBackAction() throws Throwable {
|
||||
TraceThread thread = createToyLoopTrace();
|
||||
editingService.setCurrentMode(tb.trace, StateEditingMode.RW_EMULATOR);
|
||||
controlService.setCurrentMode(tb.trace, ControlMode.RW_EMULATOR);
|
||||
|
||||
traceManager.activateThread(thread);
|
||||
waitForSwing();
|
||||
|
@ -351,7 +350,7 @@ public class DebuggerControlPluginTest extends AbstractGhidraHeadedDebuggerGUITe
|
|||
@Test
|
||||
public void testEmulateStepIntoAction() throws Throwable {
|
||||
TraceThread thread = createToyLoopTrace();
|
||||
editingService.setCurrentMode(tb.trace, StateEditingMode.RW_EMULATOR);
|
||||
controlService.setCurrentMode(tb.trace, ControlMode.RW_EMULATOR);
|
||||
|
||||
traceManager.activateThread(thread);
|
||||
waitForSwing();
|
||||
|
@ -364,7 +363,7 @@ public class DebuggerControlPluginTest extends AbstractGhidraHeadedDebuggerGUITe
|
|||
@Test
|
||||
public void testEmulateSkipOverAction() throws Throwable {
|
||||
TraceThread thread = createToyLoopTrace();
|
||||
editingService.setCurrentMode(tb.trace, StateEditingMode.RW_EMULATOR);
|
||||
controlService.setCurrentMode(tb.trace, ControlMode.RW_EMULATOR);
|
||||
|
||||
traceManager.activateThread(thread);
|
||||
waitForSwing();
|
||||
|
@ -385,7 +384,7 @@ public class DebuggerControlPluginTest extends AbstractGhidraHeadedDebuggerGUITe
|
|||
@Test
|
||||
public void testTraceSnapBackwardAction() throws Throwable {
|
||||
create2SnapTrace();
|
||||
editingService.setCurrentMode(tb.trace, StateEditingMode.RW_TRACE);
|
||||
controlService.setCurrentMode(tb.trace, ControlMode.RW_TRACE);
|
||||
|
||||
traceManager.activateTrace(tb.trace);
|
||||
waitForSwing();
|
||||
|
@ -402,7 +401,7 @@ public class DebuggerControlPluginTest extends AbstractGhidraHeadedDebuggerGUITe
|
|||
@Test
|
||||
public void testTraceSnapForwardAction() throws Throwable {
|
||||
create2SnapTrace();
|
||||
editingService.setCurrentMode(tb.trace, StateEditingMode.RW_TRACE);
|
||||
controlService.setCurrentMode(tb.trace, ControlMode.RW_TRACE);
|
||||
|
||||
traceManager.activateTrace(tb.trace);
|
||||
waitForSwing();
|
||||
|
@ -418,7 +417,7 @@ public class DebuggerControlPluginTest extends AbstractGhidraHeadedDebuggerGUITe
|
|||
DebuggerDisassemblerPlugin disassemblerPlugin =
|
||||
addPlugin(tool, DebuggerDisassemblerPlugin.class);
|
||||
|
||||
assertFalse(controlPlugin.actionEditMode.isEnabled());
|
||||
assertFalse(controlPlugin.actionControlMode.isEnabled());
|
||||
|
||||
createAndOpenTrace();
|
||||
TraceVariableSnapProgramView view = tb.trace.getProgramView();
|
||||
|
@ -440,17 +439,17 @@ public class DebuggerControlPluginTest extends AbstractGhidraHeadedDebuggerGUITe
|
|||
() -> listingProvider.goTo(view, new ProgramLocation(view, tb.addr(0x00400123))));
|
||||
waitForSwing();
|
||||
|
||||
assertTrue(controlPlugin.actionEditMode.isEnabled());
|
||||
assertTrue(controlPlugin.actionControlMode.isEnabled());
|
||||
|
||||
runSwing(() -> controlPlugin.actionEditMode
|
||||
.setCurrentActionStateByUserData(StateEditingMode.RO_TARGET));
|
||||
assertEquals(StateEditingMode.RO_TARGET, editingService.getCurrentMode(tb.trace));
|
||||
runSwing(() -> controlPlugin.actionControlMode
|
||||
.setCurrentActionStateByUserData(ControlMode.RO_TARGET));
|
||||
assertEquals(ControlMode.RO_TARGET, controlService.getCurrentMode(tb.trace));
|
||||
assertFalse(
|
||||
helper.patchInstructionAction.isAddToPopup(listingProvider.getActionContext(null)));
|
||||
|
||||
runSwing(() -> controlPlugin.actionEditMode
|
||||
.setCurrentActionStateByUserData(StateEditingMode.RW_EMULATOR));
|
||||
assertEquals(StateEditingMode.RW_EMULATOR, editingService.getCurrentMode(tb.trace));
|
||||
runSwing(() -> controlPlugin.actionControlMode
|
||||
.setCurrentActionStateByUserData(ControlMode.RW_EMULATOR));
|
||||
assertEquals(ControlMode.RW_EMULATOR, controlService.getCurrentMode(tb.trace));
|
||||
|
||||
assertTrue(
|
||||
helper.patchInstructionAction.isAddToPopup(listingProvider.getActionContext(null)));
|
||||
|
@ -469,7 +468,7 @@ public class DebuggerControlPluginTest extends AbstractGhidraHeadedDebuggerGUITe
|
|||
public void testPatchDataActionInDynamicListingEmu() throws Throwable {
|
||||
AssemblerPlugin assemblerPlugin = addPlugin(tool, AssemblerPlugin.class);
|
||||
|
||||
assertFalse(controlPlugin.actionEditMode.isEnabled());
|
||||
assertFalse(controlPlugin.actionControlMode.isEnabled());
|
||||
|
||||
createAndOpenTrace();
|
||||
TraceVariableSnapProgramView view = tb.trace.getProgramView();
|
||||
|
@ -490,16 +489,16 @@ public class DebuggerControlPluginTest extends AbstractGhidraHeadedDebuggerGUITe
|
|||
traceManager.activateTrace(tb.trace);
|
||||
waitForSwing();
|
||||
|
||||
assertTrue(controlPlugin.actionEditMode.isEnabled());
|
||||
assertTrue(controlPlugin.actionControlMode.isEnabled());
|
||||
|
||||
runSwing(() -> controlPlugin.actionEditMode
|
||||
.setCurrentActionStateByUserData(StateEditingMode.RO_TARGET));
|
||||
assertEquals(StateEditingMode.RO_TARGET, editingService.getCurrentMode(tb.trace));
|
||||
runSwing(() -> controlPlugin.actionControlMode
|
||||
.setCurrentActionStateByUserData(ControlMode.RO_TARGET));
|
||||
assertEquals(ControlMode.RO_TARGET, controlService.getCurrentMode(tb.trace));
|
||||
assertFalse(helper.patchDataAction.isAddToPopup(listingProvider.getActionContext(null)));
|
||||
|
||||
runSwing(() -> controlPlugin.actionEditMode
|
||||
.setCurrentActionStateByUserData(StateEditingMode.RW_EMULATOR));
|
||||
assertEquals(StateEditingMode.RW_EMULATOR, editingService.getCurrentMode(tb.trace));
|
||||
runSwing(() -> controlPlugin.actionControlMode
|
||||
.setCurrentActionStateByUserData(ControlMode.RW_EMULATOR));
|
||||
assertEquals(ControlMode.RW_EMULATOR, controlService.getCurrentMode(tb.trace));
|
||||
|
||||
goTo(listingProvider.getListingPanel(), new ProgramLocation(view, tb.addr(0x00400123)));
|
||||
assertTrue(helper.patchDataAction.isAddToPopup(listingProvider.getActionContext(null)));
|
||||
|
@ -525,7 +524,7 @@ public class DebuggerControlPluginTest extends AbstractGhidraHeadedDebuggerGUITe
|
|||
CodeViewerProvider listingProvider = listingPlugin.getProvider();
|
||||
DockingActionIf pasteAction = getLocalAction(listingProvider, "Paste");
|
||||
|
||||
assertFalse(controlPlugin.actionEditMode.isEnabled());
|
||||
assertFalse(controlPlugin.actionControlMode.isEnabled());
|
||||
|
||||
createAndOpenTrace();
|
||||
TraceVariableSnapProgramView view = tb.trace.getProgramView();
|
||||
|
@ -541,18 +540,18 @@ public class DebuggerControlPluginTest extends AbstractGhidraHeadedDebuggerGUITe
|
|||
|
||||
ActionContext ctx;
|
||||
|
||||
assertTrue(controlPlugin.actionEditMode.isEnabled());
|
||||
assertTrue(controlPlugin.actionControlMode.isEnabled());
|
||||
|
||||
runSwing(() -> controlPlugin.actionEditMode
|
||||
.setCurrentActionStateByUserData(StateEditingMode.RO_TARGET));
|
||||
assertEquals(StateEditingMode.RO_TARGET, editingService.getCurrentMode(tb.trace));
|
||||
runSwing(() -> controlPlugin.actionControlMode
|
||||
.setCurrentActionStateByUserData(ControlMode.RO_TARGET));
|
||||
assertEquals(ControlMode.RO_TARGET, controlService.getCurrentMode(tb.trace));
|
||||
ctx = listingProvider.getActionContext(null);
|
||||
assertTrue(pasteAction.isAddToPopup(ctx));
|
||||
assertFalse(pasteAction.isEnabledForContext(ctx));
|
||||
|
||||
runSwing(() -> controlPlugin.actionEditMode
|
||||
.setCurrentActionStateByUserData(StateEditingMode.RW_EMULATOR));
|
||||
assertEquals(StateEditingMode.RW_EMULATOR, editingService.getCurrentMode(tb.trace));
|
||||
runSwing(() -> controlPlugin.actionControlMode
|
||||
.setCurrentActionStateByUserData(ControlMode.RW_EMULATOR));
|
||||
assertEquals(ControlMode.RW_EMULATOR, controlService.getCurrentMode(tb.trace));
|
||||
|
||||
goTo(listingPlugin.getListingPanel(), new ProgramLocation(view, tb.addr(0x00400123)));
|
||||
ctx = listingProvider.getActionContext(null);
|
||||
|
|
|
@ -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.action.*;
|
||||
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.async.SwingExecutorService;
|
||||
import ghidra.program.model.address.*;
|
||||
|
@ -74,7 +74,7 @@ public class DebuggerMemoryBytesProviderTest extends AbstractGhidraHeadedDebugge
|
|||
protected DebuggerMemoryBytesPlugin memBytesPlugin;
|
||||
protected DebuggerMemoryBytesProvider memBytesProvider;
|
||||
|
||||
protected DebuggerStateEditingService editingService;
|
||||
protected DebuggerControlService editingService;
|
||||
|
||||
@Before
|
||||
public void setUpMemoryBytesProviderTest() throws Exception {
|
||||
|
@ -82,7 +82,7 @@ public class DebuggerMemoryBytesProviderTest extends AbstractGhidraHeadedDebugge
|
|||
memBytesProvider = waitForComponentProvider(DebuggerMemoryBytesProvider.class);
|
||||
memBytesProvider.setVisible(true);
|
||||
|
||||
editingService = addPlugin(tool, DebuggerStateEditingServicePlugin.class);
|
||||
editingService = addPlugin(tool, DebuggerControlServicePlugin.class);
|
||||
}
|
||||
|
||||
protected void goToDyn(Address address) {
|
||||
|
@ -1100,7 +1100,7 @@ public class DebuggerMemoryBytesProviderTest extends AbstractGhidraHeadedDebugge
|
|||
createTargetTraceMapper(mb.testProcess1));
|
||||
Trace trace = recorder.getTrace();
|
||||
|
||||
editingService.setCurrentMode(trace, StateEditingMode.RW_TARGET);
|
||||
editingService.setCurrentMode(trace, ControlMode.RW_TARGET);
|
||||
DockingActionIf actionEdit = getAction(memBytesPlugin, "Enable/Disable Byteviewer Editing");
|
||||
|
||||
mb.testProcess1.addRegion("exe:.text", mb.rng(0x55550000, 0x5555ffff), "rx");
|
||||
|
@ -1132,7 +1132,7 @@ public class DebuggerMemoryBytesProviderTest extends AbstractGhidraHeadedDebugge
|
|||
createTargetTraceMapper(mb.testProcess1));
|
||||
Trace trace = recorder.getTrace();
|
||||
|
||||
editingService.setCurrentMode(trace, StateEditingMode.RW_TRACE);
|
||||
editingService.setCurrentMode(trace, ControlMode.RW_TRACE);
|
||||
DockingActionIf actionEdit = getAction(memBytesPlugin, "Enable/Disable Byteviewer Editing");
|
||||
|
||||
mb.testProcess1.addRegion("exe:.text", mb.rng(0x55550000, 0x5555ffff), "rx");
|
||||
|
@ -1179,7 +1179,7 @@ public class DebuggerMemoryBytesProviderTest extends AbstractGhidraHeadedDebugge
|
|||
createTargetTraceMapper(mb.testProcess1));
|
||||
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");
|
||||
waitFor(() -> !trace.getMemoryManager().getAllRegions().isEmpty());
|
||||
|
|
|
@ -28,7 +28,7 @@ import generic.test.category.NightlyCategory;
|
|||
import ghidra.app.plugin.core.debug.gui.listing.DebuggerListingPlugin;
|
||||
import ghidra.app.plugin.core.debug.mapping.DebuggerTargetTraceMapper;
|
||||
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.services.TraceRecorder;
|
||||
import ghidra.dbg.target.TargetObject;
|
||||
|
@ -66,7 +66,7 @@ public class DebuggerRegistersProviderGuestTest extends DebuggerRegistersProvide
|
|||
registersPlugin = addPlugin(tool, DebuggerRegistersPlugin.class);
|
||||
registersProvider = waitForComponentProvider(DebuggerRegistersProvider.class);
|
||||
listingPlugin = addPlugin(tool, DebuggerListingPlugin.class);
|
||||
editingService = addPlugin(tool, DebuggerStateEditingServicePlugin.class);
|
||||
editingService = addPlugin(tool, DebuggerControlServicePlugin.class);
|
||||
|
||||
createTrace();
|
||||
createToyPlatform();
|
||||
|
|
|
@ -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.register.DebuggerRegistersProvider.RegisterDataSettingsDialog;
|
||||
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.docking.settings.FormatSettingsDefinition;
|
||||
import ghidra.docking.settings.Settings;
|
||||
|
@ -57,7 +57,7 @@ public class DebuggerRegistersProviderTest extends AbstractGhidraHeadedDebuggerG
|
|||
protected DebuggerRegistersPlugin registersPlugin;
|
||||
protected DebuggerRegistersProvider registersProvider;
|
||||
protected DebuggerListingPlugin listingPlugin;
|
||||
protected DebuggerStateEditingService editingService;
|
||||
protected DebuggerControlService editingService;
|
||||
|
||||
protected Register r0;
|
||||
protected Register pc;
|
||||
|
@ -78,7 +78,7 @@ public class DebuggerRegistersProviderTest extends AbstractGhidraHeadedDebuggerG
|
|||
registersPlugin = addPlugin(tool, DebuggerRegistersPlugin.class);
|
||||
registersProvider = waitForComponentProvider(DebuggerRegistersProvider.class);
|
||||
listingPlugin = addPlugin(tool, DebuggerListingPlugin.class);
|
||||
editingService = addPlugin(tool, DebuggerStateEditingServicePlugin.class);
|
||||
editingService = addPlugin(tool, DebuggerControlServicePlugin.class);
|
||||
|
||||
createTrace();
|
||||
r0 = tb.language.getRegister("r0");
|
||||
|
@ -383,7 +383,7 @@ public class DebuggerRegistersProviderTest extends AbstractGhidraHeadedDebuggerG
|
|||
activateThread(thread);
|
||||
waitForSwing();
|
||||
|
||||
editingService.setCurrentMode(tb.trace, StateEditingMode.RW_EMULATOR);
|
||||
editingService.setCurrentMode(tb.trace, ControlMode.RW_EMULATOR);
|
||||
|
||||
assertTrue(registersProvider.actionEnableEdits.isEnabled());
|
||||
performAction(registersProvider.actionEnableEdits);
|
||||
|
@ -421,7 +421,7 @@ public class DebuggerRegistersProviderTest extends AbstractGhidraHeadedDebuggerG
|
|||
activateThread(thread);
|
||||
waitForSwing();
|
||||
|
||||
editingService.setCurrentMode(tb.trace, StateEditingMode.RW_EMULATOR);
|
||||
editingService.setCurrentMode(tb.trace, ControlMode.RW_EMULATOR);
|
||||
|
||||
assertTrue(registersProvider.actionEnableEdits.isEnabled());
|
||||
performAction(registersProvider.actionEnableEdits);
|
||||
|
|
|
@ -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.register.*;
|
||||
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.services.*;
|
||||
import ghidra.dbg.model.TestTargetRegisterBankInThread;
|
||||
|
@ -71,7 +71,7 @@ public class DebuggerWatchesProviderTest extends AbstractGhidraHeadedDebuggerGUI
|
|||
protected DebuggerListingProvider listingProvider;
|
||||
protected DebuggerStaticMappingServicePlugin mappingService;
|
||||
protected CodeViewerProvider codeViewerProvider;
|
||||
protected DebuggerStateEditingService editingService;
|
||||
protected DebuggerControlService editingService;
|
||||
|
||||
protected Register r0;
|
||||
protected Register r1;
|
||||
|
@ -91,7 +91,7 @@ public class DebuggerWatchesProviderTest extends AbstractGhidraHeadedDebuggerGUI
|
|||
listingPlugin = addPlugin(tool, DebuggerListingPlugin.class);
|
||||
listingProvider = waitForComponentProvider(DebuggerListingProvider.class);
|
||||
mappingService = addPlugin(tool, DebuggerStaticMappingServicePlugin.class);
|
||||
editingService = addPlugin(tool, DebuggerStateEditingServicePlugin.class);
|
||||
editingService = addPlugin(tool, DebuggerControlServicePlugin.class);
|
||||
|
||||
createTrace();
|
||||
r0 = tb.language.getRegister("r0");
|
||||
|
@ -350,7 +350,7 @@ public class DebuggerWatchesProviderTest extends AbstractGhidraHeadedDebuggerGUI
|
|||
assertFalse(row.isRawValueEditable());
|
||||
traceManager.openTrace(tb.trace);
|
||||
traceManager.activateThread(thread);
|
||||
editingService.setCurrentMode(tb.trace, StateEditingMode.RW_EMULATOR);
|
||||
editingService.setCurrentMode(tb.trace, ControlMode.RW_EMULATOR);
|
||||
waitForWatches();
|
||||
|
||||
assertNoErr(row);
|
||||
|
@ -384,7 +384,7 @@ public class DebuggerWatchesProviderTest extends AbstractGhidraHeadedDebuggerGUI
|
|||
|
||||
traceManager.openTrace(tb.trace);
|
||||
traceManager.activateThread(thread);
|
||||
editingService.setCurrentMode(tb.trace, StateEditingMode.RW_EMULATOR);
|
||||
editingService.setCurrentMode(tb.trace, ControlMode.RW_EMULATOR);
|
||||
waitForWatches();
|
||||
|
||||
performAction(watchesProvider.actionEnableEdits);
|
||||
|
@ -547,7 +547,7 @@ public class DebuggerWatchesProviderTest extends AbstractGhidraHeadedDebuggerGUI
|
|||
|
||||
traceManager.openTrace(trace);
|
||||
traceManager.activateThread(thread);
|
||||
editingService.setCurrentMode(trace, StateEditingMode.RW_TARGET);
|
||||
editingService.setCurrentMode(trace, ControlMode.RW_TARGET);
|
||||
waitForSwing();
|
||||
|
||||
performAction(watchesProvider.actionAdd);
|
||||
|
|
|
@ -25,7 +25,7 @@ import org.junit.*;
|
|||
|
||||
import generic.Unique;
|
||||
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.services.*;
|
||||
import ghidra.app.services.LogicalBreakpoint.State;
|
||||
|
@ -1619,15 +1619,15 @@ public class DebuggerLogicalBreakpointServiceTest extends AbstractGhidraHeadedDe
|
|||
@Test
|
||||
public void testAddTraceBreakpointSetSleighThenMapThenSaveToProgramCopiesSleigh()
|
||||
throws Throwable {
|
||||
DebuggerStateEditingService editingService =
|
||||
addPlugin(tool, DebuggerStateEditingServicePlugin.class);
|
||||
DebuggerControlService editingService =
|
||||
addPlugin(tool, DebuggerControlServicePlugin.class);
|
||||
|
||||
// TODO: What if already mapped?
|
||||
// Not sure I care about tb.setEmuSleigh() out of band
|
||||
|
||||
createTrace();
|
||||
traceManager.openTrace(tb.trace);
|
||||
editingService.setCurrentMode(tb.trace, StateEditingMode.RW_EMULATOR);
|
||||
editingService.setCurrentMode(tb.trace, ControlMode.RW_EMULATOR);
|
||||
createProgramFromTrace();
|
||||
intoProject(program);
|
||||
programManager.openProgram(program);
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* 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.util.Set;
|
||||
|
@ -30,7 +30,7 @@ import ghidra.trace.model.guest.TraceGuestPlatform;
|
|||
import ghidra.trace.model.guest.TracePlatform;
|
||||
import ghidra.util.database.UndoableTransaction;
|
||||
|
||||
public class DebuggerStateEditingServiceGuestTest extends DebuggerStateEditingServiceTest {
|
||||
public class DebuggerControlServiceGuestTest extends DebuggerControlServiceTest {
|
||||
protected TraceGuestPlatform platform;
|
||||
|
||||
public void createToyPlatform() {
|
|
@ -13,7 +13,7 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* 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.*;
|
||||
|
||||
|
@ -26,8 +26,9 @@ import org.junit.Test;
|
|||
import ghidra.app.plugin.assembler.*;
|
||||
import ghidra.app.plugin.core.debug.DebuggerCoordinates;
|
||||
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.DebuggerStateEditingService.StateEditor;
|
||||
import ghidra.app.services.DebuggerControlService.StateEditor;
|
||||
import ghidra.async.AsyncUtils.TemperamentalRunnable;
|
||||
import ghidra.dbg.target.TargetRegisterBank;
|
||||
import ghidra.program.model.lang.*;
|
||||
|
@ -39,8 +40,8 @@ import ghidra.trace.model.thread.TraceThread;
|
|||
import ghidra.trace.model.time.schedule.TraceSchedule;
|
||||
import ghidra.util.database.UndoableTransaction;
|
||||
|
||||
public class DebuggerStateEditingServiceTest extends AbstractGhidraHeadedDebuggerGUITest {
|
||||
protected DebuggerStateEditingService editingService;
|
||||
public class DebuggerControlServiceTest extends AbstractGhidraHeadedDebuggerGUITest {
|
||||
protected DebuggerControlService editingService;
|
||||
|
||||
protected Register r0;
|
||||
protected Register r0h;
|
||||
|
@ -84,7 +85,7 @@ public class DebuggerStateEditingServiceTest extends AbstractGhidraHeadedDebugge
|
|||
|
||||
@Before
|
||||
public void setUpEditorTest() throws Exception {
|
||||
editingService = addPlugin(tool, DebuggerStateEditingServicePlugin.class);
|
||||
editingService = addPlugin(tool, DebuggerControlServicePlugin.class);
|
||||
Language toy = getToyBE64Language();
|
||||
r0 = toy.getRegister("r0");
|
||||
r0h = toy.getRegister("r0h");
|
||||
|
@ -104,7 +105,7 @@ public class DebuggerStateEditingServiceTest extends AbstractGhidraHeadedDebugge
|
|||
createAndOpenTrace();
|
||||
activateTrace();
|
||||
|
||||
editingService.setCurrentMode(tb.trace, StateEditingMode.RW_EMULATOR);
|
||||
editingService.setCurrentMode(tb.trace, ControlMode.RW_EMULATOR);
|
||||
|
||||
StateEditor editor = createStateEditor();
|
||||
assertFalse(editor.isVariableEditable(tb.addr(0x00400000), 4));
|
||||
|
@ -116,7 +117,7 @@ public class DebuggerStateEditingServiceTest extends AbstractGhidraHeadedDebugge
|
|||
@Test
|
||||
public void testWriteEmuRegisterNoThreadErr() throws Throwable {
|
||||
createAndOpenTrace();
|
||||
editingService.setCurrentMode(tb.trace, StateEditingMode.RW_EMULATOR);
|
||||
editingService.setCurrentMode(tb.trace, ControlMode.RW_EMULATOR);
|
||||
|
||||
activateTrace();
|
||||
waitForSwing();
|
||||
|
@ -131,7 +132,7 @@ public class DebuggerStateEditingServiceTest extends AbstractGhidraHeadedDebugge
|
|||
@Test
|
||||
public void testWriteEmuMemory() throws Throwable {
|
||||
createAndOpenTrace();
|
||||
editingService.setCurrentMode(tb.trace, StateEditingMode.RW_EMULATOR);
|
||||
editingService.setCurrentMode(tb.trace, ControlMode.RW_EMULATOR);
|
||||
|
||||
try (UndoableTransaction tid = tb.startTransaction()) {
|
||||
// NB. TraceManager should automatically activate the first thread
|
||||
|
@ -157,7 +158,7 @@ public class DebuggerStateEditingServiceTest extends AbstractGhidraHeadedDebugge
|
|||
@Test
|
||||
public void testWriteEmuRegister() throws Throwable {
|
||||
createAndOpenTrace();
|
||||
editingService.setCurrentMode(tb.trace, StateEditingMode.RW_EMULATOR);
|
||||
editingService.setCurrentMode(tb.trace, ControlMode.RW_EMULATOR);
|
||||
|
||||
TraceThread thread;
|
||||
try (UndoableTransaction tid = tb.startTransaction()) {
|
||||
|
@ -186,7 +187,7 @@ public class DebuggerStateEditingServiceTest extends AbstractGhidraHeadedDebugge
|
|||
@Test
|
||||
public void testWriteEmuMemoryAfterStep() throws Throwable {
|
||||
createAndOpenTrace();
|
||||
editingService.setCurrentMode(tb.trace, StateEditingMode.RW_TRACE);
|
||||
editingService.setCurrentMode(tb.trace, ControlMode.RW_TRACE);
|
||||
|
||||
try (UndoableTransaction tid = tb.startTransaction()) {
|
||||
// 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;");
|
||||
}
|
||||
activateTrace();
|
||||
editingService.setCurrentMode(tb.trace, StateEditingMode.RW_EMULATOR);
|
||||
editingService.setCurrentMode(tb.trace, ControlMode.RW_EMULATOR);
|
||||
waitForSwing();
|
||||
|
||||
TraceSchedule step1 = TraceSchedule.parse("0:t0-1");
|
||||
|
@ -224,7 +225,7 @@ public class DebuggerStateEditingServiceTest extends AbstractGhidraHeadedDebugge
|
|||
@Test
|
||||
public void testWriteEmuRegisterAfterStep() throws Throwable {
|
||||
createAndOpenTrace();
|
||||
editingService.setCurrentMode(tb.trace, StateEditingMode.RW_TRACE);
|
||||
editingService.setCurrentMode(tb.trace, ControlMode.RW_TRACE);
|
||||
|
||||
TraceThread thread;
|
||||
try (UndoableTransaction tid = tb.startTransaction()) {
|
||||
|
@ -238,7 +239,7 @@ public class DebuggerStateEditingServiceTest extends AbstractGhidraHeadedDebugge
|
|||
tb.exec(getPlatform(), 0, thread, 0, "pc = 0x00400000;");
|
||||
}
|
||||
activateTrace();
|
||||
editingService.setCurrentMode(tb.trace, StateEditingMode.RW_EMULATOR);
|
||||
editingService.setCurrentMode(tb.trace, ControlMode.RW_EMULATOR);
|
||||
waitForSwing();
|
||||
|
||||
TraceSchedule step1 = TraceSchedule.parse("0:t0-1");
|
||||
|
@ -264,7 +265,7 @@ public class DebuggerStateEditingServiceTest extends AbstractGhidraHeadedDebugge
|
|||
@Test
|
||||
public void testWriteEmuMemoryTwice() throws Throwable {
|
||||
createAndOpenTrace();
|
||||
editingService.setCurrentMode(tb.trace, StateEditingMode.RW_EMULATOR);
|
||||
editingService.setCurrentMode(tb.trace, ControlMode.RW_EMULATOR);
|
||||
|
||||
try (UndoableTransaction tid = tb.startTransaction()) {
|
||||
// NB. TraceManager should automatically activate the first thread
|
||||
|
@ -293,7 +294,7 @@ public class DebuggerStateEditingServiceTest extends AbstractGhidraHeadedDebugge
|
|||
@Test
|
||||
public void testWriteEmuRegisterTwice() throws Throwable {
|
||||
createAndOpenTrace();
|
||||
editingService.setCurrentMode(tb.trace, StateEditingMode.RW_EMULATOR);
|
||||
editingService.setCurrentMode(tb.trace, ControlMode.RW_EMULATOR);
|
||||
|
||||
TraceThread thread;
|
||||
try (UndoableTransaction tid = tb.startTransaction()) {
|
||||
|
@ -324,7 +325,7 @@ public class DebuggerStateEditingServiceTest extends AbstractGhidraHeadedDebugge
|
|||
public void testWriteTraceMemory() throws Throwable {
|
||||
// NB. Definitely no thread required
|
||||
createAndOpenTrace();
|
||||
editingService.setCurrentMode(tb.trace, StateEditingMode.RW_TRACE);
|
||||
editingService.setCurrentMode(tb.trace, ControlMode.RW_TRACE);
|
||||
activateTrace();
|
||||
waitForSwing();
|
||||
|
||||
|
@ -347,7 +348,7 @@ public class DebuggerStateEditingServiceTest extends AbstractGhidraHeadedDebugge
|
|||
public void testWriteTraceRegisterNoThreadErr() throws Throwable {
|
||||
// NB. Definitely no thread required
|
||||
createAndOpenTrace();
|
||||
editingService.setCurrentMode(tb.trace, StateEditingMode.RW_TRACE);
|
||||
editingService.setCurrentMode(tb.trace, ControlMode.RW_TRACE);
|
||||
activateTrace();
|
||||
waitForSwing();
|
||||
|
||||
|
@ -363,7 +364,7 @@ public class DebuggerStateEditingServiceTest extends AbstractGhidraHeadedDebugge
|
|||
public void testWriteTraceRegister() throws Throwable {
|
||||
// NB. Definitely no thread required
|
||||
createAndOpenTrace();
|
||||
editingService.setCurrentMode(tb.trace, StateEditingMode.RW_TRACE);
|
||||
editingService.setCurrentMode(tb.trace, ControlMode.RW_TRACE);
|
||||
|
||||
TraceThread thread;
|
||||
try (UndoableTransaction tid = tb.startTransaction()) {
|
||||
|
@ -396,7 +397,7 @@ public class DebuggerStateEditingServiceTest extends AbstractGhidraHeadedDebugge
|
|||
activateTrace();
|
||||
traceManager.activateThread(recorder.getTraceThread(mb.testThread1));
|
||||
waitForSwing();
|
||||
editingService.setCurrentMode(recorder.getTrace(), StateEditingMode.RW_TARGET);
|
||||
editingService.setCurrentMode(recorder.getTrace(), ControlMode.RW_TARGET);
|
||||
|
||||
StateEditor editor = createStateEditor();
|
||||
assertTrue(editor.isVariableEditable(tb.addr(0x00400000), 4));
|
||||
|
@ -416,7 +417,7 @@ public class DebuggerStateEditingServiceTest extends AbstractGhidraHeadedDebugge
|
|||
waitForSwing();
|
||||
traceManager.activateThread(recorder.getTraceThread(mb.testThread1));
|
||||
waitForSwing();
|
||||
editingService.setCurrentMode(recorder.getTrace(), StateEditingMode.RW_TARGET);
|
||||
editingService.setCurrentMode(recorder.getTrace(), ControlMode.RW_TARGET);
|
||||
|
||||
StateEditor editor = createStateEditor();
|
||||
assertTrue(editor.isRegisterEditable(r0));
|
||||
|
@ -435,7 +436,7 @@ public class DebuggerStateEditingServiceTest extends AbstractGhidraHeadedDebugge
|
|||
TraceThread thread = waitForValue(() -> recorder.getTraceThread(mb.testThread1));
|
||||
traceManager.activateThread(thread);
|
||||
waitForSwing();
|
||||
editingService.setCurrentMode(recorder.getTrace(), StateEditingMode.RW_TARGET);
|
||||
editingService.setCurrentMode(recorder.getTrace(), ControlMode.RW_TARGET);
|
||||
|
||||
StateEditor editor = createStateEditor();
|
||||
waitForPass(() -> assertTrue(editor.isRegisterEditable(r0)));
|
||||
|
@ -461,15 +462,15 @@ public class DebuggerStateEditingServiceTest extends AbstractGhidraHeadedDebugge
|
|||
traceManager.activateThread(recorder.getTraceThread(mb.testThread1));
|
||||
waitForSwing();
|
||||
|
||||
editingService.setCurrentMode(tb.trace, StateEditingMode.RW_TARGET);
|
||||
editingService.setCurrentMode(tb.trace, ControlMode.RW_TARGET);
|
||||
waitForSwing();
|
||||
assertEquals(recorder.getSnap(), traceManager.getCurrentSnap());
|
||||
|
||||
traceManager.activateSnap(traceManager.getCurrentSnap() - 1);
|
||||
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();
|
||||
assertEquals(recorder.getSnap(), traceManager.getCurrentSnap());
|
||||
}
|
||||
|
@ -479,7 +480,7 @@ public class DebuggerStateEditingServiceTest extends AbstractGhidraHeadedDebugge
|
|||
createAndOpenTrace();
|
||||
activateTrace();
|
||||
waitForSwing();
|
||||
editingService.setCurrentMode(tb.trace, StateEditingMode.RW_TARGET);
|
||||
editingService.setCurrentMode(tb.trace, ControlMode.RW_TARGET);
|
||||
waitForSwing();
|
||||
|
||||
StateEditor editor = createStateEditor();
|
||||
|
@ -494,7 +495,7 @@ public class DebuggerStateEditingServiceTest extends AbstractGhidraHeadedDebugge
|
|||
createAndOpenTrace();
|
||||
activateTrace();
|
||||
waitForSwing();
|
||||
editingService.setCurrentMode(tb.trace, StateEditingMode.RW_TARGET);
|
||||
editingService.setCurrentMode(tb.trace, ControlMode.RW_TARGET);
|
||||
waitForSwing();
|
||||
|
||||
StateEditor editor = createStateEditor();
|
||||
|
@ -508,7 +509,7 @@ public class DebuggerStateEditingServiceTest extends AbstractGhidraHeadedDebugge
|
|||
public void testWriteReadOnlyMemoryErr() throws Throwable {
|
||||
createAndOpenTrace();
|
||||
activateTrace();
|
||||
editingService.setCurrentMode(tb.trace, StateEditingMode.RO_TARGET);
|
||||
editingService.setCurrentMode(tb.trace, ControlMode.RO_TARGET);
|
||||
|
||||
StateEditor editor = createStateEditor();
|
||||
assertFalse(editor.isVariableEditable(tb.addr(0x00400000), 4));
|
||||
|
@ -521,7 +522,7 @@ public class DebuggerStateEditingServiceTest extends AbstractGhidraHeadedDebugge
|
|||
public void testWriteReadOnlyRegisterErr() throws Throwable {
|
||||
createAndOpenTrace();
|
||||
activateTrace();
|
||||
editingService.setCurrentMode(tb.trace, StateEditingMode.RO_TARGET);
|
||||
editingService.setCurrentMode(tb.trace, ControlMode.RO_TARGET);
|
||||
|
||||
StateEditor editor = createStateEditor();
|
||||
assertFalse(editor.isRegisterEditable(r0));
|
|
@ -26,7 +26,7 @@ import org.junit.experimental.categories.Category;
|
|||
import generic.test.category.NightlyCategory;
|
||||
import ghidra.app.plugin.core.debug.DebuggerCoordinates;
|
||||
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.dbg.model.TestTargetStack;
|
||||
import ghidra.dbg.model.TestTargetStackFrameHasRegisterBank;
|
||||
|
@ -47,12 +47,12 @@ import ghidra.util.database.UndoableTransaction;
|
|||
@Category(NightlyCategory.class) // this may actually be an @PortSensitive test
|
||||
public class DebuggerTraceManagerServiceTest extends AbstractGhidraHeadedDebuggerGUITest {
|
||||
|
||||
protected DebuggerStateEditingService editingService;
|
||||
protected DebuggerControlService editingService;
|
||||
|
||||
@Before
|
||||
public void setUpTraceManagerTest() throws Exception {
|
||||
addPlugin(tool, DebuggerStateEditingServicePlugin.class);
|
||||
editingService = tool.getService(DebuggerStateEditingService.class);
|
||||
addPlugin(tool, DebuggerControlServicePlugin.class);
|
||||
editingService = tool.getService(DebuggerControlService.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -359,7 +359,7 @@ public class DebuggerTraceManagerServiceTest extends AbstractGhidraHeadedDebugge
|
|||
traceManager.activateTrace(trace);
|
||||
waitForSwing();
|
||||
|
||||
assertEquals(StateEditingMode.RO_TARGET, editingService.getCurrentMode(trace));
|
||||
assertEquals(ControlMode.RO_TARGET, editingService.getCurrentMode(trace));
|
||||
long initSnap = recorder.getSnap();
|
||||
assertEquals(initSnap, traceManager.getCurrentSnap());
|
||||
|
||||
|
@ -369,7 +369,7 @@ public class DebuggerTraceManagerServiceTest extends AbstractGhidraHeadedDebugge
|
|||
assertEquals(initSnap + 1, recorder.getSnap());
|
||||
assertEquals(initSnap + 1, traceManager.getCurrentSnap());
|
||||
|
||||
editingService.setCurrentMode(trace, StateEditingMode.RO_TRACE);
|
||||
editingService.setCurrentMode(trace, ControlMode.RO_TRACE);
|
||||
|
||||
recorder.forceSnapshot();
|
||||
waitForSwing();
|
||||
|
@ -377,7 +377,7 @@ public class DebuggerTraceManagerServiceTest extends AbstractGhidraHeadedDebugge
|
|||
assertEquals(initSnap + 2, recorder.getSnap());
|
||||
assertEquals(initSnap + 1, traceManager.getCurrentSnap());
|
||||
|
||||
editingService.setCurrentMode(trace, StateEditingMode.RO_TARGET);
|
||||
editingService.setCurrentMode(trace, ControlMode.RO_TARGET);
|
||||
waitForSwing();
|
||||
|
||||
assertEquals(initSnap + 2, recorder.getSnap());
|
||||
|
|
|
@ -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.stack.vars.*;
|
||||
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.ProgramEmulationUtils;
|
||||
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.services.*;
|
||||
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.ListingField;
|
||||
import ghidra.app.util.viewer.listingpanel.ListingPanel;
|
||||
|
@ -119,7 +119,7 @@ public class StackUnwinderTest extends AbstractGhidraHeadedDebuggerGUITest {
|
|||
ListingPanel staticListing;
|
||||
DebuggerListingPlugin listingPlugin;
|
||||
ListingPanel dynamicListing;
|
||||
DebuggerStateEditingService editingService;
|
||||
DebuggerControlService editingService;
|
||||
DebuggerEmulationService emuService;
|
||||
DecompilerProvider decompilerProvider;
|
||||
DecompilerPanel decompilerPanel;
|
||||
|
@ -675,8 +675,8 @@ public class StackUnwinderTest extends AbstractGhidraHeadedDebuggerGUITest {
|
|||
addPlugin(tool, DebuggerListingPlugin.class);
|
||||
addPlugin(tool, DisassemblerPlugin.class);
|
||||
addPlugin(tool, DecompilePlugin.class);
|
||||
DebuggerStateEditingService editingService =
|
||||
addPlugin(tool, DebuggerStateEditingServicePlugin.class);
|
||||
DebuggerControlService editingService =
|
||||
addPlugin(tool, DebuggerControlServicePlugin.class);
|
||||
DebuggerEmulationService emuService = addPlugin(tool, DebuggerEmulationServicePlugin.class);
|
||||
|
||||
Function function = createSumSquaresProgramX86_32();
|
||||
|
@ -691,7 +691,7 @@ public class StackUnwinderTest extends AbstractGhidraHeadedDebuggerGUITest {
|
|||
traceManager.activateThread(thread);
|
||||
waitForSwing();
|
||||
|
||||
editingService.setCurrentMode(tb.trace, StateEditingMode.RW_TRACE);
|
||||
editingService.setCurrentMode(tb.trace, ControlMode.RW_TRACE);
|
||||
StateEditor editor = editingService.createStateEditor(tb.trace);
|
||||
|
||||
DebuggerCoordinates atSetup = traceManager.getCurrent();
|
||||
|
@ -735,8 +735,8 @@ public class StackUnwinderTest extends AbstractGhidraHeadedDebuggerGUITest {
|
|||
addPlugin(tool, DebuggerListingPlugin.class);
|
||||
addPlugin(tool, DisassemblerPlugin.class);
|
||||
addPlugin(tool, DecompilePlugin.class);
|
||||
DebuggerStateEditingService editingService =
|
||||
addPlugin(tool, DebuggerStateEditingServicePlugin.class);
|
||||
DebuggerControlService editingService =
|
||||
addPlugin(tool, DebuggerControlServicePlugin.class);
|
||||
DebuggerEmulationService emuService = addPlugin(tool, DebuggerEmulationServicePlugin.class);
|
||||
|
||||
Function function = createFibonacciProgramX86_32();
|
||||
|
@ -751,7 +751,7 @@ public class StackUnwinderTest extends AbstractGhidraHeadedDebuggerGUITest {
|
|||
traceManager.activateThread(thread);
|
||||
waitForSwing();
|
||||
|
||||
editingService.setCurrentMode(tb.trace, StateEditingMode.RW_TRACE);
|
||||
editingService.setCurrentMode(tb.trace, ControlMode.RW_TRACE);
|
||||
StateEditor editor = editingService.createStateEditor(tb.trace);
|
||||
|
||||
DebuggerCoordinates atSetup = traceManager.getCurrent();
|
||||
|
@ -872,7 +872,7 @@ public class StackUnwinderTest extends AbstractGhidraHeadedDebuggerGUITest {
|
|||
dynamicListing = listingPlugin.getProvider().getListingPanel();
|
||||
addPlugin(tool, DisassemblerPlugin.class);
|
||||
addPlugin(tool, DecompilePlugin.class);
|
||||
editingService = addPlugin(tool, DebuggerStateEditingServicePlugin.class);
|
||||
editingService = addPlugin(tool, DebuggerControlServicePlugin.class);
|
||||
emuService = addPlugin(tool, DebuggerEmulationServicePlugin.class);
|
||||
|
||||
decompilerProvider = waitForComponentProvider(DecompilerProvider.class);
|
||||
|
@ -894,7 +894,7 @@ public class StackUnwinderTest extends AbstractGhidraHeadedDebuggerGUITest {
|
|||
traceManager.activateThread(thread);
|
||||
waitForSwing();
|
||||
|
||||
editingService.setCurrentMode(tb.trace, StateEditingMode.RW_TRACE);
|
||||
editingService.setCurrentMode(tb.trace, ControlMode.RW_TRACE);
|
||||
StateEditor editor = editingService.createStateEditor(tb.trace);
|
||||
|
||||
DebuggerCoordinates atSetup = traceManager.getCurrent();
|
||||
|
@ -944,7 +944,7 @@ public class StackUnwinderTest extends AbstractGhidraHeadedDebuggerGUITest {
|
|||
traceManager.activateThread(thread);
|
||||
waitForSwing();
|
||||
|
||||
editingService.setCurrentMode(tb.trace, StateEditingMode.RW_TRACE);
|
||||
editingService.setCurrentMode(tb.trace, ControlMode.RW_TRACE);
|
||||
StateEditor editor = editingService.createStateEditor(tb.trace);
|
||||
// Move stack where it shows in UI. Not required, but nice for debugging.
|
||||
Register sp = program.getCompilerSpec().getStackPointer();
|
||||
|
@ -988,7 +988,7 @@ public class StackUnwinderTest extends AbstractGhidraHeadedDebuggerGUITest {
|
|||
traceManager.activateThread(thread);
|
||||
waitForSwing();
|
||||
|
||||
editingService.setCurrentMode(tb.trace, StateEditingMode.RW_TRACE);
|
||||
editingService.setCurrentMode(tb.trace, ControlMode.RW_TRACE);
|
||||
StateEditor editor = editingService.createStateEditor(tb.trace);
|
||||
// Move stack where it shows in UI. Not required, but nice for debugging.
|
||||
Register sp = program.getCompilerSpec().getStackPointer();
|
||||
|
@ -1032,7 +1032,7 @@ public class StackUnwinderTest extends AbstractGhidraHeadedDebuggerGUITest {
|
|||
traceManager.activateThread(thread);
|
||||
waitForSwing();
|
||||
|
||||
editingService.setCurrentMode(tb.trace, StateEditingMode.RW_TRACE);
|
||||
editingService.setCurrentMode(tb.trace, ControlMode.RW_TRACE);
|
||||
StateEditor editor = editingService.createStateEditor(tb.trace);
|
||||
// Move stack where it shows in UI. Not required, but nice for debugging.
|
||||
Register sp = program.getCompilerSpec().getStackPointer();
|
||||
|
|
|
@ -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.listing.DebuggerListingPlugin;
|
||||
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.model.TestDebuggerProgramLaunchOpinion.TestDebuggerProgramLaunchOffer;
|
||||
import ghidra.app.plugin.core.debug.service.model.launch.AbstractDebuggerProgramLaunchOffer;
|
||||
|
@ -129,7 +129,7 @@ public class FlatDebuggerAPITest extends AbstractGhidraHeadedDebuggerGUITest {
|
|||
protected DebuggerStaticMappingService mappingService;
|
||||
protected DebuggerEmulationService emulationService;
|
||||
protected DebuggerListingService listingService;
|
||||
protected DebuggerStateEditingService editingService;
|
||||
protected DebuggerControlService editingService;
|
||||
protected FlatDebuggerAPI flat;
|
||||
|
||||
@Before
|
||||
|
@ -138,7 +138,7 @@ public class FlatDebuggerAPITest extends AbstractGhidraHeadedDebuggerGUITest {
|
|||
mappingService = tool.getService(DebuggerStaticMappingService.class);
|
||||
emulationService = addPlugin(tool, DebuggerEmulationServicePlugin.class);
|
||||
listingService = addPlugin(tool, DebuggerListingPlugin.class);
|
||||
editingService = addPlugin(tool, DebuggerStateEditingServicePlugin.class);
|
||||
editingService = addPlugin(tool, DebuggerControlServicePlugin.class);
|
||||
flat = new TestFlatAPI();
|
||||
}
|
||||
|
||||
|
@ -689,7 +689,7 @@ public class FlatDebuggerAPITest extends AbstractGhidraHeadedDebuggerGUITest {
|
|||
@Test
|
||||
public void testWriteMemoryGivenContext() throws Throwable {
|
||||
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)));
|
||||
ByteBuffer buf = ByteBuffer.allocate(3);
|
||||
|
@ -700,7 +700,7 @@ public class FlatDebuggerAPITest extends AbstractGhidraHeadedDebuggerGUITest {
|
|||
@Test
|
||||
public void testWriteMemoryCurrentContext() throws Throwable {
|
||||
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)));
|
||||
ByteBuffer buf = ByteBuffer.allocate(3);
|
||||
|
@ -711,7 +711,7 @@ public class FlatDebuggerAPITest extends AbstractGhidraHeadedDebuggerGUITest {
|
|||
@Test
|
||||
public void testWriteRegisterGivenContext() throws Throwable {
|
||||
TraceThread thread = createTraceWithThreadAndStack(true);
|
||||
editingService.setCurrentMode(tb.trace, StateEditingMode.RW_TRACE);
|
||||
editingService.setCurrentMode(tb.trace, ControlMode.RW_TRACE);
|
||||
traceManager.activateThread(thread);
|
||||
waitForSwing();
|
||||
|
||||
|
@ -727,7 +727,7 @@ public class FlatDebuggerAPITest extends AbstractGhidraHeadedDebuggerGUITest {
|
|||
@Test
|
||||
public void testWriteRegisterCurrentContext() throws Throwable {
|
||||
TraceThread thread = createTraceWithThreadAndStack(true);
|
||||
editingService.setCurrentMode(tb.trace, StateEditingMode.RW_TRACE);
|
||||
editingService.setCurrentMode(tb.trace, ControlMode.RW_TRACE);
|
||||
traceManager.activateThread(thread);
|
||||
waitForSwing();
|
||||
|
||||
|
|
|
@ -22,9 +22,9 @@ import javax.swing.Icon;
|
|||
|
||||
import docking.ActionContext;
|
||||
import docking.action.*;
|
||||
import docking.menu.HorizontalRuleAction;
|
||||
import docking.menu.MultiActionDockingAction;
|
||||
import ghidra.app.util.datatype.DataTypeUrl;
|
||||
import ghidra.base.actions.HorizontalRuleAction;
|
||||
import ghidra.program.model.data.DataType;
|
||||
import ghidra.program.model.data.DataTypeManager;
|
||||
import ghidra.util.HelpLocation;
|
||||
|
|
|
@ -24,6 +24,7 @@ import javax.swing.Icon;
|
|||
|
||||
import docking.ActionContext;
|
||||
import docking.action.*;
|
||||
import docking.menu.HorizontalRuleAction;
|
||||
import docking.menu.MultiActionDockingAction;
|
||||
import docking.tool.ToolConstants;
|
||||
import generic.theme.GIcon;
|
||||
|
@ -37,7 +38,6 @@ import ghidra.app.services.GoToService;
|
|||
import ghidra.app.services.NavigationHistoryService;
|
||||
import ghidra.app.util.HelpTopics;
|
||||
import ghidra.app.util.viewer.field.BrowserCodeUnitFormat;
|
||||
import ghidra.base.actions.HorizontalRuleAction;
|
||||
import ghidra.framework.model.DomainFile;
|
||||
import ghidra.framework.plugintool.*;
|
||||
import ghidra.framework.plugintool.util.PluginStatus;
|
||||
|
|
|
@ -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 = " ";
|
||||
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
|
||||
}
|
||||
|
||||
}
|
|
@ -15,6 +15,7 @@
|
|||
*/
|
||||
package docking.action;
|
||||
|
||||
import java.awt.Component;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.util.Set;
|
||||
|
||||
|
@ -281,6 +282,21 @@ public interface DockingActionIf extends HelpDescriptor {
|
|||
*/
|
||||
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
|
||||
* secondary detached window). By default, this method will return true for the main window
|
||||
|
|
|
@ -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 = " ";
|
||||
|
||||
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();
|
||||
// }
|
||||
}
|
||||
}
|
|
@ -146,6 +146,16 @@ public abstract class MultiStateDockingAction<T> extends DockingAction {
|
|||
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() {
|
||||
updateStates();
|
||||
List<DockingActionIf> actions = new ArrayList<>(actionStates.size());
|
||||
|
@ -154,6 +164,8 @@ public abstract class MultiStateDockingAction<T> extends DockingAction {
|
|||
DockingActionIf a = useCheckboxForIcons
|
||||
? new ActionStateToggleAction(actionState, isSelected)
|
||||
: new ActionStateAction(actionState, isSelected);
|
||||
boolean isEnabled = isStateEnabled(actionState);
|
||||
a.setEnabled(isEnabled);
|
||||
actions.add(a);
|
||||
}
|
||||
return actions;
|
||||
|
|
|
@ -24,12 +24,9 @@ import javax.swing.*;
|
|||
import javax.swing.border.Border;
|
||||
import javax.swing.event.*;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import docking.*;
|
||||
import docking.action.*;
|
||||
import docking.widgets.EmptyBorderButton;
|
||||
import docking.widgets.label.GDHtmlLabel;
|
||||
import generic.theme.GThemeDefaults.Colors;
|
||||
import ghidra.util.Swing;
|
||||
import resources.ResourceManager;
|
||||
|
@ -152,6 +149,7 @@ public class MultipleActionDockingToolbarButton extends EmptyBorderButton {
|
|||
|
||||
/**
|
||||
* Show a popup containing all the actions below the button
|
||||
*
|
||||
* @return the popup menu that was shown
|
||||
*/
|
||||
JPopupMenu showPopup() {
|
||||
|
@ -181,19 +179,13 @@ public class MultipleActionDockingToolbarButton extends EmptyBorderButton {
|
|||
List<DockingActionIf> actionList = multipleAction.getActionList(getActionContext());
|
||||
for (DockingActionIf dockingAction : actionList) {
|
||||
|
||||
String[] menuPath = dockingAction.getMenuBarData().getMenuPath();
|
||||
String name = menuPath[menuPath.length - 1];
|
||||
|
||||
// this is a special signal to say we should insert a separator and not a real menu item
|
||||
if (!dockingAction.isEnabled()) {
|
||||
String description = dockingAction.getDescription();
|
||||
JSeparator separator = new ProgramNameSeparator(name, description);
|
||||
menu.add(separator);
|
||||
Component component = dockingAction.createMenuComponent(false);
|
||||
if (!(component instanceof JMenuItem item)) {
|
||||
// not an actual item, e.g., a separator as in HorizontalRuleAction
|
||||
menu.add(component);
|
||||
continue;
|
||||
}
|
||||
|
||||
JMenuItem item = dockingAction.createMenuItem(false);
|
||||
|
||||
// a custom Ghidra UI that handles alignment issues and allows for tabulating presentation
|
||||
item.setUI((DockingMenuItemUI) DockingMenuItemUI.createUI(item));
|
||||
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();
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue