diff --git a/Ghidra/Debug/Debugger-agent-frida/src/main/java/agent/frida/model/impl/FridaDebuggerBot.java b/Ghidra/Debug/Debugger-agent-frida/src/main/java/agent/frida/model/impl/FridaDebuggerBot.java index cf1527cb57..a81b477f5a 100644 --- a/Ghidra/Debug/Debugger-agent-frida/src/main/java/agent/frida/model/impl/FridaDebuggerBot.java +++ b/Ghidra/Debug/Debugger-agent-frida/src/main/java/agent/frida/model/impl/FridaDebuggerBot.java @@ -24,28 +24,27 @@ import agent.frida.manager.FridaThread; import agent.frida.manager.evt.FridaStateChangedEvent; import agent.frida.manager.evt.FridaThreadSelectedEvent; import agent.frida.manager.impl.FridaManagerImpl; -import ghidra.app.plugin.core.debug.service.workflow.DebuggerWorkflowServicePlugin; -import ghidra.app.services.DebuggerBot; -import ghidra.app.services.DebuggerBotInfo; +import ghidra.app.services.DebuggerWorkflowFrontEndService; import ghidra.dbg.*; import ghidra.dbg.error.DebuggerMemoryAccessException; import ghidra.dbg.target.*; import ghidra.dbg.target.TargetConsole.Channel; import ghidra.dbg.target.TargetExecutionStateful.TargetExecutionState; import ghidra.dbg.util.DebuggerCallbackReorderer; +import ghidra.debug.api.workflow.DebuggerBot; +import ghidra.debug.api.workflow.DebuggerBotInfo; import ghidra.framework.options.annotation.HelpInfo; import ghidra.program.model.address.Address; import ghidra.program.model.address.AddressRange; import ghidra.util.datastruct.PrivatelyQueuedListener; -@DebuggerBotInfo( // - description = "Link debugger to Frida", // - details = "Listens for debuggers to add state to Frida.", // - help = @HelpInfo(anchor = "link_frida"), // - enabledByDefault = true // -) +@DebuggerBotInfo( + description = "Link debugger to Frida", + details = "Listens for debuggers to add state to Frida.", + help = @HelpInfo(anchor = "link_frida"), + enabledByDefault = true) public class FridaDebuggerBot implements DebuggerBot { - private DebuggerWorkflowServicePlugin plugin; + private DebuggerWorkflowFrontEndService service; private FridaObjectListener listener = new FridaObjectListener(); private List models = new ArrayList<>(); @@ -53,18 +52,18 @@ public class FridaDebuggerBot implements DebuggerBot { private FridaManagerImpl manager; @Override - public void enable(DebuggerWorkflowServicePlugin wp) { - this.plugin = wp; + public void enable(DebuggerWorkflowFrontEndService service) { + this.service = service; } @Override public boolean isEnabled() { - return plugin != null; + return service != null; } @Override public void disable() { - plugin = null; + service = null; } @Override @@ -73,8 +72,9 @@ public class FridaDebuggerBot implements DebuggerBot { if (model instanceof FridaModelImpl) { primary = (FridaModelImpl) model; manager = primary.getManager(); - } else { - model.addModelListener(getListener(), true); + } + else { + model.addModelListener(getListener(), true); } } @@ -84,15 +84,16 @@ public class FridaDebuggerBot implements DebuggerBot { if (model instanceof FridaModelImpl) { primary = null; manager = null; - } else { - model.removeModelListener(getListener()); + } + else { + model.removeModelListener(getListener()); } } - + public DebuggerModelListener getListener() { return listener.queue.in; } - + private Object findMatchingObject(TargetObject object) { if (object instanceof TargetProcess) { String id = Long.toHexString(((TargetProcess) object).getPid()); @@ -109,7 +110,7 @@ public class FridaDebuggerBot implements DebuggerBot { } return null; } - + class FridaObjectListener extends AnnotatedDebuggerAttributeListener { protected final DebuggerCallbackReorderer reorderer = new DebuggerCallbackReorderer(this); protected final PrivatelyQueuedListener queue = @@ -158,7 +159,7 @@ public class FridaDebuggerBot implements DebuggerBot { if (localObject != null) { FridaThreadInfo info = new FridaThreadInfo((FridaThread) localObject); manager.processEvent(new FridaThreadSelectedEvent(info)); - } + } } } } diff --git a/Ghidra/Debug/Debugger-agent-gdb/data/debugger-launchers/local-gdb.sh b/Ghidra/Debug/Debugger-agent-gdb/data/debugger-launchers/local-gdb.sh new file mode 100755 index 0000000000..a4fe7b665b --- /dev/null +++ b/Ghidra/Debug/Debugger-agent-gdb/data/debugger-launchers/local-gdb.sh @@ -0,0 +1,58 @@ +#!/usr/bin/bash +## ### +# 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. +## +#@title gdb +#@desc +#@desc

Launch with gdb

+#@desc

This will launch the target on the local machine using gdb. GDB must already +#@desc be installed on your system, and it must embed the Python 3 interpreter. You will also +#@desc need protobuf and psutil installed for Python 3. +#@desc +#@menu-group local +#@icon icon.debugger +#@help TraceRmiLauncherServicePlugin#gdb +#@enum StartCmd:str run start starti +#@env OPT_GDB_PATH:str="gdb" "Path to gdb" "The path to gdb. Omit the full path to resolve using the system PATH." +#@env OPT_START_CMD:StartCmd="start" "Run command" "The gdb command to actually run the target." +#@arg :str "Image" "The target binary executable image" +#@args "Arguments" "Command-line arguments to pass to the target" +#@tty TTY_TARGET + +if [ -d ${GHIDRA_HOME}/ghidra/.git ] +then + export PYTHONPATH=$GHIDRA_HOME/ghidra/Ghidra/Debug/Debugger-agent-gdb/build/pypkg/src:$GHIDRA_HOME/ghidra/Ghidra/Debug/Debugger-rmi-trace/build/pypkg/src:$PYTHONPATH +elif [ -d ${GHIDRA_HOME}/.git ] +then + export PYTHONPATH=$GHIDRA_HOME/Ghidra/Debug/Debugger-agent-gdb/build/pypkg/src:$GHIDRA_HOME/Ghidra/Debug/Debugger-rmi-trace/build/pypkg/src:$PYTHONPATH +else + export PYTHONPATH=$GHIDRA_HOME/Ghidra/Debug/Debugger-agent-gdb/pypkg/src:$GHIDRA_HOME/Ghidra/Debug/Debugger-rmi-trace/build/pypkg/src:$PYTHONPATH +fi + +target_image="$1" +shift +target_args="$@" + +"$OPT_GDB_PATH" \ + -ex "set pagination off" \ + -ex "python import ghidragdb" \ + -ex "file \"$target_image\"" \ + -ex "set args $target_args" \ + -ex "set inferior-tty $TTY_TARGET" \ + -ex "ghidra trace connect \"$GHIDRA_TRACE_RMI_ADDR\"" \ + -ex "ghidra trace start" \ + -ex "ghidra trace sync-enable" \ + -ex "$OPT_START_CMD" \ + -ex "set pagination on" diff --git a/Ghidra/Debug/Debugger-agent-gdb/src/main/py/src/ghidragdb/hooks.py b/Ghidra/Debug/Debugger-agent-gdb/src/main/py/src/ghidragdb/hooks.py index e60115d114..4ae8a135d9 100644 --- a/Ghidra/Debug/Debugger-agent-gdb/src/main/py/src/ghidragdb/hooks.py +++ b/Ghidra/Debug/Debugger-agent-gdb/src/main/py/src/ghidragdb/hooks.py @@ -24,7 +24,7 @@ class GhidraHookPrefix(gdb.Command): """Commands for exporting data to a Ghidra trace""" def __init__(self): - super().__init__('ghidra-hook', gdb.COMMAND_NONE, prefix=True) + super().__init__('hooks-ghidra', gdb.COMMAND_NONE, prefix=True) GhidraHookPrefix() @@ -386,7 +386,7 @@ def on_before_prompt(): # This will be called by a catchpoint class GhidraTraceEventMemoryCommand(gdb.Command): def __init__(self): - super().__init__('ghidra-hook event-memory', gdb.COMMAND_NONE) + super().__init__('hooks-ghidra event-memory', gdb.COMMAND_NONE) def invoke(self, argument, from_tty): self.dont_repeat() @@ -401,10 +401,10 @@ def cmd_hook(name): class _ActiveCommand(gdb.Command): def __init__(self): # It seems we can't hook commands using the Python API.... - super().__init__(f"ghidra-hook def-{name}", gdb.COMMAND_USER) + super().__init__(f"hooks-ghidra def-{name}", gdb.COMMAND_USER) gdb.execute(f""" define {name} - ghidra-hook def-{name} + hooks-ghidra def-{name} end """) @@ -474,7 +474,7 @@ def install_hooks(): catch syscall group:memory commands silent - ghidra-hook event-memory + hooks-ghidra event-memory cont end """) diff --git a/Ghidra/Debug/Debugger-api/Module.manifest b/Ghidra/Debug/Debugger-api/Module.manifest new file mode 100644 index 0000000000..e69de29bb2 diff --git a/Ghidra/Debug/Debugger-api/build.gradle b/Ghidra/Debug/Debugger-api/build.gradle new file mode 100644 index 0000000000..9d53c355f6 --- /dev/null +++ b/Ghidra/Debug/Debugger-api/build.gradle @@ -0,0 +1,29 @@ +/* ### + * 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. + */ + +apply from: "${rootProject.projectDir}/gradle/javaProject.gradle" +apply from: "${rootProject.projectDir}/gradle/jacocoProject.gradle" +apply from: "${rootProject.projectDir}/gradle/javaTestProject.gradle" +apply from: "${rootProject.projectDir}/gradle/distributableGhidraModule.gradle" + +apply plugin: 'eclipse' +eclipse.project.name = 'Debug Debugger-api' + +dependencies { + api project(':SoftwareModeling') + api project(':Framework-TraceModeling') + api project(':Emulation') +} diff --git a/Ghidra/Debug/Debugger-api/certification.manifest b/Ghidra/Debug/Debugger-api/certification.manifest new file mode 100644 index 0000000000..895ac4b698 --- /dev/null +++ b/Ghidra/Debug/Debugger-api/certification.manifest @@ -0,0 +1,2 @@ +##VERSION: 2.0 +Module.manifest||GHIDRA||||END| diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/services/DebuggerConsoleService.java b/Ghidra/Debug/Debugger-api/src/main/java/ghidra/app/services/DebuggerConsoleService.java similarity index 96% rename from Ghidra/Debug/Debugger/src/main/java/ghidra/app/services/DebuggerConsoleService.java rename to Ghidra/Debug/Debugger-api/src/main/java/ghidra/app/services/DebuggerConsoleService.java index 5eac50922f..745e87bac2 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/services/DebuggerConsoleService.java +++ b/Ghidra/Debug/Debugger-api/src/main/java/ghidra/app/services/DebuggerConsoleService.java @@ -21,12 +21,11 @@ import javax.swing.Icon; import docking.ActionContext; import docking.action.DockingActionIf; -import ghidra.app.plugin.core.debug.gui.console.DebuggerConsolePlugin; import ghidra.dbg.DebuggerConsoleLogger; import ghidra.framework.plugintool.ServiceInfo; import ghidra.util.HTMLUtilities; -@ServiceInfo(defaultProvider = DebuggerConsolePlugin.class) +@ServiceInfo(defaultProviderName = "ghidra.app.plugin.core.debug.gui.console.DebuggerConsolePlugin") public interface DebuggerConsoleService extends DebuggerConsoleLogger { /** diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/services/DebuggerControlService.java b/Ghidra/Debug/Debugger-api/src/main/java/ghidra/app/services/DebuggerControlService.java similarity index 89% rename from Ghidra/Debug/Debugger/src/main/java/ghidra/app/services/DebuggerControlService.java rename to Ghidra/Debug/Debugger-api/src/main/java/ghidra/app/services/DebuggerControlService.java index 379f8aeb7a..87cefac0ea 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/services/DebuggerControlService.java +++ b/Ghidra/Debug/Debugger-api/src/main/java/ghidra/app/services/DebuggerControlService.java @@ -17,18 +17,19 @@ package ghidra.app.services; import java.util.concurrent.CompletableFuture; -import ghidra.app.plugin.core.debug.DebuggerCoordinates; -import ghidra.app.plugin.core.debug.service.control.DebuggerControlServicePlugin; +import ghidra.debug.api.control.ControlMode; +import ghidra.debug.api.tracemgr.DebuggerCoordinates; import ghidra.framework.plugintool.ServiceInfo; import ghidra.pcode.utils.Utils; import ghidra.program.model.address.Address; -import ghidra.program.model.lang.*; +import ghidra.program.model.lang.Register; +import ghidra.program.model.lang.RegisterValue; import ghidra.program.model.mem.LiveMemoryHandler; import ghidra.trace.model.Trace; import ghidra.trace.model.program.TraceProgramView; @ServiceInfo( - defaultProvider = DebuggerControlServicePlugin.class, + defaultProviderName = "ghidra.app.plugin.core.debug.service.control.DebuggerControlServicePlugin", description = "Centralized service for modifying machine states") public interface DebuggerControlService { interface StateEditor { diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/services/DebuggerEmulationService.java b/Ghidra/Debug/Debugger-api/src/main/java/ghidra/app/services/DebuggerEmulationService.java similarity index 97% rename from Ghidra/Debug/Debugger/src/main/java/ghidra/app/services/DebuggerEmulationService.java rename to Ghidra/Debug/Debugger-api/src/main/java/ghidra/app/services/DebuggerEmulationService.java index d1d5384606..897cc38891 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/services/DebuggerEmulationService.java +++ b/Ghidra/Debug/Debugger-api/src/main/java/ghidra/app/services/DebuggerEmulationService.java @@ -18,7 +18,8 @@ package ghidra.app.services; import java.util.Collection; import java.util.concurrent.CompletableFuture; -import ghidra.app.plugin.core.debug.service.emulation.*; +import ghidra.debug.api.emulation.DebuggerPcodeEmulatorFactory; +import ghidra.debug.api.emulation.DebuggerPcodeMachine; import ghidra.framework.plugintool.ServiceInfo; import ghidra.trace.model.Trace; import ghidra.trace.model.guest.TracePlatform; @@ -36,7 +37,8 @@ import ghidra.util.task.TaskMonitor; * user. Scripts may interact with these managed emulators, or they may instantiate their own * unmanaged emulators, without using this service. */ -@ServiceInfo(defaultProvider = DebuggerEmulationServicePlugin.class) +@ServiceInfo( + defaultProviderName = "ghidra.app.plugin.core.debug.service.emulation.DebuggerEmulationServicePlugin") public interface DebuggerEmulationService { interface EmulationResult extends RunResult { diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/services/DebuggerInterpreterService.java b/Ghidra/Debug/Debugger-api/src/main/java/ghidra/app/services/DebuggerInterpreterService.java similarity index 80% rename from Ghidra/Debug/Debugger/src/main/java/ghidra/app/services/DebuggerInterpreterService.java rename to Ghidra/Debug/Debugger-api/src/main/java/ghidra/app/services/DebuggerInterpreterService.java index eb4e7bfd19..f181a1239e 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/services/DebuggerInterpreterService.java +++ b/Ghidra/Debug/Debugger-api/src/main/java/ghidra/app/services/DebuggerInterpreterService.java @@ -15,16 +15,14 @@ */ package ghidra.app.services; -import ghidra.app.plugin.core.debug.gui.interpreters.DebuggerInterpreterConnection; -import ghidra.app.plugin.core.debug.gui.interpreters.DebuggerInterpreterPlugin; import ghidra.dbg.target.TargetConsole; import ghidra.dbg.target.TargetInterpreter; +import ghidra.debug.api.interpreter.DebuggerInterpreterConnection; import ghidra.framework.plugintool.ServiceInfo; -@ServiceInfo( // - defaultProvider = DebuggerInterpreterPlugin.class, // - description = "Service for managing debugger interpreter panels" // -) +@ServiceInfo( + defaultProviderName = "ghidra.app.plugin.core.debug.gui.interpreters.DebuggerInterpreterPlugin", + description = "Service for managing debugger interpreter panels") public interface DebuggerInterpreterService { DebuggerInterpreterConnection showConsole(TargetConsole console); diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/services/DebuggerListingService.java b/Ghidra/Debug/Debugger-api/src/main/java/ghidra/app/services/DebuggerListingService.java similarity index 92% rename from Ghidra/Debug/Debugger/src/main/java/ghidra/app/services/DebuggerListingService.java rename to Ghidra/Debug/Debugger-api/src/main/java/ghidra/app/services/DebuggerListingService.java index ab92e1e6a1..742bb228fb 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/services/DebuggerListingService.java +++ b/Ghidra/Debug/Debugger-api/src/main/java/ghidra/app/services/DebuggerListingService.java @@ -15,10 +15,9 @@ */ package ghidra.app.services; -import ghidra.app.plugin.core.debug.gui.action.LocationTrackingSpec; -import ghidra.app.plugin.core.debug.gui.listing.DebuggerListingPlugin; -import ghidra.app.plugin.core.debug.gui.listing.MultiBlendedListingBackgroundColorModel; import ghidra.app.util.viewer.listingpanel.ListingPanel; +import ghidra.debug.api.action.LocationTrackingSpec; +import ghidra.debug.api.listing.MultiBlendedListingBackgroundColorModel; import ghidra.framework.plugintool.ServiceInfo; import ghidra.program.model.address.Address; import ghidra.program.util.ProgramSelection; @@ -27,7 +26,7 @@ import ghidra.program.util.ProgramSelection; * A service providing access to the main listing panel */ @ServiceInfo( - defaultProvider = DebuggerListingPlugin.class, + defaultProviderName = "ghidra.app.plugin.core.debug.gui.listing.DebuggerListingPlugin", description = "Replacement CodeViewerService for Debugger") public interface DebuggerListingService extends CodeViewerService { diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/services/DebuggerLogicalBreakpointService.java b/Ghidra/Debug/Debugger-api/src/main/java/ghidra/app/services/DebuggerLogicalBreakpointService.java similarity index 97% rename from Ghidra/Debug/Debugger/src/main/java/ghidra/app/services/DebuggerLogicalBreakpointService.java rename to Ghidra/Debug/Debugger-api/src/main/java/ghidra/app/services/DebuggerLogicalBreakpointService.java index ddde74affe..b9a98ab9a2 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/services/DebuggerLogicalBreakpointService.java +++ b/Ghidra/Debug/Debugger-api/src/main/java/ghidra/app/services/DebuggerLogicalBreakpointService.java @@ -20,19 +20,21 @@ import java.util.concurrent.CompletableFuture; import java.util.function.BiFunction; import java.util.function.Supplier; -import ghidra.app.plugin.core.debug.service.breakpoint.DebuggerLogicalBreakpointServicePlugin; -import ghidra.app.services.LogicalBreakpoint.State; +import ghidra.debug.api.breakpoint.LogicalBreakpoint; +import ghidra.debug.api.breakpoint.LogicalBreakpointsChangeListener; +import ghidra.debug.api.breakpoint.LogicalBreakpoint.State; import ghidra.framework.plugintool.ServiceInfo; import ghidra.program.model.address.Address; import ghidra.program.model.listing.Program; -import ghidra.program.util.*; +import ghidra.program.util.CodeUnitLocation; +import ghidra.program.util.ProgramLocation; import ghidra.trace.model.Trace; import ghidra.trace.model.breakpoint.TraceBreakpoint; import ghidra.trace.model.breakpoint.TraceBreakpointKind; import ghidra.trace.model.program.TraceProgramView; -@ServiceInfo( // - defaultProvider = DebuggerLogicalBreakpointServicePlugin.class, +@ServiceInfo( + defaultProviderName = "ghidra.app.plugin.core.debug.service.breakpoint.DebuggerLogicalBreakpointServicePlugin", description = "Aggregate breakpoints for programs and traces") public interface DebuggerLogicalBreakpointService { /** diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/services/DebuggerModelService.java b/Ghidra/Debug/Debugger-api/src/main/java/ghidra/app/services/DebuggerModelService.java similarity index 97% rename from Ghidra/Debug/Debugger/src/main/java/ghidra/app/services/DebuggerModelService.java rename to Ghidra/Debug/Debugger-api/src/main/java/ghidra/app/services/DebuggerModelService.java index e78f3edd60..6b539da7d9 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/services/DebuggerModelService.java +++ b/Ghidra/Debug/Debugger-api/src/main/java/ghidra/app/services/DebuggerModelService.java @@ -21,13 +21,11 @@ import java.util.Set; import java.util.concurrent.CompletableFuture; import java.util.stream.Stream; -import ghidra.app.plugin.core.debug.mapping.DebuggerMappingOpinion; -import ghidra.app.plugin.core.debug.mapping.DebuggerTargetTraceMapper; -import ghidra.app.plugin.core.debug.service.model.DebuggerModelServiceProxyPlugin; -import ghidra.app.plugin.core.debug.service.model.launch.DebuggerProgramLaunchOffer; import ghidra.dbg.DebuggerModelFactory; import ghidra.dbg.DebuggerObjectModel; import ghidra.dbg.target.*; +import ghidra.debug.api.action.ActionSource; +import ghidra.debug.api.model.*; import ghidra.framework.plugintool.PluginEvent; import ghidra.framework.plugintool.ServiceInfo; import ghidra.program.model.listing.Program; @@ -36,7 +34,7 @@ import ghidra.trace.model.thread.TraceThread; import ghidra.util.datastruct.CollectionChangeListener; @ServiceInfo( - defaultProvider = DebuggerModelServiceProxyPlugin.class, + defaultProviderName = "ghidra.app.plugin.core.debug.service.model.DebuggerModelServiceProxyPlugin", description = "Service for managing debug sessions and connections") public interface DebuggerModelService { /** diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/services/DebuggerPlatformService.java b/Ghidra/Debug/Debugger-api/src/main/java/ghidra/app/services/DebuggerPlatformService.java similarity index 97% rename from Ghidra/Debug/Debugger/src/main/java/ghidra/app/services/DebuggerPlatformService.java rename to Ghidra/Debug/Debugger-api/src/main/java/ghidra/app/services/DebuggerPlatformService.java index 997ccc062f..b7957732b6 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/services/DebuggerPlatformService.java +++ b/Ghidra/Debug/Debugger-api/src/main/java/ghidra/app/services/DebuggerPlatformService.java @@ -15,7 +15,7 @@ */ package ghidra.app.services; -import ghidra.app.plugin.core.debug.mapping.DebuggerPlatformMapper; +import ghidra.debug.api.platform.DebuggerPlatformMapper; import ghidra.trace.model.Trace; import ghidra.trace.model.target.TraceObject; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/services/DebuggerStaticMappingService.java b/Ghidra/Debug/Debugger-api/src/main/java/ghidra/app/services/DebuggerStaticMappingService.java similarity index 98% rename from Ghidra/Debug/Debugger/src/main/java/ghidra/app/services/DebuggerStaticMappingService.java rename to Ghidra/Debug/Debugger-api/src/main/java/ghidra/app/services/DebuggerStaticMappingService.java index f1ba38d153..8bfcad5784 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/services/DebuggerStaticMappingService.java +++ b/Ghidra/Debug/Debugger-api/src/main/java/ghidra/app/services/DebuggerStaticMappingService.java @@ -18,9 +18,10 @@ package ghidra.app.services; import java.util.*; import java.util.concurrent.CompletableFuture; -import ghidra.app.services.ModuleMapProposal.ModuleMapEntry; -import ghidra.app.services.RegionMapProposal.RegionMapEntry; -import ghidra.app.services.SectionMapProposal.SectionMapEntry; +import ghidra.debug.api.modules.*; +import ghidra.debug.api.modules.ModuleMapProposal.ModuleMapEntry; +import ghidra.debug.api.modules.RegionMapProposal.RegionMapEntry; +import ghidra.debug.api.modules.SectionMapProposal.SectionMapEntry; import ghidra.framework.model.DomainFile; import ghidra.program.model.address.*; import ghidra.program.model.listing.Program; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/services/DebuggerTraceManagerService.java b/Ghidra/Debug/Debugger-api/src/main/java/ghidra/app/services/DebuggerTraceManagerService.java similarity index 98% rename from Ghidra/Debug/Debugger/src/main/java/ghidra/app/services/DebuggerTraceManagerService.java rename to Ghidra/Debug/Debugger-api/src/main/java/ghidra/app/services/DebuggerTraceManagerService.java index 5d0893fa67..079aa5ac38 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/services/DebuggerTraceManagerService.java +++ b/Ghidra/Debug/Debugger-api/src/main/java/ghidra/app/services/DebuggerTraceManagerService.java @@ -18,9 +18,8 @@ package ghidra.app.services; import java.util.Collection; import java.util.concurrent.CompletableFuture; -import ghidra.app.plugin.core.debug.DebuggerCoordinates; -import ghidra.app.plugin.core.debug.service.tracemgr.DebuggerTraceManagerServicePlugin; import ghidra.async.AsyncReference; +import ghidra.debug.api.tracemgr.DebuggerCoordinates; import ghidra.framework.model.DomainFile; import ghidra.framework.plugintool.ServiceInfo; import ghidra.program.model.listing.Program; @@ -35,7 +34,8 @@ import ghidra.util.TriConsumer; /** * The interface for managing open traces and navigating among them and their contents */ -@ServiceInfo(defaultProvider = DebuggerTraceManagerServicePlugin.class) +@ServiceInfo( + defaultProviderName = "ghidra.app.plugin.core.debug.service.tracemgr.DebuggerTraceManagerServicePlugin") public interface DebuggerTraceManagerService { /** diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/services/DebuggerWatchesService.java b/Ghidra/Debug/Debugger-api/src/main/java/ghidra/app/services/DebuggerWatchesService.java similarity index 87% rename from Ghidra/Debug/Debugger/src/main/java/ghidra/app/services/DebuggerWatchesService.java rename to Ghidra/Debug/Debugger-api/src/main/java/ghidra/app/services/DebuggerWatchesService.java index b183f3a0a0..d2a871971e 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/services/DebuggerWatchesService.java +++ b/Ghidra/Debug/Debugger-api/src/main/java/ghidra/app/services/DebuggerWatchesService.java @@ -17,15 +17,14 @@ package ghidra.app.services; import java.util.Collection; -import ghidra.app.plugin.core.debug.gui.watch.DebuggerWatchesPlugin; -import ghidra.app.plugin.core.debug.gui.watch.WatchRow; +import ghidra.debug.api.watch.WatchRow; import ghidra.framework.plugintool.ServiceInfo; /** * A service interface for controlling the Watches window */ @ServiceInfo( - defaultProvider = DebuggerWatchesPlugin.class, + defaultProviderName = "ghidra.app.plugin.core.debug.gui.watch.DebuggerWatchesPlugin", description = "Service for managing watches") public interface DebuggerWatchesService { /** diff --git a/Ghidra/Debug/Debugger-api/src/main/java/ghidra/app/services/DebuggerWorkflowFrontEndService.java b/Ghidra/Debug/Debugger-api/src/main/java/ghidra/app/services/DebuggerWorkflowFrontEndService.java new file mode 100644 index 0000000000..7c82695c0b --- /dev/null +++ b/Ghidra/Debug/Debugger-api/src/main/java/ghidra/app/services/DebuggerWorkflowFrontEndService.java @@ -0,0 +1,33 @@ +/* ### + * IP: GHIDRA + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ghidra.app.services; + +import java.util.Collection; + +import ghidra.framework.plugintool.PluginTool; +import ghidra.framework.plugintool.ServiceInfo; + +@ServiceInfo( + defaultProviderName = "ghidra.app.plugin.core.debug.service.workflow.DebuggerWorkflowServicePlugin", + description = "Service for managing automatic debugger actions and analysis") +public interface DebuggerWorkflowFrontEndService extends DebuggerWorkflowService { + /** + * Get all the tools with the corresponding {@link DebuggerWorkflowToolService} + * + * @return the tools proxying this service + */ + Collection getProxyingPluginTools(); +} diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/services/DebuggerWorkflowService.java b/Ghidra/Debug/Debugger-api/src/main/java/ghidra/app/services/DebuggerWorkflowService.java similarity index 74% rename from Ghidra/Debug/Debugger/src/main/java/ghidra/app/services/DebuggerWorkflowService.java rename to Ghidra/Debug/Debugger-api/src/main/java/ghidra/app/services/DebuggerWorkflowService.java index 9378b62fa9..94d250c86f 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/services/DebuggerWorkflowService.java +++ b/Ghidra/Debug/Debugger-api/src/main/java/ghidra/app/services/DebuggerWorkflowService.java @@ -17,14 +17,12 @@ package ghidra.app.services; import java.util.Set; -import ghidra.app.plugin.core.debug.service.workflow.DebuggerWorkflowServiceProxyPlugin; -import ghidra.framework.plugintool.ServiceInfo; +import ghidra.debug.api.workflow.DebuggerBot; +import ghidra.framework.plugintool.PluginTool; -@ServiceInfo( // - defaultProvider = DebuggerWorkflowServiceProxyPlugin.class, // - description = "Service for managing automatic debugger actions and analysis" // -) public interface DebuggerWorkflowService { + PluginTool getTool(); + Set getAllBots(); Set getEnabledBots(); diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/utils/FocusUtils.java b/Ghidra/Debug/Debugger-api/src/main/java/ghidra/app/services/DebuggerWorkflowToolService.java similarity index 57% rename from Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/utils/FocusUtils.java rename to Ghidra/Debug/Debugger-api/src/main/java/ghidra/app/services/DebuggerWorkflowToolService.java index d4beb161f5..6ea2e160da 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/utils/FocusUtils.java +++ b/Ghidra/Debug/Debugger-api/src/main/java/ghidra/app/services/DebuggerWorkflowToolService.java @@ -13,22 +13,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package ghidra.app.plugin.core.debug.utils; +package ghidra.app.services; -import java.awt.Component; -import java.awt.KeyboardFocusManager; +import ghidra.framework.plugintool.ServiceInfo; -import javax.swing.SwingUtilities; +@ServiceInfo( + defaultProviderName = "ghidra.app.plugin.core.debug.service.workflow.DebuggerWorkflowServiceProxyPlugin", + description = "Service for managing automatic debugger actions and analysis") +public interface DebuggerWorkflowToolService extends DebuggerWorkflowService { -public interface FocusUtils { - static boolean isFocusIn(Component c) { - Component owner = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner(); - if (c == owner) { - return true; - } - if (owner == null) { - return false; - } - return SwingUtilities.isDescendingFrom(owner, c); - } } diff --git a/Ghidra/Debug/Debugger-api/src/main/java/ghidra/app/services/TraceRmiLauncherService.java b/Ghidra/Debug/Debugger-api/src/main/java/ghidra/app/services/TraceRmiLauncherService.java new file mode 100644 index 0000000000..cc2ab03359 --- /dev/null +++ b/Ghidra/Debug/Debugger-api/src/main/java/ghidra/app/services/TraceRmiLauncherService.java @@ -0,0 +1,46 @@ +/* ### + * IP: GHIDRA + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ghidra.app.services; + +import java.util.Collection; + +import ghidra.debug.api.tracermi.TraceRmiLaunchOffer; +import ghidra.debug.api.tracermi.TraceRmiLaunchOpinion; +import ghidra.framework.plugintool.ServiceInfo; +import ghidra.program.model.listing.Program; + +/** + * The service for launching Trace RMI targets in the GUI. + */ +@ServiceInfo( + description = "Manages and presents launchers for Trace RMI Targets", + defaultProviderName = "ghidra.app.plugin.core.debug.gui.tracermi.launcher.TraceRmiLauncherServicePlugin") +public interface TraceRmiLauncherService { + /** + * Get all of the installed opinions + * + * @return the opinions + */ + Collection getOpinions(); + + /** + * Get all offers for the given program + * + * @param program the program + * @return the offers + */ + Collection getOffers(Program program); +} diff --git a/Ghidra/Debug/Debugger-api/src/main/java/ghidra/app/services/TraceRmiService.java b/Ghidra/Debug/Debugger-api/src/main/java/ghidra/app/services/TraceRmiService.java new file mode 100644 index 0000000000..35f65acf67 --- /dev/null +++ b/Ghidra/Debug/Debugger-api/src/main/java/ghidra/app/services/TraceRmiService.java @@ -0,0 +1,108 @@ +/* ### + * IP: GHIDRA + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ghidra.app.services; + +import java.io.IOException; +import java.net.SocketAddress; +import java.util.Collection; + +import ghidra.debug.api.tracermi.TraceRmiAcceptor; +import ghidra.debug.api.tracermi.TraceRmiConnection; +import ghidra.framework.plugintool.ServiceInfo; + +/** + * A service (both in the Ghidra framework sense, and in the network sense) for connecting Trace + * RMI-based back-end debuggers. + * + *

+ * This service connects to back-end debuggers, and/or allows back-end debuggers to connect to it. + * Either way, Ghidra becomes the front-end, acting as the Trace RMI server, and the back-end + * debugger acts as the Trace RMI client. The Ghidra front-end may also send control commands to the + * back-end, e.g., to step, resume, or suspend the target. + */ +@ServiceInfo( + description = "A service for accepting and creating Trace RMI connections", + defaultProviderName = "ghidra.app.plugin.core.debug.service.rmi.trace.TraceRmiPlugin") +public interface TraceRmiService { + /** + * Get the address (and port) of the Trace RMI TCP server + * + * @return + */ + SocketAddress getServerAddress(); + + /** + * Set the address (and port) of the Trace RMI TCP server + * + * @param serverAddress may be null to bind to ephemeral port + */ + void setServerAddress(SocketAddress serverAddress); + + /** + * Start the Trace RMI TCP server + * + * @throws IOException + */ + void startServer() throws IOException; + + /** + * Stop the Trace RMI TCP server + */ + void stopServer(); + + /** + * Check if the service is listening for inbound connections (other than those expected by + * {@link #acceptOne(SocketAddress)}). + * + * @return true if listening, false otherwise + */ + boolean isServerStarted(); + + /** + * Assuming a back-end debugger is listening, connect to it. + * + * @param address the address (and port) of the back-end system + * @return the connection + * @throws IOException if the connection failed + */ + TraceRmiConnection connect(SocketAddress address) throws IOException; + + /** + * Prepare to accept a single connection by listening on the given address. + * + *

+ * This essentially starts a server (separate from the one creased by {@link #startServer()}) + * that will accept a single connection. The server is started by this method. The caller can + * then invoke (on the same thread) whatever back-end system or agent that is expected to + * connect back to this service. Assuming that system runs in the background, this thread can + * then invoke {@link TraceRmiAcceptor#accept()} to actually accept that connection. Once + * accepted, the service is terminated, and the server socket is closed. The client socket + * remains open. + * + * @param address the socket address to bind, or null for ephemeral + * @return the acceptor, which can be used to retrieve the ephemeral address and accept the + * actual connection + * @throws IOException on error + */ + TraceRmiAcceptor acceptOne(SocketAddress address) throws IOException; + + /** + * Get all of the active connections + * + * @return the connections + */ + Collection getAllConnections(); +} diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/services/ActionSource.java b/Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/action/ActionSource.java similarity index 97% rename from Ghidra/Debug/Debugger/src/main/java/ghidra/app/services/ActionSource.java rename to Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/action/ActionSource.java index ebcf5289c1..f1f35da347 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/services/ActionSource.java +++ b/Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/action/ActionSource.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package ghidra.app.services; +package ghidra.debug.api.action; /** * Possible sources that drive actions or method invocations diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/GoToInput.java b/Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/action/GoToInput.java similarity index 95% rename from Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/GoToInput.java rename to Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/action/GoToInput.java index deede24f7d..0fc020c282 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/GoToInput.java +++ b/Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/action/GoToInput.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package ghidra.app.plugin.core.debug.gui.action; +package ghidra.debug.api.action; import ghidra.program.model.address.Address; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/LocationTracker.java b/Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/action/LocationTracker.java similarity index 97% rename from Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/LocationTracker.java rename to Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/action/LocationTracker.java index b2750c8ca9..28e6267046 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/LocationTracker.java +++ b/Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/action/LocationTracker.java @@ -13,11 +13,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package ghidra.app.plugin.core.debug.gui.action; +package ghidra.debug.api.action; import java.util.concurrent.CompletableFuture; -import ghidra.app.plugin.core.debug.DebuggerCoordinates; +import ghidra.debug.api.tracemgr.DebuggerCoordinates; import ghidra.framework.plugintool.PluginTool; import ghidra.program.model.address.Address; import ghidra.program.util.ProgramLocation; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/LocationTrackingSpec.java b/Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/action/LocationTrackingSpec.java similarity index 96% rename from Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/LocationTrackingSpec.java rename to Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/action/LocationTrackingSpec.java index 7ca22a96c5..1fc5f593a3 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/LocationTrackingSpec.java +++ b/Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/action/LocationTrackingSpec.java @@ -13,11 +13,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package ghidra.app.plugin.core.debug.gui.action; +package ghidra.debug.api.action; import javax.swing.Icon; -import ghidra.app.plugin.core.debug.DebuggerCoordinates; +import ghidra.debug.api.tracemgr.DebuggerCoordinates; import ghidra.framework.options.SaveState; import ghidra.framework.plugintool.AutoConfigState.ConfigFieldCodec; import ghidra.trace.model.TraceAddressSnapRange; @@ -73,6 +73,9 @@ public interface LocationTrackingSpec { return false; } if (!space.getAddressSpace().isMemorySpace()) { + if (current.getThread() == null) { + return false; + } TraceMemorySpace memSpace = current.getTrace() .getMemoryManager() .getMemoryRegisterSpace(current.getThread(), current.getFrame(), false); diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/LocationTrackingSpecFactory.java b/Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/action/LocationTrackingSpecFactory.java similarity index 97% rename from Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/LocationTrackingSpecFactory.java rename to Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/action/LocationTrackingSpecFactory.java index 2678d75f84..aa1b927f04 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/LocationTrackingSpecFactory.java +++ b/Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/action/LocationTrackingSpecFactory.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package ghidra.app.plugin.core.debug.gui.action; +package ghidra.debug.api.action; import java.util.*; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/services/LogicalBreakpoint.java b/Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/breakpoint/LogicalBreakpoint.java similarity index 91% rename from Ghidra/Debug/Debugger/src/main/java/ghidra/app/services/LogicalBreakpoint.java rename to Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/breakpoint/LogicalBreakpoint.java index c5b684825b..0741aa0b7a 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/services/LogicalBreakpoint.java +++ b/Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/breakpoint/LogicalBreakpoint.java @@ -13,14 +13,15 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package ghidra.app.services; +package ghidra.debug.api.breakpoint; import java.util.*; import java.util.concurrent.CompletableFuture; import javax.swing.Icon; -import ghidra.app.plugin.core.debug.gui.DebuggerResources; +import generic.theme.GIcon; +import ghidra.app.services.DebuggerLogicalBreakpointService; import ghidra.framework.model.DomainObject; import ghidra.program.model.address.Address; import ghidra.program.model.listing.Bookmark; @@ -29,6 +30,7 @@ import ghidra.program.util.ProgramLocation; import ghidra.trace.model.Trace; import ghidra.trace.model.breakpoint.TraceBreakpoint; import ghidra.trace.model.breakpoint.TraceBreakpointKind; +import resources.MultiIcon; /** * A logical breakpoint @@ -55,8 +57,31 @@ import ghidra.trace.model.breakpoint.TraceBreakpointKind; * {@link LogicalBreakpointsChangeListener#breakpointRemoved(LogicalBreakpoint)}. */ public interface LogicalBreakpoint { - String BREAKPOINT_ENABLED_BOOKMARK_TYPE = "BreakpointEnabled"; - String BREAKPOINT_DISABLED_BOOKMARK_TYPE = "BreakpointDisabled"; + String ENABLED_BOOKMARK_TYPE = "BreakpointEnabled"; + String DISABLED_BOOKMARK_TYPE = "BreakpointDisabled"; + + String NAME_MARKER_ENABLED = "Enabled Breakpoint"; + String NAME_MARKER_DISABLED = "Disabled Breakpoint"; + String NAME_MARKER_MIXED = "Mixed Breakpoint"; + String NAME_MARKER_INEFF_EN = "Ineffective Enabled Breakpoint"; + String NAME_MARKER_INEFF_DIS = "Ineffective Disabled Breakpoint"; + String NAME_MARKER_INEFF_MIX = "Ineffective Mixed Breakpoint"; + String NAME_MARKER_INCON_EN = "Inconsistent Enabled Breakpoint"; + String NAME_MARKER_INCON_DIS = "Inconsistent Disabled Breakpoint"; + String NAME_MARKER_INCON_MIX = "Inconsistent Mixed Breakpoint"; + + Icon ICON_OVERLAY_INCONSISTENT = new GIcon("icon.debugger.breakpoint.overlay.inconsistent"); + Icon ICON_MARKER_ENABLED = new GIcon("icon.debugger.breakpoint.marker.enabled"); + Icon ICON_MARKER_DISABLED = new GIcon("icon.debugger.breakpoint.marker.disabled"); + Icon ICON_MARKER_MIXED = new GIcon("icon.debugger.breakpoint.marker.mixed"); + + Icon ICON_MARKER_INEFF_EN = new GIcon("icon.debugger.breakpoint.marker.ineffective.enabled"); + Icon ICON_MARKER_INEFF_DIS = new GIcon("icon.debugger.breakpoint.marker.ineffective.disabled"); + Icon ICON_MARKER_INEFF_MIX = new GIcon("icon.debugger.breakpoint.marker.ineffective.mixed"); + + Icon ICON_MARKER_INCON_EN = new MultiIcon(ICON_MARKER_ENABLED, ICON_OVERLAY_INCONSISTENT); + Icon ICON_MARKER_INCON_DIS = new MultiIcon(ICON_MARKER_DISABLED, ICON_OVERLAY_INCONSISTENT); + Icon ICON_MARKER_INCON_MIX = new MultiIcon(ICON_MARKER_MIXED, ICON_OVERLAY_INCONSISTENT); /** * The state of a logical breakpoint's program bookmark @@ -407,44 +432,44 @@ public interface LogicalBreakpoint { /** * The breakpoint is enabled, and all locations and its bookmark agree */ - ENABLED(Mode.ENABLED, Consistency.NORMAL, DebuggerResources.NAME_BREAKPOINT_MARKER_ENABLED, DebuggerResources.ICON_BREAKPOINT_MARKER_ENABLED), + ENABLED(Mode.ENABLED, Consistency.NORMAL, NAME_MARKER_ENABLED, ICON_MARKER_ENABLED), /** * The breakpoint is disabled, and all locations and its bookmark agree */ - DISABLED(Mode.DISABLED, Consistency.NORMAL, DebuggerResources.NAME_BREAKPOINT_MARKER_DISABLED, DebuggerResources.ICON_BREAKPOINT_MARKER_DISABLED), + DISABLED(Mode.DISABLED, Consistency.NORMAL, NAME_MARKER_DISABLED, ICON_MARKER_DISABLED), /** * There are multiple logical breakpoints at this address, and they are all saved and * effective, but some are enabled, and some are disabled. */ - MIXED(Mode.MIXED, Consistency.NORMAL, DebuggerResources.NAME_BREAKPOINT_MARKER_MIXED, DebuggerResources.ICON_BREAKPOINT_MARKER_MIXED), + MIXED(Mode.MIXED, Consistency.NORMAL, NAME_MARKER_MIXED, ICON_MARKER_MIXED), /** * The breakpoint is saved as enabled, but one or more trace locations are absent. */ - INEFFECTIVE_ENABLED(Mode.ENABLED, Consistency.INEFFECTIVE, DebuggerResources.NAME_BREAKPOINT_MARKER_INEFF_EN, DebuggerResources.ICON_BREAKPOINT_MARKER_INEFF_EN), + INEFFECTIVE_ENABLED(Mode.ENABLED, Consistency.INEFFECTIVE, NAME_MARKER_INEFF_EN, ICON_MARKER_INEFF_EN), /** * The breakpoint is saved as disabled, and one or more trace locations are absent. */ - INEFFECTIVE_DISABLED(Mode.DISABLED, Consistency.INEFFECTIVE, DebuggerResources.NAME_BREAKPOINT_MARKER_INEFF_DIS, DebuggerResources.ICON_BREAKPOINT_MARKER_INEFF_DIS), + INEFFECTIVE_DISABLED(Mode.DISABLED, Consistency.INEFFECTIVE, NAME_MARKER_INEFF_DIS, ICON_MARKER_INEFF_DIS), /** * There are multiple logical breakpoints at this address, and they are all saved, but at * least one is ineffective; furthermore, some are enabled, and some are disabled. */ - INEFFECTIVE_MIXED(Mode.MIXED, Consistency.INEFFECTIVE, DebuggerResources.NAME_BREAKPOINT_MARKER_INEFF_MIX, DebuggerResources.ICON_BREAKPOINT_MARKER_INEFF_MIX), + INEFFECTIVE_MIXED(Mode.MIXED, Consistency.INEFFECTIVE, NAME_MARKER_INEFF_MIX, ICON_MARKER_INEFF_MIX), /** * The breakpoint is enabled, and all locations agree, but the bookmark is absent or * disagrees. */ - INCONSISTENT_ENABLED(Mode.ENABLED, Consistency.INCONSISTENT, DebuggerResources.NAME_BREAKPOINT_MARKER_INCON_EN, DebuggerResources.ICON_BREAKPOINT_MARKER_INCON_EN), + INCONSISTENT_ENABLED(Mode.ENABLED, Consistency.INCONSISTENT, NAME_MARKER_INCON_EN, ICON_MARKER_INCON_EN), /** * The breakpoint is disabled, and all locations agree, but the bookmark is absent or * disagrees. */ - INCONSISTENT_DISABLED(Mode.DISABLED, Consistency.INCONSISTENT, DebuggerResources.NAME_BREAKPOINT_MARKER_INCON_DIS, DebuggerResources.ICON_BREAKPOINT_MARKER_INCON_DIS), + INCONSISTENT_DISABLED(Mode.DISABLED, Consistency.INCONSISTENT, NAME_MARKER_INCON_DIS, ICON_MARKER_INCON_DIS), /** * The breakpoint is terribly inconsistent: its locations disagree, and the bookmark may be * absent. */ - INCONSISTENT_MIXED(Mode.MIXED, Consistency.INCONSISTENT, DebuggerResources.NAME_BREAKPOINT_MARKER_INCON_MIX, DebuggerResources.ICON_BREAKPOINT_MARKER_INCON_MIX); + INCONSISTENT_MIXED(Mode.MIXED, Consistency.INCONSISTENT, NAME_MARKER_INCON_MIX, ICON_MARKER_INCON_MIX); public final Mode mode; public final Consistency consistency; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/services/LogicalBreakpointsChangeListener.java b/Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/breakpoint/LogicalBreakpointsChangeListener.java similarity index 97% rename from Ghidra/Debug/Debugger/src/main/java/ghidra/app/services/LogicalBreakpointsChangeListener.java rename to Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/breakpoint/LogicalBreakpointsChangeListener.java index bb344e91b4..1b5966c799 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/services/LogicalBreakpointsChangeListener.java +++ b/Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/breakpoint/LogicalBreakpointsChangeListener.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package ghidra.app.services; +package ghidra.debug.api.breakpoint; import java.util.Collection; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/services/ControlMode.java b/Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/control/ControlMode.java similarity index 98% rename from Ghidra/Debug/Debugger/src/main/java/ghidra/app/services/ControlMode.java rename to Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/control/ControlMode.java index b839c1d989..3fceb0e6b3 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/services/ControlMode.java +++ b/Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/control/ControlMode.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package ghidra.app.services; +package ghidra.debug.api.control; import java.nio.ByteBuffer; import java.util.List; @@ -24,9 +24,11 @@ import javax.swing.Icon; import db.Transaction; import generic.theme.GIcon; -import ghidra.app.plugin.core.debug.DebuggerCoordinates; +import ghidra.app.services.*; import ghidra.app.services.DebuggerTraceManagerService.ActivationCause; import ghidra.async.AsyncUtils; +import ghidra.debug.api.model.TraceRecorder; +import ghidra.debug.api.tracemgr.DebuggerCoordinates; import ghidra.framework.plugintool.PluginTool; import ghidra.program.model.address.Address; import ghidra.program.model.address.AddressRange; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/emulation/DebuggerPcodeEmulatorFactory.java b/Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/emulation/DebuggerPcodeEmulatorFactory.java similarity index 78% rename from Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/emulation/DebuggerPcodeEmulatorFactory.java rename to Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/emulation/DebuggerPcodeEmulatorFactory.java index 5c9de69b42..99f4c585dc 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/emulation/DebuggerPcodeEmulatorFactory.java +++ b/Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/emulation/DebuggerPcodeEmulatorFactory.java @@ -13,11 +13,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package ghidra.app.plugin.core.debug.service.emulation; +package ghidra.debug.api.emulation; -import ghidra.app.plugin.core.debug.service.emulation.data.DefaultPcodeDebuggerAccess; -import ghidra.app.plugin.core.debug.service.emulation.data.PcodeDebuggerAccess; -import ghidra.app.services.TraceRecorder; +import ghidra.debug.api.model.TraceRecorder; import ghidra.framework.plugintool.PluginTool; import ghidra.trace.model.guest.TracePlatform; import ghidra.util.classfinder.ExtensionPoint; @@ -48,10 +46,8 @@ public interface DebuggerPcodeEmulatorFactory extends ExtensionPoint { * @param recorder if applicable, the recorder for the trace's live target * @return the emulator */ - default DebuggerPcodeMachine create(PluginTool tool, TracePlatform platform, long snap, - TraceRecorder recorder) { - return create(new DefaultPcodeDebuggerAccess(tool, recorder, platform, snap)); - } + DebuggerPcodeMachine create(PluginTool tool, TracePlatform platform, long snap, + TraceRecorder recorder); /** * Create the emulator diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/emulation/DebuggerPcodeMachine.java b/Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/emulation/DebuggerPcodeMachine.java similarity index 84% rename from Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/emulation/DebuggerPcodeMachine.java rename to Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/emulation/DebuggerPcodeMachine.java index bd8abc3090..5526ae0125 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/emulation/DebuggerPcodeMachine.java +++ b/Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/emulation/DebuggerPcodeMachine.java @@ -13,10 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package ghidra.app.plugin.core.debug.service.emulation; +package ghidra.debug.api.emulation; -import ghidra.pcode.exec.debug.auxiliary.AuxDebuggerEmulatorPartsFactory; -import ghidra.pcode.exec.debug.auxiliary.AuxDebuggerPcodeEmulator; import ghidra.pcode.exec.trace.TracePcodeMachine; /** diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/emulation/data/PcodeDebuggerAccess.java b/Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/emulation/PcodeDebuggerAccess.java similarity index 96% rename from Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/emulation/data/PcodeDebuggerAccess.java rename to Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/emulation/PcodeDebuggerAccess.java index 79e07561cd..7936ffcdf7 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/emulation/data/PcodeDebuggerAccess.java +++ b/Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/emulation/PcodeDebuggerAccess.java @@ -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.emulation.data; +package ghidra.debug.api.emulation; import ghidra.pcode.emu.PcodeThread; import ghidra.pcode.exec.trace.data.PcodeTraceAccess; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/emulation/data/PcodeDebuggerDataAccess.java b/Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/emulation/PcodeDebuggerDataAccess.java similarity index 95% rename from Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/emulation/data/PcodeDebuggerDataAccess.java rename to Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/emulation/PcodeDebuggerDataAccess.java index 4ea51634ed..60d6919405 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/emulation/data/PcodeDebuggerDataAccess.java +++ b/Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/emulation/PcodeDebuggerDataAccess.java @@ -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.emulation.data; +package ghidra.debug.api.emulation; import ghidra.pcode.exec.trace.data.PcodeTraceDataAccess; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/emulation/data/PcodeDebuggerMemoryAccess.java b/Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/emulation/PcodeDebuggerMemoryAccess.java similarity index 98% rename from Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/emulation/data/PcodeDebuggerMemoryAccess.java rename to Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/emulation/PcodeDebuggerMemoryAccess.java index 082ee7fddc..15a46021e4 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/emulation/data/PcodeDebuggerMemoryAccess.java +++ b/Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/emulation/PcodeDebuggerMemoryAccess.java @@ -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.emulation.data; +package ghidra.debug.api.emulation; import java.util.concurrent.CompletableFuture; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/emulation/data/PcodeDebuggerRegistersAccess.java b/Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/emulation/PcodeDebuggerRegistersAccess.java similarity index 97% rename from Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/emulation/data/PcodeDebuggerRegistersAccess.java rename to Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/emulation/PcodeDebuggerRegistersAccess.java index 66e43a42a4..38f5305795 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/emulation/data/PcodeDebuggerRegistersAccess.java +++ b/Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/emulation/PcodeDebuggerRegistersAccess.java @@ -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.emulation.data; +package ghidra.debug.api.emulation; import java.util.concurrent.CompletableFuture; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/interpreters/DebuggerInterpreterConnection.java b/Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/interpreter/DebuggerInterpreterConnection.java similarity index 94% rename from Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/interpreters/DebuggerInterpreterConnection.java rename to Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/interpreter/DebuggerInterpreterConnection.java index 3b501eb936..32596bea94 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/interpreters/DebuggerInterpreterConnection.java +++ b/Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/interpreter/DebuggerInterpreterConnection.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package ghidra.app.plugin.core.debug.gui.interpreters; +package ghidra.debug.api.interpreter; import ghidra.app.plugin.core.interpreter.InterpreterConnection; import ghidra.app.plugin.core.interpreter.InterpreterConsole; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/listing/MultiBlendedListingBackgroundColorModel.java b/Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/listing/MultiBlendedListingBackgroundColorModel.java similarity index 97% rename from Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/listing/MultiBlendedListingBackgroundColorModel.java rename to Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/listing/MultiBlendedListingBackgroundColorModel.java index 8cfae329e9..19e9466f36 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/listing/MultiBlendedListingBackgroundColorModel.java +++ b/Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/listing/MultiBlendedListingBackgroundColorModel.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package ghidra.app.plugin.core.debug.gui.listing; +package ghidra.debug.api.listing; import java.awt.Color; import java.math.BigInteger; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/mapping/DebuggerMappingOffer.java b/Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/model/DebuggerMappingOffer.java similarity index 98% rename from Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/mapping/DebuggerMappingOffer.java rename to Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/model/DebuggerMappingOffer.java index 3cb3619f3b..c7896098e8 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/mapping/DebuggerMappingOffer.java +++ b/Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/model/DebuggerMappingOffer.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package ghidra.app.plugin.core.debug.mapping; +package ghidra.debug.api.model; import java.util.Collection; import java.util.List; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/mapping/DebuggerMappingOpinion.java b/Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/model/DebuggerMappingOpinion.java similarity index 99% rename from Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/mapping/DebuggerMappingOpinion.java rename to Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/model/DebuggerMappingOpinion.java index 03d9da0bbd..8f3546b5e5 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/mapping/DebuggerMappingOpinion.java +++ b/Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/model/DebuggerMappingOpinion.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package ghidra.app.plugin.core.debug.mapping; +package ghidra.debug.api.model; import java.util.*; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/mapping/DebuggerMemoryMapper.java b/Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/model/DebuggerMemoryMapper.java similarity index 98% rename from Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/mapping/DebuggerMemoryMapper.java rename to Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/model/DebuggerMemoryMapper.java index 52e54f39c3..63126f86db 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/mapping/DebuggerMemoryMapper.java +++ b/Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/model/DebuggerMemoryMapper.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package ghidra.app.plugin.core.debug.mapping; +package ghidra.debug.api.model; import ghidra.program.model.address.*; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/model/launch/DebuggerProgramLaunchOffer.java b/Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/model/DebuggerProgramLaunchOffer.java similarity index 96% rename from Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/model/launch/DebuggerProgramLaunchOffer.java rename to Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/model/DebuggerProgramLaunchOffer.java index fa408d9027..7b43e4e5a4 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/model/launch/DebuggerProgramLaunchOffer.java +++ b/Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/model/DebuggerProgramLaunchOffer.java @@ -13,15 +13,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package ghidra.app.plugin.core.debug.service.model.launch; +package ghidra.debug.api.model; import java.util.Map; import java.util.concurrent.CompletableFuture; import javax.swing.Icon; -import ghidra.app.plugin.core.debug.gui.DebuggerResources; -import ghidra.app.services.TraceRecorder; import ghidra.dbg.DebuggerModelFactory; import ghidra.dbg.DebuggerObjectModel; import ghidra.dbg.target.TargetLauncher; @@ -170,9 +168,7 @@ public interface DebuggerProgramLaunchOffer { * * @return the icon */ - default Icon getIcon() { - return DebuggerResources.ICON_DEBUGGER; - } + Icon getIcon(); /** * Get the text display on the parent menu for this offer diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/mapping/DebuggerRegisterMapper.java b/Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/model/DebuggerRegisterMapper.java similarity index 93% rename from Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/mapping/DebuggerRegisterMapper.java rename to Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/model/DebuggerRegisterMapper.java index 176c59f4f5..2a317d71dd 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/mapping/DebuggerRegisterMapper.java +++ b/Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/model/DebuggerRegisterMapper.java @@ -13,13 +13,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package ghidra.app.plugin.core.debug.mapping; +package ghidra.debug.api.model; import java.math.BigInteger; import java.util.*; import java.util.Map.Entry; -import ghidra.app.plugin.core.debug.register.RegisterTypeInfo; import ghidra.dbg.target.TargetRegister; import ghidra.dbg.util.ConversionUtils; import ghidra.program.model.lang.Register; @@ -159,17 +158,6 @@ public interface DebuggerRegisterMapper { */ Register targetToTrace(TargetRegister tReg); - /** - * Get suggested type information for a given trace register - * - *

- * TODO: The recorder should apply this type when recording register values - * - * @param lReg the name of the trace register - * @return the default type information - */ - RegisterTypeInfo getDefaultTypeInfo(Register lReg); - /** * Get the (base) registers on target that can be mapped * diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/mapping/DebuggerTargetTraceMapper.java b/Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/model/DebuggerTargetTraceMapper.java similarity index 78% rename from Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/mapping/DebuggerTargetTraceMapper.java rename to Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/model/DebuggerTargetTraceMapper.java index e0afe29913..b35f3e668f 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/mapping/DebuggerTargetTraceMapper.java +++ b/Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/model/DebuggerTargetTraceMapper.java @@ -13,10 +13,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package ghidra.app.plugin.core.debug.mapping; +package ghidra.debug.api.model; -import ghidra.app.plugin.core.debug.service.model.DebuggerModelServicePlugin; -import ghidra.app.services.TraceRecorder; +import ghidra.framework.plugintool.PluginTool; import ghidra.program.model.lang.CompilerSpec; import ghidra.program.model.lang.Language; import ghidra.trace.model.Trace; @@ -27,5 +26,5 @@ public interface DebuggerTargetTraceMapper { CompilerSpec getTraceCompilerSpec(); - TraceRecorder startRecording(DebuggerModelServicePlugin service, Trace trace); + TraceRecorder startRecording(PluginTool tool, Trace trace); } diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/services/TraceRecorder.java b/Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/model/TraceRecorder.java similarity index 99% rename from Ghidra/Debug/Debugger/src/main/java/ghidra/app/services/TraceRecorder.java rename to Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/model/TraceRecorder.java index 1cc09254bb..965dfedef4 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/services/TraceRecorder.java +++ b/Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/model/TraceRecorder.java @@ -13,14 +13,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package ghidra.app.services; +package ghidra.debug.api.model; import java.util.*; import java.util.concurrent.CompletableFuture; import java.util.stream.Collectors; -import ghidra.app.plugin.core.debug.mapping.DebuggerMemoryMapper; -import ghidra.app.plugin.core.debug.mapping.DebuggerRegisterMapper; import ghidra.dbg.target.*; import ghidra.dbg.target.TargetBreakpointSpec.TargetBreakpointKind; import ghidra.dbg.target.TargetExecutionStateful.TargetExecutionState; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/services/TraceRecorderListener.java b/Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/model/TraceRecorderListener.java similarity index 98% rename from Ghidra/Debug/Debugger/src/main/java/ghidra/app/services/TraceRecorderListener.java rename to Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/model/TraceRecorderListener.java index 64787bd0d4..d23ba8458b 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/services/TraceRecorderListener.java +++ b/Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/model/TraceRecorderListener.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package ghidra.app.services; +package ghidra.debug.api.model; /** * A listener for state changes in a recorded target, or in the recorder itself diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/services/DebuggerStaticMappingChangeListener.java b/Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/modules/DebuggerStaticMappingChangeListener.java similarity index 97% rename from Ghidra/Debug/Debugger/src/main/java/ghidra/app/services/DebuggerStaticMappingChangeListener.java rename to Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/modules/DebuggerStaticMappingChangeListener.java index 97c212d88c..16bb97a026 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/services/DebuggerStaticMappingChangeListener.java +++ b/Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/modules/DebuggerStaticMappingChangeListener.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package ghidra.app.services; +package ghidra.debug.api.modules; import java.util.Set; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/services/MapEntry.java b/Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/modules/MapEntry.java similarity index 96% rename from Ghidra/Debug/Debugger/src/main/java/ghidra/app/services/MapEntry.java rename to Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/modules/MapEntry.java index 701d807103..21f4224a36 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/services/MapEntry.java +++ b/Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/modules/MapEntry.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package ghidra.app.services; +package ghidra.debug.api.modules; import ghidra.program.model.address.AddressRange; import ghidra.program.model.listing.Program; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/services/MapProposal.java b/Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/modules/MapProposal.java similarity index 97% rename from Ghidra/Debug/Debugger/src/main/java/ghidra/app/services/MapProposal.java rename to Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/modules/MapProposal.java index c8d688cc07..753d919703 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/services/MapProposal.java +++ b/Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/modules/MapProposal.java @@ -13,11 +13,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package ghidra.app.services; +package ghidra.debug.api.modules; import java.util.*; import java.util.stream.Collectors; +import ghidra.app.services.DebuggerStaticMappingService; import ghidra.program.model.listing.Program; import ghidra.trace.model.Trace; import ghidra.trace.model.modules.TraceStaticMappingManager; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/services/ModuleMapProposal.java b/Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/modules/ModuleMapProposal.java similarity index 95% rename from Ghidra/Debug/Debugger/src/main/java/ghidra/app/services/ModuleMapProposal.java rename to Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/modules/ModuleMapProposal.java index 7090f11b8c..3deea88c62 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/services/ModuleMapProposal.java +++ b/Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/modules/ModuleMapProposal.java @@ -13,9 +13,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package ghidra.app.services; +package ghidra.debug.api.modules; -import ghidra.app.services.ModuleMapProposal.ModuleMapEntry; +import ghidra.debug.api.modules.ModuleMapProposal.ModuleMapEntry; import ghidra.program.model.address.AddressRange; import ghidra.program.model.listing.Program; import ghidra.trace.model.modules.TraceModule; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/services/RegionMapProposal.java b/Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/modules/RegionMapProposal.java similarity index 93% rename from Ghidra/Debug/Debugger/src/main/java/ghidra/app/services/RegionMapProposal.java rename to Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/modules/RegionMapProposal.java index 4cd3fc82c1..dd63201936 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/services/RegionMapProposal.java +++ b/Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/modules/RegionMapProposal.java @@ -13,9 +13,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package ghidra.app.services; +package ghidra.debug.api.modules; -import ghidra.app.services.RegionMapProposal.RegionMapEntry; +import ghidra.debug.api.modules.RegionMapProposal.RegionMapEntry; import ghidra.program.model.listing.Program; import ghidra.program.model.mem.MemoryBlock; import ghidra.trace.model.memory.TraceMemoryRegion; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/services/SectionMapProposal.java b/Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/modules/SectionMapProposal.java similarity index 94% rename from Ghidra/Debug/Debugger/src/main/java/ghidra/app/services/SectionMapProposal.java rename to Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/modules/SectionMapProposal.java index eb171914a8..aba6aba8d0 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/services/SectionMapProposal.java +++ b/Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/modules/SectionMapProposal.java @@ -13,9 +13,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package ghidra.app.services; +package ghidra.debug.api.modules; -import ghidra.app.services.SectionMapProposal.SectionMapEntry; +import ghidra.debug.api.modules.SectionMapProposal.SectionMapEntry; import ghidra.program.model.listing.Program; import ghidra.program.model.mem.MemoryBlock; import ghidra.trace.model.modules.TraceModule; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/mapping/DebuggerPlatformMapper.java b/Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/platform/DebuggerPlatformMapper.java similarity index 98% rename from Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/mapping/DebuggerPlatformMapper.java rename to Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/platform/DebuggerPlatformMapper.java index 92f3268c03..8bc98f69c1 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/mapping/DebuggerPlatformMapper.java +++ b/Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/platform/DebuggerPlatformMapper.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package ghidra.app.plugin.core.debug.mapping; +package ghidra.debug.api.platform; import ghidra.program.model.address.Address; import ghidra.program.model.address.AddressSetView; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/mapping/DisassemblyResult.java b/Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/platform/DisassemblyResult.java similarity index 96% rename from Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/mapping/DisassemblyResult.java rename to Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/platform/DisassemblyResult.java index 25364d9574..ebd1a819d6 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/mapping/DisassemblyResult.java +++ b/Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/platform/DisassemblyResult.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package ghidra.app.plugin.core.debug.mapping; +package ghidra.debug.api.platform; public class DisassemblyResult { public static final DisassemblyResult SUCCESS = new DisassemblyResult(true, null); diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/DebuggerCoordinates.java b/Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/tracemgr/DebuggerCoordinates.java similarity index 99% rename from Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/DebuggerCoordinates.java rename to Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/tracemgr/DebuggerCoordinates.java index d20d8f5b1a..76aa23adce 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/DebuggerCoordinates.java +++ b/Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/tracemgr/DebuggerCoordinates.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package ghidra.app.plugin.core.debug; +package ghidra.debug.api.tracemgr; import java.io.IOException; import java.util.*; @@ -21,8 +21,8 @@ import java.util.*; import org.jdom.Element; import ghidra.app.services.DebuggerTraceManagerService; -import ghidra.app.services.TraceRecorder; import ghidra.dbg.target.TargetObject; +import ghidra.debug.api.model.TraceRecorder; import ghidra.framework.data.DefaultProjectData; import ghidra.framework.model.*; import ghidra.framework.options.SaveState; diff --git a/Ghidra/Debug/Debugger-rmi-trace/src/main/java/ghidra/app/plugin/core/debug/service/rmi/trace/RemoteAsyncResult.java b/Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/tracermi/RemoteAsyncResult.java similarity index 69% rename from Ghidra/Debug/Debugger-rmi-trace/src/main/java/ghidra/app/plugin/core/debug/service/rmi/trace/RemoteAsyncResult.java rename to Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/tracermi/RemoteAsyncResult.java index ff8fd132c5..1ba9a26cc2 100644 --- a/Ghidra/Debug/Debugger-rmi-trace/src/main/java/ghidra/app/plugin/core/debug/service/rmi/trace/RemoteAsyncResult.java +++ b/Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/tracermi/RemoteAsyncResult.java @@ -13,12 +13,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package ghidra.app.plugin.core.debug.service.rmi.trace; +package ghidra.debug.api.tracermi; -import java.util.concurrent.*; +import java.util.concurrent.CompletionStage; +import java.util.concurrent.Future; import ghidra.trace.model.target.TraceObject; -import ghidra.util.Swing; /** * The future result of invoking a {@link RemoteMethod}. @@ -40,31 +40,6 @@ import ghidra.util.Swing; * a non-swing thread, e.g., a task thread or script thread, to wait for results, or chain * callbacks. */ -public class RemoteAsyncResult extends CompletableFuture { - final ValueDecoder decoder; +public interface RemoteAsyncResult extends CompletionStage, Future { - public RemoteAsyncResult() { - this.decoder = ValueDecoder.DEFAULT; - } - - public RemoteAsyncResult(OpenTrace open) { - this.decoder = open; - } - - @Override - public Object get() throws InterruptedException, ExecutionException { - if (Swing.isSwingThread()) { - throw new AssertionError("Refusing indefinite wait on Swing thread"); - } - return super.get(); - } - - @Override - public Object get(long timeout, TimeUnit unit) - throws InterruptedException, ExecutionException, TimeoutException { - if (Swing.isSwingThread() && unit.toSeconds(timeout) > 1) { - throw new AssertionError("Refusing a timeout > 1 second on Swing thread"); - } - return super.get(timeout, unit); - } } diff --git a/Ghidra/Debug/Debugger-rmi-trace/src/main/java/ghidra/app/plugin/core/debug/service/rmi/trace/RemoteMethod.java b/Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/tracermi/RemoteMethod.java similarity index 96% rename from Ghidra/Debug/Debugger-rmi-trace/src/main/java/ghidra/app/plugin/core/debug/service/rmi/trace/RemoteMethod.java rename to Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/tracermi/RemoteMethod.java index 221db1e075..a0204dfc56 100644 --- a/Ghidra/Debug/Debugger-rmi-trace/src/main/java/ghidra/app/plugin/core/debug/service/rmi/trace/RemoteMethod.java +++ b/Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/tracermi/RemoteMethod.java @@ -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.rmi.trace; +package ghidra.debug.api.tracermi; import java.util.Map; import java.util.concurrent.CompletableFuture; @@ -316,15 +316,4 @@ public interface RemoteMethod { throw new TraceRmiError(e); } } - - record RecordRemoteMethod(TraceRmiHandler handler, String name, Action action, - String description, Map parameters, SchemaName retType) - implements RemoteMethod { - @Override - public RemoteAsyncResult invokeAsync(Map arguments) { - Trace trace = validate(arguments); - OpenTrace open = handler.getOpenTrace(trace); - return handler.invoke(open, name, arguments); - } - } } diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/register/DynamicRegisterChangeListener.java b/Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/tracermi/RemoteMethodRegistry.java similarity index 62% rename from Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/register/DynamicRegisterChangeListener.java rename to Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/tracermi/RemoteMethodRegistry.java index eb62369ac2..ba0a51ff2d 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/register/DynamicRegisterChangeListener.java +++ b/Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/tracermi/RemoteMethodRegistry.java @@ -13,14 +13,17 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package ghidra.app.plugin.core.debug.register; +package ghidra.debug.api.tracermi; -import ghidra.program.model.data.DataType; -import ghidra.program.model.lang.Register; -import ghidra.program.model.lang.RegisterValue; +import java.util.Map; +import java.util.Set; -public interface DynamicRegisterChangeListener { - void updateRegisterValue(RegisterValue registerValue); +import ghidra.debug.api.tracermi.RemoteMethod.Action; - void updateRegisterDataType(Register register, DataType dataType); +public interface RemoteMethodRegistry { + Map all(); + + RemoteMethod get(String name); + + Set getByAction(Action action); } diff --git a/Ghidra/Debug/Debugger-rmi-trace/src/main/java/ghidra/app/plugin/core/debug/service/rmi/trace/RemoteParameter.java b/Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/tracermi/RemoteParameter.java similarity index 76% rename from Ghidra/Debug/Debugger-rmi-trace/src/main/java/ghidra/app/plugin/core/debug/service/rmi/trace/RemoteParameter.java rename to Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/tracermi/RemoteParameter.java index b7caaef916..c64dfad8bf 100644 --- a/Ghidra/Debug/Debugger-rmi-trace/src/main/java/ghidra/app/plugin/core/debug/service/rmi/trace/RemoteParameter.java +++ b/Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/tracermi/RemoteParameter.java @@ -13,10 +13,14 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package ghidra.app.plugin.core.debug.service.rmi.trace; +package ghidra.debug.api.tracermi; import ghidra.dbg.target.schema.TargetObjectSchema.SchemaName; -public record RemoteParameter(String name, SchemaName type, boolean required, - ValueSupplier defaultValue, String display, String description) { +public interface RemoteParameter { + SchemaName type(); + + boolean required(); + + Object getDefaultValue(); } diff --git a/Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/tracermi/TraceRmiAcceptor.java b/Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/tracermi/TraceRmiAcceptor.java new file mode 100644 index 0000000000..d36d8fdefb --- /dev/null +++ b/Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/tracermi/TraceRmiAcceptor.java @@ -0,0 +1,51 @@ +/* ### + * 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.debug.api.tracermi; + +import java.io.IOException; +import java.net.SocketAddress; +import java.net.SocketException; + +/** + * An acceptor to receive a single Trace RMI connection from a back-end + */ +public interface TraceRmiAcceptor { + /** + * Accept a single connection + * + *

+ * This acceptor is no longer valid after the connection is accepted. + * + * @return the connection, if successful + * @throws IOException if there was an error + */ + TraceRmiConnection accept() throws IOException; + + /** + * Get the address (and port) where the acceptor is listening + * + * @return the socket address + */ + SocketAddress getAddress(); + + /** + * Set the timeout + * + * @param millis the number of milliseconds after which an {@link #accept()} will time out. + * @throws SocketException if there's a protocol error + */ + void setTimeout(int millis) throws SocketException; +} diff --git a/Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/tracermi/TraceRmiConnection.java b/Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/tracermi/TraceRmiConnection.java new file mode 100644 index 0000000000..fd0afe7ca0 --- /dev/null +++ b/Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/tracermi/TraceRmiConnection.java @@ -0,0 +1,39 @@ +/* ### + * 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.debug.api.tracermi; + +import java.io.IOException; +import java.net.SocketAddress; +import java.util.concurrent.TimeoutException; + +import ghidra.trace.model.Trace; + +public interface TraceRmiConnection extends AutoCloseable { + SocketAddress getRemoteAddress(); + + RemoteMethodRegistry getMethods(); + + Trace waitForTrace(long timeoutMillis) throws TimeoutException; + + long getLastSnapshot(Trace trace); + + @Override + void close() throws IOException; + + boolean isClosed(); + + void waitClosed(); +} diff --git a/Ghidra/Debug/Debugger-rmi-trace/src/main/java/ghidra/app/plugin/core/debug/service/rmi/trace/TraceRmiError.java b/Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/tracermi/TraceRmiError.java similarity index 94% rename from Ghidra/Debug/Debugger-rmi-trace/src/main/java/ghidra/app/plugin/core/debug/service/rmi/trace/TraceRmiError.java rename to Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/tracermi/TraceRmiError.java index 240bc6eff6..9836e09c61 100644 --- a/Ghidra/Debug/Debugger-rmi-trace/src/main/java/ghidra/app/plugin/core/debug/service/rmi/trace/TraceRmiError.java +++ b/Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/tracermi/TraceRmiError.java @@ -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.rmi.trace; +package ghidra.debug.api.tracermi; public class TraceRmiError extends RuntimeException { public TraceRmiError() { diff --git a/Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/tracermi/TraceRmiLaunchOffer.java b/Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/tracermi/TraceRmiLaunchOffer.java new file mode 100644 index 0000000000..4a510e9963 --- /dev/null +++ b/Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/tracermi/TraceRmiLaunchOffer.java @@ -0,0 +1,288 @@ +/* ### + * 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.debug.api.tracermi; + +import java.io.IOException; +import java.util.List; +import java.util.Map; + +import javax.swing.Icon; + +import ghidra.dbg.target.TargetMethod.ParameterDescription; +import ghidra.program.model.listing.Program; +import ghidra.trace.model.Trace; +import ghidra.util.HelpLocation; +import ghidra.util.task.TaskMonitor; + +/** + * An offer to launch a program with a given mechanism + * + *

+ * Typically each offer is configured with the program it's going to launch, and knows how to work a + * specific connector and platform to obtain a target executing the program's image. The mechanisms + * may vary wildly from platform to platform. + */ +public interface TraceRmiLaunchOffer { + + /** + * A terminal with some back-end element attached to it + */ + interface TerminalSession extends AutoCloseable { + @Override + void close() throws IOException; + + /** + * Terminate the session without closing the terminal + */ + void terminate() throws IOException; + } + + /** + * The result of launching a program + * + *

+ * The launch may not always be completely successful. Instead of tearing things down, partial + * launches are left in place, in case the user wishes to repair/complete the steps manually. If + * the result includes a connection, then at least that was successful. If not, then the caller + * can choose how to treat the terminal sessions. If the cause of failure was an exception, it + * is included. If the launch succeeded, but module mapping failed, the result will include a + * trace and the exception. If an error occurred in the shell script, it may not be communicated + * here, but instead displayed only in the terminal. + * + * @param program the program associated with the launch attempt + * @param sessions any terminal sessions created while launching the back-end. If there are more + * than one, they are distinguished by launcher-defined keys. If there are no + * sessions, then there was likely a catastrophic error in the launcher. + * @param connection if the target connected back to Ghidra, that connection + * @param trace if the connection started a trace, the (first) trace it created + * @param exception optional error, if failed + */ + public record LaunchResult(Program program, Map sessions, + TraceRmiConnection connection, Trace trace, Throwable exception) + implements AutoCloseable { + @Override + public void close() throws Exception { + for (TerminalSession s : sessions.values()) { + s.close(); + } + if (connection != null) { + connection.close(); + } + } + } + + /** + * When programmatically customizing launch configuration, describes callback timing relative to + * prompting the user. + */ + public enum RelPrompt { + /** + * The user is not prompted for parameters. This will be the only callback. + */ + NONE, + /** + * The user will be prompted. This callback can pre-populate suggested parameters. Another + * callback will be issued if the user does not cancel. + */ + BEFORE, + /** + * The user has confirmed the parameters. This callback can validate or override the users + * parameters. Overriding the user is discouraged. This is the final callback. + */ + AFTER; + } + + public enum PromptMode { + /** + * The user is always prompted for parameters. + */ + ALWAYS, + /** + * The user is never prompted for parameters. + */ + NEVER, + /** + * The user is prompted after an error. + */ + ON_ERROR; + } + + /** + * Callbacks for custom configuration when launching a program + */ + public interface LaunchConfigurator { + LaunchConfigurator NOP = new LaunchConfigurator() {}; + + /** + * Determine whether the user should be prompted to confirm launch parameters + * + * @return the prompt mode + */ + default PromptMode getPromptMode() { + return PromptMode.NEVER; + } + + /** + * Re-write the launcher arguments, if desired + * + * @param launcher the launcher that will create the target + * @param arguments the arguments suggested by the offer or saved settings + * @param relPrompt describes the timing of this callback relative to prompting the user + * @return the adjusted arguments + */ + default Map configureLauncher(TraceRmiLaunchOffer offer, + Map arguments, RelPrompt relPrompt) { + return arguments; + } + } + + /** + * Launch the program using the offered mechanism + * + * @param monitor a monitor for progress and cancellation + * @param configurator the configuration callback + * @return the launch result + */ + LaunchResult launchProgram(TaskMonitor monitor, LaunchConfigurator configurator); + + /** + * Launch the program using the offered mechanism + * + * @param monitor a monitor for progress and cancellation + * @return the launch result + */ + default LaunchResult launchProgram(TaskMonitor monitor) { + return launchProgram(monitor, LaunchConfigurator.NOP); + } + + /** + * A name so that this offer can be recognized later + * + *

+ * The name is saved to configuration files, so that user preferences and priorities can be + * memorized. The opinion will generate each offer fresh each time, so it's important that the + * "same offer" have the same configuration name. Note that the name cannot depend on + * the program name, but can depend on the model factory and program language and/or compiler + * spec. This name cannot contain semicolons ({@ code ;}). + * + * @return the configuration name + */ + String getConfigName(); + + /** + * Get the icon displayed in the UI for this offer + * + *

+ * Please take care when overriding this that the icon still clearly indicates the target will + * be executed. Changing it, e.g., to the same icon as "Step" would be an unwelcome prank. A + * more reasonable choice would be the standard {@code "icon.debugger"} plus an overlay, or the + * branding of the underlying technology, e.g., QEMU or GDB. + * + * @return the icon + */ + Icon getIcon(); + + /** + * Get the menu path subordinate to "Debugger.Debug [imagePath]" for this offer. + * + *

+ * By default, this is just the title, i.e., the same as in the quick-launch drop-down menu. A + * package that introduces a large number of offers should override this method to organize + * them. A general rule of thumb is "no more than seven." Except at the level immediately under + * "Debug [imagePath]," no more than seven items should be presented to the user. In some cases, + * it may be more appropriate to group things using {@link #getMenuGroup() menu groups} rather + * than sub menus. + * + *

+ * Organization is very much a matter of taste, but consider that you are cooperating with other + * packages to populate the launcher menu. The top level is especially contentious, but sub + * menus, if named appropriately, are presumed to belong to a single package. + * + * @return the path + */ + default List getMenuPath() { + return List.of(getTitle()); + } + + /** + * Get the text displayed in the quick-launch drop-down menu. + * + *

+ * No two offers should ever have the same title, even if they appear in different sub-menus. + * Otherwise, the user cannot distinguish the offers in the quick-launch drop-down menu. + * + * @return the menu title + */ + public String getTitle(); + + /** + * Get an HTML description of the connector + * + * @return the description + */ + public String getDescription(); + + /** + * Get the menu group for the offer + * + *

+ * Especially for entries immediately under to "Debugger.Debug [imagePath]", specifies the menu + * group. A package that introduces a large number of offers should instead consider + * {@link #getMenuPath() sub menus}. + * + * @return the menu group + */ + default String getMenuGroup() { + return ""; + } + + /** + * Controls the position in the menu (within its group) of the entry + * + *

+ * The menus will always be presented in the same order, barring any changes to the plugins or + * launcher properties. Groups are alphabetized and visually separated. Then sub groups are + * alphabetized, but not visually separated. Finally, offers are alphabetized by their + * final path element, usually the title. + * + *

+ * The order of entries in the quick-launch drop-down menu is always most-recently to + * least-recently used. An entry that has never been used does not appear in the quick launch + * menu. + */ + default String getMenuOrder() { + return ""; + } + + /** + * Get the location for additional help about this specific offer + * + *

+ * The default is just the entry on Trace RMI launchers in general. + * + * @return the location + */ + default HelpLocation getHelpLocation() { + return new HelpLocation("TraceRmiPlugin", "launch"); + } + + /** + * Get the parameter descriptions for the launcher + * + * @return the parameters + */ + Map> getParameters(); +} diff --git a/Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/tracermi/TraceRmiLaunchOpinion.java b/Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/tracermi/TraceRmiLaunchOpinion.java new file mode 100644 index 0000000000..519360b750 --- /dev/null +++ b/Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/tracermi/TraceRmiLaunchOpinion.java @@ -0,0 +1,78 @@ +/* ### + * 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.debug.api.tracermi; + +import java.util.Collection; + +import ghidra.framework.options.Options; +import ghidra.framework.plugintool.PluginTool; +import ghidra.program.model.listing.Program; +import ghidra.util.classfinder.ExtensionPoint; + +/** + * A factory of launch offers + * + *

+ * Each factory is instantiated only once for the entire application, even when multiple tools are + * open. Thus, {@link #init(PluginTool)} and {@link #dispose(PluginTool)} will be invoked for each + * tool. + */ +public interface TraceRmiLaunchOpinion extends ExtensionPoint { + /** + * Register any options + * + * @param tool the tool + */ + default void registerOptions(Options options) { + } + + /** + * Check if a change in the given option requires a refresh of offers + * + * @param optionName the name of the option that changed + * @return true to refresh, false otherwise + */ + default boolean requiresRefresh(String optionName) { + return false; + } + + /** + * Generate or retrieve a collection of offers based on the current program. + * + *

+ * Take care trying to "validate" a particular mechanism. For example, it is not + * appropriate to check that GDB exists, nor to execute it to derive its version. + * + *

    + *
  1. It's possible the user has dependencies installed in non-standard locations. I.e., the + * user needs a chance to configure things before the UI decides whether or not to + * display them.
  2. + *
  3. The menus are meant to display all possibilities installed in Ghidra, even if + * some dependencies are missing on the local system. Discovery of the feature is most + * important. Knowing a feature exists may motivate a user to obtain the required dependencies + * and try it out.
  4. + *
  5. An offer is only promoted to the quick-launch menu upon successful connection. + * I.e., the entries there are already validated; they've worked at least once before.
  6. + *
+ * + * @param program the current program. While this is not always used by the launcher, + * it is implied that the user expects the debugger to do something with the current + * program, even if it's just informing the back-end debugger of the target image. + * @param tool the current tool for context and services + * @return the offers. The order is not important since items are displayed alphabetically. + */ + public Collection getOffers(Program program, PluginTool tool); +} diff --git a/Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/watch/WatchRow.java b/Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/watch/WatchRow.java new file mode 100644 index 0000000000..84404b6a29 --- /dev/null +++ b/Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/watch/WatchRow.java @@ -0,0 +1,233 @@ +/* ### + * 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.debug.api.watch; + +import ghidra.docking.settings.Settings; +import ghidra.program.model.address.*; +import ghidra.program.model.data.DataType; +import ghidra.program.model.symbol.Symbol; + +/** + * A row in the Watches table + */ +public interface WatchRow { + + /** + * Get the Sleigh expression + * + * @return the expression + */ + String getExpression(); + + /** + * Set the Sleigh expression + * + * @param expression the expression + */ + void setExpression(String expression); + + /** + * Get the data type for interpreting the value + * + * @return the data type + */ + DataType getDataType(); + + /** + * Set the data type for interpreting the value + * + * @param dataType the data type + */ + void setDataType(DataType dataType); + + /** + * Get the settings on the data type + * + *

+ * The returned settings may be modified, after which {@link #settingsChanged()} must be called. + * There is no {@code setSettings} method. + * + * @return the settings + */ + Settings getSettings(); + + /** + * Notify the row that the settings were changed + * + * @see #getSettings() + */ + void settingsChanged(); + + /** + * Get the address of the value, if it exists at one (memory or register) + * + * @return the address, or null + */ + Address getAddress(); + + /** + * Get the address range of the value, if it exists at an address (memory or register) + * + * @return the range, or null + */ + AddressRange getRange(); + + /** + * Get the complete set of all addresses read to evaluate the expression + * + * @return the address set, or null + */ + AddressSetView getReads(); + + /** + * Get the nearest symbol before the value's address, if applicable + * + * @return the symbol, or null + */ + Symbol getSymbol(); + + /** + * Get the raw value + * + * @return the value, or null + */ + byte[] getValue(); + + /** + * Get the raw value displayed as a string + * + *

+ * For values in memory, this is a list of hex bytes. For others, it is a hex integer subject to + * the platform's endian. + * + * @return the value, or null + */ + String getRawValueString(); + + /** + * Get the number of bytes in the value + * + * @return the length, or 0 if evaluation failed + */ + int getValueLength(); + + /** + * Patch memory or register values such that the expression evaluates to the given raw value + * + *

+ * This is only supported when {@link #isRawValueEditable} returns true. The given value must be + * a list of hex bytes (as returned by {@link #getRawValueString()}), or a hex integer subject + * to the platform's endian. Either is accepted, regardless of whether the value resides in + * memory. + * + * @see #getAddress() + * @param value the raw value as returned by {@link #getRawValueString()} + */ + void setRawValueString(String value); + + /** + * Check if {@link #setRawValueString(String)} is supported + * + *

+ * Setting the value may not be supported for many reasons: 1) The expression is not valid, 2) + * The expression could not be evaluated, 3) The value has no address or register. Reason 3 is + * somewhat strict, but reasonable, lest we have to implement a solver. + * + * @return whether or not the value can be modified + */ + boolean isRawValueEditable(); + + /** + * Get the value as returned by the data type + * + * @return the data-type defined value + */ + Object getValueObject(); + + /** + * Get the value as represented by the data type + * + * @return the value's data-type-defined representation + */ + String getValueString(); + + /** + * Patch memory or register values such that the expression evaluates to the given value + * + *

+ * This is only supported when {@link #isValueEditable()} returns true. The given value must be + * encodable by the data type. + * + * @param value the desired value, as returned by {@link #getValueString()} + */ + void setValueString(String value); + + /** + * Check if {@link #setValueString(String)} is supported + * + *

+ * In addition to those reasons given in {@link #isRawValueEditable()}, setting the value may + * not be supported because: 1) No data type is set, or 2) The selected data type does not + * support encoding. + * + * @return whether or not the data-type interpreted value can be modified + */ + boolean isValueEditable(); + + /** + * If the watch could not be evaluated, get the cause + * + * @return the error + */ + Throwable getError(); + + /** + * If the watch could not be evaluated, get a message explaining why + * + *

+ * This is essentially the message given by {@link #getError()}. If the exception does not + * provide a message, this will at least give the name of the exception class. + * + * @return the error message, or an empty string + */ + String getErrorMessage(); + + /** + * Check if the value given is actually known to be the value + * + *

+ * If the value itself or any value encountered during the evaluation of the expression is + * stale, then the final value is considered stale, i.e., not known. + * + * @return true all memory and registers involved in the evaluation are known, false otherwise. + */ + boolean isKnown(); + + /** + * Check if the value has changed + * + *

+ * "Changed" technically deals in navigation. In the case of a step, resume-and-break, patch, + * etc. This will detect the changes as expected. When manually navigating, this compares the + * two most recent times visited. Only the value itself is compared, without consideration for + * any intermediate values encountered during evaluation. Consider an array whose elements are + * all currently 0. An expression that dereferences an index in that array will be considered + * unchanged, even if the index did change. + * + * @return true if the value changed, false otherwise. + */ + boolean isChanged(); +} diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/services/DebuggerBot.java b/Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/workflow/DebuggerBot.java similarity index 94% rename from Ghidra/Debug/Debugger/src/main/java/ghidra/app/services/DebuggerBot.java rename to Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/workflow/DebuggerBot.java index 32b2e98930..f0ebcc030e 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/services/DebuggerBot.java +++ b/Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/workflow/DebuggerBot.java @@ -13,9 +13,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package ghidra.app.services; +package ghidra.debug.api.workflow; -import ghidra.app.plugin.core.debug.service.workflow.DebuggerWorkflowServicePlugin; +import ghidra.app.services.DebuggerModelService; +import ghidra.app.services.DebuggerWorkflowFrontEndService; import ghidra.dbg.DebuggerObjectModel; import ghidra.framework.options.AutoOptions; import ghidra.framework.plugintool.PluginTool; @@ -153,15 +154,15 @@ public interface DebuggerBot extends ExtensionPoint { * If {@link #isEnabled()} is already equal to the given -enabled- value, this method has no * effect. * - * @param plugin the front-end plugin, required if -enabled- is set + * @param service the front-end service, required if -enabled- is set * @param enabled true to enable, false to disable */ - default void setEnabled(DebuggerWorkflowServicePlugin plugin, boolean enabled) { + default void setEnabled(DebuggerWorkflowFrontEndService service, boolean enabled) { if (isEnabled() == enabled) { return; } if (enabled) { - enable(plugin); + enable(service); } else { disable(); @@ -171,9 +172,9 @@ public interface DebuggerBot extends ExtensionPoint { /** * Enable and initialize the bot * - * @param plugin the front-end plugin + * @param service the front-end service */ - void enable(DebuggerWorkflowServicePlugin plugin); + void enable(DebuggerWorkflowFrontEndService service); /** * Disable and dispose the bot diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/services/DebuggerBotInfo.java b/Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/workflow/DebuggerBotInfo.java similarity index 98% rename from Ghidra/Debug/Debugger/src/main/java/ghidra/app/services/DebuggerBotInfo.java rename to Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/workflow/DebuggerBotInfo.java index da05142110..2fb237accb 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/services/DebuggerBotInfo.java +++ b/Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/workflow/DebuggerBotInfo.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package ghidra.app.services; +package ghidra.debug.api.workflow; import java.lang.annotation.*; diff --git a/Ghidra/Debug/Debugger-rmi-trace/DEVNOTES.txt b/Ghidra/Debug/Debugger-rmi-trace/DEVNOTES.txt index a96a04bdf8..0c6907099d 100644 --- a/Ghidra/Debug/Debugger-rmi-trace/DEVNOTES.txt +++ b/Ghidra/Debug/Debugger-rmi-trace/DEVNOTES.txt @@ -278,3 +278,10 @@ I wouldn't expect the user to manage multiple transaction objects. The recommendation is that the CLI can have at most one active transaction. For the user to open a second transaction may be considered an error. Take care as you're coding (and likely re-using command logic) that you don't accidentally take or otherwise conflict with the CLI's transaction manager when processing an event. + + + +# Regarding launcher shell scripts: + +Need to document all the @metadata stuff +In particular, "Image" is a special parameter that will get the program executable by default. diff --git a/Ghidra/Debug/Debugger-rmi-trace/build.gradle b/Ghidra/Debug/Debugger-rmi-trace/build.gradle index 960b5ce04c..113b165f1d 100644 --- a/Ghidra/Debug/Debugger-rmi-trace/build.gradle +++ b/Ghidra/Debug/Debugger-rmi-trace/build.gradle @@ -27,6 +27,7 @@ eclipse.project.name = 'Debug Debugger-rmi-trace' dependencies { api project(':Pty') api project(':Debugger') + api project(':Debugger-api') } task generateProtoPy { diff --git a/Ghidra/Debug/Debugger-rmi-trace/certification.manifest b/Ghidra/Debug/Debugger-rmi-trace/certification.manifest index 9a07dbeaad..6a41f8216c 100644 --- a/Ghidra/Debug/Debugger-rmi-trace/certification.manifest +++ b/Ghidra/Debug/Debugger-rmi-trace/certification.manifest @@ -1,6 +1,7 @@ ##VERSION: 2.0 DEVNOTES.txt||GHIDRA||||END| Module.manifest||GHIDRA||||END| +data/ExtensionPoint.manifest||GHIDRA||||END| src/main/py/LICENSE||GHIDRA||||END| src/main/py/README.md||GHIDRA||||END| src/main/py/pyproject.toml||GHIDRA||||END| diff --git a/Ghidra/Debug/Debugger-rmi-trace/data/ExtensionPoint.manifest b/Ghidra/Debug/Debugger-rmi-trace/data/ExtensionPoint.manifest new file mode 100644 index 0000000000..93e5865b35 --- /dev/null +++ b/Ghidra/Debug/Debugger-rmi-trace/data/ExtensionPoint.manifest @@ -0,0 +1 @@ +TraceRmiLaunchOpinion \ No newline at end of file diff --git a/Ghidra/Debug/Debugger-rmi-trace/ghidra_scripts/ConnectTraceRmiScript.java b/Ghidra/Debug/Debugger-rmi-trace/ghidra_scripts/ConnectTraceRmiScript.java index 7434cf48a9..c97af91aef 100644 --- a/Ghidra/Debug/Debugger-rmi-trace/ghidra_scripts/ConnectTraceRmiScript.java +++ b/Ghidra/Debug/Debugger-rmi-trace/ghidra_scripts/ConnectTraceRmiScript.java @@ -14,10 +14,8 @@ * limitations under the License. */ import java.net.InetSocketAddress; -import java.util.Map; import java.util.Objects; -import ghidra.app.plugin.core.debug.service.rmi.trace.TraceRmiHandler; import ghidra.app.plugin.core.debug.service.rmi.trace.TraceRmiPlugin; import ghidra.app.script.GhidraScript; import ghidra.app.services.TraceRmiService; @@ -36,10 +34,9 @@ public class ConnectTraceRmiScript extends GhidraScript { @Override protected void run() throws Exception { TraceRmiService service = getService(); - TraceRmiHandler handler = service.connect( - new InetSocketAddress(askString("Trace RMI", "hostname", "localhost"), askInt("Trace RMI", "port"))); + service.connect(new InetSocketAddress(askString("Trace RMI", "hostname", "localhost"), + askInt("Trace RMI", "port"))); println("Connected"); - handler.start(); // if (askYesNo("Execute?", "Execute 'echo test'?")) { // handler.getMethods().get("execute").invoke(Map.of("cmd", "script print('test')")); diff --git a/Ghidra/Debug/Debugger-rmi-trace/ghidra_scripts/ListenTraceRmiScript.java b/Ghidra/Debug/Debugger-rmi-trace/ghidra_scripts/ListenTraceRmiScript.java index af21cd9c7e..3014952495 100644 --- a/Ghidra/Debug/Debugger-rmi-trace/ghidra_scripts/ListenTraceRmiScript.java +++ b/Ghidra/Debug/Debugger-rmi-trace/ghidra_scripts/ListenTraceRmiScript.java @@ -16,9 +16,11 @@ import java.util.Map; import java.util.Objects; -import ghidra.app.plugin.core.debug.service.rmi.trace.*; +import ghidra.app.plugin.core.debug.service.rmi.trace.TraceRmiPlugin; import ghidra.app.script.GhidraScript; import ghidra.app.services.TraceRmiService; +import ghidra.debug.api.tracermi.TraceRmiAcceptor; +import ghidra.debug.api.tracermi.TraceRmiConnection; public class ListenTraceRmiScript extends GhidraScript { @@ -37,12 +39,11 @@ public class ListenTraceRmiScript extends GhidraScript { TraceRmiAcceptor acceptor = service.acceptOne(null); println("Listening at " + acceptor.getAddress()); - TraceRmiHandler handler = acceptor.accept(); - println("Connection from " + handler.getRemoteAddress()); - handler.start(); + TraceRmiConnection connection = acceptor.accept(); + println("Connection from " + connection.getRemoteAddress()); while (askYesNo("Execute?", "Execute 'echo test'?")) { - handler.getMethods().get("execute").invoke(Map.of("cmd", "echo test")); + connection.getMethods().get("execute").invoke(Map.of("cmd", "echo test")); } } } diff --git a/Ghidra/Debug/Debugger-rmi-trace/src/main/java/ghidra/app/plugin/core/debug/gui/tracermi/connection/TraceRmiConnectionManagerPlugin.java b/Ghidra/Debug/Debugger-rmi-trace/src/main/java/ghidra/app/plugin/core/debug/gui/tracermi/connection/TraceRmiConnectionManagerPlugin.java new file mode 100644 index 0000000000..1b15dd8dce --- /dev/null +++ b/Ghidra/Debug/Debugger-rmi-trace/src/main/java/ghidra/app/plugin/core/debug/gui/tracermi/connection/TraceRmiConnectionManagerPlugin.java @@ -0,0 +1,42 @@ +/* ### + * IP: GHIDRA + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ghidra.app.plugin.core.debug.gui.tracermi.connection; + +import ghidra.app.plugin.PluginCategoryNames; +import ghidra.app.plugin.core.debug.DebuggerPluginPackage; +import ghidra.app.services.TraceRmiService; +import ghidra.framework.plugintool.*; +import ghidra.framework.plugintool.util.PluginStatus; + +@PluginInfo( + shortDescription = "GUI elements to manage Trace RMI connections", + description = """ + Provides a panel for managing Trace RMI connections. The panel also allows users to + control the Trace RMI server and/or create manual connections. + """, + category = PluginCategoryNames.DEBUGGER, + packageName = DebuggerPluginPackage.NAME, + status = PluginStatus.RELEASED, + servicesRequired = { + TraceRmiService.class, + }) +public class TraceRmiConnectionManagerPlugin extends Plugin { + public TraceRmiConnectionManagerPlugin(PluginTool tool) { + super(tool); + } + + // TODO: Add the actual provider. This will probably replace DebuggerTargetsPlugin. +} diff --git a/Ghidra/Debug/Debugger-rmi-trace/src/main/java/ghidra/app/plugin/core/debug/gui/tracermi/launcher/AbstractTraceRmiLaunchOffer.java b/Ghidra/Debug/Debugger-rmi-trace/src/main/java/ghidra/app/plugin/core/debug/gui/tracermi/launcher/AbstractTraceRmiLaunchOffer.java new file mode 100644 index 0000000000..fb15ebff74 --- /dev/null +++ b/Ghidra/Debug/Debugger-rmi-trace/src/main/java/ghidra/app/plugin/core/debug/gui/tracermi/launcher/AbstractTraceRmiLaunchOffer.java @@ -0,0 +1,553 @@ +/* ### + * IP: GHIDRA + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ghidra.app.plugin.core.debug.gui.tracermi.launcher; + +import java.io.File; +import java.io.IOException; +import java.net.InetSocketAddress; +import java.net.SocketAddress; +import java.nio.charset.Charset; +import java.util.*; +import java.util.Map.Entry; +import java.util.concurrent.*; + +import javax.swing.Icon; + +import org.jdom.Element; +import org.jdom.JDOMException; + +import db.Transaction; +import ghidra.app.plugin.core.debug.gui.DebuggerResources; +import ghidra.app.plugin.core.debug.gui.objects.components.DebuggerMethodInvocationDialog; +import ghidra.app.plugin.core.terminal.TerminalListener; +import ghidra.app.services.*; +import ghidra.async.AsyncUtils; +import ghidra.dbg.target.TargetMethod.ParameterDescription; +import ghidra.dbg.util.ShellUtils; +import ghidra.debug.api.modules.*; +import ghidra.debug.api.modules.ModuleMapProposal.ModuleMapEntry; +import ghidra.debug.api.tracermi.*; +import ghidra.framework.options.SaveState; +import ghidra.framework.plugintool.AutoConfigState.ConfigStateField; +import ghidra.framework.plugintool.PluginTool; +import ghidra.program.model.address.*; +import ghidra.program.model.listing.*; +import ghidra.program.util.ProgramLocation; +import ghidra.pty.*; +import ghidra.trace.model.Trace; +import ghidra.trace.model.TraceLocation; +import ghidra.trace.model.modules.TraceModule; +import ghidra.util.MessageType; +import ghidra.util.Msg; +import ghidra.util.exception.CancelledException; +import ghidra.util.task.Task; +import ghidra.util.task.TaskMonitor; +import ghidra.util.xml.XmlUtilities; + +public abstract class AbstractTraceRmiLaunchOffer implements TraceRmiLaunchOffer { + + public static final String PREFIX_DBGLAUNCH = "DBGLAUNCH_"; + public static final String PARAM_DISPLAY_IMAGE = "Image"; + + protected record PtyTerminalSession(Terminal terminal, Pty pty, PtySession session, + Thread waiter) implements TerminalSession { + @Override + public void close() throws IOException { + terminate(); + terminal.close(); + } + + @Override + public void terminate() throws IOException { + terminal.terminated(); + session.destroyForcibly(); + pty.close(); + waiter.interrupt(); + } + } + + protected record NullPtyTerminalSession(Terminal terminal, Pty pty, String name) + implements TerminalSession { + @Override + public void close() throws IOException { + terminate(); + terminal.close(); + } + + @Override + public void terminate() throws IOException { + terminal.terminated(); + pty.close(); + } + } + + static class TerminateSessionTask extends Task { + private final TerminalSession session; + + public TerminateSessionTask(TerminalSession session) { + super("Terminate Session", false, false, false); + this.session = session; + } + + @Override + public void run(TaskMonitor monitor) throws CancelledException { + try { + session.close(); + } + catch (IOException e) { + Msg.error(this, "Could not terminate: " + e, e); + } + } + } + + protected final Program program; + protected final PluginTool tool; + protected final TerminalService terminalService; + + public AbstractTraceRmiLaunchOffer(Program program, PluginTool tool) { + this.program = Objects.requireNonNull(program); + this.tool = Objects.requireNonNull(tool); + this.terminalService = Objects.requireNonNull(tool.getService(TerminalService.class)); + } + + protected int getTimeoutMillis() { + return 10000; + } + + @Override + public Icon getIcon() { + return DebuggerResources.ICON_DEBUGGER; + } + + protected Address getMappingProbeAddress() { + AddressIterator eepi = program.getSymbolTable().getExternalEntryPointIterator(); + if (eepi.hasNext()) { + return eepi.next(); + } + InstructionIterator ii = program.getListing().getInstructions(true); + if (ii.hasNext()) { + return ii.next().getAddress(); + } + AddressSetView es = program.getMemory().getExecuteSet(); + if (!es.isEmpty()) { + return es.getMinAddress(); + } + if (!program.getMemory().isEmpty()) { + return program.getMinAddress(); + } + return null; // I guess we won't wait for a mapping, then + } + + protected CompletableFuture listenForMapping( + DebuggerStaticMappingService mappingService, TraceRmiConnection connection, + Trace trace) { + Address probeAddress = getMappingProbeAddress(); + if (probeAddress == null) { + return AsyncUtils.NIL; // No need to wait on mapping of nothing + } + ProgramLocation probe = new ProgramLocation(program, probeAddress); + var result = new CompletableFuture() { + DebuggerStaticMappingChangeListener listener = (affectedTraces, affectedPrograms) -> { + if (!affectedPrograms.contains(program) && + !affectedTraces.contains(trace)) { + return; + } + check(); + }; + + protected void check() { + long snap = connection.getLastSnapshot(trace); + TraceLocation result = mappingService.getOpenMappedLocation(trace, probe, snap); + if (result == null) { + return; + } + complete(null); + mappingService.removeChangeListener(listener); + } + }; + mappingService.addChangeListener(result.listener); + result.check(); + result.exceptionally(ex -> { + mappingService.removeChangeListener(result.listener); + return null; + }); + return result; + } + + protected Collection invokeMapper(TaskMonitor monitor, + DebuggerStaticMappingService mappingService, Trace trace) throws CancelledException { + Map map = mappingService + .proposeModuleMaps(trace.getModuleManager().getAllModules(), List.of(program)); + Collection proposal = MapProposal.flatten(map.values()); + mappingService.addModuleMappings(proposal, monitor, true); + return proposal; + } + + private void saveLauncherArgs(Map args, + Map> params) { + SaveState state = new SaveState(); + for (ParameterDescription param : params.values()) { + Object val = args.get(param.name); + if (val != null) { + ConfigStateField.putState(state, param.type.asSubclass(Object.class), + "param_" + param.name, val); + state.putLong("last", System.currentTimeMillis()); + } + } + if (program != null) { + ProgramUserData userData = program.getProgramUserData(); + try (Transaction tx = userData.openTransaction()) { + Element element = state.saveToXml(); + userData.setStringProperty(PREFIX_DBGLAUNCH + getConfigName(), + XmlUtilities.toString(element)); + } + } + } + + /** + * Generate the default launcher arguments + * + *

+ * It is not sufficient to simply take the defaults specified in the parameters. This must + * populate the arguments necessary to launch the requested program. + * + * @param params the parameters + * @return the default arguments + */ + @SuppressWarnings("unchecked") + protected Map generateDefaultLauncherArgs( + Map> params) { + if (program == null) { + return Map.of(); + } + Map map = new LinkedHashMap(); + ParameterDescription paramImage = null; + for (Entry> entry : params.entrySet()) { + ParameterDescription param = entry.getValue(); + map.put(entry.getKey(), param.defaultValue); + if (PARAM_DISPLAY_IMAGE.equals(param.display)) { + if (param.type != String.class) { + Msg.warn(this, "'Image' parameter has unexpected type: " + paramImage.type); + } + paramImage = (ParameterDescription) param; + } + } + if (paramImage != null) { + File imageFile = TraceRmiLauncherServicePlugin.getProgramPath(program); + if (imageFile != null) { + paramImage.set(map, imageFile.getAbsolutePath()); + } + } + return map; + } + + /** + * Prompt the user for arguments, showing those last used or defaults + * + * @param lastExc + * + * @param params the parameters of the model's launcher + * @param lastExc if re-prompting, an error to display + * @return the arguments given by the user, or null if cancelled + */ + protected Map promptLauncherArgs(LaunchConfigurator configurator, + Throwable lastExc) { + Map> params = getParameters(); + DebuggerMethodInvocationDialog dialog = + new DebuggerMethodInvocationDialog(tool, getTitle(), "Launch", getIcon()); + dialog.setDescription(getDescription()); + // NB. Do not invoke read/writeConfigState + Map args; + boolean reset = false; + do { + args = + configurator.configureLauncher(this, loadLastLauncherArgs(true), RelPrompt.BEFORE); + for (ParameterDescription param : params.values()) { + Object val = args.get(param.name); + if (val != null) { + dialog.setMemorizedArgument(param.name, param.type.asSubclass(Object.class), + val); + } + } + if (lastExc != null) { + dialog.setStatusText(lastExc.toString(), MessageType.ERROR); + } + else { + dialog.setStatusText(""); + } + args = dialog.promptArguments(params); + if (args == null) { + // Cancelled + return null; + } + reset = dialog.isResetRequested(); + if (reset) { + args = generateDefaultLauncherArgs(params); + } + saveLauncherArgs(args, params); + } + while (reset); + return args; + } + + /** + * Load the arguments last used for this offer, or give the defaults + * + *

+ * If there are no saved "last used" arguments, then this will return the defaults. If there are + * saved arguments, but they cannot be loaded, then this will behave differently depending on + * whether the user will be confirming the arguments. If there will be no prompt/confirmation, + * then this method must throw an exception in order to avoid launching with defaults, when the + * user may be expecting a customized launch. If there will be a prompt, then this may safely + * return the defaults, since the user will be given a chance to correct them. + * + * @param params the parameters of the model's launcher + * @param forPrompt true if the user will be confirming the arguments + * @return the loaded arguments, or defaults + */ + protected Map loadLastLauncherArgs(boolean forPrompt) { + /** + * TODO: Supposedly, per-program, per-user config stuff is being generalized for analyzers. + * Re-examine this if/when that gets merged + */ + if (program != null) { + Map> params = getParameters(); + ProgramUserData userData = program.getProgramUserData(); + String property = + userData.getStringProperty(PREFIX_DBGLAUNCH + getConfigName(), null); + if (property != null) { + try { + Element element = XmlUtilities.fromString(property); + SaveState state = new SaveState(element); + List names = List.of(state.getNames()); + Map args = new LinkedHashMap<>(); + for (ParameterDescription param : params.values()) { + String key = "param_" + param.name; + if (names.contains(key)) { + Object configState = ConfigStateField.getState(state, param.type, key); + if (configState != null) { + args.put(param.name, configState); + } + } + } + if (!args.isEmpty()) { + return args; + } + } + catch (JDOMException | IOException e) { + if (!forPrompt) { + throw new RuntimeException( + "Saved launcher args are corrupt, or launcher parameters changed. Not launching.", + e); + } + Msg.error(this, + "Saved launcher args are corrupt, or launcher parameters changed. Defaulting.", + e); + } + } + Map args = generateDefaultLauncherArgs(params); + saveLauncherArgs(args, params); + return args; + } + + return new LinkedHashMap<>(); + } + + /** + * Obtain the launcher args + * + *

+ * This should either call {@link #promptLauncherArgs(Map))} or + * {@link #loadLastLauncherArgs(Map, boolean))}. Note if choosing the latter, the user will not + * be prompted to confirm. + * + * @param params the parameters of the model's launcher + * @param configurator the rules for configuring the launcher + * @param lastExc if retrying, the last exception to display as an error message + * @return the chosen arguments, or null if the user cancels at the prompt + */ + public Map getLauncherArgs(boolean prompt, LaunchConfigurator configurator, + Throwable lastExc) { + return prompt + ? configurator.configureLauncher(this, promptLauncherArgs(configurator, lastExc), + RelPrompt.AFTER) + : configurator.configureLauncher(this, loadLastLauncherArgs(false), RelPrompt.NONE); + } + + public Map getLauncherArgs(boolean prompt) { + return getLauncherArgs(prompt, LaunchConfigurator.NOP, null); + } + + protected PtyFactory getPtyFactory() { + return PtyFactory.local(); + } + + protected PtyTerminalSession runInTerminal(List commandLine, Map env, + Collection subordinates) + throws IOException { + PtyFactory factory = getPtyFactory(); + Pty pty = factory.openpty(); + + PtyParent parent = pty.getParent(); + Terminal terminal = terminalService.createWithStreams(Charset.forName("UTF-8"), + parent.getInputStream(), parent.getOutputStream()); + terminal.setSubTitle(ShellUtils.generateLine(commandLine)); + TerminalListener resizeListener = new TerminalListener() { + @Override + public void resized(short cols, short rows) { + parent.setWindowSize(cols, rows); + } + }; + terminal.addTerminalListener(resizeListener); + + env.put("TERM", "xterm-256color"); + PtySession session = pty.getChild().session(commandLine.toArray(String[]::new), env); + + Thread waiter = new Thread(() -> { + try { + session.waitExited(); + terminal.terminated(); + pty.close(); + + for (TerminalSession ss : subordinates) { + ss.terminate(); + } + } + catch (InterruptedException | IOException e) { + Msg.error(this, e); + } + }, "Waiter: " + getConfigName()); + waiter.start(); + + PtyTerminalSession terminalSession = + new PtyTerminalSession(terminal, pty, session, waiter); + terminal.setTerminateAction(() -> { + tool.execute(new TerminateSessionTask(terminalSession)); + }); + return terminalSession; + } + + protected NullPtyTerminalSession nullPtyTerminal() throws IOException { + PtyFactory factory = getPtyFactory(); + Pty pty = factory.openpty(); + + PtyParent parent = pty.getParent(); + Terminal terminal = terminalService.createWithStreams(Charset.forName("UTF-8"), + parent.getInputStream(), parent.getOutputStream()); + TerminalListener resizeListener = new TerminalListener() { + @Override + public void resized(short cols, short rows) { + parent.setWindowSize(cols, rows); + } + }; + terminal.addTerminalListener(resizeListener); + + String name = pty.getChild().nullSession(); + terminal.setSubTitle(name); + + NullPtyTerminalSession terminalSession = new NullPtyTerminalSession(terminal, pty, name); + terminal.setTerminateAction(() -> { + tool.execute(new TerminateSessionTask(terminalSession)); + }); + return terminalSession; + } + + protected abstract void launchBackEnd(TaskMonitor monitor, + Map sessions, Map args, SocketAddress address) + throws Exception; + + @Override + public LaunchResult launchProgram(TaskMonitor monitor, LaunchConfigurator configurator) { + TraceRmiService service = tool.getService(TraceRmiService.class); + DebuggerStaticMappingService mappingService = + tool.getService(DebuggerStaticMappingService.class); + DebuggerTraceManagerService traceManager = + tool.getService(DebuggerTraceManagerService.class); + final PromptMode mode = configurator.getPromptMode(); + boolean prompt = mode == PromptMode.ALWAYS; + + TraceRmiAcceptor acceptor = null; + Map sessions = new LinkedHashMap<>(); + TraceRmiConnection connection = null; + Trace trace = null; + Throwable lastExc = null; + + monitor.setMaximum(5); + while (true) { + monitor.setMessage("Gathering arguments"); + Map args = getLauncherArgs(prompt, configurator, lastExc); + if (args == null) { + if (lastExc == null) { + lastExc = new CancelledException(); + } + return new LaunchResult(program, sessions, connection, trace, lastExc); + } + acceptor = null; + sessions.clear(); + connection = null; + trace = null; + lastExc = null; + + try { + monitor.setMessage("Listening for connection"); + acceptor = service.acceptOne(new InetSocketAddress("127.0.0.1", 0)); + monitor.setMessage("Launching back-end"); + launchBackEnd(monitor, sessions, args, acceptor.getAddress()); + monitor.setMessage("Waiting for connection"); + acceptor.setTimeout(getTimeoutMillis()); + connection = acceptor.accept(); + monitor.setMessage("Waiting for trace"); + trace = connection.waitForTrace(getTimeoutMillis()); + traceManager.openTrace(trace); + traceManager.activateTrace(trace); + monitor.setMessage("Waiting for module mapping"); + try { + listenForMapping(mappingService, connection, trace).get(getTimeoutMillis(), + TimeUnit.MILLISECONDS); + } + catch (TimeoutException e) { + monitor.setMessage( + "Timed out waiting for module mapping. Invoking the mapper."); + Collection mapped; + try { + mapped = invokeMapper(monitor, mappingService, trace); + } + catch (CancelledException ce) { + throw new CancellationException(e.getMessage()); + } + if (mapped.isEmpty()) { + monitor.setMessage( + "Could not formulate a mapping with the target program. " + + "Continuing without one."); + Msg.showWarn(this, null, "Launch " + program, + "The resulting target process has no mapping to the static image " + + program + ". Intervention is required before static and dynamic " + + "addresses can be translated. Check the target's module list."); + } + } + } + catch (Exception e) { + lastExc = e; + prompt = mode != PromptMode.NEVER; + if (prompt) { + continue; + } + return new LaunchResult(program, sessions, connection, trace, lastExc); + } + return new LaunchResult(program, sessions, connection, trace, null); + } + } +} diff --git a/Ghidra/Debug/Debugger-rmi-trace/src/main/java/ghidra/app/plugin/core/debug/gui/tracermi/launcher/LaunchAction.java b/Ghidra/Debug/Debugger-rmi-trace/src/main/java/ghidra/app/plugin/core/debug/gui/tracermi/launcher/LaunchAction.java new file mode 100644 index 0000000000..09bbcb8957 --- /dev/null +++ b/Ghidra/Debug/Debugger-rmi-trace/src/main/java/ghidra/app/plugin/core/debug/gui/tracermi/launcher/LaunchAction.java @@ -0,0 +1,198 @@ +/* ### + * IP: GHIDRA + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ghidra.app.plugin.core.debug.gui.tracermi.launcher; + +import java.io.IOException; +import java.util.*; +import java.util.stream.Stream; + +import javax.swing.*; + +import org.jdom.Element; +import org.jdom.JDOMException; + +import docking.ActionContext; +import docking.PopupMenuHandler; +import docking.action.*; +import docking.action.builder.ActionBuilder; +import docking.menu.*; +import ghidra.app.plugin.core.debug.gui.DebuggerResources; +import ghidra.debug.api.tracermi.TraceRmiLaunchOffer; +import ghidra.framework.options.SaveState; +import ghidra.program.model.listing.Program; +import ghidra.program.model.listing.ProgramUserData; +import ghidra.util.*; +import ghidra.util.xml.XmlUtilities; + +public class LaunchAction extends MultiActionDockingAction { + public static final String NAME = "Launch"; + public static final Icon ICON = DebuggerResources.ICON_DEBUGGER; + public static final String GROUP = DebuggerResources.GROUP_GENERAL; + public static final String HELP_ANCHOR = "launch_tracermi"; + + private final TraceRmiLauncherServicePlugin plugin; + private MenuActionDockingToolbarButton button; + + public LaunchAction(TraceRmiLauncherServicePlugin plugin) { + super(NAME, plugin.getName()); + this.plugin = plugin; + setToolBarData(new ToolBarData(ICON, GROUP, "A")); + setHelpLocation(new HelpLocation(plugin.getName(), HELP_ANCHOR)); + } + + protected String[] prependConfigAndLaunch(List menuPath) { + Program program = plugin.currentProgram; + return Stream.concat( + Stream.of("Configure and Launch " + program.getName() + " using..."), + menuPath.stream()).toArray(String[]::new); + } + + record ConfigLast(String configName, long last) { + } + + ConfigLast checkSavedConfig(ProgramUserData userData, String propName) { + if (!propName.startsWith(AbstractTraceRmiLaunchOffer.PREFIX_DBGLAUNCH)) { + return null; + } + String configName = + propName.substring(AbstractTraceRmiLaunchOffer.PREFIX_DBGLAUNCH.length()); + String propVal = Objects.requireNonNull( + userData.getStringProperty(propName, null)); + Element element; + try { + element = XmlUtilities.fromString(propVal); + } + catch (JDOMException | IOException e) { + Msg.error(this, "Could not load launcher config for " + configName + ": " + e, e); + return null; + } + SaveState state = new SaveState(element); + if (!state.hasValue("last")) { + return null; + } + return new ConfigLast(configName, state.getLong("last", 0)); + } + + ConfigLast findMostRecentConfig() { + Program program = plugin.currentProgram; + ConfigLast best = null; + + ProgramUserData userData = program.getProgramUserData(); + for (String propName : userData.getStringPropertyNames()) { + ConfigLast candidate = checkSavedConfig(userData, propName); + if (candidate == null) { + continue; + } + else if (best == null) { + best = candidate; + } + else if (candidate.last > best.last) { + best = candidate; + } + } + return best; + } + + @Override + public List getActionList(ActionContext context) { + Program program = plugin.currentProgram; + Collection offers = plugin.getOffers(program); + + List actions = new ArrayList<>(); + + ProgramUserData userData = program.getProgramUserData(); + Map saved = new HashMap<>(); + for (String propName : userData.getStringPropertyNames()) { + ConfigLast check = checkSavedConfig(userData, propName); + if (check == null) { + continue; + } + saved.put(check.configName, check.last); + } + + for (TraceRmiLaunchOffer offer : offers) { + actions.add(new ActionBuilder(offer.getConfigName(), plugin.getName()) + .popupMenuPath(prependConfigAndLaunch(offer.getMenuPath())) + .popupMenuGroup(offer.getMenuGroup(), offer.getMenuOrder()) + .popupMenuIcon(offer.getIcon()) + .helpLocation(offer.getHelpLocation()) + .enabledWhen(ctx -> true) + .onAction(ctx -> plugin.configureAndLaunch(offer)) + .build()); + Long last = saved.get(offer.getConfigName()); + if (last == null) { + continue; + } + actions.add(new ActionBuilder(offer.getConfigName(), plugin.getName()) + .popupMenuPath("Re-launch " + program.getName() + " using " + offer.getTitle()) + .popupMenuGroup("0", "%016x".formatted(Long.MAX_VALUE - last)) + .popupMenuIcon(offer.getIcon()) + .helpLocation(offer.getHelpLocation()) + .enabledWhen(ctx -> true) + .onAction(ctx -> plugin.relaunch(offer)) + .build()); + } + return actions; + } + + class MenuActionDockingToolbarButton extends MultipleActionDockingToolbarButton { + public MenuActionDockingToolbarButton(MultiActionDockingActionIf action) { + super(action); + } + + @Override + protected JPopupMenu doCreateMenu() { + ActionContext context = getActionContext(); + List actionList = getActionList(context); + MenuHandler handler = + new PopupMenuHandler(plugin.getTool().getWindowManager(), context); + MenuManager manager = + new MenuManager("Launch", (char) 0, GROUP, true, handler, null); + for (DockingActionIf action : actionList) { + manager.addAction(action); + } + return manager.getPopupMenu(); + } + + @Override + protected JPopupMenu showPopup() { + // Make accessible to this file + return super.showPopup(); + } + } + + @Override + public JButton doCreateButton() { + return button = new MenuActionDockingToolbarButton(this); + } + + @Override + public void actionPerformed(ActionContext context) { + // See comment on super method about use of runLater + ConfigLast last = findMostRecentConfig(); + if (last == null) { + Swing.runLater(() -> button.showPopup()); + return; + } + for (TraceRmiLaunchOffer offer : plugin.getOffers(plugin.currentProgram)) { + if (offer.getConfigName().equals(last.configName)) { + plugin.relaunch(offer); + return; + } + } + Swing.runLater(() -> button.showPopup()); + } +} diff --git a/Ghidra/Debug/Debugger-rmi-trace/src/main/java/ghidra/app/plugin/core/debug/gui/tracermi/launcher/ScriptPathsPropertyEditor.java b/Ghidra/Debug/Debugger-rmi-trace/src/main/java/ghidra/app/plugin/core/debug/gui/tracermi/launcher/ScriptPathsPropertyEditor.java new file mode 100644 index 0000000000..fe12aae268 --- /dev/null +++ b/Ghidra/Debug/Debugger-rmi-trace/src/main/java/ghidra/app/plugin/core/debug/gui/tracermi/launcher/ScriptPathsPropertyEditor.java @@ -0,0 +1,107 @@ +/* ### + * IP: GHIDRA + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ghidra.app.plugin.core.debug.gui.tracermi.launcher; + +import java.awt.BorderLayout; +import java.awt.Component; +import java.awt.event.ActionEvent; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import javax.swing.JButton; +import javax.swing.JPanel; + +import org.apache.commons.text.StringEscapeUtils; + +import docking.DockingWindowManager; +import docking.widgets.OptionDialog; +import docking.widgets.filechooser.GhidraFileChooserMode; +import docking.widgets.pathmanager.*; +import utility.function.Callback; + +public class ScriptPathsPropertyEditor extends AbstractTypedPropertyEditor { + + @Override + protected String fromText(String text) { + return text; + } + + @Override + public String getJavaInitializationString() { + return "\"" + StringEscapeUtils.escapeJava(getValue()) + "\""; + } + + @Override + public Component getCustomEditor() { + return new ScriptPathsEditor(); + } + + protected class ScriptPathsEditor extends JPanel { + public ScriptPathsEditor() { + super(new BorderLayout()); + JButton button = new JButton("Edit Paths"); + button.addActionListener(this::showDialog); + add(button); + } + + protected void showDialog(ActionEvent evt) { + DockingWindowManager.showDialog(this, new ScriptPathsDialog()); + } + } + + protected class ScriptPathsDialog extends AbstractPathsDialog { + protected ScriptPathsDialog() { + super("Debugger Launch Script Paths"); + } + + @Override + protected String[] loadPaths() { + return getValue().lines().filter(d -> !d.isBlank()).toArray(String[]::new); + } + + @Override + protected void savePaths(String[] paths) { + setValue(Stream.of(paths).collect(Collectors.joining("\n"))); + } + + @Override + protected PathnameTablePanel newPathnameTablePanel() { + PathnameTablePanel tablePanel = new ScriptPathsPanel(this::reset); + tablePanel.setFileChooserProperties(getTitle(), "DebuggerLaunchScriptDirectory", + GhidraFileChooserMode.DIRECTORIES_ONLY, true, null); + return tablePanel; + } + } + + protected class ScriptPathsPanel extends PathnameTablePanel { + public ScriptPathsPanel(Callback resetCallback) { + // disable edits, top/bottom irrelevant, unordered + super(null, resetCallback, false, false, false); + } + + @Override + protected int promptConfirmReset() { + String confirmation = """ + + Are you sure you would like to reload the Debugger's launcher script paths? + This will reset any changes you've made so far. + """; + String header = "Reset Script Paths?"; + + return OptionDialog.showYesNoDialog(this, header, confirmation); + } + } +} diff --git a/Ghidra/Debug/Debugger-rmi-trace/src/main/java/ghidra/app/plugin/core/debug/gui/tracermi/launcher/TraceRmiLauncherServicePlugin.java b/Ghidra/Debug/Debugger-rmi-trace/src/main/java/ghidra/app/plugin/core/debug/gui/tracermi/launcher/TraceRmiLauncherServicePlugin.java new file mode 100644 index 0000000000..521643db6a --- /dev/null +++ b/Ghidra/Debug/Debugger-rmi-trace/src/main/java/ghidra/app/plugin/core/debug/gui/tracermi/launcher/TraceRmiLauncherServicePlugin.java @@ -0,0 +1,244 @@ +/* ### + * IP: GHIDRA + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ghidra.app.plugin.core.debug.gui.tracermi.launcher; + +import java.io.File; +import java.io.IOException; +import java.util.*; +import java.util.stream.Stream; + +import docking.action.DockingActionIf; +import docking.action.builder.ActionBuilder; +import ghidra.app.events.ProgramActivatedPluginEvent; +import ghidra.app.events.ProgramClosedPluginEvent; +import ghidra.app.plugin.PluginCategoryNames; +import ghidra.app.plugin.core.debug.DebuggerPluginPackage; +import ghidra.app.plugin.core.debug.gui.DebuggerResources.DebugProgramAction; +import ghidra.app.services.*; +import ghidra.debug.api.tracermi.TraceRmiLaunchOffer; +import ghidra.debug.api.tracermi.TraceRmiLaunchOffer.LaunchConfigurator; +import ghidra.debug.api.tracermi.TraceRmiLaunchOffer.PromptMode; +import ghidra.debug.api.tracermi.TraceRmiLaunchOpinion; +import ghidra.framework.options.OptionsChangeListener; +import ghidra.framework.options.ToolOptions; +import ghidra.framework.plugintool.*; +import ghidra.framework.plugintool.util.PluginStatus; +import ghidra.program.model.listing.Program; +import ghidra.util.Msg; +import ghidra.util.bean.opteditor.OptionsVetoException; +import ghidra.util.classfinder.ClassSearcher; +import ghidra.util.exception.CancelledException; +import ghidra.util.task.Task; +import ghidra.util.task.TaskMonitor; + +@PluginInfo( + shortDescription = "GUI elements to launch targets using Trace RMI", + description = """ + Provides menus and toolbar actions to launch Trace RMI targets. + """, + category = PluginCategoryNames.DEBUGGER, + packageName = DebuggerPluginPackage.NAME, + status = PluginStatus.UNSTABLE, + eventsConsumed = { + ProgramActivatedPluginEvent.class, + ProgramClosedPluginEvent.class, + }, + servicesRequired = { + TraceRmiService.class, + TerminalService.class, + }, + servicesProvided = { + TraceRmiLauncherService.class, + }) +public class TraceRmiLauncherServicePlugin extends Plugin + implements TraceRmiLauncherService, OptionsChangeListener { + protected static final String OPTION_NAME_SCRIPT_PATHS = "Script Paths"; + + private final static LaunchConfigurator PROMPT = new LaunchConfigurator() { + @Override + public PromptMode getPromptMode() { + return PromptMode.ALWAYS; + } + }; + + private static abstract class AbstractLaunchTask extends Task { + final TraceRmiLaunchOffer offer; + + public AbstractLaunchTask(TraceRmiLaunchOffer offer) { + super(offer.getTitle(), true, true, true); + this.offer = offer; + } + } + + private static class ReLaunchTask extends AbstractLaunchTask { + public ReLaunchTask(TraceRmiLaunchOffer offer) { + super(offer); + } + + @Override + public void run(TaskMonitor monitor) throws CancelledException { + offer.launchProgram(monitor); + } + } + + private static class ConfigureAndLaunchTask extends AbstractLaunchTask { + public ConfigureAndLaunchTask(TraceRmiLaunchOffer offer) { + super(offer); + } + + @Override + public void run(TaskMonitor monitor) throws CancelledException { + offer.launchProgram(monitor, PROMPT); + } + } + + public static File getProgramPath(Program program) { + if (program == null) { + return null; + } + String path = program.getExecutablePath(); + if (path == null) { + return null; + } + File file = new File(path); + try { + if (!file.canExecute()) { + return null; + } + return file.getCanonicalFile(); + } + catch (SecurityException | IOException e) { + Msg.error(TraceRmiLauncherServicePlugin.class, "Cannot examine file " + path, e); + return null; + } + } + + protected final ToolOptions options; + + protected Program currentProgram; + protected LaunchAction launchAction; + protected List currentLaunchers = new ArrayList<>(); + + public TraceRmiLauncherServicePlugin(PluginTool tool) { + super(tool); + this.options = tool.getOptions(DebuggerPluginPackage.NAME); + this.options.addOptionsChangeListener(this); + createActions(); + } + + @Override + protected void init() { + super.init(); + for (TraceRmiLaunchOpinion opinion : ClassSearcher + .getInstances(TraceRmiLaunchOpinion.class)) { + opinion.registerOptions(options); + } + } + + protected void createActions() { + launchAction = new LaunchAction(this); + tool.addAction(launchAction); + } + + @Override + public void optionsChanged(ToolOptions options, String optionName, Object oldValue, + Object newValue) throws OptionsVetoException { + for (TraceRmiLaunchOpinion opinion : ClassSearcher + .getInstances(TraceRmiLaunchOpinion.class)) { + if (opinion.requiresRefresh(optionName)) { + updateLauncherMenu(); + return; + } + } + } + + @Override + public Collection getOpinions() { + return ClassSearcher.getInstances(TraceRmiLaunchOpinion.class); + } + + @Override + public Collection getOffers(Program program) { + if (program == null) { + return List.of(); + } + return ClassSearcher.getInstances(TraceRmiLaunchOpinion.class) + .stream() + .flatMap(op -> op.getOffers(program, getTool()).stream()) + .toList(); + } + + protected void relaunch(TraceRmiLaunchOffer offer) { + tool.execute(new ReLaunchTask(offer)); + } + + protected void configureAndLaunch(TraceRmiLaunchOffer offer) { + tool.execute(new ConfigureAndLaunchTask(offer)); + } + + protected String[] constructLaunchMenuPrefix() { + return new String[] { + DebuggerPluginPackage.NAME, + "Configure and Launch " + currentProgram.getName() + " using..." }; + } + + protected String[] prependConfigAndLaunch(List menuPath) { + return Stream.concat( + Stream.of(constructLaunchMenuPrefix()), + menuPath.stream()).toArray(String[]::new); + } + + private void updateLauncherMenu() { + Collection offers = currentProgram == null + ? List.of() + : getOffers(currentProgram); + synchronized (currentLaunchers) { + for (DockingActionIf launcher : currentLaunchers) { + tool.removeAction(launcher); + } + currentLaunchers.clear(); + + if (!offers.isEmpty()) { + tool.setMenuGroup(constructLaunchMenuPrefix(), DebugProgramAction.GROUP, "zz"); + } + for (TraceRmiLaunchOffer offer : offers) { + currentLaunchers.add(new ActionBuilder(offer.getConfigName(), getName()) + .menuPath(prependConfigAndLaunch(offer.getMenuPath())) + .menuGroup(offer.getMenuGroup(), offer.getMenuOrder()) + .menuIcon(offer.getIcon()) + .helpLocation(offer.getHelpLocation()) + .enabledWhen(ctx -> true) + .onAction(ctx -> configureAndLaunch(offer)) + .buildAndInstall(tool)); + } + } + } + + @Override + public void processEvent(PluginEvent event) { + super.processEvent(event); + if (event instanceof ProgramActivatedPluginEvent evt) { + currentProgram = evt.getActiveProgram(); + updateLauncherMenu(); + } + if (event instanceof ProgramClosedPluginEvent evt) { + if (currentProgram == evt.getProgram()) { + currentProgram = null; + updateLauncherMenu(); + } + } + } +} diff --git a/Ghidra/Debug/Debugger-rmi-trace/src/main/java/ghidra/app/plugin/core/debug/gui/tracermi/launcher/UnixShellScriptTraceRmiLaunchOffer.java b/Ghidra/Debug/Debugger-rmi-trace/src/main/java/ghidra/app/plugin/core/debug/gui/tracermi/launcher/UnixShellScriptTraceRmiLaunchOffer.java new file mode 100644 index 0000000000..09904e35b6 --- /dev/null +++ b/Ghidra/Debug/Debugger-rmi-trace/src/main/java/ghidra/app/plugin/core/debug/gui/tracermi/launcher/UnixShellScriptTraceRmiLaunchOffer.java @@ -0,0 +1,633 @@ +/* ### + * IP: GHIDRA + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ghidra.app.plugin.core.debug.gui.tracermi.launcher; + +import java.io.*; +import java.math.BigInteger; +import java.net.*; +import java.util.*; +import java.util.Map.Entry; + +import javax.swing.Icon; + +import generic.theme.GIcon; +import generic.theme.Gui; +import ghidra.dbg.target.TargetMethod.ParameterDescription; +import ghidra.dbg.util.ShellUtils; +import ghidra.framework.Application; +import ghidra.framework.plugintool.PluginTool; +import ghidra.program.model.listing.Program; +import ghidra.util.HelpLocation; +import ghidra.util.Msg; +import ghidra.util.task.TaskMonitor; + +/** + * A launcher implemented by a simple UNIX shell script. + * + *

+ * The script must start with an attributes header in a comment block. Some attributes are required. + * Others are optional: + *

    + *
  • {@code @menu-path}: (Required)
  • + *
+ */ +public class UnixShellScriptTraceRmiLaunchOffer extends AbstractTraceRmiLaunchOffer { + public static final String SHEBANG = "#!"; + + public static final String AT_TITLE = "@title"; + public static final String AT_DESC = "@desc"; + public static final String AT_MENU_PATH = "@menu-path"; + public static final String AT_MENU_GROUP = "@menu-group"; + public static final String AT_MENU_ORDER = "@menu-order"; + public static final String AT_ICON = "@icon"; + public static final String AT_HELP = "@help"; + public static final String AT_ENUM = "@enum"; + public static final String AT_ENV = "@env"; + public static final String AT_ARG = "@arg"; + public static final String AT_ARGS = "@args"; + public static final String AT_TTY = "@tty"; + + public static final String PREFIX_ENV = "env:"; + public static final String PREFIX_ARG = "arg:"; + public static final String KEY_ARGS = "args"; + + public static final String MSGPAT_INVALID_HELP_SYNTAX = + "%s: Invalid %s syntax. Use Topic#anchor"; + public static final String MSGPAT_INVALID_ENUM_SYNTAX = + "%s: Invalid %s syntax. Use NAME:type Choice1 [ChoiceN...]"; + public static final String MSGPAT_INVALID_ENV_SYNTAX = + "%s: Invalid %s syntax. Use NAME:type=default \"Display\" \"Tool Tip\""; + public static final String MSGPAT_INVALID_ARG_SYNTAX = + "%s: Invalid %s syntax. Use :type \"Display\" \"Tool Tip\""; + public static final String MSGPAT_INVALID_ARGS_SYNTAX = + "%s: Invalid %s syntax. Use \"Display\" \"Tool Tip\""; + + protected record Location(String fileName, int lineNo) { + @Override + public String toString() { + return "%s:%d".formatted(fileName, lineNo); + } + } + + protected interface OptType { + static OptType parse(Location loc, String typeName, + Map> userEnums) { + OptType type = switch (typeName) { + case "str" -> BaseType.STRING; + case "int" -> BaseType.INT; + case "bool" -> BaseType.BOOL; + default -> userEnums.get(typeName); + }; + if (type == null) { + Msg.error(AttributesParser.class, "%s: Invalid type %s".formatted(loc, typeName)); + return null; + } + return type; + } + + default TypeAndDefault withCastDefault(Object defaultValue) { + return new TypeAndDefault<>(this, cls().cast(defaultValue)); + } + + Class cls(); + + T decode(Location loc, String str); + + ParameterDescription createParameter(String name, T defaultValue, String display, + String description); + } + + protected interface BaseType extends OptType { + static BaseType parse(Location loc, String typeName) { + BaseType type = switch (typeName) { + case "str" -> BaseType.STRING; + case "int" -> BaseType.INT; + case "bool" -> BaseType.BOOL; + default -> null; + }; + if (type == null) { + Msg.error(AttributesParser.class, + "%s: Invalid base type %s".formatted(loc, typeName)); + return null; + } + return type; + } + + public static final BaseType STRING = new BaseType<>() { + @Override + public Class cls() { + return String.class; + } + + @Override + public String decode(Location loc, String str) { + return str; + } + }; + public static final BaseType INT = new BaseType<>() { + @Override + public Class cls() { + return BigInteger.class; + } + + @Override + public BigInteger decode(Location loc, String str) { + try { + if (str.startsWith("0x")) { + return new BigInteger(str.substring(2), 16); + } + return new BigInteger(str); + } + catch (NumberFormatException e) { + Msg.error(AttributesParser.class, + ("%s: Invalid int for %s: %s. You may prefix with 0x for hexadecimal. " + + "Otherwise, decimal is used.").formatted(loc, AT_ENV, str)); + return null; + } + } + }; + public static final BaseType BOOL = new BaseType<>() { + @Override + public Class cls() { + return Boolean.class; + } + + @Override + public Boolean decode(Location loc, String str) { + Boolean result = switch (str) { + case "true" -> true; + case "false" -> false; + default -> null; + }; + if (result == null) { + Msg.error(AttributesParser.class, + "%s: Invalid bool for %s: %s. Only true or false (in lower case) is allowed." + .formatted(loc, AT_ENV, str)); + return null; + } + return result; + } + }; + + default UserType withCastChoices(List choices) { + return new UserType<>(this, choices.stream().map(cls()::cast).toList()); + } + + @Override + default ParameterDescription createParameter(String name, T defaultValue, String display, + String description) { + return ParameterDescription.create(cls(), name, false, defaultValue, display, + description); + } + } + + protected record UserType (BaseType base, List choices) implements OptType { + @Override + public Class cls() { + return base.cls(); + } + + @Override + public T decode(Location loc, String str) { + return base.decode(loc, str); + } + + @Override + public ParameterDescription createParameter(String name, T defaultValue, String display, + String description) { + return ParameterDescription.choices(cls(), name, choices, defaultValue, display, + description); + } + } + + protected record TypeAndDefault (OptType type, T defaultValue) { + public static TypeAndDefault parse(Location loc, String typeName, String defaultString, + Map> userEnums) { + OptType tac = OptType.parse(loc, typeName, userEnums); + if (tac == null) { + return null; + } + Object value = tac.decode(loc, defaultString); + if (value == null) { + return null; + } + return tac.withCastDefault(value); + } + + public ParameterDescription createParameter(String name, String display, + String description) { + return type.createParameter(name, defaultValue, display, description); + } + } + + protected static class AttributesParser { + protected int argc = 0; + protected String title; + protected StringBuilder description; + protected List menuPath; + protected String menuGroup; + protected String menuOrder; + protected String iconId; + protected HelpLocation helpLocation; + protected final Map> userTypes = new HashMap<>(); + protected final Map> parameters = new LinkedHashMap<>(); + protected final Set extraTtys = new LinkedHashSet<>(); + + /** + * Process a line in the metadata comment block + * + * @param line the line, excluding any comment delimiters + */ + public void parseLine(Location loc, String line) { + String afterHash = line.stripLeading().substring(1); + if (afterHash.isBlank()) { + return; + } + String[] parts = afterHash.split("\\s+", 2); + if (!parts[0].startsWith("@")) { + return; + } + if (parts.length < 2) { + Msg.error(this, "%s: Too few tokens: %s".formatted(loc, line)); + return; + } + switch (parts[0].trim()) { + case AT_TITLE -> parseTitle(loc, parts[1]); + case AT_DESC -> parseDesc(loc, parts[1]); + case AT_MENU_PATH -> parseMenuPath(loc, parts[1]); + case AT_MENU_GROUP -> parseMenuGroup(loc, parts[1]); + case AT_MENU_ORDER -> parseMenuOrder(loc, parts[1]); + case AT_ICON -> parseIcon(loc, parts[1]); + case AT_HELP -> parseHelp(loc, parts[1]); + case AT_ENUM -> parseEnum(loc, parts[1]); + case AT_ENV -> parseEnv(loc, parts[1]); + case AT_ARG -> parseArg(loc, parts[1], ++argc); + case AT_ARGS -> parseArgs(loc, parts[1]); + case AT_TTY -> parseTty(loc, parts[1]); + default -> parseUnrecognized(loc, line); + } + } + + protected void parseTitle(Location loc, String str) { + if (title != null) { + Msg.warn(this, "%s: Duplicate @title".formatted(loc)); + } + title = str; + } + + protected void parseDesc(Location loc, String str) { + if (description == null) { + description = new StringBuilder(); + } + description.append(str); + description.append("\n"); + } + + protected void parseMenuPath(Location loc, String str) { + if (menuPath != null) { + Msg.warn(this, "%s: Duplicate %s".formatted(loc, AT_MENU_PATH)); + } + menuPath = List.of(str.trim().split("\\.")); + if (menuPath.isEmpty()) { + Msg.error(this, + "%s: Empty %s. Ignoring.".formatted(loc, AT_MENU_PATH)); + } + } + + protected void parseMenuGroup(Location loc, String str) { + if (menuGroup != null) { + Msg.warn(this, "%s: Duplicate %s".formatted(loc, AT_MENU_GROUP)); + } + menuGroup = str; + } + + protected void parseMenuOrder(Location loc, String str) { + if (menuOrder != null) { + Msg.warn(this, "%s: Duplicate %s".formatted(loc, AT_MENU_ORDER)); + } + menuOrder = str; + } + + protected void parseIcon(Location loc, String str) { + if (iconId != null) { + Msg.warn(this, "%s: Duplicate %s".formatted(loc, AT_ICON)); + } + iconId = str.trim(); + if (!Gui.hasIcon(iconId)) { + Msg.error(this, + "%s: Icon id %s not registered in the theme".formatted(loc, iconId)); + } + } + + protected void parseHelp(Location loc, String str) { + if (helpLocation != null) { + Msg.warn(this, "%s: Duplicate %s".formatted(loc, AT_HELP)); + } + String[] parts = str.trim().split("#", 2); + if (parts.length != 2) { + Msg.error(this, MSGPAT_INVALID_HELP_SYNTAX.formatted(loc, AT_HELP)); + return; + } + helpLocation = new HelpLocation(parts[0].trim(), parts[1].trim()); + } + + protected void parseEnum(Location loc, String str) { + List parts = ShellUtils.parseArgs(str); + if (parts.size() < 2) { + Msg.error(this, MSGPAT_INVALID_ENUM_SYNTAX.formatted(loc, AT_ENUM)); + return; + } + String[] nameParts = parts.get(0).split(":", 2); + if (nameParts.length != 2) { + Msg.error(this, MSGPAT_INVALID_ENUM_SYNTAX.formatted(loc, AT_ENUM)); + return; + } + String name = nameParts[0].trim(); + BaseType baseType = BaseType.parse(loc, nameParts[1]); + if (baseType == null) { + return; + } + List choices = parts.stream().skip(1).map(s -> baseType.decode(loc, s)).toList(); + if (choices.contains(null)) { + return; + } + UserType userType = baseType.withCastChoices(choices); + if (userTypes.put(name, userType) != null) { + Msg.warn(this, "%s: Duplicate %s %s. Replaced.".formatted(loc, AT_ENUM, name)); + } + } + + protected void parseEnv(Location loc, String str) { + List parts = ShellUtils.parseArgs(str); + if (parts.size() != 3) { + Msg.error(this, MSGPAT_INVALID_ENV_SYNTAX.formatted(loc, AT_ENV)); + return; + } + String[] nameParts = parts.get(0).split(":", 2); + if (nameParts.length != 2) { + Msg.error(this, MSGPAT_INVALID_ENV_SYNTAX.formatted(loc, AT_ENV)); + return; + } + String trimmed = nameParts[0].trim(); + String name = PREFIX_ENV + trimmed; + String[] tadParts = nameParts[1].split("=", 2); + if (tadParts.length != 2) { + Msg.error(this, MSGPAT_INVALID_ENV_SYNTAX.formatted(loc, AT_ENV)); + return; + } + TypeAndDefault tad = + TypeAndDefault.parse(loc, tadParts[0].trim(), tadParts[1].trim(), userTypes); + ParameterDescription param = tad.createParameter(name, parts.get(1), parts.get(2)); + if (parameters.put(name, param) != null) { + Msg.warn(this, "%s: Duplicate %s %s. Replaced.".formatted(loc, AT_ENV, trimmed)); + } + } + + protected void parseArg(Location loc, String str, int argNum) { + List parts = ShellUtils.parseArgs(str); + if (parts.size() != 3) { + Msg.error(this, MSGPAT_INVALID_ARG_SYNTAX.formatted(loc, AT_ARG)); + return; + } + String colonType = parts.get(0).trim(); + if (!colonType.startsWith(":")) { + Msg.error(this, MSGPAT_INVALID_ARG_SYNTAX.formatted(loc, AT_ARG)); + return; + } + OptType type = OptType.parse(loc, colonType.substring(1), userTypes); + if (type == null) { + return; + } + String name = PREFIX_ARG + argNum; + parameters.put(name, ParameterDescription.create(type.cls(), name, true, null, + parts.get(1), parts.get(2))); + } + + protected void parseArgs(Location loc, String str) { + List parts = ShellUtils.parseArgs(str); + if (parts.size() != 2) { + Msg.error(this, MSGPAT_INVALID_ARGS_SYNTAX.formatted(loc, AT_ARGS)); + return; + } + ParameterDescription parameter = ParameterDescription.create(String.class, + "args", false, "", parts.get(0), parts.get(1)); + if (parameters.put(KEY_ARGS, parameter) != null) { + Msg.warn(this, "%s: Duplicate %s. Replaced".formatted(loc, AT_ARGS)); + } + } + + protected void parseTty(Location loc, String str) { + if (!extraTtys.add(str)) { + Msg.warn(this, "%s: Duplicate %s. Ignored".formatted(loc, AT_TTY)); + } + } + + protected void parseUnrecognized(Location loc, String line) { + Msg.warn(this, "%s: Unrecognized metadata: %s".formatted(loc, line)); + } + + protected void validate(String fileName) { + if (title == null) { + Msg.error(this, "%s is required. Using script file name.".formatted(AT_TITLE)); + title = fileName; + } + if (menuPath == null) { + menuPath = List.of(title); + } + if (menuGroup == null) { + menuGroup = ""; + } + if (menuOrder == null) { + menuOrder = ""; + } + if (iconId == null) { + iconId = "icon.debugger"; + } + } + + public String getDescription() { + return description == null ? null : description.toString(); + } + } + + /** + * Create a launch offer from the given shell script. + * + * @param program the current program, usually the target image. In general, this should be used + * for at least two purposes. 1) To populate the default command line. 2) To ensure + * the target image is mapped in the resulting target trace. + * @throws FileNotFoundException + */ + public static UnixShellScriptTraceRmiLaunchOffer create(Program program, PluginTool tool, + File script) throws FileNotFoundException { + try (BufferedReader reader = + new BufferedReader(new InputStreamReader(new FileInputStream(script)))) { + AttributesParser attrs = new AttributesParser(); + String line; + for (int lineNo = 1; (line = reader.readLine()) != null; lineNo++) { + if (line.startsWith(SHEBANG) && lineNo == 1) { + } + else if (line.isBlank()) { + continue; + } + else if (line.stripLeading().startsWith("#")) { + attrs.parseLine(new Location(script.getName(), lineNo), line); + } + else { + break; + } + } + attrs.validate(script.getName()); + return new UnixShellScriptTraceRmiLaunchOffer(program, tool, script, + "UNIX_SHELL:" + script.getName(), attrs.title, attrs.getDescription(), + attrs.menuPath, attrs.menuGroup, attrs.menuOrder, new GIcon(attrs.iconId), + attrs.helpLocation, attrs.parameters, attrs.extraTtys); + } + catch (FileNotFoundException e) { + // Avoid capture by IOException + throw e; + } + catch (IOException e) { + throw new AssertionError(e); + } + } + + protected final File script; + protected final String configName; + protected final String title; + protected final String description; + protected final List menuPath; + protected final String menuGroup; + protected final String menuOrder; + protected final Icon icon; + protected final HelpLocation helpLocation; + protected final Map> parameters; + protected final List extraTtys; + + public UnixShellScriptTraceRmiLaunchOffer(Program program, PluginTool tool, File script, + String configName, String title, String description, List menuPath, + String menuGroup, String menuOrder, Icon icon, HelpLocation helpLocation, + Map> parameters, Collection extraTtys) { + super(program, tool); + this.script = script; + this.configName = configName; + this.title = title; + this.description = description; + this.menuPath = List.copyOf(menuPath); + this.menuGroup = menuGroup; + this.menuOrder = menuOrder; + this.icon = icon; + this.helpLocation = helpLocation; + this.parameters = Collections.unmodifiableMap(new LinkedHashMap<>(parameters)); + this.extraTtys = List.copyOf(extraTtys); + } + + @Override + public String getConfigName() { + return configName; + } + + @Override + public String getTitle() { + return title; + } + + @Override + public String getDescription() { + return description; + } + + @Override + public List getMenuPath() { + return menuPath; + } + + @Override + public String getMenuGroup() { + return menuGroup; + } + + @Override + public String getMenuOrder() { + return menuOrder; + } + + @Override + public Icon getIcon() { + return icon; + } + + @Override + public HelpLocation getHelpLocation() { + return helpLocation; + } + + @Override + public Map> getParameters() { + return parameters; + } + + protected static String addrToString(InetAddress address) { + if (address.isAnyLocalAddress()) { + return "127.0.0.1"; // Can't connect to 0.0.0.0 as such. Choose localhost. + } + return address.getHostAddress(); + } + + protected static String sockToString(SocketAddress address) { + if (address instanceof InetSocketAddress tcp) { + return addrToString(tcp.getAddress()) + ":" + tcp.getPort(); + } + throw new AssertionError("Unhandled address type " + address); + } + + @Override + protected void launchBackEnd(TaskMonitor monitor, Map sessions, + Map args, SocketAddress address) throws Exception { + List commandLine = new ArrayList<>(); + Map env = new HashMap<>(System.getenv()); + + commandLine.add(script.getAbsolutePath()); + env.put("GHIDRA_HOME", Application.getInstallationDirectory().getAbsolutePath()); + env.put("GHIDRA_TRACE_RMI_ADDR", sockToString(address)); + + ParameterDescription paramDesc; + for (int i = 1; (paramDesc = parameters.get("arg:" + i)) != null; i++) { + commandLine.add(Objects.toString(paramDesc.get(args))); + } + + paramDesc = parameters.get("args"); + if (paramDesc != null) { + commandLine.addAll(ShellUtils.parseArgs((String) paramDesc.get(args))); + } + + for (Entry> ent : parameters.entrySet()) { + String key = ent.getKey(); + if (key.startsWith(PREFIX_ENV)) { + String varName = key.substring(PREFIX_ENV.length()); + env.put(varName, Objects.toString(ent.getValue().get(args))); + } + } + + for (String tty : extraTtys) { + NullPtyTerminalSession ns = nullPtyTerminal(); + env.put(tty, ns.name()); + sessions.put(ns.name(), ns); + } + + sessions.put("Shell", runInTerminal(commandLine, env, sessions.values())); + } +} diff --git a/Ghidra/Debug/Debugger-rmi-trace/src/main/java/ghidra/app/plugin/core/debug/gui/tracermi/launcher/UnixShellScriptTraceRmiLaunchOpinion.java b/Ghidra/Debug/Debugger-rmi-trace/src/main/java/ghidra/app/plugin/core/debug/gui/tracermi/launcher/UnixShellScriptTraceRmiLaunchOpinion.java new file mode 100644 index 0000000000..5c99c800d1 --- /dev/null +++ b/Ghidra/Debug/Debugger-rmi-trace/src/main/java/ghidra/app/plugin/core/debug/gui/tracermi/launcher/UnixShellScriptTraceRmiLaunchOpinion.java @@ -0,0 +1,81 @@ +/* ### + * IP: GHIDRA + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ghidra.app.plugin.core.debug.gui.tracermi.launcher; + +import java.util.Collection; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import generic.jar.ResourceFile; +import ghidra.app.plugin.core.debug.DebuggerPluginPackage; +import ghidra.debug.api.tracermi.TraceRmiLaunchOffer; +import ghidra.debug.api.tracermi.TraceRmiLaunchOpinion; +import ghidra.framework.Application; +import ghidra.framework.options.OptionType; +import ghidra.framework.options.Options; +import ghidra.framework.plugintool.PluginTool; +import ghidra.framework.plugintool.util.PluginUtils; +import ghidra.program.model.listing.Program; +import ghidra.util.HelpLocation; +import ghidra.util.Msg; + +public class UnixShellScriptTraceRmiLaunchOpinion implements TraceRmiLaunchOpinion { + + @Override + public void registerOptions(Options options) { + String pluginName = PluginUtils.getPluginNameFromClass(TraceRmiLauncherServicePlugin.class); + options.registerOption(TraceRmiLauncherServicePlugin.OPTION_NAME_SCRIPT_PATHS, + OptionType.STRING_TYPE, "", new HelpLocation(pluginName, "options"), + "Paths to search for user-created debugger launchers", new ScriptPathsPropertyEditor()); + } + + @Override + public boolean requiresRefresh(String optionName) { + return TraceRmiLauncherServicePlugin.OPTION_NAME_SCRIPT_PATHS.equals(optionName); + } + + protected Stream getModuleScriptPaths() { + return Application.findModuleSubDirectories("data/debugger-launchers").stream(); + } + + protected Stream getUserScriptPaths(PluginTool tool) { + Options options = tool.getOptions(DebuggerPluginPackage.NAME); + String scriptPaths = + options.getString(TraceRmiLauncherServicePlugin.OPTION_NAME_SCRIPT_PATHS, ""); + return scriptPaths.lines().filter(d -> !d.isBlank()).map(ResourceFile::new); + } + + protected Stream getScriptPaths(PluginTool tool) { + return Stream.concat(getModuleScriptPaths(), getUserScriptPaths(tool)); + } + + @Override + public Collection getOffers(Program program, PluginTool tool) { + return getScriptPaths(tool) + .flatMap(rf -> Stream.of(rf.listFiles(crf -> crf.getName().endsWith(".sh")))) + .flatMap(sf -> { + try { + return Stream.of(UnixShellScriptTraceRmiLaunchOffer.create(program, tool, + sf.getFile(false))); + } + catch (Exception e) { + Msg.error(this, "Could not offer " + sf + ":" + e.getMessage(), e); + return Stream.of(); + } + }) + .collect(Collectors.toList()); + } +} diff --git a/Ghidra/Debug/Debugger-rmi-trace/src/main/java/ghidra/app/plugin/core/debug/service/rmi/trace/DefaultRemoteAsyncResult.java b/Ghidra/Debug/Debugger-rmi-trace/src/main/java/ghidra/app/plugin/core/debug/service/rmi/trace/DefaultRemoteAsyncResult.java new file mode 100644 index 0000000000..ee9fdec583 --- /dev/null +++ b/Ghidra/Debug/Debugger-rmi-trace/src/main/java/ghidra/app/plugin/core/debug/service/rmi/trace/DefaultRemoteAsyncResult.java @@ -0,0 +1,51 @@ +/* ### + * IP: GHIDRA + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ghidra.app.plugin.core.debug.service.rmi.trace; + +import java.util.concurrent.*; + +import ghidra.debug.api.tracermi.RemoteAsyncResult; +import ghidra.util.Swing; + +public class DefaultRemoteAsyncResult extends CompletableFuture + implements RemoteAsyncResult { + final ValueDecoder decoder; + + public DefaultRemoteAsyncResult() { + this.decoder = ValueDecoder.DEFAULT; + } + + public DefaultRemoteAsyncResult(OpenTrace open) { + this.decoder = open; + } + + @Override + public Object get() throws InterruptedException, ExecutionException { + if (Swing.isSwingThread()) { + throw new AssertionError("Refusing indefinite wait on Swing thread"); + } + return super.get(); + } + + @Override + public Object get(long timeout, TimeUnit unit) + throws InterruptedException, ExecutionException, TimeoutException { + if (Swing.isSwingThread() && unit.toSeconds(timeout) > 1) { + throw new AssertionError("Refusing a timeout > 1 second on Swing thread"); + } + return super.get(timeout, unit); + } +} diff --git a/Ghidra/Debug/Debugger-rmi-trace/src/main/java/ghidra/app/plugin/core/debug/service/rmi/trace/RemoteMethodRegistry.java b/Ghidra/Debug/Debugger-rmi-trace/src/main/java/ghidra/app/plugin/core/debug/service/rmi/trace/DefaultRemoteMethodRegistry.java similarity index 83% rename from Ghidra/Debug/Debugger-rmi-trace/src/main/java/ghidra/app/plugin/core/debug/service/rmi/trace/RemoteMethodRegistry.java rename to Ghidra/Debug/Debugger-rmi-trace/src/main/java/ghidra/app/plugin/core/debug/service/rmi/trace/DefaultRemoteMethodRegistry.java index 04521f6360..5c8aafeea2 100644 --- a/Ghidra/Debug/Debugger-rmi-trace/src/main/java/ghidra/app/plugin/core/debug/service/rmi/trace/RemoteMethodRegistry.java +++ b/Ghidra/Debug/Debugger-rmi-trace/src/main/java/ghidra/app/plugin/core/debug/service/rmi/trace/DefaultRemoteMethodRegistry.java @@ -17,9 +17,11 @@ package ghidra.app.plugin.core.debug.service.rmi.trace; import java.util.*; -import ghidra.app.plugin.core.debug.service.rmi.trace.RemoteMethod.Action; +import ghidra.debug.api.tracermi.RemoteMethod; +import ghidra.debug.api.tracermi.RemoteMethodRegistry; +import ghidra.debug.api.tracermi.RemoteMethod.Action; -public class RemoteMethodRegistry { +public class DefaultRemoteMethodRegistry implements RemoteMethodRegistry { private final Map map = new HashMap<>(); private final Map> byAction = new HashMap<>(); @@ -30,18 +32,21 @@ public class RemoteMethodRegistry { } } + @Override public Map all() { synchronized (map) { return Map.copyOf(map); } } + @Override public RemoteMethod get(String name) { synchronized (map) { return map.get(name); } } + @Override public Set getByAction(Action action) { synchronized (map) { return byAction.getOrDefault(action, Set.of()); diff --git a/Ghidra/Debug/Debugger-rmi-trace/src/main/java/ghidra/app/plugin/core/debug/service/rmi/trace/TraceRmiAcceptor.java b/Ghidra/Debug/Debugger-rmi-trace/src/main/java/ghidra/app/plugin/core/debug/service/rmi/trace/DefaultTraceRmiAcceptor.java similarity index 83% rename from Ghidra/Debug/Debugger-rmi-trace/src/main/java/ghidra/app/plugin/core/debug/service/rmi/trace/TraceRmiAcceptor.java rename to Ghidra/Debug/Debugger-rmi-trace/src/main/java/ghidra/app/plugin/core/debug/service/rmi/trace/DefaultTraceRmiAcceptor.java index 31530db7fe..0dff0d177f 100644 --- a/Ghidra/Debug/Debugger-rmi-trace/src/main/java/ghidra/app/plugin/core/debug/service/rmi/trace/TraceRmiAcceptor.java +++ b/Ghidra/Debug/Debugger-rmi-trace/src/main/java/ghidra/app/plugin/core/debug/service/rmi/trace/DefaultTraceRmiAcceptor.java @@ -19,9 +19,11 @@ import java.io.IOException; import java.net.ServerSocket; import java.net.SocketAddress; -public class TraceRmiAcceptor extends TraceRmiServer { +import ghidra.debug.api.tracermi.TraceRmiAcceptor; - public TraceRmiAcceptor(TraceRmiPlugin plugin, SocketAddress address) { +public class DefaultTraceRmiAcceptor extends TraceRmiServer implements TraceRmiAcceptor { + + public DefaultTraceRmiAcceptor(TraceRmiPlugin plugin, SocketAddress address) { super(plugin, address); } diff --git a/Ghidra/Debug/Debugger-rmi-trace/src/main/java/ghidra/app/plugin/core/debug/service/rmi/trace/OpenTrace.java b/Ghidra/Debug/Debugger-rmi-trace/src/main/java/ghidra/app/plugin/core/debug/service/rmi/trace/OpenTrace.java index 7ab709aa93..2bff60bc60 100644 --- a/Ghidra/Debug/Debugger-rmi-trace/src/main/java/ghidra/app/plugin/core/debug/service/rmi/trace/OpenTrace.java +++ b/Ghidra/Debug/Debugger-rmi-trace/src/main/java/ghidra/app/plugin/core/debug/service/rmi/trace/OpenTrace.java @@ -16,6 +16,7 @@ package ghidra.app.plugin.core.debug.service.rmi.trace; import ghidra.app.plugin.core.debug.service.rmi.trace.TraceRmiHandler.*; +import ghidra.debug.api.tracermi.TraceRmiError; import ghidra.program.model.address.*; import ghidra.program.model.lang.Register; import ghidra.rmi.trace.TraceRmi.*; diff --git a/Ghidra/Debug/Debugger-rmi-trace/src/main/java/ghidra/app/plugin/core/debug/service/rmi/trace/RecordRemoteMethod.java b/Ghidra/Debug/Debugger-rmi-trace/src/main/java/ghidra/app/plugin/core/debug/service/rmi/trace/RecordRemoteMethod.java new file mode 100644 index 0000000000..8168874d6b --- /dev/null +++ b/Ghidra/Debug/Debugger-rmi-trace/src/main/java/ghidra/app/plugin/core/debug/service/rmi/trace/RecordRemoteMethod.java @@ -0,0 +1,35 @@ +/* ### + * IP: GHIDRA + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ghidra.app.plugin.core.debug.service.rmi.trace; + +import java.util.Map; + +import ghidra.dbg.target.schema.TargetObjectSchema.SchemaName; +import ghidra.debug.api.tracermi.RemoteMethod; +import ghidra.debug.api.tracermi.RemoteParameter; +import ghidra.debug.api.tracermi.RemoteMethod.Action; +import ghidra.trace.model.Trace; + +public record RecordRemoteMethod(TraceRmiHandler handler, String name, Action action, + String description, Map parameters, SchemaName retType) + implements RemoteMethod { + @Override + public DefaultRemoteAsyncResult invokeAsync(Map arguments) { + Trace trace = validate(arguments); + OpenTrace open = handler.getOpenTrace(trace); + return handler.invoke(open, name, arguments); + } +} diff --git a/Ghidra/Debug/Debugger-rmi-trace/src/main/java/ghidra/app/plugin/core/debug/service/rmi/trace/RecordRemoteParameter.java b/Ghidra/Debug/Debugger-rmi-trace/src/main/java/ghidra/app/plugin/core/debug/service/rmi/trace/RecordRemoteParameter.java new file mode 100644 index 0000000000..b855904bf4 --- /dev/null +++ b/Ghidra/Debug/Debugger-rmi-trace/src/main/java/ghidra/app/plugin/core/debug/service/rmi/trace/RecordRemoteParameter.java @@ -0,0 +1,49 @@ +/* ### + * IP: GHIDRA + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ghidra.app.plugin.core.debug.service.rmi.trace; + +import ghidra.dbg.target.schema.TargetObjectSchema.SchemaName; +import ghidra.debug.api.tracermi.RemoteParameter; +import ghidra.program.model.address.AddressOverflowException; +import ghidra.trace.model.Trace; + +public record RecordRemoteParameter(TraceRmiHandler handler, String name, SchemaName type, + boolean required, ValueSupplier defaultValue, String display, String description) + implements RemoteParameter { + + public Object getDefaultValue(Trace trace) { + OpenTrace open = handler.getOpenTrace(trace); + if (open == null) { + throw new IllegalArgumentException("Trace is not from this connection"); + } + try { + return defaultValue().get(open); + } + catch (AddressOverflowException e) { + throw new AssertionError(e); + } + } + + @Override + public Object getDefaultValue() { + try { + return defaultValue().get(ValueDecoder.DEFAULT); + } + catch (AddressOverflowException e) { + throw new AssertionError(e); + } + } +} diff --git a/Ghidra/Debug/Debugger-rmi-trace/src/main/java/ghidra/app/plugin/core/debug/service/rmi/trace/TraceRmiHandler.java b/Ghidra/Debug/Debugger-rmi-trace/src/main/java/ghidra/app/plugin/core/debug/service/rmi/trace/TraceRmiHandler.java index 49a8f0cb76..0d74bd134f 100644 --- a/Ghidra/Debug/Debugger-rmi-trace/src/main/java/ghidra/app/plugin/core/debug/service/rmi/trace/TraceRmiHandler.java +++ b/Ghidra/Debug/Debugger-rmi-trace/src/main/java/ghidra/app/plugin/core/debug/service/rmi/trace/TraceRmiHandler.java @@ -25,8 +25,7 @@ import java.nio.file.Paths; import java.time.Instant; import java.time.format.DateTimeFormatter; import java.util.*; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ExecutionException; +import java.util.concurrent.*; import java.util.stream.*; import org.apache.commons.lang3.ArrayUtils; @@ -35,16 +34,16 @@ import org.apache.commons.lang3.exception.ExceptionUtils; import com.google.protobuf.ByteString; import db.Transaction; -import ghidra.app.plugin.core.debug.DebuggerCoordinates; import ghidra.app.plugin.core.debug.disassemble.DebuggerDisassemblerPlugin; import ghidra.app.plugin.core.debug.disassemble.TraceDisassembleCommand; -import ghidra.app.plugin.core.debug.service.rmi.trace.RemoteMethod.Action; -import ghidra.app.plugin.core.debug.service.rmi.trace.RemoteMethod.RecordRemoteMethod; import ghidra.app.services.DebuggerTraceManagerService; import ghidra.dbg.target.schema.TargetObjectSchema.SchemaName; import ghidra.dbg.target.schema.XmlSchemaContext; import ghidra.dbg.util.PathPattern; import ghidra.dbg.util.PathUtils; +import ghidra.debug.api.tracemgr.DebuggerCoordinates; +import ghidra.debug.api.tracermi.*; +import ghidra.debug.api.tracermi.RemoteMethod.Action; import ghidra.framework.model.*; import ghidra.framework.plugintool.AutoService; import ghidra.framework.plugintool.AutoService.Wiring; @@ -69,7 +68,7 @@ import ghidra.util.exception.CancelledException; import ghidra.util.exception.DuplicateFileException; import ghidra.util.task.TaskMonitor; -public class TraceRmiHandler { +public class TraceRmiHandler implements TraceRmiConnection { public static final String VERSION = "10.4"; protected static class VersionMismatchError extends TraceRmiError { @@ -139,6 +138,7 @@ public class TraceRmiHandler { protected static class OpenTraceMap { private final Map byId = new HashMap<>(); private final Map byTrace = new HashMap<>(); + private final CompletableFuture first = new CompletableFuture<>(); public synchronized boolean isEmpty() { return byId.isEmpty(); @@ -168,6 +168,11 @@ public class TraceRmiHandler { public synchronized void put(OpenTrace openTrace) { byId.put(openTrace.doId, openTrace); byTrace.put(openTrace.trace, openTrace); + first.complete(openTrace); + } + + public CompletableFuture getFirstAsync() { + return first; } } @@ -181,9 +186,9 @@ public class TraceRmiHandler { private final OpenTraceMap openTraces = new OpenTraceMap(); private final Map openTxes = new HashMap<>(); - private final RemoteMethodRegistry methodRegistry = new RemoteMethodRegistry(); + private final DefaultRemoteMethodRegistry methodRegistry = new DefaultRemoteMethodRegistry(); // The remote must service requests and reply in the order received. - private final Deque xReqQueue = new ArrayDeque<>(); + private final Deque xReqQueue = new ArrayDeque<>(); @AutoServiceConsumed private DebuggerTraceManagerService traceManager; @@ -201,6 +206,7 @@ public class TraceRmiHandler { */ public TraceRmiHandler(TraceRmiPlugin plugin, Socket socket) throws IOException { this.plugin = plugin; + plugin.addHandler(this); this.socket = socket; this.in = socket.getInputStream(); this.out = socket.getOutputStream(); @@ -211,17 +217,18 @@ public class TraceRmiHandler { } protected void flushXReqQueue(Throwable exc) { - List copy; + List copy; synchronized (xReqQueue) { copy = List.copyOf(xReqQueue); xReqQueue.clear(); } - for (RemoteAsyncResult result : copy) { + for (DefaultRemoteAsyncResult result : copy) { result.completeExceptionally(exc); } } public void dispose() throws IOException { + plugin.removeHandler(this); flushXReqQueue(new TraceRmiError("Socket closed")); socket.close(); while (!openTxes.isEmpty()) { @@ -248,12 +255,24 @@ public class TraceRmiHandler { closed.complete(null); } + @Override + public void close() throws IOException { + dispose(); + } + + @Override public boolean isClosed() { return socket.isClosed() && closed.isDone(); } - public void waitClosed() throws InterruptedException, ExecutionException { - closed.get(); + @Override + public void waitClosed() { + try { + closed.get(); + } + catch (InterruptedException | ExecutionException e) { + throw new TraceRmiError(e); + } } protected DomainFolder getOrCreateNewTracesFolder() @@ -442,8 +461,9 @@ public class TraceRmiHandler { req.getRequestActivate().getObject().getPath().getPath()); case REQUEST_END_TX -> "endTx(%d)".formatted( req.getRequestEndTx().getTxid().getId()); - case REQUEST_START_TX -> "startTx(%d)".formatted( - req.getRequestStartTx().getTxid().getId()); + case REQUEST_START_TX -> "startTx(%d,%s)".formatted( + req.getRequestStartTx().getTxid().getId(), + req.getRequestStartTx().getDescription()); default -> null; }; } @@ -728,7 +748,12 @@ public class TraceRmiHandler { OpenTrace open = requireOpenTrace(req.getOid()); TraceObject object = open.getObject(req.getObject(), true); DebuggerCoordinates coords = traceManager.getCurrent(); - coords = coords.object(object); + if (coords.getTrace() == object.getTrace()) { + coords = coords.object(object); + } + else { + coords = DebuggerCoordinates.NOWHERE.object(object); + } if (open.lastSnapshot != null) { coords = coords.snap(open.lastSnapshot.getKey()); } @@ -738,7 +763,7 @@ public class TraceRmiHandler { } else { Trace currentTrace = traceManager.getCurrentTrace(); - if (currentTrace == null || currentTrace == open.trace) { + if (currentTrace == null || openTraces.getByTrace(currentTrace) != null) { traceManager.activate(coords); } } @@ -939,8 +964,7 @@ public class TraceRmiHandler { RemoteMethod rm = new RecordRemoteMethod(this, m.getName(), new Action(m.getAction()), m.getDescription(), m.getParametersList() .stream() - .collect(Collectors.toMap(MethodParameter::getName, - TraceRmiHandler::makeParameter)), + .collect(Collectors.toMap(MethodParameter::getName, this::makeParameter)), new SchemaName(m.getReturnType().getName())); methodRegistry.add(rm); } @@ -978,8 +1002,8 @@ public class TraceRmiHandler { return ReplyPutRegisterValue.getDefaultInstance(); } - protected static RemoteParameter makeParameter(MethodParameter mp) { - return new RemoteParameter(mp.getName(), new SchemaName(mp.getType().getName()), + protected RecordRemoteParameter makeParameter(MethodParameter mp) { + return new RecordRemoteParameter(this, mp.getName(), new SchemaName(mp.getType().getName()), mp.getRequired(), ot -> ot.toValue(mp.getDefaultValue()), mp.getDisplay(), mp.getDescription()); } @@ -1084,7 +1108,7 @@ public class TraceRmiHandler { protected RootMessage.Builder handleXInvokeMethod(XReplyInvokeMethod xrep) { String error = xrep.getError(); - RemoteAsyncResult result; + DefaultRemoteAsyncResult result; synchronized (xReqQueue) { result = xReqQueue.poll(); } @@ -1102,11 +1126,13 @@ public class TraceRmiHandler { return null; } + @Override public SocketAddress getRemoteAddress() { return socket.getRemoteSocketAddress(); } - public RemoteMethodRegistry getMethods() { + @Override + public DefaultRemoteMethodRegistry getMethods() { return methodRegistry; } @@ -1121,20 +1147,20 @@ public class TraceRmiHandler { return open; } - protected RemoteAsyncResult invoke(OpenTrace open, String methodName, + protected DefaultRemoteAsyncResult invoke(OpenTrace open, String methodName, Map arguments) { RootMessage.Builder req = RootMessage.newBuilder(); XRequestInvokeMethod.Builder invoke = XRequestInvokeMethod.newBuilder() .setName(methodName) .addAllArguments( arguments.entrySet().stream().map(TraceRmiHandler::makeArgument).toList()); - RemoteAsyncResult result; + DefaultRemoteAsyncResult result; if (open != null) { - result = new RemoteAsyncResult(open); + result = new DefaultRemoteAsyncResult(open); invoke.setOid(open.doId.toDomObjId()); } else { - result = new RemoteAsyncResult(); + result = new DefaultRemoteAsyncResult(); } req.setXrequestInvokeMethod(invoke); synchronized (xReqQueue) { @@ -1151,6 +1177,7 @@ public class TraceRmiHandler { } } + @Override @Internal public long getLastSnapshot(Trace trace) { TraceSnapshot lastSnapshot = openTraces.getByTrace(trace).lastSnapshot; @@ -1159,4 +1186,14 @@ public class TraceRmiHandler { } return lastSnapshot.getKey(); } + + @Override + public Trace waitForTrace(long timeoutMillis) throws TimeoutException { + try { + return openTraces.getFirstAsync().get(timeoutMillis, TimeUnit.MILLISECONDS).trace; + } + catch (InterruptedException | ExecutionException e) { + throw new TraceRmiError(e); + } + } } diff --git a/Ghidra/Debug/Debugger-rmi-trace/src/main/java/ghidra/app/plugin/core/debug/service/rmi/trace/TraceRmiPlugin.java b/Ghidra/Debug/Debugger-rmi-trace/src/main/java/ghidra/app/plugin/core/debug/service/rmi/trace/TraceRmiPlugin.java index 01f83e1c6a..2f6cb6c516 100644 --- a/Ghidra/Debug/Debugger-rmi-trace/src/main/java/ghidra/app/plugin/core/debug/service/rmi/trace/TraceRmiPlugin.java +++ b/Ghidra/Debug/Debugger-rmi-trace/src/main/java/ghidra/app/plugin/core/debug/service/rmi/trace/TraceRmiPlugin.java @@ -17,12 +17,14 @@ package ghidra.app.plugin.core.debug.service.rmi.trace; import java.io.IOException; import java.net.*; +import java.util.*; import ghidra.app.plugin.PluginCategoryNames; import ghidra.app.plugin.core.debug.DebuggerPluginPackage; import ghidra.app.plugin.core.debug.event.TraceActivatedPluginEvent; import ghidra.app.plugin.core.debug.event.TraceClosedPluginEvent; import ghidra.app.services.TraceRmiService; +import ghidra.debug.api.tracermi.TraceRmiConnection; import ghidra.framework.plugintool.*; import ghidra.framework.plugintool.util.PluginStatus; import ghidra.util.task.ConsoleTaskMonitor; @@ -31,11 +33,8 @@ import ghidra.util.task.TaskMonitor; @PluginInfo( shortDescription = "Connect to back-end debuggers via Trace RMI", description = """ - Provides an alternative for connecting to back-end debuggers. The DebuggerModel has - become a bit onerous to implement. Despite its apparent flexibility, the recorder at - the front-end imposes many restrictions, and getting it to work turns into a lot of - guess work and frustration. Trace RMI should offer a more direct means of recording a - trace from a back-end. + Provides a means for connecting to back-end debuggers. + NOTE this is an alternative to the DebuggerModel and is meant to replace it. """, category = PluginCategoryNames.DEBUGGER, packageName = DebuggerPluginPackage.NAME, @@ -54,6 +53,8 @@ public class TraceRmiPlugin extends Plugin implements TraceRmiService { private SocketAddress serverAddress = new InetSocketAddress("0.0.0.0", DEFAULT_PORT); private TraceRmiServer server; + private final Set handlers = new LinkedHashSet<>(); + public TraceRmiPlugin(PluginTool tool) { super(tool); } @@ -107,13 +108,28 @@ public class TraceRmiPlugin extends Plugin implements TraceRmiService { public TraceRmiHandler connect(SocketAddress address) throws IOException { Socket socket = new Socket(); socket.connect(address); - return new TraceRmiHandler(this, socket); + TraceRmiHandler handler = new TraceRmiHandler(this, socket); + handler.start(); + return handler; } @Override - public TraceRmiAcceptor acceptOne(SocketAddress address) throws IOException { - TraceRmiAcceptor acceptor = new TraceRmiAcceptor(this, address); + public DefaultTraceRmiAcceptor acceptOne(SocketAddress address) throws IOException { + DefaultTraceRmiAcceptor acceptor = new DefaultTraceRmiAcceptor(this, address); acceptor.start(); return acceptor; } + + void addHandler(TraceRmiHandler handler) { + handlers.add(handler); + } + + void removeHandler(TraceRmiHandler handler) { + handlers.remove(handler); + } + + @Override + public Collection getAllConnections() { + return List.copyOf(handlers); + } } diff --git a/Ghidra/Debug/Debugger-rmi-trace/src/main/java/ghidra/app/services/TraceRmiService.java b/Ghidra/Debug/Debugger-rmi-trace/src/main/java/ghidra/app/services/TraceRmiService.java deleted file mode 100644 index 8a9526da74..0000000000 --- a/Ghidra/Debug/Debugger-rmi-trace/src/main/java/ghidra/app/services/TraceRmiService.java +++ /dev/null @@ -1,51 +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.app.services; - -import java.io.IOException; -import java.net.SocketAddress; - -import ghidra.app.plugin.core.debug.service.rmi.trace.TraceRmiAcceptor; -import ghidra.app.plugin.core.debug.service.rmi.trace.TraceRmiHandler; - -public interface TraceRmiService { - SocketAddress getServerAddress(); - - /** - * Set the server address and port - * - * @param serverAddress may be null to bind to ephemeral port - */ - void setServerAddress(SocketAddress serverAddress); - - void startServer() throws IOException; - - void stopServer(); - - boolean isServerStarted(); - - TraceRmiHandler connect(SocketAddress address) throws IOException; - - /** - * Accept a single connection by listening on the given address - * - * @param address the socket address to bind, or null for ephemeral - * @return the acceptor, which can be used to retrieve the ephemeral address and accept the - * actual connection - * @throws IOException on error - */ - TraceRmiAcceptor acceptOne(SocketAddress address) throws IOException; -} diff --git a/Ghidra/Debug/Debugger/build.gradle b/Ghidra/Debug/Debugger/build.gradle index bd63aa1c01..a20880b23d 100644 --- a/Ghidra/Debug/Debugger/build.gradle +++ b/Ghidra/Debug/Debugger/build.gradle @@ -23,6 +23,7 @@ apply plugin: 'eclipse' eclipse.project.name = 'Debug Debugger' dependencies { + api project(':Debugger-api') api project(':Framework-AsyncComm') api project(':Framework-Debugging') api project(':Framework-TraceModeling') diff --git a/Ghidra/Debug/Debugger/ghidra_scripts/DemoDebuggerScript.java b/Ghidra/Debug/Debugger/ghidra_scripts/DemoDebuggerScript.java index ec4769a3ff..f38cbc8339 100644 --- a/Ghidra/Debug/Debugger/ghidra_scripts/DemoDebuggerScript.java +++ b/Ghidra/Debug/Debugger/ghidra_scripts/DemoDebuggerScript.java @@ -25,9 +25,9 @@ import java.util.Set; import java.util.concurrent.TimeUnit; -import ghidra.app.plugin.core.debug.service.model.launch.DebuggerProgramLaunchOffer.LaunchResult; import ghidra.app.script.GhidraScript; -import ghidra.app.services.LogicalBreakpoint; +import ghidra.debug.api.breakpoint.LogicalBreakpoint; +import ghidra.debug.api.model.DebuggerProgramLaunchOffer.LaunchResult; import ghidra.debug.flatapi.FlatDebuggerAPI; import ghidra.program.model.address.Address; import ghidra.trace.model.Trace; diff --git a/Ghidra/Debug/Debugger/ghidra_scripts/RefreshRegistersScript.java b/Ghidra/Debug/Debugger/ghidra_scripts/RefreshRegistersScript.java index 3922e2b9ea..20ce21ba43 100644 --- a/Ghidra/Debug/Debugger/ghidra_scripts/RefreshRegistersScript.java +++ b/Ghidra/Debug/Debugger/ghidra_scripts/RefreshRegistersScript.java @@ -15,7 +15,6 @@ */ import java.util.Set; -import ghidra.app.plugin.core.debug.DebuggerCoordinates; import ghidra.app.script.GhidraScript; import ghidra.app.services.*; import ghidra.dbg.DebuggerObjectModel; @@ -23,6 +22,8 @@ import ghidra.dbg.DebuggerObjectModel.RefreshBehavior; import ghidra.dbg.target.TargetObject; import ghidra.dbg.target.TargetRegisterBank; import ghidra.dbg.util.PathMatcher; +import ghidra.debug.api.model.TraceRecorder; +import ghidra.debug.api.tracemgr.DebuggerCoordinates; public class RefreshRegistersScript extends GhidraScript { @Override diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/disassemble/CurrentPlatformTraceDisassembleAction.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/disassemble/CurrentPlatformTraceDisassembleAction.java index c909e5edfe..c504213b8d 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/disassemble/CurrentPlatformTraceDisassembleAction.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/disassemble/CurrentPlatformTraceDisassembleAction.java @@ -18,11 +18,11 @@ package ghidra.app.plugin.core.debug.disassemble; import docking.ActionContext; import docking.action.*; import ghidra.app.context.ListingActionContext; -import ghidra.app.plugin.core.debug.DebuggerCoordinates; import ghidra.app.plugin.core.debug.disassemble.DebuggerDisassemblerPlugin.Reqs; import ghidra.app.plugin.core.debug.gui.listing.DebuggerListingActionContext; -import ghidra.app.plugin.core.debug.mapping.DebuggerPlatformMapper; -import ghidra.app.plugin.core.debug.mapping.DisassemblyResult; +import ghidra.debug.api.platform.DebuggerPlatformMapper; +import ghidra.debug.api.platform.DisassemblyResult; +import ghidra.debug.api.tracemgr.DebuggerCoordinates; import ghidra.framework.cmd.TypedBackgroundCommand; import ghidra.program.model.address.*; import ghidra.program.util.ProgramSelection; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/disassemble/DebuggerDisassemblerPlugin.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/disassemble/DebuggerDisassemblerPlugin.java index 046a4644aa..5c3674931b 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/disassemble/DebuggerDisassemblerPlugin.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/disassemble/DebuggerDisassemblerPlugin.java @@ -25,9 +25,9 @@ import generic.jar.ResourceFile; import ghidra.app.plugin.PluginCategoryNames; import ghidra.app.plugin.core.debug.DebuggerPluginPackage; import ghidra.app.plugin.core.debug.gui.listing.DebuggerListingActionContext; -import ghidra.app.plugin.core.debug.mapping.DebuggerPlatformMapper; import ghidra.app.services.DebuggerPlatformService; import ghidra.app.services.DebuggerTraceManagerService; +import ghidra.debug.api.platform.DebuggerPlatformMapper; import ghidra.framework.plugintool.*; import ghidra.framework.plugintool.AutoService.Wiring; import ghidra.framework.plugintool.annotation.AutoServiceConsumed; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/event/DebuggerPlatformPluginEvent.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/event/DebuggerPlatformPluginEvent.java index 09ea9d2528..9abec507f1 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/event/DebuggerPlatformPluginEvent.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/event/DebuggerPlatformPluginEvent.java @@ -15,7 +15,7 @@ */ package ghidra.app.plugin.core.debug.event; -import ghidra.app.plugin.core.debug.mapping.DebuggerPlatformMapper; +import ghidra.debug.api.platform.DebuggerPlatformMapper; import ghidra.framework.plugintool.PluginEvent; import ghidra.trace.model.Trace; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/event/TraceActivatedPluginEvent.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/event/TraceActivatedPluginEvent.java index 642b4fbc66..ce6a140d82 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/event/TraceActivatedPluginEvent.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/event/TraceActivatedPluginEvent.java @@ -15,8 +15,8 @@ */ package ghidra.app.plugin.core.debug.event; -import ghidra.app.plugin.core.debug.DebuggerCoordinates; import ghidra.app.services.DebuggerTraceManagerService.ActivationCause; +import ghidra.debug.api.tracemgr.DebuggerCoordinates; import ghidra.framework.plugintool.PluginEvent; public class TraceActivatedPluginEvent extends PluginEvent { diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/event/TraceInactiveCoordinatesPluginEvent.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/event/TraceInactiveCoordinatesPluginEvent.java index e17cf03e3d..7790c02896 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/event/TraceInactiveCoordinatesPluginEvent.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/event/TraceInactiveCoordinatesPluginEvent.java @@ -15,7 +15,7 @@ */ package ghidra.app.plugin.core.debug.event; -import ghidra.app.plugin.core.debug.DebuggerCoordinates; +import ghidra.debug.api.tracemgr.DebuggerCoordinates; import ghidra.framework.plugintool.PluginEvent; public class TraceInactiveCoordinatesPluginEvent extends PluginEvent { diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/event/TraceRecorderAdvancedPluginEvent.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/event/TraceRecorderAdvancedPluginEvent.java index d572737956..2e58d83c3f 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/event/TraceRecorderAdvancedPluginEvent.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/event/TraceRecorderAdvancedPluginEvent.java @@ -15,7 +15,7 @@ */ package ghidra.app.plugin.core.debug.event; -import ghidra.app.services.TraceRecorder; +import ghidra.debug.api.model.TraceRecorder; import ghidra.framework.plugintool.PluginEvent; public class TraceRecorderAdvancedPluginEvent extends PluginEvent { diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/DebuggerLocationLabel.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/DebuggerLocationLabel.java index 5336bce079..7925e3aab9 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/DebuggerLocationLabel.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/DebuggerLocationLabel.java @@ -21,9 +21,9 @@ import javax.swing.JLabel; import org.apache.commons.collections4.ComparatorUtils; -import ghidra.app.plugin.core.debug.DebuggerCoordinates; import ghidra.async.AsyncDebouncer; import ghidra.async.AsyncTimer; +import ghidra.debug.api.tracemgr.DebuggerCoordinates; import ghidra.program.model.address.Address; import ghidra.trace.model.Trace; import ghidra.trace.model.Trace.*; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/DebuggerResources.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/DebuggerResources.java index 7be4880d25..fea61370b3 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/DebuggerResources.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/DebuggerResources.java @@ -49,9 +49,9 @@ import ghidra.app.plugin.core.debug.gui.target.DebuggerTargetsPlugin; import ghidra.app.plugin.core.debug.gui.thread.DebuggerThreadsPlugin; import ghidra.app.plugin.core.debug.gui.time.DebuggerTimePlugin; import ghidra.app.plugin.core.debug.gui.watch.DebuggerWatchesPlugin; -import ghidra.app.plugin.core.debug.service.model.launch.DebuggerProgramLaunchOffer; import ghidra.app.services.DebuggerTraceManagerService.BooleanChangeAdapter; import ghidra.async.AsyncUtils; +import ghidra.debug.api.model.DebuggerProgramLaunchOffer; import ghidra.framework.plugintool.Plugin; import ghidra.framework.plugintool.util.PluginUtils; import ghidra.program.database.ProgramContentHandler; @@ -275,37 +275,6 @@ public interface DebuggerResources { Color COLOR_VALUE_CHANGED_SEL = new GColor("color.debugger.plugin.resources.value.changed.selected"); - String NAME_BREAKPOINT_MARKER_ENABLED = "Enabled Breakpoint"; - String NAME_BREAKPOINT_MARKER_DISABLED = "Disabled Breakpoint"; - String NAME_BREAKPOINT_MARKER_MIXED = "Mixed Breakpoint"; - String NAME_BREAKPOINT_MARKER_INEFF_EN = "Ineffective Enabled Breakpoint"; - String NAME_BREAKPOINT_MARKER_INEFF_DIS = "Ineffective Disabled Breakpoint"; - String NAME_BREAKPOINT_MARKER_INEFF_MIX = "Ineffective Mixed Breakpoint"; - String NAME_BREAKPOINT_MARKER_INCON_EN = "Inconsistent Enabled Breakpoint"; - String NAME_BREAKPOINT_MARKER_INCON_DIS = "Inconsistent Disabled Breakpoint"; - String NAME_BREAKPOINT_MARKER_INCON_MIX = "Inconsistent Mixed Breakpoint"; - - Icon ICON_BREAKPOINT_OVERLAY_INCONSISTENT = - new GIcon("icon.debugger.breakpoint.overlay.inconsistent"); - Icon ICON_BREAKPOINT_MARKER_ENABLED = new GIcon("icon.debugger.breakpoint.marker.enabled"); - Icon ICON_BREAKPOINT_MARKER_DISABLED = new GIcon("icon.debugger.breakpoint.marker.disabled"); - Icon ICON_BREAKPOINT_MARKER_MIXED = - new GIcon("icon.debugger.breakpoint.marker.mixed"); - - Icon ICON_BREAKPOINT_MARKER_INEFF_EN = - new GIcon("icon.debugger.breakpoint.marker.ineffective.enabled"); - Icon ICON_BREAKPOINT_MARKER_INEFF_DIS = - new GIcon("icon.debugger.breakpoint.marker.ineffective.disabled"); - Icon ICON_BREAKPOINT_MARKER_INEFF_MIX = - new GIcon("icon.debugger.breakpoint.marker.ineffective.mixed"); - - Icon ICON_BREAKPOINT_MARKER_INCON_EN = - new MultiIcon(ICON_BREAKPOINT_MARKER_ENABLED, ICON_BREAKPOINT_OVERLAY_INCONSISTENT); - Icon ICON_BREAKPOINT_MARKER_INCON_DIS = - new MultiIcon(ICON_BREAKPOINT_MARKER_DISABLED, ICON_BREAKPOINT_OVERLAY_INCONSISTENT); - Icon ICON_BREAKPOINT_MARKER_INCON_MIX = - new MultiIcon(ICON_BREAKPOINT_MARKER_MIXED, ICON_BREAKPOINT_OVERLAY_INCONSISTENT); - Icon ICON_UNIQUE_REF_READ = new GIcon("icon.debugger.unique.ref.read"); // TODO Icon ICON_UNIQUE_REF_WRITE = new GIcon("icon.debugger.unique.ref.write"); // TODO Icon ICON_UNIQUE_REF_RW = new MultiIcon(ICON_UNIQUE_REF_READ, ICON_UNIQUE_REF_WRITE); // TODO @@ -1147,19 +1116,6 @@ public interface DebuggerResources { } } - abstract class AbstractToggleBreakpointAction extends DockingAction { - public static final String NAME = "Toggle Breakpoint"; - // TODO: A "toggle breakpoint" icon - public static final Icon ICON = ICON_BREAKPOINT_MARKER_MIXED; - public static final String HELP_ANCHOR = "toggle_breakpoint"; - - public AbstractToggleBreakpointAction(Plugin owner) { - super(NAME, owner.getName()); - setDescription("Set, enable, or disable a breakpoint"); - setHelpLocation(new HelpLocation(owner.getName(), HELP_ANCHOR)); - } - } - abstract class AbstractSetBreakpointAction extends DockingAction { public static final String NAME = "Set Breakpoint"; public static final Icon ICON = ICON_SET_BREAKPOINT; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/AutoReadMemorySpec.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/AutoReadMemorySpec.java index 331894795a..d36df7e09e 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/AutoReadMemorySpec.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/AutoReadMemorySpec.java @@ -22,8 +22,8 @@ import javax.swing.Icon; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; -import ghidra.app.plugin.core.debug.DebuggerCoordinates; import ghidra.app.plugin.core.debug.utils.MiscellaneousUtils; +import ghidra.debug.api.tracemgr.DebuggerCoordinates; import ghidra.framework.options.SaveState; import ghidra.framework.plugintool.AutoConfigState.ConfigFieldCodec; import ghidra.framework.plugintool.PluginTool; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/BasicLocationTrackingSpecFactory.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/BasicLocationTrackingSpecFactory.java index 0e5c991870..9c1a8c540d 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/BasicLocationTrackingSpecFactory.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/BasicLocationTrackingSpecFactory.java @@ -20,6 +20,8 @@ import java.util.Map; import java.util.function.Function; import java.util.stream.Collectors; +import ghidra.debug.api.action.LocationTrackingSpec; +import ghidra.debug.api.action.LocationTrackingSpecFactory; import ghidra.framework.plugintool.PluginTool; /** diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/DebuggerGoToDialog.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/DebuggerGoToDialog.java index 83907f0092..c9c3fe305a 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/DebuggerGoToDialog.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/DebuggerGoToDialog.java @@ -31,6 +31,7 @@ import ghidra.app.plugin.core.debug.gui.breakpoint.AbstractDebuggerSleighInputDi import ghidra.app.plugin.core.debug.gui.listing.DebuggerListingPlugin; import ghidra.app.plugin.processors.sleigh.SleighLanguage; import ghidra.async.AsyncUtils; +import ghidra.debug.api.action.GoToInput; import ghidra.framework.plugintool.util.PluginUtils; import ghidra.pcode.exec.SleighUtils; import ghidra.program.model.address.*; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/DebuggerGoToTrait.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/DebuggerGoToTrait.java index bcf2f20b80..7e78868c59 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/DebuggerGoToTrait.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/DebuggerGoToTrait.java @@ -20,10 +20,11 @@ import java.util.concurrent.CompletableFuture; import docking.ActionContext; import docking.ComponentProvider; import docking.action.DockingAction; -import ghidra.app.plugin.core.debug.DebuggerCoordinates; import ghidra.app.plugin.core.debug.gui.DebuggerResources.GoToAction; import ghidra.app.plugin.processors.sleigh.SleighLanguage; import ghidra.async.AsyncUtils; +import ghidra.debug.api.action.GoToInput; +import ghidra.debug.api.tracemgr.DebuggerCoordinates; import ghidra.framework.plugintool.Plugin; import ghidra.framework.plugintool.PluginTool; import ghidra.pcode.exec.*; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/DebuggerReadsMemoryTrait.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/DebuggerReadsMemoryTrait.java index a2898c8826..aca113f5e0 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/DebuggerReadsMemoryTrait.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/DebuggerReadsMemoryTrait.java @@ -27,18 +27,18 @@ import docking.action.ToolBarData; import docking.menu.ActionState; import docking.menu.MultiStateDockingAction; import docking.widgets.EventTrigger; -import ghidra.app.plugin.core.debug.DebuggerCoordinates; import ghidra.app.plugin.core.debug.gui.DebuggerResources; import ghidra.app.plugin.core.debug.gui.DebuggerResources.AbstractRefreshSelectedMemoryAction; import ghidra.app.plugin.core.debug.gui.action.AutoReadMemorySpec.AutoReadMemorySpecConfigFieldCodec; import ghidra.app.plugin.core.debug.utils.BackgroundUtils; -import ghidra.app.services.TraceRecorder; -import ghidra.app.services.TraceRecorderListener; import ghidra.app.util.viewer.listingpanel.AddressSetDisplayListener; import ghidra.dbg.DebuggerObjectModel; import ghidra.dbg.target.TargetMemory; import ghidra.dbg.target.TargetObject; import ghidra.dbg.util.PathMatcher; +import ghidra.debug.api.model.TraceRecorder; +import ghidra.debug.api.model.TraceRecorderListener; +import ghidra.debug.api.tracemgr.DebuggerCoordinates; import ghidra.framework.options.SaveState; import ghidra.framework.plugintool.*; import ghidra.framework.plugintool.annotation.AutoConfigStateField; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/DebuggerStaticSyncTrait.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/DebuggerStaticSyncTrait.java index 40bd7ebcaa..af52f25d48 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/DebuggerStaticSyncTrait.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/DebuggerStaticSyncTrait.java @@ -25,11 +25,11 @@ import docking.action.DockingAction; import docking.action.ToggleDockingAction; import docking.widgets.EventTrigger; import ghidra.app.context.ProgramLocationActionContext; -import ghidra.app.plugin.core.debug.DebuggerCoordinates; import ghidra.app.plugin.core.debug.gui.DebuggerResources.*; -import ghidra.app.services.DebuggerStaticMappingChangeListener; import ghidra.app.services.DebuggerStaticMappingService; import ghidra.app.services.DebuggerStaticMappingService.MappedAddressRange; +import ghidra.debug.api.modules.DebuggerStaticMappingChangeListener; +import ghidra.debug.api.tracemgr.DebuggerCoordinates; import ghidra.framework.options.SaveState; import ghidra.framework.plugintool.*; import ghidra.framework.plugintool.annotation.AutoConfigStateField; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/DebuggerTrackLocationAction.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/DebuggerTrackLocationAction.java index 62924c29c6..b1c438db02 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/DebuggerTrackLocationAction.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/DebuggerTrackLocationAction.java @@ -17,6 +17,7 @@ package ghidra.app.plugin.core.debug.gui.action; import docking.action.builder.MultiStateActionBuilder; import ghidra.app.plugin.core.debug.gui.DebuggerResources.TrackLocationAction; +import ghidra.debug.api.action.LocationTrackingSpec; import ghidra.framework.plugintool.Plugin; public interface DebuggerTrackLocationAction extends TrackLocationAction { diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/DebuggerTrackLocationTrait.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/DebuggerTrackLocationTrait.java index 19c849ce76..ff91cb64ac 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/DebuggerTrackLocationTrait.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/DebuggerTrackLocationTrait.java @@ -28,15 +28,16 @@ import docking.menu.MultiStateDockingAction; import docking.widgets.EventTrigger; import docking.widgets.fieldpanel.support.BackgroundColorModel; import docking.widgets.fieldpanel.support.FieldSelection; -import ghidra.app.plugin.core.debug.DebuggerCoordinates; import ghidra.app.plugin.core.debug.gui.DebuggerResources; -import ghidra.app.plugin.core.debug.gui.action.LocationTrackingSpec.TrackingSpecConfigFieldCodec; import ghidra.app.plugin.core.debug.gui.colors.*; import ghidra.app.plugin.core.debug.gui.colors.MultiSelectionBlendedLayoutBackgroundColorManager.ColoredFieldSelection; import ghidra.app.plugin.core.debug.gui.listing.DebuggerTrackedRegisterListingBackgroundColorModel; import ghidra.app.util.viewer.listingpanel.ListingBackgroundColorModel; import ghidra.app.util.viewer.listingpanel.ListingPanel; import ghidra.async.AsyncUtils; +import ghidra.debug.api.action.*; +import ghidra.debug.api.action.LocationTrackingSpec.TrackingSpecConfigFieldCodec; +import ghidra.debug.api.tracemgr.DebuggerCoordinates; import ghidra.framework.options.SaveState; import ghidra.framework.plugintool.*; import ghidra.framework.plugintool.annotation.AutoConfigStateField; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/LoadEmulatorAutoReadMemorySpec.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/LoadEmulatorAutoReadMemorySpec.java index 52a0fd06e4..b87fc30f89 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/LoadEmulatorAutoReadMemorySpec.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/LoadEmulatorAutoReadMemorySpec.java @@ -21,13 +21,13 @@ import java.util.concurrent.CompletableFuture; import javax.swing.Icon; import db.Transaction; -import ghidra.app.plugin.core.debug.DebuggerCoordinates; import ghidra.app.plugin.core.debug.gui.DebuggerResources.AutoReadMemoryAction; import ghidra.app.plugin.core.debug.service.emulation.ProgramEmulationUtils; import ghidra.app.plugin.core.debug.service.model.record.RecorderUtils; import ghidra.app.plugin.core.debug.utils.AbstractMappedMemoryBytesVisitor; import ghidra.app.services.DebuggerStaticMappingService; import ghidra.async.AsyncUtils; +import ghidra.debug.api.tracemgr.DebuggerCoordinates; import ghidra.framework.plugintool.PluginTool; import ghidra.program.model.address.*; import ghidra.program.model.mem.MemoryAccessException; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/NoneAutoReadMemorySpec.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/NoneAutoReadMemorySpec.java index 65ef9a8503..4989dbdb6c 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/NoneAutoReadMemorySpec.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/NoneAutoReadMemorySpec.java @@ -19,9 +19,9 @@ import java.util.concurrent.CompletableFuture; import javax.swing.Icon; -import ghidra.app.plugin.core.debug.DebuggerCoordinates; import ghidra.app.plugin.core.debug.gui.DebuggerResources.AutoReadMemoryAction; import ghidra.async.AsyncUtils; +import ghidra.debug.api.tracemgr.DebuggerCoordinates; import ghidra.framework.plugintool.PluginTool; import ghidra.program.model.address.AddressSetView; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/NoneLocationTrackingSpec.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/NoneLocationTrackingSpec.java index 443cb5896a..b51f3355bc 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/NoneLocationTrackingSpec.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/NoneLocationTrackingSpec.java @@ -19,9 +19,10 @@ import java.util.concurrent.CompletableFuture; import javax.swing.Icon; -import ghidra.app.plugin.core.debug.DebuggerCoordinates; import ghidra.app.plugin.core.debug.gui.DebuggerResources.TrackLocationAction; import ghidra.async.AsyncUtils; +import ghidra.debug.api.action.*; +import ghidra.debug.api.tracemgr.DebuggerCoordinates; import ghidra.framework.plugintool.PluginTool; import ghidra.program.model.address.Address; import ghidra.program.util.ProgramLocation; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/PCByRegisterLocationTrackingSpec.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/PCByRegisterLocationTrackingSpec.java index 9aaa48aef3..4250d7ff3f 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/PCByRegisterLocationTrackingSpec.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/PCByRegisterLocationTrackingSpec.java @@ -17,8 +17,8 @@ package ghidra.app.plugin.core.debug.gui.action; import javax.swing.Icon; -import ghidra.app.plugin.core.debug.DebuggerCoordinates; import ghidra.app.plugin.core.debug.gui.DebuggerResources.TrackLocationAction; +import ghidra.debug.api.tracemgr.DebuggerCoordinates; import ghidra.program.model.address.AddressSpace; import ghidra.program.model.lang.Register; import ghidra.trace.model.guest.TracePlatform; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/PCByStackLocationTrackingSpec.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/PCByStackLocationTrackingSpec.java index dee6cd3193..72702963ba 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/PCByStackLocationTrackingSpec.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/PCByStackLocationTrackingSpec.java @@ -19,8 +19,9 @@ import java.util.concurrent.CompletableFuture; import javax.swing.Icon; -import ghidra.app.plugin.core.debug.DebuggerCoordinates; import ghidra.app.plugin.core.debug.gui.DebuggerResources.TrackLocationAction; +import ghidra.debug.api.action.*; +import ghidra.debug.api.tracemgr.DebuggerCoordinates; import ghidra.framework.plugintool.PluginTool; import ghidra.program.model.address.Address; import ghidra.program.util.ProgramLocation; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/PCLocationTrackingSpec.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/PCLocationTrackingSpec.java index 511800da22..05df644bec 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/PCLocationTrackingSpec.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/PCLocationTrackingSpec.java @@ -19,8 +19,9 @@ import java.util.concurrent.CompletableFuture; import javax.swing.Icon; -import ghidra.app.plugin.core.debug.DebuggerCoordinates; import ghidra.app.plugin.core.debug.gui.DebuggerResources.TrackLocationAction; +import ghidra.debug.api.action.*; +import ghidra.debug.api.tracemgr.DebuggerCoordinates; import ghidra.framework.plugintool.PluginTool; import ghidra.program.model.address.Address; import ghidra.program.util.ProgramLocation; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/RegisterLocationTrackingSpec.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/RegisterLocationTrackingSpec.java index ee7b8e4798..05a5ba62fe 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/RegisterLocationTrackingSpec.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/RegisterLocationTrackingSpec.java @@ -17,7 +17,8 @@ package ghidra.app.plugin.core.debug.gui.action; import java.util.concurrent.CompletableFuture; -import ghidra.app.plugin.core.debug.DebuggerCoordinates; +import ghidra.debug.api.action.*; +import ghidra.debug.api.tracemgr.DebuggerCoordinates; import ghidra.framework.plugintool.PluginTool; import ghidra.program.model.address.*; import ghidra.program.model.lang.Register; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/SPLocationTrackingSpec.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/SPLocationTrackingSpec.java index 80eddf48eb..f3dc396ad3 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/SPLocationTrackingSpec.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/SPLocationTrackingSpec.java @@ -17,8 +17,8 @@ package ghidra.app.plugin.core.debug.gui.action; import javax.swing.Icon; -import ghidra.app.plugin.core.debug.DebuggerCoordinates; import ghidra.app.plugin.core.debug.gui.DebuggerResources.TrackLocationAction; +import ghidra.debug.api.tracemgr.DebuggerCoordinates; import ghidra.program.model.address.AddressSpace; import ghidra.program.model.lang.Register; import ghidra.trace.model.guest.TracePlatform; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/VisibleAutoReadMemorySpec.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/VisibleAutoReadMemorySpec.java index 141ce1dfdd..64a73b53c6 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/VisibleAutoReadMemorySpec.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/VisibleAutoReadMemorySpec.java @@ -19,10 +19,10 @@ import java.util.concurrent.CompletableFuture; import javax.swing.Icon; -import ghidra.app.plugin.core.debug.DebuggerCoordinates; import ghidra.app.plugin.core.debug.gui.DebuggerResources.AutoReadMemoryAction; -import ghidra.app.services.TraceRecorder; import ghidra.async.AsyncUtils; +import ghidra.debug.api.model.TraceRecorder; +import ghidra.debug.api.tracemgr.DebuggerCoordinates; import ghidra.framework.plugintool.PluginTool; import ghidra.program.model.address.AddressSet; import ghidra.program.model.address.AddressSetView; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/VisibleROOnceAutoReadMemorySpec.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/VisibleROOnceAutoReadMemorySpec.java index 49d3768d08..af5cc3b042 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/VisibleROOnceAutoReadMemorySpec.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/VisibleROOnceAutoReadMemorySpec.java @@ -20,10 +20,10 @@ import java.util.concurrent.CompletableFuture; import javax.swing.Icon; -import ghidra.app.plugin.core.debug.DebuggerCoordinates; import ghidra.app.plugin.core.debug.gui.DebuggerResources.AutoReadMemoryAction; -import ghidra.app.services.TraceRecorder; import ghidra.async.AsyncUtils; +import ghidra.debug.api.model.TraceRecorder; +import ghidra.debug.api.tracemgr.DebuggerCoordinates; import ghidra.framework.plugintool.PluginTool; import ghidra.program.model.address.*; import ghidra.trace.model.Lifespan; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/WatchLocationTrackingSpec.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/WatchLocationTrackingSpec.java index 62afdfc624..ae814d73d4 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/WatchLocationTrackingSpec.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/WatchLocationTrackingSpec.java @@ -20,11 +20,12 @@ import java.util.concurrent.CompletableFuture; import javax.swing.Icon; -import ghidra.app.plugin.core.debug.DebuggerCoordinates; import ghidra.app.plugin.core.debug.gui.DebuggerResources; import ghidra.app.plugin.core.debug.gui.DebuggerResources.TrackLocationAction; -import ghidra.app.plugin.core.debug.gui.watch.WatchRow; import ghidra.async.AsyncUtils; +import ghidra.debug.api.action.*; +import ghidra.debug.api.tracemgr.DebuggerCoordinates; +import ghidra.debug.api.watch.WatchRow; import ghidra.framework.plugintool.PluginTool; import ghidra.pcode.exec.*; import ghidra.pcode.exec.DebuggerPcodeUtils.WatchValue; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/WatchLocationTrackingSpecFactory.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/WatchLocationTrackingSpecFactory.java index 874afb0b82..0e28191fa0 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/WatchLocationTrackingSpecFactory.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/WatchLocationTrackingSpecFactory.java @@ -19,6 +19,8 @@ import java.util.List; import java.util.stream.Collectors; import ghidra.app.services.DebuggerWatchesService; +import ghidra.debug.api.action.LocationTrackingSpec; +import ghidra.debug.api.action.LocationTrackingSpecFactory; import ghidra.framework.plugintool.PluginTool; /** diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/breakpoint/BreakpointLocationRow.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/breakpoint/BreakpointLocationRow.java index 2423c56544..07c4272ee6 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/breakpoint/BreakpointLocationRow.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/breakpoint/BreakpointLocationRow.java @@ -19,8 +19,8 @@ import java.util.Set; import java.util.stream.Collectors; import db.Transaction; -import ghidra.app.services.LogicalBreakpoint; -import ghidra.app.services.LogicalBreakpoint.State; +import ghidra.debug.api.breakpoint.LogicalBreakpoint; +import ghidra.debug.api.breakpoint.LogicalBreakpoint.State; import ghidra.pcode.exec.SleighUtils; import ghidra.program.model.address.Address; import ghidra.trace.model.breakpoint.TraceBreakpoint; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/breakpoint/BreakpointsDecompilerMarginProvider.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/breakpoint/BreakpointsDecompilerMarginProvider.java index 2921048c83..4335ad352d 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/breakpoint/BreakpointsDecompilerMarginProvider.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/breakpoint/BreakpointsDecompilerMarginProvider.java @@ -30,8 +30,8 @@ import docking.widgets.fieldpanel.listener.LayoutModelListener; import ghidra.app.decompiler.ClangLine; import ghidra.app.decompiler.component.margin.DecompilerMarginProvider; import ghidra.app.decompiler.component.margin.LayoutPixelIndexMap; -import ghidra.app.services.LogicalBreakpoint; -import ghidra.app.services.LogicalBreakpoint.State; +import ghidra.debug.api.breakpoint.LogicalBreakpoint; +import ghidra.debug.api.breakpoint.LogicalBreakpoint.State; import ghidra.program.model.listing.Program; import ghidra.program.util.ProgramLocation; import ghidra.trace.model.breakpoint.TraceBreakpointKind; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/breakpoint/DebuggerBreakpointMarkerPlugin.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/breakpoint/DebuggerBreakpointMarkerPlugin.java index ddca50a4b5..5629dc5fa3 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/breakpoint/DebuggerBreakpointMarkerPlugin.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/breakpoint/DebuggerBreakpointMarkerPlugin.java @@ -42,10 +42,14 @@ import ghidra.app.plugin.core.debug.gui.DebuggerResources; import ghidra.app.plugin.core.debug.gui.DebuggerResources.*; import ghidra.app.plugin.core.decompile.DecompilerActionContext; import ghidra.app.services.*; -import ghidra.app.services.LogicalBreakpoint.State; import ghidra.app.util.viewer.listingpanel.MarkerClickedListener; import ghidra.async.AsyncDebouncer; import ghidra.async.AsyncTimer; +import ghidra.debug.api.breakpoint.LogicalBreakpoint; +import ghidra.debug.api.breakpoint.LogicalBreakpointsChangeListener; +import ghidra.debug.api.breakpoint.LogicalBreakpoint.State; +import ghidra.debug.api.control.ControlMode; +import ghidra.debug.api.model.TraceRecorder; import ghidra.framework.options.AutoOptions; import ghidra.framework.options.annotation.*; import ghidra.framework.plugintool.*; @@ -62,6 +66,7 @@ import ghidra.trace.model.TraceLocation; import ghidra.trace.model.breakpoint.TraceBreakpointKind; import ghidra.trace.model.breakpoint.TraceBreakpointKind.TraceBreakpointKindSet; import ghidra.trace.model.program.TraceProgramView; +import ghidra.util.HelpLocation; import ghidra.util.Msg; @PluginInfo( @@ -385,10 +390,10 @@ public class DebuggerBreakpointMarkerPlugin extends Plugin // Prevent default bookmark icons from obscuring breakpoints if (!(program instanceof TraceProgramView)) { BookmarkManager manager = program.getBookmarkManager(); - manager.defineType(LogicalBreakpoint.BREAKPOINT_ENABLED_BOOKMARK_TYPE, + manager.defineType(LogicalBreakpoint.ENABLED_BOOKMARK_TYPE, DebuggerResources.ICON_BLANK, COLOR_BREAKPOINT_ENABLED_MARKER, MarkerService.BREAKPOINT_PRIORITY - 1); - manager.defineType(LogicalBreakpoint.BREAKPOINT_DISABLED_BOOKMARK_TYPE, + manager.defineType(LogicalBreakpoint.DISABLED_BOOKMARK_TYPE, DebuggerResources.ICON_BLANK, COLOR_BREAKPOINT_DISABLED_MARKER, MarkerService.BREAKPOINT_PRIORITY - 1); } @@ -519,6 +524,19 @@ public class DebuggerBreakpointMarkerPlugin extends Plugin return breakpointService.computeState(col, locs.get(0)); } + public abstract class AbstractToggleBreakpointAction extends DockingAction { + public static final String NAME = "Toggle Breakpoint"; + // TODO: A "toggle breakpoint" icon + public static final Icon ICON = LogicalBreakpoint.ICON_MARKER_MIXED; + public static final String HELP_ANCHOR = "toggle_breakpoint"; + + public AbstractToggleBreakpointAction(Plugin owner) { + super(NAME, owner.getName()); + setDescription("Set, enable, or disable a breakpoint"); + setHelpLocation(new HelpLocation(owner.getName(), HELP_ANCHOR)); + } + } + protected class ToggleBreakpointAction extends AbstractToggleBreakpointAction { public static final String GROUP = DebuggerResources.GROUP_BREAKPOINTS; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/breakpoint/DebuggerBreakpointStateTableCellEditor.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/breakpoint/DebuggerBreakpointStateTableCellEditor.java index 90f34e4b39..bda58a96ce 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/breakpoint/DebuggerBreakpointStateTableCellEditor.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/breakpoint/DebuggerBreakpointStateTableCellEditor.java @@ -24,7 +24,7 @@ import javax.swing.plaf.basic.BasicButtonUI; import javax.swing.table.TableCellEditor; import docking.widgets.table.GTableFilterPanel; -import ghidra.app.services.LogicalBreakpoint.State; +import ghidra.debug.api.breakpoint.LogicalBreakpoint.State; public abstract class DebuggerBreakpointStateTableCellEditor extends AbstractCellEditor implements TableCellEditor, ActionListener { diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/breakpoint/DebuggerBreakpointStateTableCellRenderer.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/breakpoint/DebuggerBreakpointStateTableCellRenderer.java index f970509342..e146f5486b 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/breakpoint/DebuggerBreakpointStateTableCellRenderer.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/breakpoint/DebuggerBreakpointStateTableCellRenderer.java @@ -20,7 +20,7 @@ import java.awt.Component; import javax.swing.SwingConstants; import docking.widgets.table.GTableCellRenderingData; -import ghidra.app.services.LogicalBreakpoint.State; +import ghidra.debug.api.breakpoint.LogicalBreakpoint.State; import ghidra.docking.settings.Settings; import ghidra.util.table.column.AbstractGColumnRenderer; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/breakpoint/DebuggerBreakpointsProvider.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/breakpoint/DebuggerBreakpointsProvider.java index 55de3e9e53..736c51d505 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/breakpoint/DebuggerBreakpointsProvider.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/breakpoint/DebuggerBreakpointsProvider.java @@ -32,13 +32,17 @@ import docking.action.builder.ActionBuilder; import docking.widgets.table.*; import docking.widgets.table.DefaultEnumeratedColumnTableModel.EnumeratedTableColumn; import ghidra.app.context.ProgramLocationActionContext; -import ghidra.app.plugin.core.debug.DebuggerCoordinates; 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.DebuggerControlService.ControlModeChangeListener; -import ghidra.app.services.LogicalBreakpoint.State; +import ghidra.debug.api.breakpoint.LogicalBreakpoint; +import ghidra.debug.api.breakpoint.LogicalBreakpointsChangeListener; +import ghidra.debug.api.breakpoint.LogicalBreakpoint.State; +import ghidra.debug.api.control.ControlMode; +import ghidra.debug.api.model.TraceRecorder; +import ghidra.debug.api.tracemgr.DebuggerCoordinates; import ghidra.framework.model.DomainObject; import ghidra.framework.plugintool.*; import ghidra.framework.plugintool.annotation.AutoServiceConsumed; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/breakpoint/DebuggerLogicalBreakpointsActionContext.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/breakpoint/DebuggerLogicalBreakpointsActionContext.java index 14d5d331ba..057522f0dc 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/breakpoint/DebuggerLogicalBreakpointsActionContext.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/breakpoint/DebuggerLogicalBreakpointsActionContext.java @@ -19,7 +19,7 @@ import java.util.Collection; import java.util.stream.Collectors; import docking.DefaultActionContext; -import ghidra.app.services.LogicalBreakpoint; +import ghidra.debug.api.breakpoint.LogicalBreakpoint; public class DebuggerLogicalBreakpointsActionContext extends DefaultActionContext { private final Collection selection; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/breakpoint/LogicalBreakpointRow.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/breakpoint/LogicalBreakpointRow.java index 362ee3d67a..cc8fe0d9b6 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/breakpoint/LogicalBreakpointRow.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/breakpoint/LogicalBreakpointRow.java @@ -17,9 +17,9 @@ package ghidra.app.plugin.core.debug.gui.breakpoint; import java.util.concurrent.CompletableFuture; -import ghidra.app.services.LogicalBreakpoint; -import ghidra.app.services.LogicalBreakpoint.Mode; -import ghidra.app.services.LogicalBreakpoint.State; +import ghidra.debug.api.breakpoint.LogicalBreakpoint; +import ghidra.debug.api.breakpoint.LogicalBreakpoint.Mode; +import ghidra.debug.api.breakpoint.LogicalBreakpoint.State; import ghidra.framework.model.DomainFile; import ghidra.framework.model.DomainObject; import ghidra.pcode.exec.SleighUtils; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/control/DebuggerControlPlugin.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/control/DebuggerControlPlugin.java index 8e84fb196f..a23408fbb8 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/control/DebuggerControlPlugin.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/control/DebuggerControlPlugin.java @@ -37,7 +37,6 @@ import ghidra.app.plugin.PluginCategoryNames; import ghidra.app.plugin.core.debug.*; 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; @@ -48,6 +47,10 @@ import ghidra.dbg.DebuggerObjectModel; import ghidra.dbg.target.*; import ghidra.dbg.target.TargetExecutionStateful.TargetExecutionState; import ghidra.dbg.target.TargetSteppable.TargetStepKind; +import ghidra.debug.api.control.ControlMode; +import ghidra.debug.api.emulation.DebuggerPcodeMachine; +import ghidra.debug.api.model.TraceRecorder; +import ghidra.debug.api.tracemgr.DebuggerCoordinates; import ghidra.framework.plugintool.*; import ghidra.framework.plugintool.annotation.AutoServiceConsumed; import ghidra.framework.plugintool.util.PluginStatus; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/control/DebuggerMethodActionsPlugin.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/control/DebuggerMethodActionsPlugin.java index f13244d443..09db27c0bc 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/control/DebuggerMethodActionsPlugin.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/control/DebuggerMethodActionsPlugin.java @@ -23,7 +23,6 @@ import docking.action.*; import docking.actions.PopupActionProvider; import ghidra.app.context.ProgramLocationActionContext; import ghidra.app.plugin.PluginCategoryNames; -import ghidra.app.plugin.core.debug.DebuggerCoordinates; import ghidra.app.plugin.core.debug.DebuggerPluginPackage; import ghidra.app.services.*; import ghidra.dbg.target.TargetMethod; @@ -31,6 +30,9 @@ import ghidra.dbg.target.TargetMethod.ParameterDescription; import ghidra.dbg.target.TargetMethod.TargetParameterMap; import ghidra.dbg.target.TargetObject; import ghidra.dbg.util.PathPredicates; +import ghidra.debug.api.control.ControlMode; +import ghidra.debug.api.model.TraceRecorder; +import ghidra.debug.api.tracemgr.DebuggerCoordinates; import ghidra.framework.plugintool.*; import ghidra.framework.plugintool.annotation.AutoServiceConsumed; import ghidra.framework.plugintool.util.PluginStatus; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/copying/DebuggerCopyIntoProgramDialog.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/copying/DebuggerCopyIntoProgramDialog.java index c353155b98..ced2af66f9 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/copying/DebuggerCopyIntoProgramDialog.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/copying/DebuggerCopyIntoProgramDialog.java @@ -31,11 +31,12 @@ import db.Transaction; import docking.ReusableDialogComponentProvider; import docking.widgets.table.*; import docking.widgets.table.DefaultEnumeratedColumnTableModel.EnumeratedTableColumn; -import ghidra.app.plugin.core.debug.DebuggerCoordinates; import ghidra.app.plugin.core.debug.gui.DebuggerResources; import ghidra.app.plugin.core.debug.gui.copying.DebuggerCopyPlan.Copier; import ghidra.app.services.*; import ghidra.app.services.DebuggerStaticMappingService.MappedAddressRange; +import ghidra.debug.api.model.TraceRecorder; +import ghidra.debug.api.tracemgr.DebuggerCoordinates; import ghidra.framework.plugintool.PluginTool; import ghidra.program.database.ProgramDB; import ghidra.program.model.address.*; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/diff/DebuggerTraceViewDiffPlugin.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/diff/DebuggerTraceViewDiffPlugin.java index fcfd181360..66ea77c363 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/diff/DebuggerTraceViewDiffPlugin.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/diff/DebuggerTraceViewDiffPlugin.java @@ -35,8 +35,6 @@ import ghidra.app.plugin.core.debug.*; import ghidra.app.plugin.core.debug.event.TraceClosedPluginEvent; import ghidra.app.plugin.core.debug.gui.DebuggerResources.*; import ghidra.app.plugin.core.debug.gui.action.DebuggerTrackLocationTrait; -import ghidra.app.plugin.core.debug.gui.action.LocationTrackingSpec; -import ghidra.app.plugin.core.debug.gui.listing.MultiBlendedListingBackgroundColorModel; import ghidra.app.plugin.core.debug.gui.time.DebuggerTimeSelectionDialog; import ghidra.app.plugin.core.debug.utils.BackgroundUtils.PluginToolExecutorService; import ghidra.app.plugin.core.debug.utils.BackgroundUtils.PluginToolExecutorService.TaskOpt; @@ -44,6 +42,9 @@ import ghidra.app.services.*; import ghidra.app.services.DebuggerListingService.LocationTrackingSpecChangeListener; import ghidra.app.util.viewer.listingpanel.ListingPanel; import ghidra.async.AsyncUtils; +import ghidra.debug.api.action.LocationTrackingSpec; +import ghidra.debug.api.listing.MultiBlendedListingBackgroundColorModel; +import ghidra.debug.api.tracemgr.DebuggerCoordinates; import ghidra.framework.plugintool.*; import ghidra.framework.plugintool.annotation.AutoServiceConsumed; import ghidra.framework.plugintool.util.PluginStatus; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/interpreters/AbstractDebuggerWrappedConsoleConnection.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/interpreters/AbstractDebuggerWrappedConsoleConnection.java index eb380fbce7..7af5c3e75b 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/interpreters/AbstractDebuggerWrappedConsoleConnection.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/interpreters/AbstractDebuggerWrappedConsoleConnection.java @@ -37,6 +37,7 @@ import ghidra.dbg.AnnotatedDebuggerAttributeListener; import ghidra.dbg.DebugModelConventions; import ghidra.dbg.target.*; import ghidra.dbg.target.TargetConsole.Channel; +import ghidra.debug.api.interpreter.DebuggerInterpreterConnection; import ghidra.util.Msg; import ghidra.util.Swing; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/interpreters/DebuggerInterpreterPlugin.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/interpreters/DebuggerInterpreterPlugin.java index 3e09ff8168..37bdd8714b 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/interpreters/DebuggerInterpreterPlugin.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/interpreters/DebuggerInterpreterPlugin.java @@ -26,6 +26,7 @@ import ghidra.app.plugin.core.debug.DebuggerPluginPackage; import ghidra.app.plugin.core.interpreter.*; import ghidra.app.services.DebuggerInterpreterService; import ghidra.dbg.target.*; +import ghidra.debug.api.interpreter.DebuggerInterpreterConnection; import ghidra.framework.plugintool.PluginInfo; import ghidra.framework.plugintool.PluginTool; import ghidra.framework.plugintool.annotation.AutoServiceConsumed; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/listing/DebuggerListingPlugin.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/listing/DebuggerListingPlugin.java index 998f40b916..75923b2ebd 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/listing/DebuggerListingPlugin.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/listing/DebuggerListingPlugin.java @@ -29,7 +29,6 @@ import ghidra.app.events.*; import ghidra.app.plugin.PluginCategoryNames; import ghidra.app.plugin.core.codebrowser.AbstractCodeBrowserPlugin; import ghidra.app.plugin.core.codebrowser.CodeViewerProvider; -import ghidra.app.plugin.core.debug.DebuggerCoordinates; import ghidra.app.plugin.core.debug.DebuggerPluginPackage; import ghidra.app.plugin.core.debug.event.*; import ghidra.app.plugin.core.debug.gui.DebuggerResources.AbstractNewListingAction; @@ -37,6 +36,9 @@ import ghidra.app.plugin.core.debug.gui.action.*; import ghidra.app.services.*; import ghidra.app.util.viewer.format.FormatManager; import ghidra.app.util.viewer.listingpanel.ListingPanel; +import ghidra.debug.api.action.LocationTrackingSpec; +import ghidra.debug.api.listing.MultiBlendedListingBackgroundColorModel; +import ghidra.debug.api.tracemgr.DebuggerCoordinates; import ghidra.framework.options.SaveState; import ghidra.framework.plugintool.*; import ghidra.framework.plugintool.annotation.AutoServiceConsumed; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/listing/DebuggerListingProvider.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/listing/DebuggerListingProvider.java index 061da0f907..39e63dfb94 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/listing/DebuggerListingProvider.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/listing/DebuggerListingProvider.java @@ -47,7 +47,6 @@ import ghidra.app.nav.ListingPanelContainer; import ghidra.app.plugin.core.clipboard.CodeBrowserClipboardProvider; import ghidra.app.plugin.core.codebrowser.CodeViewerProvider; import ghidra.app.plugin.core.codebrowser.MarkerServiceBackgroundColorModel; -import ghidra.app.plugin.core.debug.DebuggerCoordinates; import ghidra.app.plugin.core.debug.gui.DebuggerLocationLabel; import ghidra.app.plugin.core.debug.gui.DebuggerResources; import ghidra.app.plugin.core.debug.gui.DebuggerResources.FollowsCurrentThreadAction; @@ -62,6 +61,12 @@ import ghidra.app.services.*; import ghidra.app.services.DebuggerListingService.LocationTrackingSpecChangeListener; import ghidra.app.util.viewer.format.FormatManager; import ghidra.app.util.viewer.listingpanel.ListingPanel; +import ghidra.debug.api.action.GoToInput; +import ghidra.debug.api.action.LocationTrackingSpec; +import ghidra.debug.api.control.ControlMode; +import ghidra.debug.api.listing.MultiBlendedListingBackgroundColorModel; +import ghidra.debug.api.modules.DebuggerStaticMappingChangeListener; +import ghidra.debug.api.tracemgr.DebuggerCoordinates; import ghidra.framework.model.DomainFile; import ghidra.framework.options.SaveState; import ghidra.framework.plugintool.AutoConfigState; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/memory/CachedBytePage.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/memory/CachedBytePage.java index 7f2dfb7af3..374638a305 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/memory/CachedBytePage.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/memory/CachedBytePage.java @@ -17,7 +17,7 @@ package ghidra.app.plugin.core.debug.gui.memory; import java.nio.ByteBuffer; -import ghidra.app.plugin.core.debug.DebuggerCoordinates; +import ghidra.debug.api.tracemgr.DebuggerCoordinates; import ghidra.program.model.address.Address; public class CachedBytePage { diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/memory/DebuggerLegacyRegionsPanel.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/memory/DebuggerLegacyRegionsPanel.java index 6305335d24..b387a055e5 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/memory/DebuggerLegacyRegionsPanel.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/memory/DebuggerLegacyRegionsPanel.java @@ -30,10 +30,10 @@ import javax.swing.table.TableColumnModel; import docking.ActionContext; import docking.widgets.table.CustomToStringCellRenderer; import docking.widgets.table.DefaultEnumeratedColumnTableModel.EnumeratedTableColumn; -import ghidra.app.plugin.core.debug.DebuggerCoordinates; import ghidra.app.plugin.core.debug.gui.DebuggerResources; import ghidra.app.plugin.core.debug.utils.DebouncedRowWrappedEnumeratedColumnTableModel; import ghidra.app.services.DebuggerListingService; +import ghidra.debug.api.tracemgr.DebuggerCoordinates; import ghidra.framework.model.DomainObject; import ghidra.framework.plugintool.AutoService; import ghidra.framework.plugintool.PluginTool; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/memory/DebuggerMemoryByteViewerComponent.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/memory/DebuggerMemoryByteViewerComponent.java index 27a4236a19..8bfade0898 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/memory/DebuggerMemoryByteViewerComponent.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/memory/DebuggerMemoryByteViewerComponent.java @@ -24,11 +24,11 @@ import java.util.List; import docking.widgets.fieldpanel.internal.LayoutBackgroundColorManager; import docking.widgets.fieldpanel.support.FieldSelection; import ghidra.app.plugin.core.byteviewer.*; -import ghidra.app.plugin.core.debug.DebuggerCoordinates; import ghidra.app.plugin.core.debug.gui.DebuggerResources; import ghidra.app.plugin.core.debug.gui.colors.*; import ghidra.app.plugin.core.debug.gui.colors.MultiSelectionBlendedLayoutBackgroundColorManager.ColoredFieldSelection; import ghidra.app.plugin.core.format.DataFormatModel; +import ghidra.debug.api.tracemgr.DebuggerCoordinates; import ghidra.program.model.address.*; import ghidra.trace.model.Trace; import ghidra.trace.model.memory.TraceMemoryState; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/memory/DebuggerMemoryBytesPlugin.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/memory/DebuggerMemoryBytesPlugin.java index 1e7032fb40..bb9cc4e6dd 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/memory/DebuggerMemoryBytesPlugin.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/memory/DebuggerMemoryBytesPlugin.java @@ -26,13 +26,13 @@ import ghidra.app.events.ProgramLocationPluginEvent; import ghidra.app.events.ProgramSelectionPluginEvent; import ghidra.app.plugin.PluginCategoryNames; import ghidra.app.plugin.core.byteviewer.*; -import ghidra.app.plugin.core.debug.DebuggerCoordinates; import ghidra.app.plugin.core.debug.DebuggerPluginPackage; import ghidra.app.plugin.core.debug.event.*; import ghidra.app.plugin.core.debug.gui.DebuggerResources.NewMemoryAction; -import ghidra.app.plugin.core.debug.gui.action.LocationTrackingSpec; import ghidra.app.plugin.core.debug.gui.action.NoneLocationTrackingSpec; import ghidra.app.services.*; +import ghidra.debug.api.action.LocationTrackingSpec; +import ghidra.debug.api.tracemgr.DebuggerCoordinates; import ghidra.framework.options.SaveState; import ghidra.framework.plugintool.*; import ghidra.framework.plugintool.annotation.AutoServiceConsumed; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/memory/DebuggerMemoryBytesProvider.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/memory/DebuggerMemoryBytesProvider.java index 46d1014850..8c81d18925 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/memory/DebuggerMemoryBytesProvider.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/memory/DebuggerMemoryBytesProvider.java @@ -33,7 +33,6 @@ import docking.menu.MultiStateDockingAction; import docking.widgets.fieldpanel.support.ViewerPosition; import generic.theme.GThemeDefaults.Colors; import ghidra.app.plugin.core.byteviewer.*; -import ghidra.app.plugin.core.debug.DebuggerCoordinates; import ghidra.app.plugin.core.debug.gui.DebuggerLocationLabel; import ghidra.app.plugin.core.debug.gui.DebuggerResources; import ghidra.app.plugin.core.debug.gui.DebuggerResources.FollowsCurrentThreadAction; @@ -41,6 +40,9 @@ import ghidra.app.plugin.core.debug.gui.action.*; import ghidra.app.plugin.core.debug.gui.action.AutoReadMemorySpec.AutoReadMemorySpecConfigFieldCodec; import ghidra.app.plugin.core.format.ByteBlock; import ghidra.app.services.DebuggerTraceManagerService; +import ghidra.debug.api.action.GoToInput; +import ghidra.debug.api.action.LocationTrackingSpec; +import ghidra.debug.api.tracemgr.DebuggerCoordinates; import ghidra.framework.options.SaveState; import ghidra.framework.plugintool.*; import ghidra.framework.plugintool.annotation.AutoConfigStateField; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/memory/DebuggerRegionMapProposalDialog.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/memory/DebuggerRegionMapProposalDialog.java index 99dc7934e4..5368c27eed 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/memory/DebuggerRegionMapProposalDialog.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/memory/DebuggerRegionMapProposalDialog.java @@ -27,7 +27,7 @@ import docking.widgets.table.*; import docking.widgets.table.DefaultEnumeratedColumnTableModel.EnumeratedTableColumn; import ghidra.app.plugin.core.debug.gui.AbstractDebuggerMapProposalDialog; import ghidra.app.plugin.core.debug.gui.DebuggerResources; -import ghidra.app.services.RegionMapProposal.RegionMapEntry; +import ghidra.debug.api.modules.RegionMapProposal.RegionMapEntry; import ghidra.framework.plugintool.PluginTool; import ghidra.program.model.address.Address; import ghidra.program.model.listing.Program; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/memory/DebuggerRegionsProvider.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/memory/DebuggerRegionsProvider.java index 8764d66853..0a437acc0d 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/memory/DebuggerRegionsProvider.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/memory/DebuggerRegionsProvider.java @@ -30,7 +30,6 @@ import docking.WindowPosition; import docking.action.*; import docking.action.builder.ActionBuilder; import docking.action.builder.ToggleActionBuilder; -import ghidra.app.plugin.core.debug.DebuggerCoordinates; import ghidra.app.plugin.core.debug.DebuggerPluginPackage; import ghidra.app.plugin.core.debug.gui.DebuggerBlockChooserDialog; import ghidra.app.plugin.core.debug.gui.DebuggerResources; @@ -40,7 +39,10 @@ import ghidra.app.plugin.core.debug.gui.model.DebuggerObjectActionContext; import ghidra.app.plugin.core.debug.gui.modules.DebuggerModulesProvider; import ghidra.app.plugin.core.debug.service.modules.MapRegionsBackgroundCommand; import ghidra.app.services.*; -import ghidra.app.services.RegionMapProposal.RegionMapEntry; +import ghidra.debug.api.modules.MapProposal; +import ghidra.debug.api.modules.RegionMapProposal; +import ghidra.debug.api.modules.RegionMapProposal.RegionMapEntry; +import ghidra.debug.api.tracemgr.DebuggerCoordinates; import ghidra.framework.plugintool.*; import ghidra.framework.plugintool.annotation.AutoServiceConsumed; import ghidra.program.model.address.AddressRange; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/memview/DebuggerMemviewTraceListener.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/memview/DebuggerMemviewTraceListener.java index 3b761a96d3..68be49f1fe 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/memview/DebuggerMemviewTraceListener.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/memview/DebuggerMemviewTraceListener.java @@ -17,10 +17,10 @@ package ghidra.app.plugin.core.debug.gui.memview; import java.util.*; -import ghidra.app.plugin.core.debug.DebuggerCoordinates; -import ghidra.app.services.TraceRecorder; import ghidra.async.AsyncDebouncer; import ghidra.async.AsyncTimer; +import ghidra.debug.api.model.TraceRecorder; +import ghidra.debug.api.tracemgr.DebuggerCoordinates; import ghidra.program.model.address.*; import ghidra.trace.model.*; import ghidra.trace.model.Trace.*; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/model/AbstractObjectsTableBasedPanel.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/model/AbstractObjectsTableBasedPanel.java index d8373a9821..bb2de30f08 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/model/AbstractObjectsTableBasedPanel.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/model/AbstractObjectsTableBasedPanel.java @@ -25,11 +25,11 @@ import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; import docking.ComponentProvider; -import ghidra.app.plugin.core.debug.DebuggerCoordinates; import ghidra.app.plugin.core.debug.gui.model.AbstractQueryTablePanel.CellActivationListener; import ghidra.app.plugin.core.debug.gui.model.ObjectTableModel.ValueProperty; import ghidra.app.plugin.core.debug.gui.model.ObjectTableModel.ValueRow; import ghidra.app.services.DebuggerListingService; +import ghidra.debug.api.tracemgr.DebuggerCoordinates; import ghidra.framework.plugintool.AutoService; import ghidra.framework.plugintool.Plugin; import ghidra.framework.plugintool.annotation.AutoServiceConsumed; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/model/AbstractQueryTablePanel.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/model/AbstractQueryTablePanel.java index c19706bb95..2c21024c7f 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/model/AbstractQueryTablePanel.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/model/AbstractQueryTablePanel.java @@ -26,7 +26,7 @@ import javax.swing.event.ListSelectionListener; import docking.widgets.table.DynamicTableColumn; import docking.widgets.table.RangeCursorTableHeaderRenderer.SeekListener; -import ghidra.app.plugin.core.debug.DebuggerCoordinates; +import ghidra.debug.api.tracemgr.DebuggerCoordinates; import ghidra.framework.plugintool.Plugin; import ghidra.trace.model.Lifespan; import ghidra.trace.model.Trace; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/model/DebuggerModelPlugin.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/model/DebuggerModelPlugin.java index 9de81801a7..d23f124983 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/model/DebuggerModelPlugin.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/model/DebuggerModelPlugin.java @@ -18,12 +18,12 @@ package ghidra.app.plugin.core.debug.gui.model; import java.util.*; import ghidra.app.plugin.PluginCategoryNames; -import ghidra.app.plugin.core.debug.DebuggerCoordinates; import ghidra.app.plugin.core.debug.DebuggerPluginPackage; import ghidra.app.plugin.core.debug.event.TraceActivatedPluginEvent; import ghidra.app.plugin.core.debug.event.TraceClosedPluginEvent; import ghidra.app.plugin.core.debug.gui.MultiProviderSaveBehavior; import ghidra.app.services.DebuggerTraceManagerService; +import ghidra.debug.api.tracemgr.DebuggerCoordinates; import ghidra.framework.options.SaveState; import ghidra.framework.plugintool.*; import ghidra.framework.plugintool.util.PluginStatus; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/model/DebuggerModelProvider.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/model/DebuggerModelProvider.java index 5ddd9665da..2e4d654697 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/model/DebuggerModelProvider.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/model/DebuggerModelProvider.java @@ -31,7 +31,6 @@ import docking.action.ToggleDockingAction; import docking.widgets.table.RangeCursorTableHeaderRenderer.SeekListener; import docking.widgets.tree.support.GTreeSelectionEvent.EventOrigin; import generic.theme.GColor; -import ghidra.app.plugin.core.debug.DebuggerCoordinates; import ghidra.app.plugin.core.debug.DebuggerPluginPackage; import ghidra.app.plugin.core.debug.gui.DebuggerResources; import ghidra.app.plugin.core.debug.gui.DebuggerResources.*; @@ -42,6 +41,7 @@ import ghidra.app.plugin.core.debug.gui.model.ObjectTableModel.ValueRow; import ghidra.app.plugin.core.debug.gui.model.ObjectTreeModel.AbstractNode; import ghidra.app.plugin.core.debug.gui.model.PathTableModel.PathRow; import ghidra.app.services.DebuggerTraceManagerService; +import ghidra.debug.api.tracemgr.DebuggerCoordinates; import ghidra.framework.options.SaveState; import ghidra.framework.plugintool.AutoConfigState; import ghidra.framework.plugintool.AutoService; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/model/ObjectsTreePanel.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/model/ObjectsTreePanel.java index 0e73710a53..59ddc1cdcf 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/model/ObjectsTreePanel.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/model/ObjectsTreePanel.java @@ -29,9 +29,9 @@ import docking.widgets.tree.GTreeNode; import docking.widgets.tree.support.GTreeRenderer; import docking.widgets.tree.support.GTreeSelectionEvent.EventOrigin; import docking.widgets.tree.support.GTreeSelectionListener; -import ghidra.app.plugin.core.debug.DebuggerCoordinates; import ghidra.app.plugin.core.debug.gui.DebuggerResources; import ghidra.app.plugin.core.debug.gui.model.ObjectTreeModel.AbstractNode; +import ghidra.debug.api.tracemgr.DebuggerCoordinates; import ghidra.trace.model.Lifespan; import ghidra.trace.model.Trace; import ghidra.trace.model.target.*; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/modules/DebuggerLegacyModulesPanel.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/modules/DebuggerLegacyModulesPanel.java index 789241ffd0..29056eb4fb 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/modules/DebuggerLegacyModulesPanel.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/modules/DebuggerLegacyModulesPanel.java @@ -29,9 +29,9 @@ import javax.swing.table.TableColumnModel; import docking.widgets.table.CustomToStringCellRenderer; import docking.widgets.table.DefaultEnumeratedColumnTableModel.EnumeratedTableColumn; -import ghidra.app.plugin.core.debug.DebuggerCoordinates; import ghidra.app.plugin.core.debug.gui.DebuggerResources; import ghidra.app.plugin.core.debug.utils.DebouncedRowWrappedEnumeratedColumnTableModel; +import ghidra.debug.api.tracemgr.DebuggerCoordinates; import ghidra.framework.model.DomainObject; import ghidra.framework.plugintool.PluginTool; import ghidra.program.model.address.*; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/modules/DebuggerLegacySectionsPanel.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/modules/DebuggerLegacySectionsPanel.java index 93d44ee24e..e58fb76d8d 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/modules/DebuggerLegacySectionsPanel.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/modules/DebuggerLegacySectionsPanel.java @@ -30,9 +30,9 @@ import javax.swing.table.TableColumnModel; import docking.widgets.table.CustomToStringCellRenderer; import docking.widgets.table.DefaultEnumeratedColumnTableModel.EnumeratedTableColumn; import docking.widgets.table.TableFilter; -import ghidra.app.plugin.core.debug.DebuggerCoordinates; import ghidra.app.plugin.core.debug.gui.DebuggerResources; import ghidra.app.plugin.core.debug.utils.DebouncedRowWrappedEnumeratedColumnTableModel; +import ghidra.debug.api.tracemgr.DebuggerCoordinates; import ghidra.framework.model.DomainObject; import ghidra.framework.plugintool.PluginTool; import ghidra.program.model.address.*; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/modules/DebuggerModuleMapProposalDialog.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/modules/DebuggerModuleMapProposalDialog.java index 327a976af7..f86003460d 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/modules/DebuggerModuleMapProposalDialog.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/modules/DebuggerModuleMapProposalDialog.java @@ -26,7 +26,7 @@ import docking.widgets.table.*; import docking.widgets.table.DefaultEnumeratedColumnTableModel.EnumeratedTableColumn; import ghidra.app.plugin.core.debug.gui.AbstractDebuggerMapProposalDialog; import ghidra.app.plugin.core.debug.gui.DebuggerResources; -import ghidra.app.services.ModuleMapProposal.ModuleMapEntry; +import ghidra.debug.api.modules.ModuleMapProposal.ModuleMapEntry; import ghidra.framework.model.DomainFile; import ghidra.framework.plugintool.PluginTool; import ghidra.program.model.address.Address; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/modules/DebuggerModulesProvider.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/modules/DebuggerModulesProvider.java index f4461e6061..bcd52e020c 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/modules/DebuggerModulesProvider.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/modules/DebuggerModulesProvider.java @@ -29,7 +29,6 @@ import docking.*; import docking.action.*; import docking.action.builder.ActionBuilder; import docking.widgets.filechooser.GhidraFileChooser; -import ghidra.app.plugin.core.debug.DebuggerCoordinates; import ghidra.app.plugin.core.debug.DebuggerPluginPackage; import ghidra.app.plugin.core.debug.gui.DebuggerBlockChooserDialog; import ghidra.app.plugin.core.debug.gui.DebuggerResources; @@ -39,11 +38,14 @@ import ghidra.app.plugin.core.debug.service.modules.MapModulesBackgroundCommand; import ghidra.app.plugin.core.debug.service.modules.MapSectionsBackgroundCommand; import ghidra.app.plugin.core.debug.utils.BackgroundUtils; import ghidra.app.services.*; -import ghidra.app.services.ModuleMapProposal.ModuleMapEntry; -import ghidra.app.services.SectionMapProposal.SectionMapEntry; import ghidra.async.AsyncUtils; import ghidra.async.TypeSpec; import ghidra.dbg.target.TargetModule; +import ghidra.debug.api.model.TraceRecorder; +import ghidra.debug.api.modules.*; +import ghidra.debug.api.modules.ModuleMapProposal.ModuleMapEntry; +import ghidra.debug.api.modules.SectionMapProposal.SectionMapEntry; +import ghidra.debug.api.tracemgr.DebuggerCoordinates; import ghidra.framework.main.AppInfo; import ghidra.framework.main.DataTreeDialog; import ghidra.framework.model.*; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/modules/DebuggerSectionMapProposalDialog.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/modules/DebuggerSectionMapProposalDialog.java index a22c8d7601..40e7dc6b53 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/modules/DebuggerSectionMapProposalDialog.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/modules/DebuggerSectionMapProposalDialog.java @@ -27,7 +27,7 @@ import docking.widgets.table.*; import docking.widgets.table.DefaultEnumeratedColumnTableModel.EnumeratedTableColumn; import ghidra.app.plugin.core.debug.gui.AbstractDebuggerMapProposalDialog; import ghidra.app.plugin.core.debug.gui.DebuggerResources; -import ghidra.app.services.SectionMapProposal.SectionMapEntry; +import ghidra.debug.api.modules.SectionMapProposal.SectionMapEntry; import ghidra.framework.plugintool.PluginTool; import ghidra.program.model.address.Address; import ghidra.program.model.listing.Program; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/objects/DebuggerObjectsProvider.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/objects/DebuggerObjectsProvider.java index e8f82e8693..af64681694 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/objects/DebuggerObjectsProvider.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/objects/DebuggerObjectsProvider.java @@ -43,13 +43,11 @@ import docking.widgets.table.DefaultEnumeratedColumnTableModel; import docking.widgets.tree.GTree; import generic.jar.ResourceFile; import generic.theme.GColor; -import ghidra.app.plugin.core.debug.DebuggerCoordinates; import ghidra.app.plugin.core.debug.DebuggerPluginPackage; import ghidra.app.plugin.core.debug.gui.DebuggerResources; import ghidra.app.plugin.core.debug.gui.DebuggerResources.*; import ghidra.app.plugin.core.debug.gui.objects.actions.*; import ghidra.app.plugin.core.debug.gui.objects.components.*; -import ghidra.app.plugin.core.debug.mapping.DebuggerMemoryMapper; import ghidra.app.script.*; import ghidra.app.services.*; import ghidra.app.services.DebuggerTraceManagerService.ActivationCause; @@ -65,6 +63,9 @@ import ghidra.dbg.target.TargetMethod.TargetParameterMap; import ghidra.dbg.target.TargetSteppable.TargetStepKind; import ghidra.dbg.util.DebuggerCallbackReorderer; import ghidra.dbg.util.PathUtils; +import ghidra.debug.api.model.DebuggerMemoryMapper; +import ghidra.debug.api.model.TraceRecorder; +import ghidra.debug.api.tracemgr.DebuggerCoordinates; import ghidra.framework.model.Project; import ghidra.framework.options.AutoOptions; import ghidra.framework.options.SaveState; @@ -1684,7 +1685,7 @@ public class DebuggerObjectsProvider extends ComponentProviderAdapter TargetObject result = null; try { result = DebugModelConventions.findSuitable(TargetExecutionStateful.class, object) - .get(100, TimeUnit.MILLISECONDS); + .get(100, TimeUnit.MILLISECONDS); } catch (Exception e) { // IGNORE diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/objects/components/DebuggerMethodInvocationDialog.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/objects/components/DebuggerMethodInvocationDialog.java index 483eca06b3..5947928fa0 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/objects/components/DebuggerMethodInvocationDialog.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/objects/components/DebuggerMethodInvocationDialog.java @@ -15,18 +15,20 @@ */ package ghidra.app.plugin.core.debug.gui.objects.components; -import java.awt.BorderLayout; -import java.awt.FlowLayout; +import java.awt.*; import java.awt.event.ActionEvent; import java.beans.*; import java.util.*; +import java.util.List; import javax.swing.*; import javax.swing.border.EmptyBorder; import org.apache.commons.collections4.BidiMap; import org.apache.commons.collections4.bidimap.DualLinkedHashBidiMap; +import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.tuple.MutablePair; +import org.apache.commons.text.StringEscapeUtils; import org.jdom.Element; import docking.DialogComponentProvider; @@ -44,6 +46,113 @@ public class DebuggerMethodInvocationDialog extends DialogComponentProvider implements PropertyChangeListener { private static final String KEY_MEMORIZED_ARGUMENTS = "memorizedArguments"; + static class ChoicesPropertyEditor implements PropertyEditor { + private final List choices; + private final String[] tags; + + private final List listeners = new ArrayList<>(); + + private Object value; + + public ChoicesPropertyEditor(Set choices) { + this.choices = List.copyOf(choices); + this.tags = choices.stream().map(Objects::toString).toArray(String[]::new); + } + + @Override + public void setValue(Object value) { + if (Objects.equals(value, this.value)) { + return; + } + if (!choices.contains(value)) { + throw new IllegalArgumentException("Unsupported value: " + value); + } + Object oldValue; + List listeners; + synchronized (this.listeners) { + oldValue = this.value; + this.value = value; + if (this.listeners.isEmpty()) { + return; + } + listeners = List.copyOf(this.listeners); + } + PropertyChangeEvent evt = new PropertyChangeEvent(this, null, oldValue, value); + for (PropertyChangeListener l : listeners) { + l.propertyChange(evt); + } + } + + @Override + public Object getValue() { + return value; + } + + @Override + public boolean isPaintable() { + return false; + } + + @Override + public void paintValue(Graphics gfx, Rectangle box) { + // Not paintable + } + + @Override + public String getJavaInitializationString() { + if (value == null) { + return "null"; + } + if (value instanceof String str) { + return "\"" + StringEscapeUtils.escapeJava(str) + "\""; + } + return Objects.toString(value); + } + + @Override + public String getAsText() { + return Objects.toString(value); + } + + @Override + public void setAsText(String text) throws IllegalArgumentException { + int index = ArrayUtils.indexOf(tags, text); + if (index < 0) { + throw new IllegalArgumentException("Unsupported value: " + text); + } + setValue(choices.get(index)); + } + + @Override + public String[] getTags() { + return tags.clone(); + } + + @Override + public Component getCustomEditor() { + return null; + } + + @Override + public boolean supportsCustomEditor() { + return false; + } + + @Override + public void addPropertyChangeListener(PropertyChangeListener listener) { + synchronized (listeners) { + listeners.add(listener); + } + } + + @Override + public void removePropertyChangeListener(PropertyChangeListener listener) { + synchronized (listeners) { + listeners.remove(listener); + } + } + } + final static class NameTypePair extends MutablePair> { public static NameTypePair fromParameter(ParameterDescription parameter) { @@ -87,6 +196,7 @@ public class DebuggerMethodInvocationDialog extends DialogComponentProvider new DualLinkedHashBidiMap<>(); private JPanel panel; + private JLabel descriptionLabel; private JPanel pairPanel; private PairLayout layout; @@ -103,10 +213,10 @@ public class DebuggerMethodInvocationDialog extends DialogComponentProvider public DebuggerMethodInvocationDialog(PluginTool tool, String title, String buttonText, Icon buttonIcon) { - super(title, true, false, true, false); + super(title, true, true, true, false); this.tool = tool; - populateComponents(buttonText, buttonIcon, "Reset", DebuggerResources.ICON_REFRESH); + populateComponents(buttonText, buttonIcon); setRememberSize(false); } @@ -127,8 +237,7 @@ public class DebuggerMethodInvocationDialog extends DialogComponentProvider populateOptions(); } - private void populateComponents(String buttonText, Icon buttonIcon, - String resetText, Icon resetIcon) { + private void populateComponents(String buttonText, Icon buttonIcon) { panel = new JPanel(new BorderLayout()); panel.setBorder(new EmptyBorder(10, 10, 10, 10)); @@ -142,11 +251,15 @@ public class DebuggerMethodInvocationDialog extends DialogComponentProvider panel.add(scrolling, BorderLayout.CENTER); centering.add(pairPanel); + descriptionLabel = new JLabel(); + descriptionLabel.setMaximumSize(new Dimension(300, 100)); + panel.add(descriptionLabel, BorderLayout.NORTH); + addWorkPanel(panel); invokeButton = new JButton(buttonText, buttonIcon); addButton(invokeButton); - resetButton = new JButton(resetText, resetIcon); + resetButton = new JButton("Reset", DebuggerResources.ICON_REFRESH); addButton(resetButton); addCancelButton(); @@ -174,26 +287,32 @@ public class DebuggerMethodInvocationDialog extends DialogComponentProvider close(); } + protected PropertyEditor getEditor(ParameterDescription param) { + if (!param.choices.isEmpty()) { + return new ChoicesPropertyEditor(param.choices); + } + Class type = param.type; + PropertyEditor editor = PropertyEditorManager.findEditor(type); + if (editor != null) { + return editor; + } + Msg.warn(this, "No editor for " + type + "? Trying String instead"); + return PropertyEditorManager.findEditor(String.class); + } + void populateOptions() { pairPanel.removeAll(); - //layout.setRows(Math.max(1, parameters.size())); paramEditors.clear(); for (ParameterDescription param : parameters.values()) { JLabel label = new JLabel(param.display); label.setToolTipText(param.description); pairPanel.add(label); - Class type = param.type; - PropertyEditor editor = PropertyEditorManager.findEditor(type); - if (editor == null) { - Msg.warn(this, "No editor for " + type + "? Trying String instead"); - editor = PropertyEditorManager.findEditor(String.class); - } + PropertyEditor editor = getEditor(param); Object val = computeMemorizedValue(param); editor.setValue(val); editor.addPropertyChangeListener(this); pairPanel.add(MiscellaneousUtils.getEditorComponent(editor)); - // TODO: How to handle parameter with choices? paramEditors.put(param, editor); } } @@ -214,7 +333,6 @@ public class DebuggerMethodInvocationDialog extends DialogComponentProvider } public void setMemorizedArgument(String name, Class type, T value) { - //name = addContext(name, currentContext); if (value == null) { return; } @@ -222,7 +340,6 @@ public class DebuggerMethodInvocationDialog extends DialogComponentProvider } public T getMemorizedArgument(String name, Class type) { - //name = addContext(name, currentContext); return type.cast(memorized.get(new NameTypePair(name, type))); } @@ -265,4 +382,14 @@ public class DebuggerMethodInvocationDialog extends DialogComponentProvider return resetRequested; } + public void setDescription(String htmlDescription) { + if (htmlDescription == null) { + descriptionLabel.setBorder(BorderFactory.createEmptyBorder()); + descriptionLabel.setText(""); + } + else { + descriptionLabel.setBorder(BorderFactory.createEmptyBorder(0, 0, 10, 0)); + descriptionLabel.setText(htmlDescription); + } + } } diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/pcode/DebuggerPcodeStepperProvider.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/pcode/DebuggerPcodeStepperProvider.java index 740487b813..fe854d8336 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/pcode/DebuggerPcodeStepperProvider.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/pcode/DebuggerPcodeStepperProvider.java @@ -33,11 +33,9 @@ import docking.action.DockingAction; import docking.widgets.table.*; import docking.widgets.table.DefaultEnumeratedColumnTableModel.EnumeratedTableColumn; import generic.theme.GColor; -import ghidra.app.plugin.core.debug.DebuggerCoordinates; import ghidra.app.plugin.core.debug.DebuggerPluginPackage; import ghidra.app.plugin.core.debug.gui.DebuggerResources; import ghidra.app.plugin.core.debug.gui.pcode.UniqueRow.RefType; -import ghidra.app.plugin.core.debug.service.emulation.DebuggerPcodeMachine; import ghidra.app.plugin.processors.sleigh.template.OpTpl; import ghidra.app.services.DebuggerEmulationService; import ghidra.app.services.DebuggerTraceManagerService; @@ -45,6 +43,8 @@ import ghidra.app.util.pcode.AbstractAppender; import ghidra.app.util.pcode.AbstractPcodeFormatter; import ghidra.async.SwingExecutorService; import ghidra.base.widgets.table.DataTypeTableCellEditor; +import ghidra.debug.api.emulation.DebuggerPcodeMachine; +import ghidra.debug.api.tracemgr.DebuggerCoordinates; import ghidra.docking.settings.Settings; import ghidra.framework.plugintool.*; import ghidra.framework.plugintool.annotation.AutoServiceConsumed; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/platform/DebuggerPlatformPlugin.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/platform/DebuggerPlatformPlugin.java index 874c0f17f8..57220d4710 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/platform/DebuggerPlatformPlugin.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/platform/DebuggerPlatformPlugin.java @@ -26,13 +26,14 @@ import docking.action.ToggleDockingAction; import docking.action.builder.ActionBuilder; import docking.action.builder.ToggleActionBuilder; import ghidra.app.plugin.PluginCategoryNames; -import ghidra.app.plugin.core.debug.DebuggerCoordinates; import ghidra.app.plugin.core.debug.DebuggerPluginPackage; import ghidra.app.plugin.core.debug.event.*; import ghidra.app.plugin.core.debug.gui.DebuggerResources; import ghidra.app.plugin.core.debug.mapping.*; import ghidra.app.services.DebuggerPlatformService; import ghidra.app.services.DebuggerTraceManagerService; +import ghidra.debug.api.platform.DebuggerPlatformMapper; +import ghidra.debug.api.tracemgr.DebuggerCoordinates; import ghidra.framework.plugintool.*; import ghidra.framework.plugintool.AutoService.Wiring; import ghidra.framework.plugintool.annotation.AutoServiceConsumed; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/register/DebuggerRegistersProvider.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/register/DebuggerRegistersProvider.java index bdf3585fcb..a886b31567 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/register/DebuggerRegistersProvider.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/register/DebuggerRegistersProvider.java @@ -41,11 +41,9 @@ import docking.widgets.table.ColumnSortState.SortDirection; import docking.widgets.table.DefaultEnumeratedColumnTableModel.EnumeratedTableColumn; import generic.theme.GColor; import ghidra.app.plugin.core.data.DataSettingsDialog; -import ghidra.app.plugin.core.debug.DebuggerCoordinates; import ghidra.app.plugin.core.debug.DebuggerPluginPackage; 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.DebuggerControlService.StateEditor; import ghidra.async.AsyncLazyValue; @@ -54,6 +52,8 @@ import ghidra.base.widgets.table.DataTypeTableCellEditor; import ghidra.dbg.error.DebuggerModelAccessException; import ghidra.dbg.target.TargetRegisterBank; import ghidra.dbg.target.TargetThread; +import ghidra.debug.api.model.*; +import ghidra.debug.api.tracemgr.DebuggerCoordinates; import ghidra.docking.settings.Settings; import ghidra.framework.model.DomainObject; import ghidra.framework.model.DomainObjectChangeRecord; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/register/RegisterRow.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/register/RegisterRow.java index 1537c71989..fa2cfce02b 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/register/RegisterRow.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/register/RegisterRow.java @@ -18,8 +18,8 @@ package ghidra.app.plugin.core.debug.gui.register; import java.math.BigInteger; import java.util.Objects; -import ghidra.app.plugin.core.debug.DebuggerCoordinates; import ghidra.app.services.DebuggerControlService; +import ghidra.debug.api.tracemgr.DebuggerCoordinates; import ghidra.program.model.data.DataType; import ghidra.program.model.lang.Language; import ghidra.program.model.lang.Register; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/stack/DebuggerLegacyStackPanel.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/stack/DebuggerLegacyStackPanel.java index 286cb42c95..c076f5f5a7 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/stack/DebuggerLegacyStackPanel.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/stack/DebuggerLegacyStackPanel.java @@ -27,8 +27,9 @@ import javax.swing.table.*; import docking.widgets.table.*; import docking.widgets.table.DefaultEnumeratedColumnTableModel.EnumeratedTableColumn; -import ghidra.app.plugin.core.debug.DebuggerCoordinates; import ghidra.app.services.*; +import ghidra.debug.api.modules.DebuggerStaticMappingChangeListener; +import ghidra.debug.api.tracemgr.DebuggerCoordinates; import ghidra.docking.settings.Settings; import ghidra.framework.plugintool.AutoService; import ghidra.framework.plugintool.PluginTool; @@ -41,6 +42,7 @@ import ghidra.trace.model.*; import ghidra.trace.model.Trace.TraceMemoryBytesChangeType; import ghidra.trace.model.Trace.TraceStackChangeType; import ghidra.trace.model.memory.TraceMemorySpace; +import ghidra.trace.model.program.TraceProgramView; import ghidra.trace.model.stack.TraceStack; import ghidra.trace.model.stack.TraceStackFrame; import ghidra.trace.model.thread.TraceThread; @@ -159,7 +161,11 @@ public class DebuggerLegacyStackPanel extends JPanel { if (space.getThread() != curThread || space.getFrameLevel() != 0) { return; } - if (!current.getView().getViewport().containsAnyUpper(range.getLifespan())) { + TraceProgramView view = current.getView(); + if (view == null) { + return; + } + if (!view.getViewport().containsAnyUpper(range.getLifespan())) { return; } List stackData = stackTableModel.getModelData(); diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/stack/DebuggerStackPanel.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/stack/DebuggerStackPanel.java index 2f99376745..c36264fa4c 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/stack/DebuggerStackPanel.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/stack/DebuggerStackPanel.java @@ -22,7 +22,6 @@ import javax.swing.event.ListSelectionListener; import docking.widgets.table.AbstractDynamicTableColumn; import docking.widgets.table.TableColumnDescriptor; -import ghidra.app.plugin.core.debug.DebuggerCoordinates; import ghidra.app.plugin.core.debug.gui.model.*; import ghidra.app.plugin.core.debug.gui.model.AbstractQueryTablePanel.CellActivationListener; import ghidra.app.plugin.core.debug.gui.model.ObjectTableModel.ValueRow; @@ -33,6 +32,7 @@ import ghidra.dbg.target.TargetStack; import ghidra.dbg.target.TargetStackFrame; import ghidra.dbg.target.schema.TargetObjectSchema; import ghidra.dbg.util.PathMatcher; +import ghidra.debug.api.tracemgr.DebuggerCoordinates; import ghidra.docking.settings.Settings; import ghidra.framework.plugintool.Plugin; import ghidra.framework.plugintool.ServiceProvider; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/stack/DebuggerStackProvider.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/stack/DebuggerStackProvider.java index dfee8e9c01..c78e4a31c2 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/stack/DebuggerStackProvider.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/stack/DebuggerStackProvider.java @@ -28,11 +28,11 @@ import docking.ActionContext; import docking.WindowPosition; import docking.action.DockingAction; import docking.action.builder.ActionBuilder; -import ghidra.app.plugin.core.debug.DebuggerCoordinates; import ghidra.app.plugin.core.debug.DebuggerPluginPackage; import ghidra.app.plugin.core.debug.gui.DebuggerResources; import ghidra.app.plugin.core.debug.stack.UnwindStackCommand; import ghidra.app.services.DebuggerStaticMappingService; +import ghidra.debug.api.tracemgr.DebuggerCoordinates; import ghidra.framework.plugintool.*; import ghidra.framework.plugintool.annotation.AutoServiceConsumed; import ghidra.program.model.address.Address; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/stack/vars/VariableValueHoverService.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/stack/vars/VariableValueHoverService.java index 3e21874a4a..64a196c75e 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/stack/vars/VariableValueHoverService.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/stack/vars/VariableValueHoverService.java @@ -32,7 +32,6 @@ import ghidra.app.decompiler.component.ClangTextField; import ghidra.app.decompiler.component.hover.DataTypeDecompilerHover; import ghidra.app.decompiler.component.hover.DecompilerHoverService; import ghidra.app.plugin.core.codebrowser.hover.ListingHoverService; -import ghidra.app.plugin.core.debug.DebuggerCoordinates; import ghidra.app.plugin.core.debug.gui.stack.vars.VariableValueRow.*; import ghidra.app.plugin.core.debug.gui.stack.vars.VariableValueUtils.VariableEvaluator; import ghidra.app.plugin.core.debug.stack.*; @@ -44,6 +43,7 @@ import ghidra.app.services.DebuggerStaticMappingService; import ghidra.app.services.DebuggerTraceManagerService; import ghidra.async.AsyncUtils; import ghidra.async.SwingExecutorService; +import ghidra.debug.api.tracemgr.DebuggerCoordinates; import ghidra.framework.plugintool.AutoService; import ghidra.framework.plugintool.PluginTool; import ghidra.framework.plugintool.annotation.AutoServiceConsumed; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/stack/vars/VariableValueUtils.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/stack/vars/VariableValueUtils.java index 14ebf70608..bed3d870e0 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/stack/vars/VariableValueUtils.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/stack/vars/VariableValueUtils.java @@ -19,9 +19,9 @@ import java.util.*; import ghidra.app.decompiler.ClangLine; import ghidra.app.decompiler.ClangToken; -import ghidra.app.plugin.core.debug.DebuggerCoordinates; import ghidra.app.plugin.core.debug.stack.*; import ghidra.app.plugin.core.debug.stack.StackUnwindWarning.CustomStackUnwindWarning; +import ghidra.debug.api.tracemgr.DebuggerCoordinates; import ghidra.docking.settings.Settings; import ghidra.docking.settings.SettingsDefinition; import ghidra.framework.plugintool.PluginTool; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/thread/DebuggerLegacyThreadsPanel.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/thread/DebuggerLegacyThreadsPanel.java index aae22837da..dbce409919 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/thread/DebuggerLegacyThreadsPanel.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/thread/DebuggerLegacyThreadsPanel.java @@ -29,9 +29,9 @@ import docking.ActionContext; import docking.widgets.table.*; import docking.widgets.table.DefaultEnumeratedColumnTableModel.EnumeratedTableColumn; import docking.widgets.table.RangeCursorTableHeaderRenderer.SeekListener; -import ghidra.app.plugin.core.debug.DebuggerCoordinates; import ghidra.app.plugin.core.debug.gui.DebuggerSnapActionContext; import ghidra.app.services.DebuggerTraceManagerService; +import ghidra.debug.api.tracemgr.DebuggerCoordinates; import ghidra.docking.settings.Settings; import ghidra.framework.model.DomainObject; import ghidra.framework.model.DomainObjectChangeRecord; @@ -344,7 +344,8 @@ public class DebuggerLegacyThreadsPanel extends JPanel { } protected void updateTimelineMax() { - long max = orZero(current.getTrace().getTimeManager().getMaxSnap()); + Trace trace = current.getTrace(); + long max = orZero(trace == null ? null : trace.getTimeManager().getMaxSnap()); Lifespan fullRange = Lifespan.span(0, max + 1); spanRenderer.setFullRange(fullRange); headerRenderer.setFullRange(fullRange); diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/thread/DebuggerThreadsPanel.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/thread/DebuggerThreadsPanel.java index 413526b8ce..fba8b4e73e 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/thread/DebuggerThreadsPanel.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/thread/DebuggerThreadsPanel.java @@ -22,13 +22,13 @@ import javax.swing.JTable; import docking.widgets.table.RangeCursorTableHeaderRenderer.SeekListener; import docking.widgets.table.threaded.ThreadedTableModelListener; import docking.widgets.table.TableColumnDescriptor; -import ghidra.app.plugin.core.debug.DebuggerCoordinates; import ghidra.app.plugin.core.debug.gui.model.*; import ghidra.app.plugin.core.debug.gui.model.ObjectTableModel.*; import ghidra.app.plugin.core.debug.gui.model.columns.*; import ghidra.app.services.DebuggerTraceManagerService; import ghidra.dbg.target.*; import ghidra.dbg.target.schema.TargetObjectSchema; +import ghidra.debug.api.tracemgr.DebuggerCoordinates; import ghidra.docking.settings.Settings; import ghidra.framework.plugintool.Plugin; import ghidra.framework.plugintool.ServiceProvider; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/thread/DebuggerThreadsProvider.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/thread/DebuggerThreadsProvider.java index 7498047856..e06f0d44bb 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/thread/DebuggerThreadsProvider.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/thread/DebuggerThreadsProvider.java @@ -26,13 +26,13 @@ import org.apache.commons.lang3.ArrayUtils; import docking.ActionContext; import docking.WindowPosition; import docking.action.*; -import ghidra.app.plugin.core.debug.DebuggerCoordinates; import ghidra.app.plugin.core.debug.DebuggerPluginPackage; import ghidra.app.plugin.core.debug.gui.DebuggerResources; import ghidra.app.plugin.core.debug.gui.DebuggerResources.SynchronizeTargetAction; import ghidra.app.plugin.core.debug.gui.DebuggerResources.ToToggleSelectionListener; import ghidra.app.services.*; import ghidra.app.services.DebuggerTraceManagerService.BooleanChangeAdapter; +import ghidra.debug.api.tracemgr.DebuggerCoordinates; import ghidra.framework.model.DomainObject; import ghidra.framework.model.DomainObjectChangeRecord; import ghidra.framework.plugintool.AutoService; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/thread/DebuggerTraceTabPanel.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/thread/DebuggerTraceTabPanel.java index 78dc211c87..0478108b12 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/thread/DebuggerTraceTabPanel.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/thread/DebuggerTraceTabPanel.java @@ -25,12 +25,13 @@ import javax.swing.event.ListSelectionEvent; import docking.action.DockingAction; import docking.widgets.HorizontalTabPanel; -import ghidra.app.plugin.core.debug.DebuggerCoordinates; import ghidra.app.plugin.core.debug.event.TraceClosedPluginEvent; import ghidra.app.plugin.core.debug.event.TraceOpenedPluginEvent; import ghidra.app.plugin.core.debug.gui.DebuggerResources; import ghidra.app.plugin.core.debug.gui.DebuggerResources.*; import ghidra.app.services.*; +import ghidra.debug.api.model.TraceRecorder; +import ghidra.debug.api.tracemgr.DebuggerCoordinates; import ghidra.framework.plugintool.*; import ghidra.framework.plugintool.annotation.AutoServiceConsumed; import ghidra.framework.plugintool.util.PluginEventListener; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/thread/ThreadRow.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/thread/ThreadRow.java index a25e398a10..0c16d6c92b 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/thread/ThreadRow.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/thread/ThreadRow.java @@ -17,8 +17,8 @@ package ghidra.app.plugin.core.debug.gui.thread; import db.Transaction; import ghidra.app.services.DebuggerModelService; -import ghidra.app.services.TraceRecorder; import ghidra.dbg.target.TargetExecutionStateful.TargetExecutionState; +import ghidra.debug.api.model.TraceRecorder; import ghidra.trace.model.Lifespan; import ghidra.trace.model.Trace; import ghidra.trace.model.thread.TraceThread; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/time/DebuggerTimeProvider.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/time/DebuggerTimeProvider.java index 6c5b66e699..0ece8829a2 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/time/DebuggerTimeProvider.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/time/DebuggerTimeProvider.java @@ -27,11 +27,11 @@ import javax.swing.JComponent; import docking.ActionContext; import docking.action.*; import docking.action.builder.ActionBuilder; -import ghidra.app.plugin.core.debug.DebuggerCoordinates; import ghidra.app.plugin.core.debug.DebuggerPluginPackage; import ghidra.app.plugin.core.debug.gui.DebuggerResources; import ghidra.app.plugin.core.debug.gui.DebuggerSnapActionContext; import ghidra.app.services.DebuggerTraceManagerService; +import ghidra.debug.api.tracemgr.DebuggerCoordinates; import ghidra.framework.options.SaveState; import ghidra.framework.plugintool.*; import ghidra.framework.plugintool.AutoService.Wiring; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/watch/DebuggerWatchActionContext.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/watch/DebuggerWatchActionContext.java index e646fde36a..597430cc9d 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/watch/DebuggerWatchActionContext.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/watch/DebuggerWatchActionContext.java @@ -20,12 +20,13 @@ import java.util.Collection; import java.util.Set; import docking.DefaultActionContext; +import ghidra.debug.api.watch.WatchRow; public class DebuggerWatchActionContext extends DefaultActionContext { private final Set sel; public DebuggerWatchActionContext(DebuggerWatchesProvider provider, - Collection sel, Component sourceComponent) { + Collection sel, Component sourceComponent) { super(provider, sel, sourceComponent); this.sel = Set.copyOf(sel); } diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/watch/DebuggerWatchesProvider.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/watch/DebuggerWatchesProvider.java index 01c7b4652a..7fc4af896f 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/watch/DebuggerWatchesProvider.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/watch/DebuggerWatchesProvider.java @@ -43,7 +43,6 @@ import generic.theme.GColor; import ghidra.app.context.ListingActionContext; import ghidra.app.context.ProgramLocationActionContext; import ghidra.app.plugin.core.data.AbstractSettingsDialog; -import ghidra.app.plugin.core.debug.DebuggerCoordinates; import ghidra.app.plugin.core.debug.DebuggerPluginPackage; import ghidra.app.plugin.core.debug.gui.DebuggerResources; import ghidra.app.plugin.core.debug.gui.DebuggerResources.*; @@ -54,6 +53,8 @@ import ghidra.app.services.*; import ghidra.async.AsyncDebouncer; import ghidra.async.AsyncTimer; import ghidra.base.widgets.table.DataTypeTableCellEditor; +import ghidra.debug.api.tracemgr.DebuggerCoordinates; +import ghidra.debug.api.watch.WatchRow; import ghidra.docking.settings.*; import ghidra.framework.model.DomainObject; import ghidra.framework.model.DomainObjectChangeRecord; @@ -149,7 +150,8 @@ public class DebuggerWatchesProvider extends ComponentProviderAdapter } } - protected enum WatchTableColumns implements EnumeratedTableColumn { + protected enum WatchTableColumns + implements EnumeratedTableColumn { EXPRESSION("Expression", String.class, WatchRow::getExpression, WatchRow::setExpression), ADDRESS("Address", Address.class, WatchRow::getAddress), SYMBOL("Symbol", Symbol.class, WatchRow::getSymbol), @@ -191,7 +193,7 @@ public class DebuggerWatchesProvider extends ComponentProviderAdapter } @Override - public Object getValueOf(WatchRow row) { + public Object getValueOf(DefaultWatchRow row) { return getter.apply(row); } @@ -201,18 +203,18 @@ public class DebuggerWatchesProvider extends ComponentProviderAdapter } @Override - public void setValueOf(WatchRow row, Object value) { + public void setValueOf(DefaultWatchRow row, Object value) { setter.accept(row, value); } @Override - public boolean isEditable(WatchRow row) { + public boolean isEditable(DefaultWatchRow row) { return setter != null && (editable == null || editable.test(row)); } } protected static class WatchTableModel - extends DefaultEnumeratedColumnTableModel { + extends DefaultEnumeratedColumnTableModel { public WatchTableModel(PluginTool tool) { super(tool, "Watches", WatchTableColumns.class); } @@ -356,7 +358,7 @@ public class DebuggerWatchesProvider extends ComponentProviderAdapter protected final WatchTableModel watchTableModel; protected GhidraTable watchTable; - protected GhidraTableFilterPanel watchFilterPanel; + protected GhidraTableFilterPanel watchFilterPanel; ToggleDockingAction actionEnableEdits; DockingAction actionApplyDataType; @@ -467,7 +469,7 @@ public class DebuggerWatchesProvider extends ComponentProviderAdapter } } else if (modelCol == WatchTableColumns.REPR.ordinal()) { - Object val = row.getValueObj(); + Object val = row.getValueObject(); if (val instanceof Address) { navigateToAddress((Address) val); } @@ -806,8 +808,8 @@ public class DebuggerWatchesProvider extends ComponentProviderAdapter } @Override - public WatchRow addWatch(String expression) { - WatchRow row = new WatchRow(this, ""); + public DefaultWatchRow addWatch(String expression) { + DefaultWatchRow row = new DefaultWatchRow(this, ""); watchTableModel.add(row); row.setExpression(expression); return row; @@ -815,7 +817,7 @@ public class DebuggerWatchesProvider extends ComponentProviderAdapter @Override public void removeWatch(WatchRow row) { - watchTableModel.delete(row); + watchTableModel.delete((DefaultWatchRow) row); } @Override @@ -849,7 +851,7 @@ public class DebuggerWatchesProvider extends ComponentProviderAdapter removeOldListeners(); this.currentTrace = trace; addNewListeners(); - for (WatchRow row : watchTableModel.getModelData()) { + for (DefaultWatchRow row : watchTableModel.getModelData()) { row.updateType(); } } @@ -894,8 +896,8 @@ public class DebuggerWatchesProvider extends ComponentProviderAdapter if (asyncWatchExecutor == null) { return; } - List toReevaluate = new ArrayList<>(); - for (WatchRow row : watchTableModel.getModelData()) { + List toReevaluate = new ArrayList<>(); + for (DefaultWatchRow row : watchTableModel.getModelData()) { AddressSetView reads = row.getReads(); if (reads == null || reads.intersects(changed)) { toReevaluate.add(row); @@ -903,7 +905,7 @@ public class DebuggerWatchesProvider extends ComponentProviderAdapter } if (!toReevaluate.isEmpty()) { clearCachedState(); - for (WatchRow row : toReevaluate) { + for (DefaultWatchRow row : toReevaluate) { row.reevaluate(); } } @@ -915,17 +917,17 @@ public class DebuggerWatchesProvider extends ComponentProviderAdapter return; } clearCachedState(); - for (WatchRow row : watchTableModel.getModelData()) { + for (DefaultWatchRow row : watchTableModel.getModelData()) { row.reevaluate(); } changed.clear(); } public void writeConfigState(SaveState saveState) { - List rows = List.copyOf(watchTableModel.getModelData()); + List rows = List.copyOf(watchTableModel.getModelData()); saveState.putInt(KEY_ROW_COUNT, rows.size()); for (int i = 0; i < rows.size(); i++) { - WatchRow row = rows.get(i); + DefaultWatchRow row = rows.get(i); String stateName = PREFIX_ROW + i; SaveState rowState = new SaveState(); row.writeConfigState(rowState); @@ -935,12 +937,12 @@ public class DebuggerWatchesProvider extends ComponentProviderAdapter public void readConfigState(SaveState saveState) { int rowCount = saveState.getInt(KEY_ROW_COUNT, 0); - List rows = new ArrayList<>(); + List rows = new ArrayList<>(); for (int i = 0; i < rowCount; i++) { String stateName = PREFIX_ROW + i; Element rowElement = saveState.getXmlElement(stateName); if (rowElement != null) { - WatchRow r = new WatchRow(this, ""); + DefaultWatchRow r = new DefaultWatchRow(this, ""); SaveState rowState = new SaveState(rowElement); r.readConfigState(rowState); rows.add(r); diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/watch/WatchRow.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/watch/DefaultWatchRow.java similarity index 96% rename from Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/watch/WatchRow.java rename to Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/watch/DefaultWatchRow.java index 436536ff30..7f857534fc 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/watch/WatchRow.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/watch/DefaultWatchRow.java @@ -20,11 +20,12 @@ import java.util.*; import java.util.concurrent.CompletableFuture; import db.Transaction; -import ghidra.app.plugin.core.debug.DebuggerCoordinates; import ghidra.app.services.DataTypeManagerService; import ghidra.app.services.DebuggerControlService; import ghidra.app.services.DebuggerControlService.StateEditor; import ghidra.async.AsyncUtils; +import ghidra.debug.api.tracemgr.DebuggerCoordinates; +import ghidra.debug.api.watch.WatchRow; import ghidra.docking.settings.Settings; import ghidra.docking.settings.SettingsImpl; import ghidra.framework.options.SaveState; @@ -45,7 +46,7 @@ import ghidra.trace.model.symbol.TraceLabelSymbol; import ghidra.util.Msg; import ghidra.util.NumericUtilities; -public class WatchRow { +public class DefaultWatchRow implements WatchRow { public static final int TRUNCATE_BYTES_LENGTH = 64; private static final String KEY_EXPRESSION = "expression"; private static final String KEY_DATA_TYPE = "dataType"; @@ -70,7 +71,7 @@ public class WatchRow { private Object valueObj; private Throwable error = null; - public WatchRow(DebuggerWatchesProvider provider, String expression) { + public DefaultWatchRow(DebuggerWatchesProvider provider, String expression) { this.provider = provider; this.expression = expression; } @@ -169,6 +170,7 @@ public class WatchRow { return dataType.getValue(buffer, settings, value.length); } + @Override public void setExpression(String expression) { if (!Objects.equals(this.expression, expression)) { prevValue = null; @@ -179,6 +181,7 @@ public class WatchRow { reevaluate(); } + @Override public String getExpression() { return expression; } @@ -214,6 +217,7 @@ public class WatchRow { return typePath; } + @Override public void setDataType(DataType dataType) { if (dataType instanceof Pointer ptrType && address != null && address.isRegisterAddress()) { @@ -247,6 +251,7 @@ public class WatchRow { } } + @Override public DataType getDataType() { return dataType; } @@ -260,11 +265,13 @@ public class WatchRow { * * @return the settings */ + @Override public Settings getSettings() { return settings; } - protected void settingsChanged() { + @Override + public void settingsChanged() { if (dataType != null) { savedSettings.write(dataType.getSettingsDefinitions(), dataType.getDefaultSettings()); } @@ -272,10 +279,12 @@ public class WatchRow { provider.watchTableModel.fireTableDataChanged(); } + @Override public Address getAddress() { return address; } + @Override public AddressRange getRange() { if (address == null || value == null) { return null; @@ -291,6 +300,7 @@ public class WatchRow { } } + @Override public String getRawValueString() { if (value == null || provider.language == null) { return "??"; @@ -315,6 +325,7 @@ public class WatchRow { * * @return the reads */ + @Override public AddressSetView getReads() { return reads; } @@ -323,18 +334,22 @@ public class WatchRow { return state; } + @Override public byte[] getValue() { return value; } + @Override public String getValueString() { return valueString; } - public Object getValueObj() { + @Override + public Object getValueObject() { return valueObj; } + @Override public boolean isRawValueEditable() { if (!provider.isEditsEnabled()) { return false; @@ -350,6 +365,7 @@ public class WatchRow { return editor.isVariableEditable(address, getValueLength()); } + @Override public void setRawValueString(String valueString) { valueString = valueString.trim(); if (valueString.startsWith("{")) { @@ -405,6 +421,7 @@ public class WatchRow { }); } + @Override public void setValueString(String valueString) { if (dataType == null || value == null) { // isValueEditable should have been false @@ -422,6 +439,7 @@ public class WatchRow { } } + @Override public boolean isValueEditable() { if (!isRawValueEditable()) { return false; @@ -432,6 +450,7 @@ public class WatchRow { return dataType.isEncodable(); } + @Override public int getValueLength() { return value == null ? 0 : value.length; } @@ -475,10 +494,12 @@ public class WatchRow { return null; } + @Override public Symbol getSymbol() { return symbol; } + @Override public String getErrorMessage() { if (error == null) { return ""; @@ -490,14 +511,17 @@ public class WatchRow { return error.getClass().getSimpleName(); } + @Override public Throwable getError() { return error; } + @Override public boolean isKnown() { return state == TraceMemoryState.KNOWN; } + @Override public boolean isChanged() { if (prevValue == null) { return false; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/mapping/AbstractDebuggerPlatformMapper.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/mapping/AbstractDebuggerPlatformMapper.java index 32fcd97de4..19332dfc8b 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/mapping/AbstractDebuggerPlatformMapper.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/mapping/AbstractDebuggerPlatformMapper.java @@ -20,6 +20,8 @@ import java.util.Set; import ghidra.app.plugin.core.debug.disassemble.TraceDisassembleCommand; import ghidra.app.plugin.core.debug.workflow.DisassemblyInject; +import ghidra.debug.api.platform.DebuggerPlatformMapper; +import ghidra.debug.api.platform.DisassemblyResult; import ghidra.framework.plugintool.PluginTool; import ghidra.program.model.address.*; import ghidra.program.model.lang.*; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/mapping/DebuggerPlatformOffer.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/mapping/DebuggerPlatformOffer.java index c836929c1f..f52215fe0d 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/mapping/DebuggerPlatformOffer.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/mapping/DebuggerPlatformOffer.java @@ -15,6 +15,7 @@ */ package ghidra.app.plugin.core.debug.mapping; +import ghidra.debug.api.platform.DebuggerPlatformMapper; import ghidra.framework.plugintool.PluginTool; import ghidra.program.model.lang.*; import ghidra.program.util.DefaultLanguageService; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/mapping/DebuggerPlatformOpinion.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/mapping/DebuggerPlatformOpinion.java index 8bf311b196..d9fcb111f9 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/mapping/DebuggerPlatformOpinion.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/mapping/DebuggerPlatformOpinion.java @@ -19,6 +19,7 @@ import java.util.*; import ghidra.dbg.target.TargetEnvironment; import ghidra.dbg.util.PathPredicates; +import ghidra.debug.api.model.DebuggerMappingOpinion; import ghidra.program.model.lang.Endian; import ghidra.trace.model.Lifespan; import ghidra.trace.model.Trace; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/mapping/DefaultDebuggerMappingOffer.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/mapping/DefaultDebuggerMappingOffer.java index a7a04a4c60..760e8bfdcb 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/mapping/DefaultDebuggerMappingOffer.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/mapping/DefaultDebuggerMappingOffer.java @@ -20,6 +20,8 @@ import java.util.Set; import ghidra.dbg.target.TargetObject; import ghidra.dbg.util.PathUtils; +import ghidra.debug.api.model.DebuggerMappingOffer; +import ghidra.debug.api.model.DebuggerTargetTraceMapper; import ghidra.program.model.lang.*; public class DefaultDebuggerMappingOffer implements DebuggerMappingOffer { diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/mapping/DefaultDebuggerMemoryMapper.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/mapping/DefaultDebuggerMemoryMapper.java index 9555526385..574270ca8b 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/mapping/DefaultDebuggerMemoryMapper.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/mapping/DefaultDebuggerMemoryMapper.java @@ -16,6 +16,7 @@ package ghidra.app.plugin.core.debug.mapping; import ghidra.dbg.DebuggerObjectModel; +import ghidra.debug.api.model.DebuggerMemoryMapper; import ghidra.program.model.address.*; import ghidra.program.model.lang.Language; import ghidra.util.MathUtilities; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/mapping/DefaultDebuggerRegisterMapper.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/mapping/DefaultDebuggerRegisterMapper.java index 95ed649f58..370a043f8e 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/mapping/DefaultDebuggerRegisterMapper.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/mapping/DefaultDebuggerRegisterMapper.java @@ -17,10 +17,9 @@ package ghidra.app.plugin.core.debug.mapping; import java.util.*; -import ghidra.app.plugin.core.debug.register.RegisterTypeInfo; import ghidra.dbg.target.TargetRegister; import ghidra.dbg.target.TargetRegisterContainer; -import ghidra.program.model.data.PointerDataType; +import ghidra.debug.api.model.DebuggerRegisterMapper; import ghidra.program.model.lang.*; public class DefaultDebuggerRegisterMapper implements DebuggerRegisterMapper { @@ -33,9 +32,6 @@ public class DefaultDebuggerRegisterMapper implements DebuggerRegisterMapper { protected final Map filtLanguageRegs = new LinkedHashMap<>(); protected final Map targetRegs = new HashMap<>(); - protected final RegisterTypeInfo instrCtrTypeInfo; - protected final RegisterTypeInfo stackPtrTypeInfo; - public DefaultDebuggerRegisterMapper(CompilerSpec cSpec, TargetRegisterContainer targetRegContainer, boolean caseSensitive) { this.language = cSpec.getLanguage(); @@ -43,11 +39,6 @@ public class DefaultDebuggerRegisterMapper implements DebuggerRegisterMapper { //this.targetRegContainer = targetRegContainer; this.caseSensitive = caseSensitive; - this.instrCtrTypeInfo = new RegisterTypeInfo(PointerDataType.dataType, - PointerDataType.dataType.getDefaultSettings(), language.getDefaultSpace()); - this.stackPtrTypeInfo = new RegisterTypeInfo(PointerDataType.dataType, - PointerDataType.dataType.getDefaultSettings(), cSpec.getStackSpace()); - collectFilteredLanguageRegs(); } @@ -147,17 +138,6 @@ public class DefaultDebuggerRegisterMapper implements DebuggerRegisterMapper { return languageRegs.get(normalizeName(tReg.getIndex())); } - @Override - public RegisterTypeInfo getDefaultTypeInfo(Register register) { - if (register == language.getProgramCounter()) { - return instrCtrTypeInfo; - } - if (register == cspec.getStackPointer()) { - return stackPtrTypeInfo; - } - return null; - } - @Override public synchronized Set getRegistersOnTarget() { return Set.copyOf(languageRegs.values()); diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/mapping/DefaultDebuggerTargetTraceMapper.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/mapping/DefaultDebuggerTargetTraceMapper.java index 07231a1e32..8808d5a135 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/mapping/DefaultDebuggerTargetTraceMapper.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/mapping/DefaultDebuggerTargetTraceMapper.java @@ -19,10 +19,10 @@ import java.util.Collection; import java.util.Set; import java.util.concurrent.CompletableFuture; -import ghidra.app.plugin.core.debug.service.model.DebuggerModelServicePlugin; import ghidra.app.plugin.core.debug.service.model.DefaultTraceRecorder; -import ghidra.app.services.TraceRecorder; import ghidra.dbg.target.*; +import ghidra.debug.api.model.*; +import ghidra.framework.plugintool.PluginTool; import ghidra.program.model.lang.*; import ghidra.program.util.DefaultLanguageService; import ghidra.trace.model.Trace; @@ -97,7 +97,7 @@ public class DefaultDebuggerTargetTraceMapper implements DebuggerTargetTraceMapp } @Override - public TraceRecorder startRecording(DebuggerModelServicePlugin service, Trace trace) { - return new DefaultTraceRecorder(service, trace, target, this); + public TraceRecorder startRecording(PluginTool tool, Trace trace) { + return new DefaultTraceRecorder(tool, trace, target, this); } } diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/mapping/ObjectBasedDebuggerMappingOffer.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/mapping/ObjectBasedDebuggerMappingOffer.java index 9f875e3d05..e2ff2f0f2c 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/mapping/ObjectBasedDebuggerMappingOffer.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/mapping/ObjectBasedDebuggerMappingOffer.java @@ -18,6 +18,7 @@ package ghidra.app.plugin.core.debug.mapping; import java.util.Set; import ghidra.dbg.target.TargetObject; +import ghidra.debug.api.model.DebuggerTargetTraceMapper; import ghidra.program.model.lang.*; public class ObjectBasedDebuggerMappingOffer extends DefaultDebuggerMappingOffer { diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/mapping/ObjectBasedDebuggerMappingOpinion.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/mapping/ObjectBasedDebuggerMappingOpinion.java index 6e729e8eb7..8f2d2d4ff7 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/mapping/ObjectBasedDebuggerMappingOpinion.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/mapping/ObjectBasedDebuggerMappingOpinion.java @@ -19,6 +19,8 @@ import java.util.Set; import ghidra.dbg.target.TargetEnvironment; import ghidra.dbg.target.TargetObject; +import ghidra.debug.api.model.DebuggerMappingOffer; +import ghidra.debug.api.model.DebuggerMappingOpinion; public class ObjectBasedDebuggerMappingOpinion implements DebuggerMappingOpinion { diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/mapping/ObjectBasedDebuggerMemoryMapper.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/mapping/ObjectBasedDebuggerMemoryMapper.java index 96087f40e1..11b9ecbb30 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/mapping/ObjectBasedDebuggerMemoryMapper.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/mapping/ObjectBasedDebuggerMemoryMapper.java @@ -19,6 +19,7 @@ import java.util.HashMap; import java.util.Map; import db.Transaction; +import ghidra.debug.api.model.DebuggerMemoryMapper; import ghidra.program.model.address.*; import ghidra.trace.model.Trace; import ghidra.util.exception.DuplicateNameException; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/mapping/ObjectBasedDebuggerTargetTraceMapper.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/mapping/ObjectBasedDebuggerTargetTraceMapper.java index e0125c17c2..7b41497d9f 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/mapping/ObjectBasedDebuggerTargetTraceMapper.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/mapping/ObjectBasedDebuggerTargetTraceMapper.java @@ -17,10 +17,10 @@ package ghidra.app.plugin.core.debug.mapping; import java.util.Collection; -import ghidra.app.plugin.core.debug.service.model.DebuggerModelServicePlugin; import ghidra.app.plugin.core.debug.service.model.record.ObjectBasedTraceRecorder; -import ghidra.app.services.TraceRecorder; import ghidra.dbg.target.*; +import ghidra.debug.api.model.*; +import ghidra.framework.plugintool.PluginTool; import ghidra.program.model.lang.*; import ghidra.trace.model.Trace; @@ -47,8 +47,8 @@ public class ObjectBasedDebuggerTargetTraceMapper extends DefaultDebuggerTargetT } @Override - public TraceRecorder startRecording(DebuggerModelServicePlugin service, Trace trace) { + public TraceRecorder startRecording(PluginTool tool, Trace trace) { this.memoryMapper = new ObjectBasedDebuggerMemoryMapper(trace); - return new ObjectBasedTraceRecorder(service, trace, target, this); + return new ObjectBasedTraceRecorder(tool, trace, target, this); } } diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/mapping/legacy/LegacyDebuggerPlatformOpinion.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/mapping/legacy/LegacyDebuggerPlatformOpinion.java index bd9481fba6..bcdcdd2bfc 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/mapping/legacy/LegacyDebuggerPlatformOpinion.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/mapping/legacy/LegacyDebuggerPlatformOpinion.java @@ -20,6 +20,7 @@ import java.util.stream.Collectors; import ghidra.app.plugin.core.debug.mapping.*; import ghidra.app.plugin.core.debug.workflow.DisassemblyInject; +import ghidra.debug.api.platform.DebuggerPlatformMapper; import ghidra.framework.plugintool.PluginTool; import ghidra.lifecycle.Transitional; import ghidra.program.model.lang.CompilerSpec; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/platform/OverrideDebuggerPlatformOpinion.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/platform/OverrideDebuggerPlatformOpinion.java index a5eb05c5a3..a1eacb6f4c 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/platform/OverrideDebuggerPlatformOpinion.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/platform/OverrideDebuggerPlatformOpinion.java @@ -19,6 +19,7 @@ import java.util.*; import java.util.stream.Collectors; import ghidra.app.plugin.core.debug.mapping.*; +import ghidra.debug.api.platform.DebuggerPlatformMapper; import ghidra.framework.plugintool.PluginTool; import ghidra.program.model.lang.*; import ghidra.program.util.DefaultLanguageService; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/platform/OverridesDebuggerMappingOpinion.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/platform/OverridesDebuggerMappingOpinion.java index b878513a7c..c5e4892944 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/platform/OverridesDebuggerMappingOpinion.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/platform/OverridesDebuggerMappingOpinion.java @@ -21,6 +21,8 @@ import java.util.stream.Collectors; import ghidra.app.plugin.core.debug.mapping.*; import ghidra.dbg.target.TargetEnvironment; import ghidra.dbg.target.TargetObject; +import ghidra.debug.api.model.DebuggerMappingOffer; +import ghidra.debug.api.model.DebuggerMappingOpinion; import ghidra.program.model.lang.*; import ghidra.program.util.DefaultLanguageService; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/platform/dbgeng/DbgDebuggerProgramLaunchOpinion.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/platform/dbgeng/DbgDebuggerProgramLaunchOpinion.java index 19920d9d1d..c0bf45a179 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/platform/dbgeng/DbgDebuggerProgramLaunchOpinion.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/platform/dbgeng/DbgDebuggerProgramLaunchOpinion.java @@ -21,6 +21,7 @@ import java.util.List; import ghidra.app.plugin.core.debug.service.model.launch.*; import ghidra.dbg.DebuggerModelFactory; import ghidra.dbg.util.PathUtils; +import ghidra.debug.api.model.DebuggerProgramLaunchOffer; import ghidra.framework.plugintool.PluginTool; import ghidra.program.model.listing.Program; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/platform/dbgeng/DbgengDebuggerPlatformOpinion.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/platform/dbgeng/DbgengDebuggerPlatformOpinion.java index 95b4dc606e..8135cc7dbf 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/platform/dbgeng/DbgengDebuggerPlatformOpinion.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/platform/dbgeng/DbgengDebuggerPlatformOpinion.java @@ -20,6 +20,7 @@ import java.util.Set; import ghidra.app.plugin.core.debug.mapping.*; import ghidra.app.plugin.core.debug.workflow.DisassemblyInject; +import ghidra.debug.api.platform.DebuggerPlatformMapper; import ghidra.framework.plugintool.PluginTool; import ghidra.program.model.lang.*; import ghidra.trace.model.Trace; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/platform/dbgeng/DbgengX64DebuggerMappingOpinion.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/platform/dbgeng/DbgengX64DebuggerMappingOpinion.java index a0d58a095c..81ca4f020b 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/platform/dbgeng/DbgengX64DebuggerMappingOpinion.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/platform/dbgeng/DbgengX64DebuggerMappingOpinion.java @@ -20,6 +20,7 @@ import java.util.Set; import ghidra.app.plugin.core.debug.mapping.*; import ghidra.dbg.target.*; +import ghidra.debug.api.model.*; import ghidra.program.model.lang.*; public class DbgengX64DebuggerMappingOpinion implements DebuggerMappingOpinion { diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/platform/dbgeng/DbgengX64DisassemblyInject.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/platform/dbgeng/DbgengX64DisassemblyInject.java index 918e2a657b..6fee5eb1e8 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/platform/dbgeng/DbgengX64DisassemblyInject.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/platform/dbgeng/DbgengX64DisassemblyInject.java @@ -26,11 +26,11 @@ import ghidra.app.plugin.core.debug.disassemble.TraceDisassembleCommand; import ghidra.app.plugin.core.debug.workflow.DisassemblyInject; import ghidra.app.plugin.core.debug.workflow.DisassemblyInjectInfo; import ghidra.app.services.DebuggerModelService; -import ghidra.app.services.TraceRecorder; import ghidra.app.util.bin.ByteProvider; import ghidra.app.util.bin.MemBufferByteProvider; import ghidra.app.util.bin.format.pe.*; import ghidra.app.util.bin.format.pe.PortableExecutable.SectionLayout; +import ghidra.debug.api.model.TraceRecorder; import ghidra.framework.plugintool.PluginTool; import ghidra.program.model.address.*; import ghidra.program.model.lang.*; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/platform/frida/FridaArmDebuggerMappingOpinion.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/platform/frida/FridaArmDebuggerMappingOpinion.java index d4bff8ee9c..c7aaaf5f1f 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/platform/frida/FridaArmDebuggerMappingOpinion.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/platform/frida/FridaArmDebuggerMappingOpinion.java @@ -19,6 +19,8 @@ import java.util.Set; import ghidra.app.plugin.core.debug.mapping.*; import ghidra.dbg.target.*; +import ghidra.debug.api.model.DebuggerMappingOffer; +import ghidra.debug.api.model.DebuggerMappingOpinion; import ghidra.program.model.lang.*; import ghidra.util.Msg; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/platform/frida/FridaDebuggerPlatformOpinion.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/platform/frida/FridaDebuggerPlatformOpinion.java index 08db7f4cba..ec37ed0102 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/platform/frida/FridaDebuggerPlatformOpinion.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/platform/frida/FridaDebuggerPlatformOpinion.java @@ -18,6 +18,7 @@ package ghidra.app.plugin.core.debug.platform.frida; import java.util.Set; import ghidra.app.plugin.core.debug.mapping.*; +import ghidra.debug.api.platform.DebuggerPlatformMapper; import ghidra.framework.plugintool.PluginTool; import ghidra.program.model.lang.*; import ghidra.trace.model.Trace; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/platform/frida/FridaDebuggerProgramLaunchOpinion.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/platform/frida/FridaDebuggerProgramLaunchOpinion.java index ee23cdfeec..8b75e53ae4 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/platform/frida/FridaDebuggerProgramLaunchOpinion.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/platform/frida/FridaDebuggerProgramLaunchOpinion.java @@ -21,6 +21,7 @@ import java.util.List; import ghidra.app.plugin.core.debug.service.model.launch.*; import ghidra.dbg.DebuggerModelFactory; import ghidra.dbg.util.PathUtils; +import ghidra.debug.api.model.DebuggerProgramLaunchOffer; import ghidra.framework.plugintool.PluginTool; import ghidra.program.model.listing.Program; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/platform/frida/FridaX86DebuggerMappingOpinion.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/platform/frida/FridaX86DebuggerMappingOpinion.java index 5807ab8228..98c652b41b 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/platform/frida/FridaX86DebuggerMappingOpinion.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/platform/frida/FridaX86DebuggerMappingOpinion.java @@ -19,6 +19,8 @@ import java.util.Set; import ghidra.app.plugin.core.debug.mapping.*; import ghidra.dbg.target.*; +import ghidra.debug.api.model.DebuggerMappingOffer; +import ghidra.debug.api.model.DebuggerMappingOpinion; import ghidra.program.model.lang.CompilerSpecID; import ghidra.program.model.lang.LanguageID; import ghidra.util.Msg; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/platform/gdb/DefaultGdbDebuggerMappingOpinion.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/platform/gdb/DefaultGdbDebuggerMappingOpinion.java index cb5525ff41..e49031d8db 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/platform/gdb/DefaultGdbDebuggerMappingOpinion.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/platform/gdb/DefaultGdbDebuggerMappingOpinion.java @@ -23,6 +23,8 @@ import org.apache.commons.lang3.tuple.Pair; import ghidra.app.plugin.core.debug.mapping.*; import ghidra.dbg.target.TargetEnvironment; import ghidra.dbg.target.TargetObject; +import ghidra.debug.api.model.DebuggerMappingOffer; +import ghidra.debug.api.model.DebuggerMappingOpinion; import ghidra.program.model.lang.*; import ghidra.program.util.DefaultLanguageService; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/platform/gdb/GdbArmDebuggerMappingOpinion.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/platform/gdb/GdbArmDebuggerMappingOpinion.java index 66090dbb93..c15085cd85 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/platform/gdb/GdbArmDebuggerMappingOpinion.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/platform/gdb/GdbArmDebuggerMappingOpinion.java @@ -18,8 +18,8 @@ package ghidra.app.plugin.core.debug.platform.gdb; import java.util.Collection; import java.util.Set; -import ghidra.app.plugin.core.debug.mapping.DebuggerMappingOffer; import ghidra.dbg.target.TargetObject; +import ghidra.debug.api.model.DebuggerMappingOffer; import ghidra.program.model.lang.*; import ghidra.program.util.DefaultLanguageService; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/platform/gdb/GdbDebuggerPlatformOpinion.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/platform/gdb/GdbDebuggerPlatformOpinion.java index 842dfa338f..eb61acf5d7 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/platform/gdb/GdbDebuggerPlatformOpinion.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/platform/gdb/GdbDebuggerPlatformOpinion.java @@ -21,6 +21,7 @@ import java.util.stream.Collectors; import org.apache.commons.lang3.tuple.Pair; import ghidra.app.plugin.core.debug.mapping.*; +import ghidra.debug.api.platform.DebuggerPlatformMapper; import ghidra.framework.plugintool.PluginTool; import ghidra.program.model.lang.*; import ghidra.program.util.DefaultLanguageService; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/platform/gdb/GdbDebuggerProgramLaunchOpinion.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/platform/gdb/GdbDebuggerProgramLaunchOpinion.java index 1aeb16fe98..ef2c1a1acb 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/platform/gdb/GdbDebuggerProgramLaunchOpinion.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/platform/gdb/GdbDebuggerProgramLaunchOpinion.java @@ -20,6 +20,7 @@ import java.util.*; import ghidra.app.plugin.core.debug.service.model.launch.*; import ghidra.dbg.DebuggerModelFactory; import ghidra.dbg.util.ConfigurableFactory.Property; +import ghidra.debug.api.model.DebuggerProgramLaunchOffer; import ghidra.dbg.util.PathUtils; import ghidra.framework.plugintool.PluginTool; import ghidra.program.model.listing.Program; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/platform/gdb/GdbM68kDebuggerMappingOpinion.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/platform/gdb/GdbM68kDebuggerMappingOpinion.java index 5977d23864..29e9326d85 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/platform/gdb/GdbM68kDebuggerMappingOpinion.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/platform/gdb/GdbM68kDebuggerMappingOpinion.java @@ -19,6 +19,8 @@ import java.util.Set; import ghidra.app.plugin.core.debug.mapping.*; import ghidra.dbg.target.*; +import ghidra.debug.api.model.DebuggerMappingOffer; +import ghidra.debug.api.model.DebuggerMappingOpinion; import ghidra.program.model.lang.CompilerSpecID; import ghidra.program.model.lang.LanguageID; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/platform/gdb/GdbMipsDebuggerMappingOpinion.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/platform/gdb/GdbMipsDebuggerMappingOpinion.java index b6d32009a9..97055dcd70 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/platform/gdb/GdbMipsDebuggerMappingOpinion.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/platform/gdb/GdbMipsDebuggerMappingOpinion.java @@ -19,6 +19,8 @@ import java.util.Set; import ghidra.app.plugin.core.debug.mapping.*; import ghidra.dbg.target.*; +import ghidra.debug.api.model.DebuggerMappingOffer; +import ghidra.debug.api.model.DebuggerMappingOpinion; import ghidra.program.model.lang.CompilerSpecID; import ghidra.program.model.lang.LanguageID; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/platform/gdb/GdbPowerPCDebuggerMappingOpinion.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/platform/gdb/GdbPowerPCDebuggerMappingOpinion.java index 6592c98f1b..b734bc60a5 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/platform/gdb/GdbPowerPCDebuggerMappingOpinion.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/platform/gdb/GdbPowerPCDebuggerMappingOpinion.java @@ -19,6 +19,8 @@ import java.util.Set; import ghidra.app.plugin.core.debug.mapping.*; import ghidra.dbg.target.*; +import ghidra.debug.api.model.DebuggerMappingOffer; +import ghidra.debug.api.model.DebuggerMappingOpinion; import ghidra.program.model.lang.CompilerSpecID; import ghidra.program.model.lang.LanguageID; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/platform/gdb/GdbX86DebuggerMappingOpinion.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/platform/gdb/GdbX86DebuggerMappingOpinion.java index 6c28faceba..95569e7b22 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/platform/gdb/GdbX86DebuggerMappingOpinion.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/platform/gdb/GdbX86DebuggerMappingOpinion.java @@ -20,6 +20,7 @@ import java.util.Set; import ghidra.app.plugin.core.debug.mapping.*; import ghidra.dbg.target.*; +import ghidra.debug.api.model.*; import ghidra.program.model.lang.*; import ghidra.util.Msg; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/platform/jdi/JdiDalvikDebuggerMappingOpinion.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/platform/jdi/JdiDalvikDebuggerMappingOpinion.java index 9ed15f80ee..7baaf694b5 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/platform/jdi/JdiDalvikDebuggerMappingOpinion.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/platform/jdi/JdiDalvikDebuggerMappingOpinion.java @@ -20,6 +20,7 @@ import java.util.Set; import ghidra.app.plugin.core.debug.mapping.*; import ghidra.dbg.target.*; +import ghidra.debug.api.model.*; import ghidra.program.model.lang.*; public class JdiDalvikDebuggerMappingOpinion implements DebuggerMappingOpinion { diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/platform/jdi/JdiDebuggerPlatformOpinion.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/platform/jdi/JdiDebuggerPlatformOpinion.java index a2fc91c6a6..f31600b506 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/platform/jdi/JdiDebuggerPlatformOpinion.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/platform/jdi/JdiDebuggerPlatformOpinion.java @@ -18,6 +18,7 @@ package ghidra.app.plugin.core.debug.platform.jdi; import java.util.Set; import ghidra.app.plugin.core.debug.mapping.*; +import ghidra.debug.api.platform.DebuggerPlatformMapper; import ghidra.framework.plugintool.PluginTool; import ghidra.program.model.lang.*; import ghidra.trace.model.Trace; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/platform/jdi/JdiJvmDebuggerMappingOpinion.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/platform/jdi/JdiJvmDebuggerMappingOpinion.java index 08449559e3..3db516abff 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/platform/jdi/JdiJvmDebuggerMappingOpinion.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/platform/jdi/JdiJvmDebuggerMappingOpinion.java @@ -20,6 +20,7 @@ import java.util.Set; import ghidra.app.plugin.core.debug.mapping.*; import ghidra.dbg.target.*; +import ghidra.debug.api.model.*; import ghidra.program.model.lang.*; public class JdiJvmDebuggerMappingOpinion implements DebuggerMappingOpinion { diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/platform/lldb/LldbArmDebuggerMappingOpinion.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/platform/lldb/LldbArmDebuggerMappingOpinion.java index 23545ab032..63eb512829 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/platform/lldb/LldbArmDebuggerMappingOpinion.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/platform/lldb/LldbArmDebuggerMappingOpinion.java @@ -19,6 +19,8 @@ import java.util.Set; import ghidra.app.plugin.core.debug.mapping.*; import ghidra.dbg.target.*; +import ghidra.debug.api.model.DebuggerMappingOffer; +import ghidra.debug.api.model.DebuggerMappingOpinion; import ghidra.program.model.lang.*; import ghidra.util.Msg; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/platform/lldb/LldbDebuggerPlatformOpinion.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/platform/lldb/LldbDebuggerPlatformOpinion.java index 56d6b559e6..5d5bfe00e2 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/platform/lldb/LldbDebuggerPlatformOpinion.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/platform/lldb/LldbDebuggerPlatformOpinion.java @@ -18,6 +18,7 @@ package ghidra.app.plugin.core.debug.platform.lldb; import java.util.Set; import ghidra.app.plugin.core.debug.mapping.*; +import ghidra.debug.api.platform.DebuggerPlatformMapper; import ghidra.framework.plugintool.PluginTool; import ghidra.program.model.lang.*; import ghidra.trace.model.Trace; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/platform/lldb/LldbDebuggerProgramLaunchOpinion.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/platform/lldb/LldbDebuggerProgramLaunchOpinion.java index eda5389e89..82a7480a89 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/platform/lldb/LldbDebuggerProgramLaunchOpinion.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/platform/lldb/LldbDebuggerProgramLaunchOpinion.java @@ -21,6 +21,7 @@ import java.util.List; import ghidra.app.plugin.core.debug.service.model.launch.*; import ghidra.dbg.DebuggerModelFactory; import ghidra.dbg.util.PathUtils; +import ghidra.debug.api.model.DebuggerProgramLaunchOffer; import ghidra.framework.plugintool.PluginTool; import ghidra.program.model.listing.Program; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/platform/lldb/LldbX86DebuggerMappingOpinion.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/platform/lldb/LldbX86DebuggerMappingOpinion.java index 463610d14e..ab4ac525ae 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/platform/lldb/LldbX86DebuggerMappingOpinion.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/platform/lldb/LldbX86DebuggerMappingOpinion.java @@ -19,6 +19,8 @@ import java.util.Set; import ghidra.app.plugin.core.debug.mapping.*; import ghidra.dbg.target.*; +import ghidra.debug.api.model.DebuggerMappingOffer; +import ghidra.debug.api.model.DebuggerMappingOpinion; import ghidra.program.model.lang.CompilerSpecID; import ghidra.program.model.lang.LanguageID; import ghidra.util.Msg; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/register/RegisterTypeInfo.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/register/RegisterTypeInfo.java deleted file mode 100644 index 8b583eba5e..0000000000 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/register/RegisterTypeInfo.java +++ /dev/null @@ -1,40 +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.app.plugin.core.debug.register; - -import ghidra.docking.settings.Settings; -import ghidra.program.model.address.AddressSpace; -import ghidra.program.model.data.DataType; - -public class RegisterTypeInfo { - public final DataType type; - public final Settings settings; - public final AddressSpace pointerSpace; - - public RegisterTypeInfo(DataType type, AddressSpace pointerSpace) { - this(type, type.getDefaultSettings(), pointerSpace); - } - - public RegisterTypeInfo(DataType type, Settings settings, AddressSpace pointerSpace) { - this.type = type; - this.settings = settings; - this.pointerSpace = pointerSpace; - } - - public Class getValueClass() { - return type.getValueClass(settings); - } -} diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/breakpoint/DebuggerLogicalBreakpointServicePlugin.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/breakpoint/DebuggerLogicalBreakpointServicePlugin.java index 5a9f934331..bb686870ed 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/breakpoint/DebuggerLogicalBreakpointServicePlugin.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/breakpoint/DebuggerLogicalBreakpointServicePlugin.java @@ -27,16 +27,21 @@ import generic.CatenatedCollection; import ghidra.app.events.ProgramClosedPluginEvent; import ghidra.app.events.ProgramOpenedPluginEvent; import ghidra.app.plugin.PluginCategoryNames; -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.DebuggerControlService.ControlModeChangeListener; -import ghidra.app.services.LogicalBreakpoint.State; import ghidra.async.SwingExecutorService; import ghidra.dbg.target.TargetBreakpointLocation; import ghidra.dbg.target.TargetObject; import ghidra.dbg.util.PathUtils; +import ghidra.debug.api.breakpoint.LogicalBreakpoint; +import ghidra.debug.api.breakpoint.LogicalBreakpoint.State; +import ghidra.debug.api.breakpoint.LogicalBreakpointsChangeListener; +import ghidra.debug.api.control.ControlMode; +import ghidra.debug.api.model.TraceRecorder; +import ghidra.debug.api.modules.DebuggerStaticMappingChangeListener; +import ghidra.debug.api.tracemgr.DebuggerCoordinates; import ghidra.framework.model.*; import ghidra.framework.plugintool.*; import ghidra.framework.plugintool.annotation.AutoServiceConsumed; @@ -320,8 +325,8 @@ public class DebuggerLogicalBreakpointServicePlugin extends Plugin ProgramChangeRecord pcrec = (ProgramChangeRecord) rec; // Eww Bookmark pb = (Bookmark) pcrec.getObject(); // So gross String bmType = pb.getTypeString(); - if (LogicalBreakpoint.BREAKPOINT_ENABLED_BOOKMARK_TYPE.equals(bmType) || - LogicalBreakpoint.BREAKPOINT_DISABLED_BOOKMARK_TYPE.equals(bmType)) { + if (LogicalBreakpoint.ENABLED_BOOKMARK_TYPE.equals(bmType) || + LogicalBreakpoint.DISABLED_BOOKMARK_TYPE.equals(bmType)) { handler.accept(pb); } }; @@ -582,8 +587,12 @@ public class DebuggerLogicalBreakpointServicePlugin extends Plugin */ return null; } + Address minAddress = tb.getMinAddress(); + if (minAddress == null) { + return null; + } return mappingService.getOpenMappedLocation( - new DefaultTraceLocation(trace, null, Lifespan.at(snap), tb.getMinAddress())); + new DefaultTraceLocation(trace, null, Lifespan.at(snap), minAddress)); } protected void trackTraceBreakpoint(AddCollector a, TraceBreakpoint tb, @@ -719,10 +728,10 @@ public class DebuggerLogicalBreakpointServicePlugin extends Plugin protected void forgetAllBreakpoints(RemoveCollector r) { Collection marks = new ArrayList<>(); program.getBookmarkManager() - .getBookmarksIterator(LogicalBreakpoint.BREAKPOINT_ENABLED_BOOKMARK_TYPE) + .getBookmarksIterator(LogicalBreakpoint.ENABLED_BOOKMARK_TYPE) .forEachRemaining(marks::add); program.getBookmarkManager() - .getBookmarksIterator(LogicalBreakpoint.BREAKPOINT_DISABLED_BOOKMARK_TYPE) + .getBookmarksIterator(LogicalBreakpoint.DISABLED_BOOKMARK_TYPE) .forEachRemaining(marks::add); for (Bookmark pb : marks) { forgetProgramBreakpoint(r, pb, false); @@ -759,9 +768,9 @@ public class DebuggerLogicalBreakpointServicePlugin extends Plugin protected void trackAllProgramBreakpoints(AddCollector a) { BookmarkManager bookmarks = program.getBookmarkManager(); trackProgramBreakpoints(a, IteratorUtils.asIterable(bookmarks - .getBookmarksIterator(LogicalBreakpoint.BREAKPOINT_ENABLED_BOOKMARK_TYPE))); + .getBookmarksIterator(LogicalBreakpoint.ENABLED_BOOKMARK_TYPE))); trackProgramBreakpoints(a, IteratorUtils.asIterable(bookmarks - .getBookmarksIterator(LogicalBreakpoint.BREAKPOINT_DISABLED_BOOKMARK_TYPE))); + .getBookmarksIterator(LogicalBreakpoint.DISABLED_BOOKMARK_TYPE))); } protected void trackProgramBreakpoints(AddCollector a, Iterable bptMarks) { diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/breakpoint/LogicalBreakpointInternal.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/breakpoint/LogicalBreakpointInternal.java index 121288fcef..a54dc239b2 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/breakpoint/LogicalBreakpointInternal.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/breakpoint/LogicalBreakpointInternal.java @@ -15,8 +15,8 @@ */ package ghidra.app.plugin.core.debug.service.breakpoint; -import ghidra.app.services.LogicalBreakpoint; -import ghidra.app.services.TraceRecorder; +import ghidra.debug.api.breakpoint.LogicalBreakpoint; +import ghidra.debug.api.model.TraceRecorder; import ghidra.program.model.address.Address; import ghidra.program.model.listing.*; import ghidra.trace.model.Trace; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/breakpoint/LoneLogicalBreakpoint.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/breakpoint/LoneLogicalBreakpoint.java index b3f2d1205f..e25b456609 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/breakpoint/LoneLogicalBreakpoint.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/breakpoint/LoneLogicalBreakpoint.java @@ -18,8 +18,8 @@ package ghidra.app.plugin.core.debug.service.breakpoint; import java.util.*; import java.util.concurrent.CompletableFuture; -import ghidra.app.services.TraceRecorder; import ghidra.async.AsyncUtils; +import ghidra.debug.api.model.TraceRecorder; import ghidra.framework.model.DomainObject; import ghidra.framework.plugintool.PluginTool; import ghidra.program.model.address.Address; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/breakpoint/MappedLogicalBreakpoint.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/breakpoint/MappedLogicalBreakpoint.java index 34f4ef5c33..3ad7a1cd93 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/breakpoint/MappedLogicalBreakpoint.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/breakpoint/MappedLogicalBreakpoint.java @@ -19,8 +19,8 @@ import java.util.*; import java.util.concurrent.CompletableFuture; import ghidra.app.services.DebuggerModelService; -import ghidra.app.services.TraceRecorder; import ghidra.async.AsyncUtils; +import ghidra.debug.api.model.TraceRecorder; import ghidra.framework.model.DomainObject; import ghidra.framework.plugintool.PluginTool; import ghidra.pcode.exec.SleighUtils; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/breakpoint/ProgramBreakpoint.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/breakpoint/ProgramBreakpoint.java index 0f243790b6..2557d78e07 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/breakpoint/ProgramBreakpoint.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/breakpoint/ProgramBreakpoint.java @@ -20,8 +20,8 @@ import java.util.*; import com.google.gson.*; import db.Transaction; -import ghidra.app.services.LogicalBreakpoint; -import ghidra.app.services.LogicalBreakpoint.ProgramMode; +import ghidra.debug.api.breakpoint.LogicalBreakpoint; +import ghidra.debug.api.breakpoint.LogicalBreakpoint.ProgramMode; import ghidra.program.model.address.Address; import ghidra.program.model.address.AddressSet; import ghidra.program.model.listing.*; @@ -353,8 +353,7 @@ public class ProgramBreakpoint { * @return true if this changed the breakpoint state */ public boolean add(Bookmark bookmark) { - if (LogicalBreakpointInternal.BREAKPOINT_ENABLED_BOOKMARK_TYPE - .equals(bookmark.getTypeString())) { + if (LogicalBreakpoint.ENABLED_BOOKMARK_TYPE.equals(bookmark.getTypeString())) { if (eBookmark == bookmark) { return false; } @@ -362,8 +361,7 @@ public class ProgramBreakpoint { syncProperties(bookmark); return true; } - if (LogicalBreakpointInternal.BREAKPOINT_DISABLED_BOOKMARK_TYPE - .equals(bookmark.getTypeString())) { + if (LogicalBreakpoint.DISABLED_BOOKMARK_TYPE.equals(bookmark.getTypeString())) { if (dBookmark == bookmark) { return false; } @@ -452,11 +450,11 @@ public class ProgramBreakpoint { */ public void toggleWithComment(boolean enabled, String comment) { String addType = - enabled ? LogicalBreakpoint.BREAKPOINT_ENABLED_BOOKMARK_TYPE - : LogicalBreakpoint.BREAKPOINT_DISABLED_BOOKMARK_TYPE; + enabled ? LogicalBreakpoint.ENABLED_BOOKMARK_TYPE + : LogicalBreakpoint.DISABLED_BOOKMARK_TYPE; String delType = - enabled ? LogicalBreakpoint.BREAKPOINT_DISABLED_BOOKMARK_TYPE - : LogicalBreakpoint.BREAKPOINT_ENABLED_BOOKMARK_TYPE; + enabled ? LogicalBreakpoint.DISABLED_BOOKMARK_TYPE + : LogicalBreakpoint.ENABLED_BOOKMARK_TYPE; try (Transaction tx = program.openTransaction("Toggle breakpoint")) { BookmarkManager manager = program.getBookmarkManager(); String catStr = computeCategory(); diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/breakpoint/TraceBreakpointSet.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/breakpoint/TraceBreakpointSet.java index bf3cbdc12f..6717e23027 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/breakpoint/TraceBreakpointSet.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/breakpoint/TraceBreakpointSet.java @@ -20,9 +20,11 @@ import java.util.stream.Collectors; import db.Transaction; import ghidra.app.services.*; -import ghidra.app.services.LogicalBreakpoint.TraceMode; import ghidra.dbg.target.*; import ghidra.dbg.target.TargetBreakpointSpec.TargetBreakpointKind; +import ghidra.debug.api.breakpoint.LogicalBreakpoint.TraceMode; +import ghidra.debug.api.control.ControlMode; +import ghidra.debug.api.model.TraceRecorder; import ghidra.framework.plugintool.PluginTool; import ghidra.pcode.exec.SleighUtils; import ghidra.program.model.address.Address; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/control/DebuggerControlServicePlugin.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/control/DebuggerControlServicePlugin.java index 790943238c..9c04e11d7c 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/control/DebuggerControlServicePlugin.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/control/DebuggerControlServicePlugin.java @@ -24,6 +24,8 @@ import ghidra.app.plugin.core.debug.*; import ghidra.app.plugin.core.debug.event.*; import ghidra.app.services.*; import ghidra.app.services.DebuggerTraceManagerService.ActivationCause; +import ghidra.debug.api.control.ControlMode; +import ghidra.debug.api.tracemgr.DebuggerCoordinates; import ghidra.framework.plugintool.*; import ghidra.framework.plugintool.annotation.AutoServiceConsumed; import ghidra.framework.plugintool.util.PluginStatus; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/emulation/AbstractDebuggerPcodeEmulatorFactory.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/emulation/AbstractDebuggerPcodeEmulatorFactory.java new file mode 100644 index 0000000000..d76bfcfc19 --- /dev/null +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/emulation/AbstractDebuggerPcodeEmulatorFactory.java @@ -0,0 +1,31 @@ +/* ### + * IP: GHIDRA + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ghidra.app.plugin.core.debug.service.emulation; + +import ghidra.app.plugin.core.debug.service.emulation.data.DefaultPcodeDebuggerAccess; +import ghidra.debug.api.emulation.DebuggerPcodeEmulatorFactory; +import ghidra.debug.api.emulation.DebuggerPcodeMachine; +import ghidra.debug.api.model.TraceRecorder; +import ghidra.framework.plugintool.PluginTool; +import ghidra.trace.model.guest.TracePlatform; + +public abstract class AbstractDebuggerPcodeEmulatorFactory implements DebuggerPcodeEmulatorFactory { + @Override + public DebuggerPcodeMachine create(PluginTool tool, TracePlatform platform, long snap, + TraceRecorder recorder) { + return create(new DefaultPcodeDebuggerAccess(tool, recorder, platform, snap)); + } +} diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/emulation/AbstractRWTargetPcodeExecutorStatePiece.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/emulation/AbstractRWTargetPcodeExecutorStatePiece.java index 463d0c3eaf..42975795ec 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/emulation/AbstractRWTargetPcodeExecutorStatePiece.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/emulation/AbstractRWTargetPcodeExecutorStatePiece.java @@ -19,7 +19,7 @@ import java.util.Map; import java.util.concurrent.*; import generic.ULongSpan.ULongSpanSet; -import ghidra.app.plugin.core.debug.service.emulation.data.PcodeDebuggerDataAccess; +import ghidra.debug.api.emulation.PcodeDebuggerDataAccess; import ghidra.generic.util.datastruct.SemisparseByteArray; import ghidra.pcode.exec.AccessPcodeExecutionException; import ghidra.pcode.exec.trace.BytesTracePcodeExecutorStatePiece; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/emulation/BytesDebuggerPcodeEmulator.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/emulation/BytesDebuggerPcodeEmulator.java index 52dcdbeb50..ca5c6681fb 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/emulation/BytesDebuggerPcodeEmulator.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/emulation/BytesDebuggerPcodeEmulator.java @@ -16,6 +16,8 @@ package ghidra.app.plugin.core.debug.service.emulation; import ghidra.app.plugin.core.debug.service.emulation.data.*; +import ghidra.debug.api.emulation.DebuggerPcodeMachine; +import ghidra.debug.api.emulation.PcodeDebuggerAccess; import ghidra.pcode.emu.PcodeEmulator; import ghidra.pcode.emu.PcodeThread; import ghidra.pcode.exec.trace.BytesTracePcodeEmulator; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/emulation/BytesDebuggerPcodeEmulatorFactory.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/emulation/BytesDebuggerPcodeEmulatorFactory.java index c2b68ddcfd..e18a9a1cdf 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/emulation/BytesDebuggerPcodeEmulatorFactory.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/emulation/BytesDebuggerPcodeEmulatorFactory.java @@ -15,12 +15,13 @@ */ package ghidra.app.plugin.core.debug.service.emulation; -import ghidra.app.plugin.core.debug.service.emulation.data.PcodeDebuggerAccess; +import ghidra.debug.api.emulation.DebuggerPcodeMachine; +import ghidra.debug.api.emulation.PcodeDebuggerAccess; /** * The Debugger's default emulator factory */ -public class BytesDebuggerPcodeEmulatorFactory implements DebuggerPcodeEmulatorFactory { +public class BytesDebuggerPcodeEmulatorFactory extends AbstractDebuggerPcodeEmulatorFactory { // TODO: Config options: // 1) userop library diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/emulation/DebuggerEmulationServicePlugin.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/emulation/DebuggerEmulationServicePlugin.java index 0c2c99a873..e7da93cf71 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/emulation/DebuggerEmulationServicePlugin.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/emulation/DebuggerEmulationServicePlugin.java @@ -37,12 +37,15 @@ import ghidra.app.context.ProgramLocationActionContext; import ghidra.app.events.ProgramActivatedPluginEvent; import ghidra.app.events.ProgramClosedPluginEvent; import ghidra.app.plugin.PluginCategoryNames; -import ghidra.app.plugin.core.debug.DebuggerCoordinates; import ghidra.app.plugin.core.debug.DebuggerPluginPackage; import ghidra.app.plugin.core.debug.event.TraceClosedPluginEvent; import ghidra.app.plugin.core.debug.gui.DebuggerResources; import ghidra.app.services.*; import ghidra.async.AsyncLazyMap; +import ghidra.debug.api.control.ControlMode; +import ghidra.debug.api.emulation.DebuggerPcodeEmulatorFactory; +import ghidra.debug.api.emulation.DebuggerPcodeMachine; +import ghidra.debug.api.tracemgr.DebuggerCoordinates; import ghidra.framework.plugintool.*; import ghidra.framework.plugintool.annotation.AutoServiceConsumed; import ghidra.framework.plugintool.util.PluginStatus; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/emulation/RWTargetMemoryPcodeExecutorState.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/emulation/RWTargetMemoryPcodeExecutorState.java index 85fb25c77b..2a111a5a1d 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/emulation/RWTargetMemoryPcodeExecutorState.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/emulation/RWTargetMemoryPcodeExecutorState.java @@ -15,7 +15,7 @@ */ package ghidra.app.plugin.core.debug.service.emulation; -import ghidra.app.plugin.core.debug.service.emulation.data.PcodeDebuggerMemoryAccess; +import ghidra.debug.api.emulation.PcodeDebuggerMemoryAccess; import ghidra.pcode.exec.trace.*; /** diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/emulation/RWTargetMemoryPcodeExecutorStatePiece.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/emulation/RWTargetMemoryPcodeExecutorStatePiece.java index b7c20a682b..a6f84bee78 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/emulation/RWTargetMemoryPcodeExecutorStatePiece.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/emulation/RWTargetMemoryPcodeExecutorStatePiece.java @@ -20,8 +20,8 @@ import java.util.concurrent.CompletableFuture; import generic.ULongSpan; import generic.ULongSpan.ULongSpanSet; -import ghidra.app.plugin.core.debug.service.emulation.data.PcodeDebuggerDataAccess; -import ghidra.app.plugin.core.debug.service.emulation.data.PcodeDebuggerMemoryAccess; +import ghidra.debug.api.emulation.PcodeDebuggerDataAccess; +import ghidra.debug.api.emulation.PcodeDebuggerMemoryAccess; import ghidra.generic.util.datastruct.SemisparseByteArray; import ghidra.program.model.address.*; import ghidra.program.model.lang.Language; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/emulation/RWTargetRegistersPcodeExecutorState.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/emulation/RWTargetRegistersPcodeExecutorState.java index 46a7f40ea7..14f00dd88d 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/emulation/RWTargetRegistersPcodeExecutorState.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/emulation/RWTargetRegistersPcodeExecutorState.java @@ -15,7 +15,7 @@ */ package ghidra.app.plugin.core.debug.service.emulation; -import ghidra.app.plugin.core.debug.service.emulation.data.PcodeDebuggerRegistersAccess; +import ghidra.debug.api.emulation.PcodeDebuggerRegistersAccess; import ghidra.pcode.exec.trace.*; /** diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/emulation/RWTargetRegistersPcodeExecutorStatePiece.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/emulation/RWTargetRegistersPcodeExecutorStatePiece.java index 5832ec8882..d6d63e2299 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/emulation/RWTargetRegistersPcodeExecutorStatePiece.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/emulation/RWTargetRegistersPcodeExecutorStatePiece.java @@ -19,8 +19,8 @@ import java.util.Map; import java.util.concurrent.CompletableFuture; import generic.ULongSpan.ULongSpanSet; -import ghidra.app.plugin.core.debug.service.emulation.data.PcodeDebuggerDataAccess; -import ghidra.app.plugin.core.debug.service.emulation.data.PcodeDebuggerRegistersAccess; +import ghidra.debug.api.emulation.PcodeDebuggerDataAccess; +import ghidra.debug.api.emulation.PcodeDebuggerRegistersAccess; import ghidra.generic.util.datastruct.SemisparseByteArray; import ghidra.program.model.address.*; import ghidra.program.model.lang.Language; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/emulation/data/AbstractPcodeDebuggerAccess.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/emulation/data/AbstractPcodeDebuggerAccess.java index b2c4f6e0dd..8729a6e7fa 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/emulation/data/AbstractPcodeDebuggerAccess.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/emulation/data/AbstractPcodeDebuggerAccess.java @@ -15,7 +15,8 @@ */ package ghidra.app.plugin.core.debug.service.emulation.data; -import ghidra.app.services.TraceRecorder; +import ghidra.debug.api.emulation.*; +import ghidra.debug.api.model.TraceRecorder; import ghidra.framework.plugintool.PluginTool; import ghidra.pcode.exec.trace.data.AbstractPcodeTraceAccess; import ghidra.trace.model.guest.TracePlatform; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/emulation/data/DefaultPcodeDebuggerAccess.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/emulation/data/DefaultPcodeDebuggerAccess.java index c17ef1b270..fcc0685f2a 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/emulation/data/DefaultPcodeDebuggerAccess.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/emulation/data/DefaultPcodeDebuggerAccess.java @@ -15,7 +15,7 @@ */ package ghidra.app.plugin.core.debug.service.emulation.data; -import ghidra.app.services.TraceRecorder; +import ghidra.debug.api.model.TraceRecorder; import ghidra.framework.plugintool.PluginTool; import ghidra.trace.model.guest.TracePlatform; import ghidra.trace.model.thread.TraceThread; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/emulation/data/DefaultPcodeDebuggerMemoryAccess.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/emulation/data/DefaultPcodeDebuggerMemoryAccess.java index 80d025fa14..76a4998a25 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/emulation/data/DefaultPcodeDebuggerMemoryAccess.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/emulation/data/DefaultPcodeDebuggerMemoryAccess.java @@ -21,7 +21,8 @@ import java.util.concurrent.CompletableFuture; import ghidra.app.plugin.core.debug.utils.AbstractMappedMemoryBytesVisitor; import ghidra.app.services.DebuggerStaticMappingService; import ghidra.app.services.DebuggerStaticMappingService.MappedAddressRange; -import ghidra.app.services.TraceRecorder; +import ghidra.debug.api.emulation.PcodeDebuggerMemoryAccess; +import ghidra.debug.api.model.TraceRecorder; import ghidra.framework.plugintool.PluginTool; import ghidra.generic.util.datastruct.SemisparseByteArray; import ghidra.pcode.exec.trace.data.DefaultPcodeTraceMemoryAccess; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/emulation/data/DefaultPcodeDebuggerRegistersAccess.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/emulation/data/DefaultPcodeDebuggerRegistersAccess.java index 9cd01ca33b..0b33d367d0 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/emulation/data/DefaultPcodeDebuggerRegistersAccess.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/emulation/data/DefaultPcodeDebuggerRegistersAccess.java @@ -19,7 +19,8 @@ import java.util.HashSet; import java.util.Set; import java.util.concurrent.CompletableFuture; -import ghidra.app.services.TraceRecorder; +import ghidra.debug.api.emulation.PcodeDebuggerRegistersAccess; +import ghidra.debug.api.model.TraceRecorder; import ghidra.framework.plugintool.PluginTool; import ghidra.pcode.exec.trace.data.DefaultPcodeTraceRegistersAccess; import ghidra.program.model.address.*; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/emulation/data/InternalPcodeDebuggerDataAccess.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/emulation/data/InternalPcodeDebuggerDataAccess.java index 06805d3ddf..877698bd94 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/emulation/data/InternalPcodeDebuggerDataAccess.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/emulation/data/InternalPcodeDebuggerDataAccess.java @@ -15,7 +15,7 @@ */ package ghidra.app.plugin.core.debug.service.emulation.data; -import ghidra.app.services.TraceRecorder; +import ghidra.debug.api.model.TraceRecorder; import ghidra.framework.plugintool.PluginTool; import ghidra.lifecycle.Internal; import ghidra.pcode.exec.trace.data.InternalPcodeTraceDataAccess; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/model/DebuggerModelServiceInternal.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/model/DebuggerModelServiceInternal.java index 91cb690cb1..cd84597602 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/model/DebuggerModelServiceInternal.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/model/DebuggerModelServiceInternal.java @@ -19,11 +19,12 @@ import java.io.IOException; import java.util.Collection; import ghidra.app.plugin.core.debug.event.*; -import ghidra.app.plugin.core.debug.mapping.DebuggerTargetTraceMapper; import ghidra.app.services.*; import ghidra.dbg.DebuggerModelFactory; import ghidra.dbg.DebuggerObjectModel; import ghidra.dbg.target.TargetObject; +import ghidra.debug.api.model.DebuggerTargetTraceMapper; +import ghidra.debug.api.model.TraceRecorder; import ghidra.framework.plugintool.PluginEvent; import ghidra.lifecycle.Internal; import ghidra.util.Swing; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/model/DebuggerModelServicePlugin.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/model/DebuggerModelServicePlugin.java index 4ceb3aaa21..1a9adcaa41 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/model/DebuggerModelServicePlugin.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/model/DebuggerModelServicePlugin.java @@ -15,7 +15,7 @@ */ package ghidra.app.plugin.core.debug.service.model; -import static ghidra.app.plugin.core.debug.gui.DebuggerResources.*; +import static ghidra.app.plugin.core.debug.gui.DebuggerResources.showError; import java.io.IOException; import java.lang.invoke.MethodHandles; @@ -36,8 +36,6 @@ import docking.action.DockingAction; import ghidra.app.plugin.PluginCategoryNames; import ghidra.app.plugin.core.debug.DebuggerPluginPackage; import ghidra.app.plugin.core.debug.gui.DebuggerResources.DisconnectAllAction; -import ghidra.app.plugin.core.debug.mapping.*; -import ghidra.app.plugin.core.debug.service.model.launch.DebuggerProgramLaunchOffer; import ghidra.app.plugin.core.debug.service.model.launch.DebuggerProgramLaunchOpinion; import ghidra.app.services.*; import ghidra.app.services.DebuggerTraceManagerService.ActivationCause; @@ -45,6 +43,8 @@ import ghidra.async.AsyncFence; import ghidra.dbg.*; import ghidra.dbg.target.*; import ghidra.dbg.util.PathUtils; +import ghidra.debug.api.action.ActionSource; +import ghidra.debug.api.model.*; import ghidra.framework.main.AppInfo; import ghidra.framework.main.ApplicationLevelOnlyPlugin; import ghidra.framework.options.SaveState; @@ -62,7 +62,6 @@ import ghidra.util.classfinder.ClassSearcher; import ghidra.util.datastruct.CollectionChangeListener; import ghidra.util.datastruct.ListenerSet; -//@formatter:off @PluginInfo( shortDescription = "Debugger models manager service", description = "Manage debug sessions, connections, and trace recording", @@ -73,7 +72,6 @@ import ghidra.util.datastruct.ListenerSet; servicesProvided = { DebuggerModelService.class }) -//@formatter:on public class DebuggerModelServicePlugin extends Plugin implements DebuggerModelServiceInternal, ApplicationLevelOnlyPlugin { @@ -487,7 +485,7 @@ public class DebuggerModelServicePlugin extends Plugin throws IOException { String traceName = nameTrace(target); Trace trace = new DBTrace(traceName, mapper.getTraceCompilerSpec(), this); - TraceRecorder recorder = mapper.startRecording(this, trace); + TraceRecorder recorder = mapper.startRecording(tool, trace); trace.release(this); // The recorder now owns it (on behalf of the service) return recorder; } @@ -672,4 +670,6 @@ public class DebuggerModelServicePlugin extends Plugin public CompletableFuture showConnectDialog(DebuggerModelFactory factory) { return doShowConnectDialog(tool, factory, null); } + + } diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/model/DebuggerModelServiceProxyPlugin.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/model/DebuggerModelServiceProxyPlugin.java index 392f9fbbf7..faadc3dae9 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/model/DebuggerModelServiceProxyPlugin.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/model/DebuggerModelServiceProxyPlugin.java @@ -23,6 +23,8 @@ import java.util.concurrent.CompletableFuture; import java.util.stream.Collectors; import java.util.stream.Stream; +import javax.swing.Icon; + import org.apache.commons.lang3.exception.ExceptionUtils; import db.Transaction; @@ -36,11 +38,9 @@ import ghidra.app.events.ProgramActivatedPluginEvent; import ghidra.app.events.ProgramClosedPluginEvent; import ghidra.app.plugin.PluginCategoryNames; import ghidra.app.plugin.core.debug.DebuggerPluginPackage; +import ghidra.app.plugin.core.debug.gui.DebuggerResources; import ghidra.app.plugin.core.debug.gui.DebuggerResources.DebugProgramAction; import ghidra.app.plugin.core.debug.gui.DebuggerResources.DisconnectAllAction; -import ghidra.app.plugin.core.debug.mapping.DebuggerTargetTraceMapper; -import ghidra.app.plugin.core.debug.service.model.launch.DebuggerProgramLaunchOffer; -import ghidra.app.plugin.core.debug.service.model.launch.DebuggerProgramLaunchOffer.PromptMode; import ghidra.app.plugin.core.debug.utils.BackgroundUtils; import ghidra.app.services.*; import ghidra.async.AsyncUtils; @@ -48,6 +48,9 @@ import ghidra.dbg.DebuggerModelFactory; import ghidra.dbg.DebuggerObjectModel; import ghidra.dbg.target.TargetObject; import ghidra.dbg.target.TargetThread; +import ghidra.debug.api.action.ActionSource; +import ghidra.debug.api.model.*; +import ghidra.debug.api.model.DebuggerProgramLaunchOffer.PromptMode; import ghidra.framework.main.AppInfo; import ghidra.framework.main.FrontEndTool; import ghidra.framework.plugintool.*; @@ -98,6 +101,11 @@ public class DebuggerModelServiceProxyPlugin extends Plugin return "DUMMY"; } + @Override + public Icon getIcon() { + return DebuggerResources.ICON_DEBUGGER; + } + @Override public String getMenuParentTitle() { return ""; @@ -466,14 +474,12 @@ public class DebuggerModelServiceProxyPlugin extends Plugin @Override public void processEvent(PluginEvent event) { super.processEvent(event); - if (event instanceof ProgramActivatedPluginEvent) { - ProgramActivatedPluginEvent evt = (ProgramActivatedPluginEvent) event; + if (event instanceof ProgramActivatedPluginEvent evt) { currentProgram = evt.getActiveProgram(); currentProgramPath = getProgramPath(currentProgram); updateActionDebugProgram(); } - if (event instanceof ProgramClosedPluginEvent) { - ProgramClosedPluginEvent evt = (ProgramClosedPluginEvent) event; + if (event instanceof ProgramClosedPluginEvent evt) { if (currentProgram == evt.getProgram()) { currentProgram = null; currentProgramPath = null; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/model/DebuggerSelectMappingOfferDialog.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/model/DebuggerSelectMappingOfferDialog.java index 3f5f66278a..9a6637d4d0 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/model/DebuggerSelectMappingOfferDialog.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/model/DebuggerSelectMappingOfferDialog.java @@ -28,7 +28,7 @@ import docking.widgets.table.*; import docking.widgets.table.ColumnSortState.SortDirection; import docking.widgets.table.DefaultEnumeratedColumnTableModel.EnumeratedTableColumn; import ghidra.app.plugin.core.debug.gui.DebuggerResources; -import ghidra.app.plugin.core.debug.mapping.DebuggerMappingOffer; +import ghidra.debug.api.model.DebuggerMappingOffer; import ghidra.framework.plugintool.PluginTool; import ghidra.program.model.lang.*; import ghidra.program.util.DefaultLanguageService; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/model/DefaultBreakpointRecorder.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/model/DefaultBreakpointRecorder.java index c3909d86c7..e899d41125 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/model/DefaultBreakpointRecorder.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/model/DefaultBreakpointRecorder.java @@ -19,9 +19,9 @@ import java.util.Collection; import java.util.Set; import ghidra.app.plugin.core.debug.service.model.interfaces.ManagedBreakpointRecorder; -import ghidra.app.services.TraceRecorder; import ghidra.dbg.target.*; import ghidra.dbg.util.PathUtils; +import ghidra.debug.api.model.TraceRecorder; import ghidra.program.model.address.*; import ghidra.trace.model.Trace; import ghidra.trace.model.breakpoint.*; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/model/DefaultProcessRecorder.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/model/DefaultProcessRecorder.java index 0177c7ee6e..1ad4ccfbb2 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/model/DefaultProcessRecorder.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/model/DefaultProcessRecorder.java @@ -17,8 +17,8 @@ package ghidra.app.plugin.core.debug.service.model; import java.util.concurrent.CompletableFuture; -import ghidra.app.plugin.core.debug.mapping.DebuggerMemoryMapper; import ghidra.app.plugin.core.debug.service.model.interfaces.*; +import ghidra.debug.api.model.DebuggerMemoryMapper; import ghidra.program.model.address.Address; import ghidra.program.model.address.AddressSetView; import ghidra.trace.model.Trace; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/model/DefaultStackRecorder.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/model/DefaultStackRecorder.java index f9ad574dc1..a554dc23cf 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/model/DefaultStackRecorder.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/model/DefaultStackRecorder.java @@ -18,11 +18,11 @@ package ghidra.app.plugin.core.debug.service.model; import java.util.*; import java.util.stream.Collectors; -import ghidra.app.plugin.core.debug.mapping.DebuggerMemoryMapper; import ghidra.app.plugin.core.debug.service.model.interfaces.ManagedStackRecorder; import ghidra.dbg.target.TargetObject; import ghidra.dbg.target.TargetStackFrame; import ghidra.dbg.util.PathUtils; +import ghidra.debug.api.model.DebuggerMemoryMapper; import ghidra.program.model.address.Address; import ghidra.trace.model.Trace; import ghidra.trace.model.stack.*; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/model/DefaultThreadRecorder.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/model/DefaultThreadRecorder.java index b7e8af226b..e63fc58a99 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/model/DefaultThreadRecorder.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/model/DefaultThreadRecorder.java @@ -27,6 +27,8 @@ import ghidra.async.AsyncUtils; import ghidra.dbg.target.*; import ghidra.dbg.target.TargetExecutionStateful.TargetExecutionState; import ghidra.dbg.util.PathUtils; +import ghidra.debug.api.model.DebuggerMemoryMapper; +import ghidra.debug.api.model.DebuggerRegisterMapper; import ghidra.program.model.address.*; import ghidra.program.model.data.Pointer; import ghidra.program.model.lang.*; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/model/DefaultTraceRecorder.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/model/DefaultTraceRecorder.java index fc75ed19e2..cf2ccd2d37 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/model/DefaultTraceRecorder.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/model/DefaultTraceRecorder.java @@ -20,12 +20,10 @@ import java.util.concurrent.*; import org.apache.commons.lang3.concurrent.BasicThreadFactory; -import ghidra.app.plugin.core.debug.mapping.*; +import ghidra.app.plugin.core.debug.mapping.DefaultDebuggerTargetTraceMapper; import ghidra.app.plugin.core.debug.service.model.interfaces.*; import ghidra.app.plugin.core.debug.service.model.record.DataTypeRecorder; import ghidra.app.plugin.core.debug.service.model.record.SymbolRecorder; -import ghidra.app.services.TraceRecorder; -import ghidra.app.services.TraceRecorderListener; import ghidra.async.AsyncLazyValue; import ghidra.async.AsyncUtils; import ghidra.dbg.agent.AbstractDebuggerObjectModel; @@ -34,6 +32,7 @@ import ghidra.dbg.target.*; import ghidra.dbg.target.TargetBreakpointSpec.TargetBreakpointKind; import ghidra.dbg.target.TargetExecutionStateful.TargetExecutionState; import ghidra.dbg.util.PathUtils; +import ghidra.debug.api.model.*; import ghidra.framework.plugintool.PluginTool; import ghidra.program.model.address.Address; import ghidra.program.model.address.AddressSetView; @@ -58,7 +57,6 @@ import ghidra.util.task.TaskMonitor; public class DefaultTraceRecorder implements TraceRecorder { static final int POOL_SIZE = Math.min(16, Runtime.getRuntime().availableProcessors()); - protected final DebuggerModelServicePlugin plugin; protected final PluginTool tool; protected final TargetObject target; protected final Trace trace; @@ -83,11 +81,10 @@ public class DefaultTraceRecorder implements TraceRecorder { protected final AsyncLazyValue lazyInit = new AsyncLazyValue<>(this::doInit); private boolean valid = true; - public DefaultTraceRecorder(DebuggerModelServicePlugin plugin, Trace trace, TargetObject target, + public DefaultTraceRecorder(PluginTool tool, Trace trace, TargetObject target, DefaultDebuggerTargetTraceMapper mapper) { trace.addConsumer(this); - this.plugin = plugin; - this.tool = plugin.getTool(); + this.tool = tool; this.trace = trace; this.target = target; @@ -453,7 +450,7 @@ public class DefaultTraceRecorder implements TraceRecorder { return focusScope.requestFocus(focus).thenApply(__ -> true).exceptionally(ex -> { ex = AsyncUtils.unwrapThrowable(ex); String msg = "Could not focus " + focus + ": " + ex.getMessage(); - plugin.getTool().setStatusInfo(msg); + tool.setStatusInfo(msg); if (ex instanceof DebuggerModelAccessException) { Msg.info(this, msg); } @@ -483,7 +480,7 @@ public class DefaultTraceRecorder implements TraceRecorder { return activeScope.requestActivation(active).thenApply(__ -> true).exceptionally(ex -> { ex = AsyncUtils.unwrapThrowable(ex); String msg = "Could not activate " + active + ": " + ex.getMessage(); - plugin.getTool().setStatusInfo(msg); + tool.setStatusInfo(msg); if (ex instanceof DebuggerModelAccessException) { Msg.info(this, msg); } diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/model/RecorderSimpleMemory.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/model/RecorderSimpleMemory.java index 65022f0a70..54080e0032 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/model/RecorderSimpleMemory.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/model/RecorderSimpleMemory.java @@ -21,9 +21,9 @@ import java.util.TreeMap; import java.util.concurrent.CompletableFuture; import java.util.function.Predicate; -import ghidra.app.plugin.core.debug.mapping.DebuggerMemoryMapper; import ghidra.app.plugin.core.debug.service.model.interfaces.AbstractRecorderMemory; import ghidra.dbg.target.*; +import ghidra.debug.api.model.DebuggerMemoryMapper; import ghidra.program.model.address.*; public class RecorderSimpleMemory implements AbstractRecorderMemory { diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/model/RecorderSimpleRegisterSet.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/model/RecorderSimpleRegisterSet.java index 375191e70d..c2d024b8ef 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/model/RecorderSimpleRegisterSet.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/model/RecorderSimpleRegisterSet.java @@ -15,8 +15,8 @@ */ package ghidra.app.plugin.core.debug.service.model; -import ghidra.app.services.TraceRecorder; import ghidra.dbg.target.TargetRegisterBank; +import ghidra.debug.api.model.TraceRecorder; public class RecorderSimpleRegisterSet { diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/model/TraceObjectManager.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/model/TraceObjectManager.java index 55198c1707..22f93f6743 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/model/TraceObjectManager.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/model/TraceObjectManager.java @@ -25,12 +25,11 @@ import java.util.stream.Collectors; import db.Transaction; import ghidra.app.plugin.core.debug.mapping.*; import ghidra.app.plugin.core.debug.service.model.interfaces.*; -import ghidra.app.services.TraceRecorder; -import ghidra.app.services.TraceRecorderListener; import ghidra.async.AsyncLazyMap; import ghidra.dbg.target.*; import ghidra.dbg.util.PathUtils; import ghidra.dbg.util.PathUtils.PathComparator; +import ghidra.debug.api.model.*; import ghidra.program.model.address.AddressRange; import ghidra.trace.model.breakpoint.TraceBreakpoint; import ghidra.trace.model.breakpoint.TraceBreakpointKind; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/model/interfaces/AbstractRecorderMemory.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/model/interfaces/AbstractRecorderMemory.java index 02efe8bc89..5b5e22c68a 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/model/interfaces/AbstractRecorderMemory.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/model/interfaces/AbstractRecorderMemory.java @@ -18,8 +18,8 @@ package ghidra.app.plugin.core.debug.service.model.interfaces; import java.util.concurrent.CompletableFuture; import java.util.function.Predicate; -import ghidra.app.plugin.core.debug.mapping.DebuggerMemoryMapper; import ghidra.dbg.target.*; +import ghidra.debug.api.model.DebuggerMemoryMapper; import ghidra.program.model.address.*; public interface AbstractRecorderMemory { diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/model/interfaces/AbstractTraceRecorder.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/model/interfaces/AbstractTraceRecorder.java index 2887617879..1c460e8ea0 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/model/interfaces/AbstractTraceRecorder.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/model/interfaces/AbstractTraceRecorder.java @@ -15,7 +15,7 @@ */ package ghidra.app.plugin.core.debug.service.model.interfaces; -import ghidra.app.plugin.core.debug.mapping.DebuggerMemoryMapper; +import ghidra.debug.api.model.DebuggerMemoryMapper; import ghidra.trace.model.Trace; public interface AbstractTraceRecorder { diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/model/interfaces/ManagedThreadRecorder.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/model/interfaces/ManagedThreadRecorder.java index 2c7eb4d730..e9cdda6b86 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/model/interfaces/ManagedThreadRecorder.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/model/interfaces/ManagedThreadRecorder.java @@ -18,9 +18,9 @@ package ghidra.app.plugin.core.debug.service.model.interfaces; import java.util.Map; import java.util.concurrent.CompletableFuture; -import ghidra.app.plugin.core.debug.mapping.DebuggerRegisterMapper; import ghidra.dbg.target.*; import ghidra.dbg.target.TargetExecutionStateful.TargetExecutionState; +import ghidra.debug.api.model.DebuggerRegisterMapper; import ghidra.trace.model.thread.TraceThread; public interface ManagedThreadRecorder extends AbstractTraceRecorder { diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/model/launch/AbstractDebuggerProgramLaunchOffer.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/model/launch/AbstractDebuggerProgramLaunchOffer.java index b6a9a796a3..5449811a0f 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/model/launch/AbstractDebuggerProgramLaunchOffer.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/model/launch/AbstractDebuggerProgramLaunchOffer.java @@ -24,16 +24,17 @@ import java.util.concurrent.CancellationException; import java.util.concurrent.CompletableFuture; import java.util.stream.Collectors; +import javax.swing.Icon; import javax.swing.JOptionPane; import org.jdom.Element; import org.jdom.JDOMException; import db.Transaction; +import ghidra.app.plugin.core.debug.gui.DebuggerResources; import ghidra.app.plugin.core.debug.gui.objects.components.DebuggerMethodInvocationDialog; import ghidra.app.services.*; import ghidra.app.services.DebuggerTraceManagerService.ActivationCause; -import ghidra.app.services.ModuleMapProposal.ModuleMapEntry; import ghidra.async.*; import ghidra.dbg.*; import ghidra.dbg.target.*; @@ -42,6 +43,10 @@ import ghidra.dbg.target.TargetMethod.ParameterDescription; import ghidra.dbg.target.TargetMethod.TargetParameterMap; import ghidra.dbg.target.schema.TargetObjectSchema; import ghidra.dbg.util.PathUtils; +import ghidra.debug.api.model.DebuggerProgramLaunchOffer; +import ghidra.debug.api.model.TraceRecorder; +import ghidra.debug.api.modules.*; +import ghidra.debug.api.modules.ModuleMapProposal.ModuleMapEntry; import ghidra.framework.model.DomainFile; import ghidra.framework.options.SaveState; import ghidra.framework.plugintool.AutoConfigState.ConfigStateField; @@ -77,6 +82,11 @@ public abstract class AbstractDebuggerProgramLaunchOffer implements DebuggerProg this.factory = factory; } + @Override + public Icon getIcon() { + return DebuggerResources.ICON_DEBUGGER; + } + @Override public String getMenuParentTitle() { String name = program.getName(); diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/model/launch/AbstractDebuggerProgramLaunchOpinion.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/model/launch/AbstractDebuggerProgramLaunchOpinion.java index b29dfc7faf..620346df67 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/model/launch/AbstractDebuggerProgramLaunchOpinion.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/model/launch/AbstractDebuggerProgramLaunchOpinion.java @@ -22,6 +22,7 @@ import java.util.*; import ghidra.app.services.DebuggerModelService; import ghidra.dbg.DebuggerModelFactory; +import ghidra.debug.api.model.DebuggerProgramLaunchOffer; import ghidra.framework.plugintool.PluginTool; import ghidra.program.model.listing.Program; import ghidra.util.Msg; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/model/launch/DebuggerProgramLaunchOpinion.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/model/launch/DebuggerProgramLaunchOpinion.java index 6f686afa4d..7797551e22 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/model/launch/DebuggerProgramLaunchOpinion.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/model/launch/DebuggerProgramLaunchOpinion.java @@ -18,6 +18,7 @@ package ghidra.app.plugin.core.debug.service.model.launch; import java.util.Collection; import ghidra.app.services.DebuggerModelService; +import ghidra.debug.api.model.DebuggerProgramLaunchOffer; import ghidra.framework.plugintool.PluginTool; import ghidra.program.model.listing.Program; import ghidra.util.classfinder.ExtensionPoint; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/model/record/DataTypeRecorder.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/model/record/DataTypeRecorder.java index 3a277359cc..cab36653ce 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/model/record/DataTypeRecorder.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/model/record/DataTypeRecorder.java @@ -19,12 +19,12 @@ import java.util.*; import java.util.concurrent.CompletableFuture; import ghidra.app.plugin.core.debug.service.model.RecorderPermanentTransaction; -import ghidra.app.services.TraceRecorder; import ghidra.async.AsyncFence; import ghidra.async.AsyncUtils; import ghidra.dbg.target.*; import ghidra.dbg.util.PathUtils; import ghidra.dbg.util.TargetDataTypeConverter; +import ghidra.debug.api.model.TraceRecorder; import ghidra.program.model.data.*; import ghidra.trace.model.Trace; import ghidra.util.task.TaskMonitor; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/model/record/EmptyDebuggerRegisterMapper.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/model/record/EmptyDebuggerRegisterMapper.java index e9224e9563..f3aebc3ebf 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/model/record/EmptyDebuggerRegisterMapper.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/model/record/EmptyDebuggerRegisterMapper.java @@ -17,9 +17,8 @@ package ghidra.app.plugin.core.debug.service.model.record; import java.util.Set; -import ghidra.app.plugin.core.debug.mapping.DebuggerRegisterMapper; -import ghidra.app.plugin.core.debug.register.RegisterTypeInfo; import ghidra.dbg.target.TargetRegister; +import ghidra.debug.api.model.DebuggerRegisterMapper; import ghidra.program.model.lang.Register; public class EmptyDebuggerRegisterMapper implements DebuggerRegisterMapper { @@ -43,11 +42,6 @@ public class EmptyDebuggerRegisterMapper implements DebuggerRegisterMapper { return null; } - @Override - public RegisterTypeInfo getDefaultTypeInfo(Register lReg) { - return null; - } - @Override public Set getRegistersOnTarget() { return Set.of(); diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/model/record/ObjectBasedTraceRecorder.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/model/record/ObjectBasedTraceRecorder.java index 590d2e7383..e470d129ac 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/model/record/ObjectBasedTraceRecorder.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/model/record/ObjectBasedTraceRecorder.java @@ -22,11 +22,8 @@ import java.util.concurrent.CompletableFuture; import java.util.stream.Collectors; import db.Transaction; -import ghidra.app.plugin.core.debug.mapping.*; -import ghidra.app.plugin.core.debug.service.model.DebuggerModelServicePlugin; +import ghidra.app.plugin.core.debug.mapping.ObjectBasedDebuggerTargetTraceMapper; import ghidra.app.plugin.core.debug.service.model.PermanentTransactionExecutor; -import ghidra.app.services.TraceRecorder; -import ghidra.app.services.TraceRecorderListener; import ghidra.async.AsyncFence; import ghidra.async.AsyncUtils; import ghidra.dbg.AnnotatedDebuggerAttributeListener; @@ -38,6 +35,8 @@ import ghidra.dbg.target.TargetEventScope.TargetEventType; import ghidra.dbg.target.TargetExecutionStateful.TargetExecutionState; import ghidra.dbg.util.PathMatcher; import ghidra.dbg.util.PathUtils; +import ghidra.debug.api.model.*; +import ghidra.framework.plugintool.PluginTool; import ghidra.pcode.utils.Utils; import ghidra.program.model.address.*; import ghidra.program.model.lang.Register; @@ -270,8 +269,8 @@ public class ObjectBasedTraceRecorder implements TraceRecorder { } } - public ObjectBasedTraceRecorder(DebuggerModelServicePlugin service, Trace trace, - TargetObject target, ObjectBasedDebuggerTargetTraceMapper mapper) { + public ObjectBasedTraceRecorder(PluginTool tool, Trace trace, TargetObject target, + ObjectBasedDebuggerTargetTraceMapper mapper) { trace.addConsumer(this); this.trace = trace; this.target = target; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/model/record/RecorderUtils.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/model/record/RecorderUtils.java index 3be64da08b..ec365c3afd 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/model/record/RecorderUtils.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/model/record/RecorderUtils.java @@ -17,9 +17,9 @@ package ghidra.app.plugin.core.debug.service.model.record; import java.util.concurrent.CompletableFuture; -import ghidra.app.services.TraceRecorder; import ghidra.async.AsyncUtils; import ghidra.async.TypeSpec; +import ghidra.debug.api.model.TraceRecorder; import ghidra.program.model.address.*; import ghidra.util.Msg; import ghidra.util.task.TaskMonitor; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/model/record/SymbolRecorder.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/model/record/SymbolRecorder.java index 9c12c10d8b..8dd2240270 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/model/record/SymbolRecorder.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/model/record/SymbolRecorder.java @@ -19,10 +19,10 @@ import java.util.Map; import java.util.concurrent.CompletableFuture; import ghidra.app.plugin.core.debug.service.model.RecorderPermanentTransaction; -import ghidra.app.services.TraceRecorder; import ghidra.async.AsyncFence; import ghidra.dbg.target.*; import ghidra.dbg.util.PathUtils; +import ghidra.debug.api.model.TraceRecorder; import ghidra.program.model.address.Address; import ghidra.program.model.symbol.SourceType; import ghidra.trace.model.Trace; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/modules/AbstractMapEntry.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/modules/AbstractMapEntry.java index 3765a1284d..03f4ebde67 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/modules/AbstractMapEntry.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/modules/AbstractMapEntry.java @@ -17,7 +17,7 @@ package ghidra.app.plugin.core.debug.service.modules; import java.util.Objects; -import ghidra.app.services.MapEntry; +import ghidra.debug.api.modules.MapEntry; import ghidra.program.model.listing.Program; import ghidra.program.util.ProgramLocation; import ghidra.trace.model.*; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/modules/AbstractMapProposal.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/modules/AbstractMapProposal.java index 1ed834ea38..d9a183771a 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/modules/AbstractMapProposal.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/modules/AbstractMapProposal.java @@ -19,8 +19,8 @@ import java.util.*; import java.util.function.Function; import java.util.stream.Collectors; -import ghidra.app.services.MapEntry; -import ghidra.app.services.MapProposal; +import ghidra.debug.api.modules.MapEntry; +import ghidra.debug.api.modules.MapProposal; import ghidra.program.model.address.AddressRange; import ghidra.program.model.listing.Program; import ghidra.trace.model.Trace; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/modules/DebuggerStaticMappingProposals.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/modules/DebuggerStaticMappingProposals.java index ea80f4e9c8..73894b0232 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/modules/DebuggerStaticMappingProposals.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/modules/DebuggerStaticMappingProposals.java @@ -25,6 +25,7 @@ import java.util.stream.Stream; import ghidra.app.plugin.core.debug.service.modules.ProgramModuleIndexer.IndexEntry; import ghidra.app.services.*; import ghidra.dbg.util.PathUtils; +import ghidra.debug.api.modules.*; import ghidra.framework.model.DomainFile; import ghidra.graph.*; import ghidra.graph.jung.JungDirectedGraph; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/modules/DebuggerStaticMappingServicePlugin.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/modules/DebuggerStaticMappingServicePlugin.java index 4ccfe7d996..8bfb56affe 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/modules/DebuggerStaticMappingServicePlugin.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/modules/DebuggerStaticMappingServicePlugin.java @@ -34,11 +34,12 @@ import ghidra.app.plugin.core.debug.event.TraceOpenedPluginEvent; import ghidra.app.plugin.core.debug.service.modules.DebuggerStaticMappingProposals.ModuleMapProposalGenerator; import ghidra.app.plugin.core.debug.utils.*; import ghidra.app.services.*; -import ghidra.app.services.ModuleMapProposal.ModuleMapEntry; -import ghidra.app.services.RegionMapProposal.RegionMapEntry; -import ghidra.app.services.SectionMapProposal.SectionMapEntry; import ghidra.async.AsyncDebouncer; import ghidra.async.AsyncTimer; +import ghidra.debug.api.modules.*; +import ghidra.debug.api.modules.ModuleMapProposal.ModuleMapEntry; +import ghidra.debug.api.modules.RegionMapProposal.RegionMapEntry; +import ghidra.debug.api.modules.SectionMapProposal.SectionMapEntry; import ghidra.framework.model.*; import ghidra.framework.plugintool.*; import ghidra.framework.plugintool.annotation.AutoServiceConsumed; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/modules/DebuggerStaticMappingUtils.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/modules/DebuggerStaticMappingUtils.java index 33079cb094..1f0c5e9871 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/modules/DebuggerStaticMappingUtils.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/modules/DebuggerStaticMappingUtils.java @@ -20,7 +20,7 @@ import java.util.*; import java.util.stream.Collectors; import ghidra.app.plugin.core.debug.utils.ProgramURLUtils; -import ghidra.app.services.MapEntry; +import ghidra.debug.api.modules.MapEntry; import ghidra.framework.model.DomainFile; import ghidra.framework.model.ProjectData; import ghidra.program.model.address.*; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/modules/DefaultModuleMapProposal.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/modules/DefaultModuleMapProposal.java index 3382dbbb6a..a8c45398cf 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/modules/DefaultModuleMapProposal.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/modules/DefaultModuleMapProposal.java @@ -18,8 +18,8 @@ package ghidra.app.plugin.core.debug.service.modules; import java.util.*; import ghidra.app.services.DebuggerStaticMappingService; -import ghidra.app.services.ModuleMapProposal; -import ghidra.app.services.ModuleMapProposal.ModuleMapEntry; +import ghidra.debug.api.modules.ModuleMapProposal; +import ghidra.debug.api.modules.ModuleMapProposal.ModuleMapEntry; import ghidra.program.model.address.*; import ghidra.program.model.listing.Program; import ghidra.program.model.mem.MemoryBlock; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/modules/DefaultRegionMapProposal.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/modules/DefaultRegionMapProposal.java index 88390c3397..fc11c251af 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/modules/DefaultRegionMapProposal.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/modules/DefaultRegionMapProposal.java @@ -18,8 +18,8 @@ package ghidra.app.plugin.core.debug.service.modules; import java.util.*; import java.util.stream.Collectors; -import ghidra.app.services.RegionMapProposal; -import ghidra.app.services.RegionMapProposal.RegionMapEntry; +import ghidra.debug.api.modules.RegionMapProposal; +import ghidra.debug.api.modules.RegionMapProposal.RegionMapEntry; import ghidra.program.model.address.*; import ghidra.program.model.listing.Program; import ghidra.program.model.mem.MemoryBlock; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/modules/DefaultSectionMapProposal.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/modules/DefaultSectionMapProposal.java index 18f5293cc6..fb02aa776f 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/modules/DefaultSectionMapProposal.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/modules/DefaultSectionMapProposal.java @@ -18,8 +18,8 @@ package ghidra.app.plugin.core.debug.service.modules; import java.util.Map; import ghidra.app.services.DebuggerStaticMappingService; -import ghidra.app.services.SectionMapProposal; -import ghidra.app.services.SectionMapProposal.SectionMapEntry; +import ghidra.debug.api.modules.SectionMapProposal; +import ghidra.debug.api.modules.SectionMapProposal.SectionMapEntry; import ghidra.program.model.address.AddressRange; import ghidra.program.model.address.AddressRangeImpl; import ghidra.program.model.listing.Program; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/modules/MapModulesBackgroundCommand.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/modules/MapModulesBackgroundCommand.java index 24100cad36..ded0013c33 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/modules/MapModulesBackgroundCommand.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/modules/MapModulesBackgroundCommand.java @@ -18,7 +18,7 @@ package ghidra.app.plugin.core.debug.service.modules; import java.util.Collection; import ghidra.app.services.DebuggerStaticMappingService; -import ghidra.app.services.ModuleMapProposal.ModuleMapEntry; +import ghidra.debug.api.modules.ModuleMapProposal.ModuleMapEntry; import ghidra.framework.cmd.BackgroundCommand; import ghidra.framework.model.DomainObject; import ghidra.util.exception.CancelledException; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/modules/MapRegionsBackgroundCommand.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/modules/MapRegionsBackgroundCommand.java index c7a32177dd..32edcb1acc 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/modules/MapRegionsBackgroundCommand.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/modules/MapRegionsBackgroundCommand.java @@ -18,7 +18,7 @@ package ghidra.app.plugin.core.debug.service.modules; import java.util.Collection; import ghidra.app.services.DebuggerStaticMappingService; -import ghidra.app.services.RegionMapProposal.RegionMapEntry; +import ghidra.debug.api.modules.RegionMapProposal.RegionMapEntry; import ghidra.framework.cmd.BackgroundCommand; import ghidra.framework.model.DomainObject; import ghidra.util.exception.CancelledException; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/modules/MapSectionsBackgroundCommand.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/modules/MapSectionsBackgroundCommand.java index b502b9007a..88da52fbed 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/modules/MapSectionsBackgroundCommand.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/modules/MapSectionsBackgroundCommand.java @@ -18,7 +18,7 @@ package ghidra.app.plugin.core.debug.service.modules; import java.util.Collection; import ghidra.app.services.DebuggerStaticMappingService; -import ghidra.app.services.SectionMapProposal.SectionMapEntry; +import ghidra.debug.api.modules.SectionMapProposal.SectionMapEntry; import ghidra.framework.cmd.BackgroundCommand; import ghidra.framework.model.DomainObject; import ghidra.util.exception.CancelledException; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/platform/DebuggerPlatformServicePlugin.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/platform/DebuggerPlatformServicePlugin.java index 18c2da95d9..b5c7461d3c 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/platform/DebuggerPlatformServicePlugin.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/platform/DebuggerPlatformServicePlugin.java @@ -24,6 +24,7 @@ import ghidra.app.plugin.core.debug.event.TraceClosedPluginEvent; import ghidra.app.plugin.core.debug.mapping.*; import ghidra.app.services.DebuggerPlatformService; import ghidra.app.services.DebuggerTraceManagerService; +import ghidra.debug.api.platform.DebuggerPlatformMapper; import ghidra.framework.plugintool.*; import ghidra.framework.plugintool.annotation.AutoServiceConsumed; import ghidra.framework.plugintool.util.PluginStatus; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/tracemgr/DebuggerTraceManagerServicePlugin.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/tracemgr/DebuggerTraceManagerServicePlugin.java index 3d227507a4..3e31c7d659 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/tracemgr/DebuggerTraceManagerServicePlugin.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/tracemgr/DebuggerTraceManagerServicePlugin.java @@ -27,16 +27,18 @@ import docking.ActionContext; import docking.action.DockingAction; import docking.action.ToggleDockingAction; import ghidra.app.plugin.PluginCategoryNames; -import ghidra.app.plugin.core.debug.DebuggerCoordinates; import ghidra.app.plugin.core.debug.DebuggerPluginPackage; 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.DebuggerControlService.ControlModeChangeListener; import ghidra.async.*; import ghidra.async.AsyncConfigFieldCodec.BooleanAsyncConfigFieldCodec; import ghidra.dbg.target.*; +import ghidra.debug.api.control.ControlMode; +import ghidra.debug.api.model.TraceRecorder; +import ghidra.debug.api.platform.DebuggerPlatformMapper; +import ghidra.debug.api.tracemgr.DebuggerCoordinates; import ghidra.framework.client.ClientUtil; import ghidra.framework.client.NotConnectedException; import ghidra.framework.data.DomainObjectAdapterDB; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/workflow/DebuggerWorkflowServicePlugin.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/workflow/DebuggerWorkflowServicePlugin.java index 8eeda6d604..32fae1a468 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/workflow/DebuggerWorkflowServicePlugin.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/workflow/DebuggerWorkflowServicePlugin.java @@ -31,6 +31,7 @@ import ghidra.app.plugin.core.debug.event.TraceOpenedPluginEvent; import ghidra.app.plugin.core.debug.gui.DebuggerResources; import ghidra.app.services.*; import ghidra.dbg.DebuggerObjectModel; +import ghidra.debug.api.workflow.DebuggerBot; import ghidra.framework.main.ApplicationLevelOnlyPlugin; import ghidra.framework.main.FrontEndTool; import ghidra.framework.options.*; @@ -44,18 +45,18 @@ import ghidra.util.SystemUtilities; import ghidra.util.classfinder.ClassSearcher; import ghidra.util.datastruct.CollectionChangeListener; -@PluginInfo( // - shortDescription = "Debugger workflow service", // - description = "Manage automatic debugging actions and analysis", // - category = PluginCategoryNames.DEBUGGER, // - packageName = DebuggerPluginPackage.NAME, // - status = PluginStatus.RELEASED, // - servicesProvided = { // - DebuggerWorkflowService.class, // - } // -) +@PluginInfo( + shortDescription = "Debugger workflow service", + description = "Manage automatic debugging actions and analysis", + category = PluginCategoryNames.DEBUGGER, + packageName = DebuggerPluginPackage.NAME, + status = PluginStatus.RELEASED, + servicesProvided = { + DebuggerWorkflowFrontEndService.class, + }) public class DebuggerWorkflowServicePlugin extends Plugin - implements DebuggerWorkflowService, ApplicationLevelOnlyPlugin, OptionsChangeListener { + implements DebuggerWorkflowFrontEndService, ApplicationLevelOnlyPlugin, + OptionsChangeListener { protected class ForBotsModelsChangeListener implements CollectionChangeListener { @@ -290,6 +291,7 @@ public class DebuggerWorkflowServicePlugin extends Plugin } } + @Override public Collection getProxyingPluginTools() { synchronized (trackStuffListenersByTool) { return List.copyOf(trackStuffListenersByTool.keySet()); diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/workflow/DebuggerWorkflowServiceProxyPlugin.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/workflow/DebuggerWorkflowServiceProxyPlugin.java index ef3bb38248..55eb491a52 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/workflow/DebuggerWorkflowServiceProxyPlugin.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/workflow/DebuggerWorkflowServiceProxyPlugin.java @@ -19,24 +19,24 @@ import java.util.Set; import ghidra.app.plugin.PluginCategoryNames; import ghidra.app.plugin.core.debug.DebuggerPluginPackage; -import ghidra.app.services.DebuggerBot; -import ghidra.app.services.DebuggerWorkflowService; +import ghidra.app.services.DebuggerWorkflowToolService; +import ghidra.debug.api.workflow.DebuggerBot; import ghidra.framework.main.AppInfo; import ghidra.framework.main.FrontEndTool; import ghidra.framework.plugintool.*; import ghidra.framework.plugintool.util.*; -@PluginInfo( // - shortDescription = "Debugger workflow service (proxy to front-end)", // - description = "Manage automatic debugging actions and analysis", // - category = PluginCategoryNames.DEBUGGER, // - packageName = DebuggerPluginPackage.NAME, // - status = PluginStatus.RELEASED, // - servicesProvided = { // - DebuggerWorkflowService.class, // - } // -) -public class DebuggerWorkflowServiceProxyPlugin extends Plugin implements DebuggerWorkflowService { +@PluginInfo( + shortDescription = "Debugger workflow service (proxy to front-end)", + description = "Manage automatic debugging actions and analysis", + category = PluginCategoryNames.DEBUGGER, + packageName = DebuggerPluginPackage.NAME, + status = PluginStatus.RELEASED, + servicesProvided = { + DebuggerWorkflowToolService.class, + }) +public class DebuggerWorkflowServiceProxyPlugin extends Plugin + implements DebuggerWorkflowToolService { protected static DebuggerWorkflowServicePlugin getOrCreateFrontEndDelegate() { FrontEndTool frontEnd = AppInfo.getFrontEndTool(); diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/workflow/MultiToolTraceListenerManager.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/workflow/MultiToolTraceListenerManager.java index 6c42b54586..0d401725bf 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/workflow/MultiToolTraceListenerManager.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/workflow/MultiToolTraceListenerManager.java @@ -19,6 +19,7 @@ import java.util.*; import java.util.function.Function; import ghidra.app.services.DebuggerTraceManagerService; +import ghidra.app.services.DebuggerWorkflowFrontEndService; import ghidra.framework.plugintool.PluginTool; import ghidra.trace.model.Trace; @@ -30,8 +31,8 @@ public class MultiToolTraceListenerManager> getChangeTypes(); - private DebuggerWorkflowServicePlugin plugin; + private DebuggerWorkflowFrontEndService service; private final MultiToolTraceListenerManager listeners = new MultiToolTraceListenerManager<>(ForChangesTraceListener::new); @@ -63,11 +64,11 @@ public abstract class AbstractMapDebuggerBot implements DebuggerBot { } @Override - public void enable(DebuggerWorkflowServicePlugin wp) { - this.plugin = wp; + public void enable(DebuggerWorkflowFrontEndService service) { + this.service = service; - listeners.enable(wp); - for (PluginTool t : plugin.getProxyingPluginTools()) { + listeners.enable(service); + for (PluginTool t : service.getProxyingPluginTools()) { DebuggerTraceManagerService traceManager = t.getService(DebuggerTraceManagerService.class); if (traceManager == null) { @@ -79,14 +80,14 @@ public abstract class AbstractMapDebuggerBot implements DebuggerBot { @Override public void disable() { - plugin = null; + service = null; listeners.disable(); } @Override public boolean isEnabled() { - return plugin != null; + return service != null; } @Override @@ -132,7 +133,7 @@ public abstract class AbstractMapDebuggerBot implements DebuggerBot { Map>> toAnalyze = new HashMap<>(); for (Trace trace : traces) { - for (PluginTool tool : plugin.getProxyingPluginTools()) { + for (PluginTool tool : service.getProxyingPluginTools()) { DebuggerTraceManagerService traceManager = tool.getService(DebuggerTraceManagerService.class); if (traceManager == null) { diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/workflow/DisassembleAtPcDebuggerBot.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/workflow/DisassembleAtPcDebuggerBot.java index 24cd2047db..8dfe25776e 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/workflow/DisassembleAtPcDebuggerBot.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/workflow/DisassembleAtPcDebuggerBot.java @@ -23,12 +23,16 @@ import javax.swing.event.ChangeListener; import db.Transaction; import docking.DockingWindowManager; import docking.Tool; -import ghidra.app.plugin.core.debug.mapping.DebuggerPlatformMapper; -import ghidra.app.plugin.core.debug.mapping.DisassemblyResult; -import ghidra.app.plugin.core.debug.service.workflow.*; -import ghidra.app.services.*; +import ghidra.app.plugin.core.debug.service.workflow.AbstractMultiToolTraceListener; +import ghidra.app.plugin.core.debug.service.workflow.MultiToolTraceListenerManager; +import ghidra.app.services.DebuggerPlatformService; +import ghidra.app.services.DebuggerWorkflowFrontEndService; import ghidra.async.AsyncDebouncer; import ghidra.async.AsyncTimer; +import ghidra.debug.api.platform.DebuggerPlatformMapper; +import ghidra.debug.api.platform.DisassemblyResult; +import ghidra.debug.api.workflow.DebuggerBot; +import ghidra.debug.api.workflow.DebuggerBotInfo; import ghidra.framework.cmd.BackgroundCommand; import ghidra.framework.model.DomainObject; import ghidra.framework.options.annotation.HelpInfo; @@ -53,12 +57,11 @@ import ghidra.util.*; import ghidra.util.classfinder.ClassSearcher; import ghidra.util.task.TaskMonitor; -@DebuggerBotInfo( // - description = "Disassemble memory at the program counter", // - details = "Listens for changes in memory or pc (stack or registers) and disassembles", // - help = @HelpInfo(anchor = "disassemble_at_pc"), // - enabledByDefault = true // -) +@DebuggerBotInfo( + description = "Disassemble memory at the program counter", + details = "Listens for changes in memory or pc (stack or registers) and disassembles", + help = @HelpInfo(anchor = "disassemble_at_pc"), + enabledByDefault = true) public class DisassembleAtPcDebuggerBot implements DebuggerBot { protected class ForDisassemblyTraceListener extends AbstractMultiToolTraceListener { @@ -338,11 +341,11 @@ public class DisassembleAtPcDebuggerBot implements DebuggerBot { } }; // TODO: Queue commands so no two for the same trace run concurrently - plugin.getTool().executeBackgroundCommand(cmd, view); + service.getTool().executeBackgroundCommand(cmd, view); } } - private DebuggerWorkflowServicePlugin plugin; + private DebuggerWorkflowFrontEndService service; private final MultiToolTraceListenerManager listeners = new MultiToolTraceListenerManager<>(ForDisassemblyTraceListener::new); @@ -351,7 +354,7 @@ public class DisassembleAtPcDebuggerBot implements DebuggerBot { } protected void reportError(String error, Throwable t) { - for (PluginTool tool : plugin.getProxyingPluginTools()) { + for (PluginTool tool : service.getProxyingPluginTools()) { Msg.error(this, error, t); tool.setStatusInfo(error, true); } @@ -370,7 +373,7 @@ public class DisassembleAtPcDebuggerBot implements DebuggerBot { * @return the service, or null */ protected T findService(Class cls) { - Collection proxied = plugin.getProxyingPluginTools(); + Collection proxied = service.getProxyingPluginTools(); List all = DockingWindowManager.getAllDockingWindowManagers(); Collections.reverse(all); for (DockingWindowManager dwm : all) { @@ -389,19 +392,19 @@ public class DisassembleAtPcDebuggerBot implements DebuggerBot { @Override public boolean isEnabled() { - return plugin != null; + return service != null; } @Override - public void enable(DebuggerWorkflowServicePlugin wp) { - this.plugin = wp; + public void enable(DebuggerWorkflowFrontEndService service) { + this.service = service; - listeners.enable(wp); + listeners.enable(service); } @Override public void disable() { - this.plugin = null; + this.service = null; listeners.disable(); } diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/workflow/MapModulesDebuggerBot.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/workflow/MapModulesDebuggerBot.java index 324d75a18a..7931cb3413 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/workflow/MapModulesDebuggerBot.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/workflow/MapModulesDebuggerBot.java @@ -17,8 +17,11 @@ package ghidra.app.plugin.core.debug.workflow; import java.util.*; -import ghidra.app.services.*; -import ghidra.app.services.ModuleMapProposal.ModuleMapEntry; +import ghidra.app.services.DebuggerStaticMappingService; +import ghidra.debug.api.modules.MapProposal; +import ghidra.debug.api.modules.ModuleMapProposal; +import ghidra.debug.api.modules.ModuleMapProposal.ModuleMapEntry; +import ghidra.debug.api.workflow.DebuggerBotInfo; import ghidra.framework.options.annotation.HelpInfo; import ghidra.framework.plugintool.PluginTool; import ghidra.program.model.listing.Program; @@ -29,12 +32,11 @@ import ghidra.trace.util.TraceChangeType; import ghidra.util.exception.CancelledException; import ghidra.util.task.TaskMonitor; -@DebuggerBotInfo( // - description = "Map modules to open programs", // - details = "Monitors open traces and programs, attempting to map modules by \"best\" match.", // - help = @HelpInfo(anchor = "map_modules"), // - enabledByDefault = true // -) +@DebuggerBotInfo( + description = "Map modules to open programs", + details = "Monitors open traces and programs, attempting to map modules by \"best\" match.", + help = @HelpInfo(anchor = "map_modules"), + enabledByDefault = true) public class MapModulesDebuggerBot extends AbstractMapDebuggerBot { @Override diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/workflow/MapRegionsDebuggerBot.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/workflow/MapRegionsDebuggerBot.java index 14a372c4e1..0c72dde00b 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/workflow/MapRegionsDebuggerBot.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/workflow/MapRegionsDebuggerBot.java @@ -17,8 +17,11 @@ package ghidra.app.plugin.core.debug.workflow; import java.util.*; -import ghidra.app.services.*; -import ghidra.app.services.RegionMapProposal.RegionMapEntry; +import ghidra.app.services.DebuggerStaticMappingService; +import ghidra.debug.api.modules.MapProposal; +import ghidra.debug.api.modules.RegionMapProposal; +import ghidra.debug.api.modules.RegionMapProposal.RegionMapEntry; +import ghidra.debug.api.workflow.DebuggerBotInfo; import ghidra.framework.options.annotation.HelpInfo; import ghidra.framework.plugintool.PluginTool; import ghidra.program.model.listing.Program; @@ -28,12 +31,11 @@ import ghidra.trace.util.TraceChangeType; import ghidra.util.exception.CancelledException; import ghidra.util.task.TaskMonitor; -@DebuggerBotInfo( // - description = "Map regions to open programs", // - details = "Monitors open traces and programs, attempting to map regions by \"best\" match.", // - help = @HelpInfo(anchor = "map_regions"), // - enabledByDefault = false // -) +@DebuggerBotInfo( + description = "Map regions to open programs", + details = "Monitors open traces and programs, attempting to map regions by \"best\" match.", + help = @HelpInfo(anchor = "map_regions"), + enabledByDefault = false) public class MapRegionsDebuggerBot extends AbstractMapDebuggerBot { @Override diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/workflow/MapSectionsDebuggerBot.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/workflow/MapSectionsDebuggerBot.java index c7a893a08d..c5251767a4 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/workflow/MapSectionsDebuggerBot.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/workflow/MapSectionsDebuggerBot.java @@ -17,8 +17,11 @@ package ghidra.app.plugin.core.debug.workflow; import java.util.*; -import ghidra.app.services.*; -import ghidra.app.services.SectionMapProposal.SectionMapEntry; +import ghidra.app.services.DebuggerStaticMappingService; +import ghidra.debug.api.modules.MapProposal; +import ghidra.debug.api.modules.SectionMapProposal; +import ghidra.debug.api.modules.SectionMapProposal.SectionMapEntry; +import ghidra.debug.api.workflow.DebuggerBotInfo; import ghidra.framework.options.annotation.HelpInfo; import ghidra.framework.plugintool.PluginTool; import ghidra.program.model.listing.Program; @@ -28,12 +31,11 @@ import ghidra.trace.util.TraceChangeType; import ghidra.util.exception.CancelledException; import ghidra.util.task.TaskMonitor; -@DebuggerBotInfo( // - description = "Map sections to open programs", // - details = "Monitors open traces and programs, attempting to map sections by \"best\" match.", // - help = @HelpInfo(anchor = "map_sections"), // - enabledByDefault = false // -) +@DebuggerBotInfo( + description = "Map sections to open programs", + details = "Monitors open traces and programs, attempting to map sections by \"best\" match.", + help = @HelpInfo(anchor = "map_sections"), + enabledByDefault = false) public class MapSectionsDebuggerBot extends AbstractMapDebuggerBot { @Override diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/workflow/ShowInterpreterDebuggerBot.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/workflow/ShowInterpreterDebuggerBot.java index 3dcf8978a2..f70ce99ec6 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/workflow/ShowInterpreterDebuggerBot.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/workflow/ShowInterpreterDebuggerBot.java @@ -17,41 +17,43 @@ package ghidra.app.plugin.core.debug.workflow; import java.util.concurrent.CompletableFuture; -import ghidra.app.plugin.core.debug.service.workflow.DebuggerWorkflowServicePlugin; -import ghidra.app.services.*; +import ghidra.app.services.DebuggerInterpreterService; +import ghidra.app.services.DebuggerWorkflowFrontEndService; import ghidra.dbg.DebugModelConventions; import ghidra.dbg.DebuggerObjectModel; import ghidra.dbg.target.TargetInterpreter; +import ghidra.debug.api.workflow.DebuggerBot; +import ghidra.debug.api.workflow.DebuggerBotInfo; import ghidra.framework.options.annotation.HelpInfo; import ghidra.framework.plugintool.PluginToolUtils; import ghidra.util.Msg; import ghidra.util.Swing; -@DebuggerBotInfo( // - description = "Show debugger interpreters", // - details = "Listens for new debuggers supporting the interpreter interface," + - " and when found, displays that interpeter.", // - help = @HelpInfo(anchor = "show_interpreter"), // - enabledByDefault = true // -) +@DebuggerBotInfo( + description = "Show debugger interpreters", + details = """ + Listens for new debuggers supporting the interpreter interface, and when found, + displays that interpeter.""", + help = @HelpInfo(anchor = "show_interpreter"), + enabledByDefault = true) public class ShowInterpreterDebuggerBot implements DebuggerBot { - private DebuggerWorkflowServicePlugin plugin; + private DebuggerWorkflowFrontEndService service; @Override - public void enable(DebuggerWorkflowServicePlugin wp) { - this.plugin = wp; + public void enable(DebuggerWorkflowFrontEndService service) { + this.service = service; // Do not retroactively display interpreters } @Override public boolean isEnabled() { - return plugin != null; + return service != null; } @Override public void disable() { - plugin = null; + service = null; } @Override @@ -64,14 +66,14 @@ public class ShowInterpreterDebuggerBot implements DebuggerBot { if (interpreter == null) { return; } - DebuggerInterpreterService service = - PluginToolUtils.getServiceFromRunningCompatibleTool(plugin.getTool(), + DebuggerInterpreterService interpreterService = + PluginToolUtils.getServiceFromRunningCompatibleTool(service.getTool(), DebuggerInterpreterService.class); - if (service == null) { + if (interpreterService == null) { return; } Swing.runIfSwingOrRunLater(() -> { - service.showConsole(interpreter); + interpreterService.showConsole(interpreter); }); }).exceptionally(ex -> { Msg.error(this, "Error displaying debugger interpreter for " + model, ex); diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/debug/flatapi/FlatDebuggerAPI.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/debug/flatapi/FlatDebuggerAPI.java index d727dec67e..d7f391a322 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/debug/flatapi/FlatDebuggerAPI.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/debug/flatapi/FlatDebuggerAPI.java @@ -23,10 +23,7 @@ import java.util.*; import java.util.concurrent.*; import java.util.stream.Collectors; -import ghidra.app.plugin.core.debug.DebuggerCoordinates; import ghidra.app.plugin.core.debug.service.emulation.ProgramEmulationUtils; -import ghidra.app.plugin.core.debug.service.model.launch.DebuggerProgramLaunchOffer; -import ghidra.app.plugin.core.debug.service.model.launch.DebuggerProgramLaunchOffer.*; import ghidra.app.script.GhidraScript; import ghidra.app.script.GhidraState; import ghidra.app.services.*; @@ -38,6 +35,12 @@ import ghidra.dbg.target.TargetExecutionStateful.TargetExecutionState; import ghidra.dbg.target.TargetLauncher.TargetCmdLineLauncher; import ghidra.dbg.target.TargetSteppable.TargetStepKind; import ghidra.dbg.util.PathUtils; +import ghidra.debug.api.breakpoint.LogicalBreakpoint; +import ghidra.debug.api.control.ControlMode; +import ghidra.debug.api.model.DebuggerProgramLaunchOffer; +import ghidra.debug.api.model.TraceRecorder; +import ghidra.debug.api.model.DebuggerProgramLaunchOffer.*; +import ghidra.debug.api.tracemgr.DebuggerCoordinates; import ghidra.pcode.exec.trace.TraceSleighUtils; import ghidra.program.flatapi.FlatProgramAPI; import ghidra.program.model.address.*; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/pcode/exec/DebuggerPcodeUtils.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/pcode/exec/DebuggerPcodeUtils.java index b31c7fd031..f81243f9f1 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/pcode/exec/DebuggerPcodeUtils.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/pcode/exec/DebuggerPcodeUtils.java @@ -19,12 +19,12 @@ import java.math.BigInteger; import java.util.*; import java.util.Map.Entry; -import ghidra.app.plugin.core.debug.DebuggerCoordinates; import ghidra.app.plugin.core.debug.service.emulation.*; import ghidra.app.plugin.core.debug.service.emulation.data.DefaultPcodeDebuggerAccess; import ghidra.app.plugin.processors.sleigh.SleighException; import ghidra.app.plugin.processors.sleigh.SleighLanguage; import ghidra.app.services.DebuggerStaticMappingService; +import ghidra.debug.api.tracemgr.DebuggerCoordinates; import ghidra.framework.plugintool.PluginTool; import ghidra.pcode.emu.ThreadPcodeExecutorState; import ghidra.pcode.exec.PcodeArithmetic.Purpose; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/pcode/exec/debug/auxiliary/AuxDebuggerEmulatorPartsFactory.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/pcode/exec/debug/auxiliary/AuxDebuggerEmulatorPartsFactory.java index 9bf0148e45..e75d75a5b0 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/pcode/exec/debug/auxiliary/AuxDebuggerEmulatorPartsFactory.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/pcode/exec/debug/auxiliary/AuxDebuggerEmulatorPartsFactory.java @@ -18,6 +18,7 @@ package ghidra.pcode.exec.debug.auxiliary; import org.apache.commons.lang3.tuple.Pair; import ghidra.app.plugin.core.debug.service.emulation.*; +import ghidra.debug.api.emulation.DebuggerPcodeEmulatorFactory; import ghidra.pcode.emu.PcodeThread; import ghidra.pcode.emu.auxiliary.AuxEmulatorPartsFactory; import ghidra.pcode.emu.auxiliary.AuxPcodeEmulator; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/pcode/exec/debug/auxiliary/AuxDebuggerPcodeEmulator.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/pcode/exec/debug/auxiliary/AuxDebuggerPcodeEmulator.java index cc8dc9aa26..5ac7843ae6 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/pcode/exec/debug/auxiliary/AuxDebuggerPcodeEmulator.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/pcode/exec/debug/auxiliary/AuxDebuggerPcodeEmulator.java @@ -18,7 +18,8 @@ package ghidra.pcode.exec.debug.auxiliary; import org.apache.commons.lang3.tuple.Pair; import ghidra.app.plugin.core.debug.service.emulation.*; -import ghidra.app.plugin.core.debug.service.emulation.data.PcodeDebuggerAccess; +import ghidra.debug.api.emulation.DebuggerPcodeMachine; +import ghidra.debug.api.emulation.PcodeDebuggerAccess; import ghidra.pcode.emu.PcodeThread; import ghidra.pcode.emu.auxiliary.AuxEmulatorPartsFactory; import ghidra.pcode.exec.trace.TracePcodeExecutorState; diff --git a/Ghidra/Debug/Debugger/src/screen/java/ghidra/app/plugin/core/debug/gui/breakpoint/DebuggerBreakpointMarkerPluginScreenShots.java b/Ghidra/Debug/Debugger/src/screen/java/ghidra/app/plugin/core/debug/gui/breakpoint/DebuggerBreakpointMarkerPluginScreenShots.java index 48ebc15dda..776c71b8c9 100644 --- a/Ghidra/Debug/Debugger/src/screen/java/ghidra/app/plugin/core/debug/gui/breakpoint/DebuggerBreakpointMarkerPluginScreenShots.java +++ b/Ghidra/Debug/Debugger/src/screen/java/ghidra/app/plugin/core/debug/gui/breakpoint/DebuggerBreakpointMarkerPluginScreenShots.java @@ -33,9 +33,12 @@ import ghidra.app.plugin.core.decompile.DecompilePlugin; import ghidra.app.plugin.core.decompile.DecompilerProvider; import ghidra.app.plugin.core.progmgr.ProgramManagerPlugin; import ghidra.app.services.*; -import ghidra.app.services.LogicalBreakpoint.State; import ghidra.app.util.viewer.listingpanel.ListingPanel; import ghidra.dbg.model.TestDebuggerModelBuilder; +import ghidra.debug.api.action.ActionSource; +import ghidra.debug.api.breakpoint.LogicalBreakpoint; +import ghidra.debug.api.breakpoint.LogicalBreakpoint.State; +import ghidra.debug.api.model.TraceRecorder; import ghidra.program.model.address.Address; import ghidra.program.model.listing.Program; import ghidra.program.util.ProgramLocation; diff --git a/Ghidra/Debug/Debugger/src/screen/java/ghidra/app/plugin/core/debug/gui/breakpoint/DebuggerBreakpointsPluginScreenShots.java b/Ghidra/Debug/Debugger/src/screen/java/ghidra/app/plugin/core/debug/gui/breakpoint/DebuggerBreakpointsPluginScreenShots.java index f48d746ba2..209ce2e260 100644 --- a/Ghidra/Debug/Debugger/src/screen/java/ghidra/app/plugin/core/debug/gui/breakpoint/DebuggerBreakpointsPluginScreenShots.java +++ b/Ghidra/Debug/Debugger/src/screen/java/ghidra/app/plugin/core/debug/gui/breakpoint/DebuggerBreakpointsPluginScreenShots.java @@ -37,6 +37,9 @@ import ghidra.dbg.target.TargetBreakpointSpec.TargetBreakpointKind; import ghidra.dbg.target.TargetBreakpointSpecContainer; import ghidra.dbg.target.TargetTogglable; import ghidra.dbg.testutil.DebuggerModelTestUtils; +import ghidra.debug.api.action.ActionSource; +import ghidra.debug.api.breakpoint.LogicalBreakpoint; +import ghidra.debug.api.model.TraceRecorder; import ghidra.program.model.address.Address; import ghidra.program.model.listing.Program; import ghidra.program.util.ProgramLocation; @@ -140,13 +143,11 @@ public class DebuggerBreakpointsPluginScreenShots extends GhidraScreenShotGenera try (Transaction tx = program.openTransaction("Add breakpoint")) { program.getBookmarkManager() - .setBookmark(addr(program, 0x00401234), - LogicalBreakpoint.BREAKPOINT_ENABLED_BOOKMARK_TYPE, "SW_EXECUTE;1", - "before connect"); + .setBookmark(addr(program, 0x00401234), LogicalBreakpoint.ENABLED_BOOKMARK_TYPE, + "SW_EXECUTE;1", "before connect"); program.getBookmarkManager() - .setBookmark(addr(program, 0x00604321), - LogicalBreakpoint.BREAKPOINT_ENABLED_BOOKMARK_TYPE, "WRITE;4", - "write version"); + .setBookmark(addr(program, 0x00604321), LogicalBreakpoint.ENABLED_BOOKMARK_TYPE, + "WRITE;4", "write version"); } TargetBreakpointSpecContainer bc1 = diff --git a/Ghidra/Debug/Debugger/src/screen/java/ghidra/app/plugin/core/debug/gui/copying/DebuggerCopyActionsPluginScreenShots.java b/Ghidra/Debug/Debugger/src/screen/java/ghidra/app/plugin/core/debug/gui/copying/DebuggerCopyActionsPluginScreenShots.java index 12bb9e1a8a..1cc0dcd343 100644 --- a/Ghidra/Debug/Debugger/src/screen/java/ghidra/app/plugin/core/debug/gui/copying/DebuggerCopyActionsPluginScreenShots.java +++ b/Ghidra/Debug/Debugger/src/screen/java/ghidra/app/plugin/core/debug/gui/copying/DebuggerCopyActionsPluginScreenShots.java @@ -29,6 +29,8 @@ import ghidra.app.plugin.core.debug.service.tracemgr.DebuggerTraceManagerService import ghidra.app.plugin.core.progmgr.ProgramManagerPlugin; import ghidra.app.services.*; import ghidra.dbg.model.TestDebuggerModelBuilder; +import ghidra.debug.api.action.ActionSource; +import ghidra.debug.api.model.TraceRecorder; import ghidra.framework.model.DomainFolder; import ghidra.program.model.address.AddressSpace; import ghidra.program.model.mem.Memory; diff --git a/Ghidra/Debug/Debugger/src/screen/java/ghidra/app/plugin/core/debug/gui/modules/DebuggerStaticMappingPluginScreenShots.java b/Ghidra/Debug/Debugger/src/screen/java/ghidra/app/plugin/core/debug/gui/modules/DebuggerStaticMappingPluginScreenShots.java index 23938841af..5a26f90a69 100644 --- a/Ghidra/Debug/Debugger/src/screen/java/ghidra/app/plugin/core/debug/gui/modules/DebuggerStaticMappingPluginScreenShots.java +++ b/Ghidra/Debug/Debugger/src/screen/java/ghidra/app/plugin/core/debug/gui/modules/DebuggerStaticMappingPluginScreenShots.java @@ -24,7 +24,9 @@ import ghidra.app.plugin.core.debug.service.modules.DebuggerStaticMappingService import ghidra.app.plugin.core.debug.service.tracemgr.DebuggerTraceManagerServicePlugin; import ghidra.app.plugin.core.progmgr.ProgramManagerPlugin; import ghidra.app.services.*; -import ghidra.app.services.ModuleMapProposal.ModuleMapEntry; +import ghidra.debug.api.modules.MapProposal; +import ghidra.debug.api.modules.ModuleMapProposal; +import ghidra.debug.api.modules.ModuleMapProposal.ModuleMapEntry; import ghidra.framework.model.DomainFolder; import ghidra.program.database.ProgramBuilder; import ghidra.program.model.address.Address; diff --git a/Ghidra/Debug/Debugger/src/screen/java/ghidra/app/plugin/core/debug/gui/stack/DebuggerStackPluginScreenShots.java b/Ghidra/Debug/Debugger/src/screen/java/ghidra/app/plugin/core/debug/gui/stack/DebuggerStackPluginScreenShots.java index d1ec26e7bb..8c5e7ee812 100644 --- a/Ghidra/Debug/Debugger/src/screen/java/ghidra/app/plugin/core/debug/gui/stack/DebuggerStackPluginScreenShots.java +++ b/Ghidra/Debug/Debugger/src/screen/java/ghidra/app/plugin/core/debug/gui/stack/DebuggerStackPluginScreenShots.java @@ -25,7 +25,6 @@ import org.junit.*; import db.Transaction; import generic.Unique; import ghidra.app.plugin.assembler.*; -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; @@ -41,6 +40,8 @@ import ghidra.app.services.*; import ghidra.app.services.DebuggerControlService.StateEditor; import ghidra.app.services.DebuggerEmulationService.EmulationResult; import ghidra.async.AsyncTestUtils; +import ghidra.debug.api.control.ControlMode; +import ghidra.debug.api.tracemgr.DebuggerCoordinates; import ghidra.framework.model.DomainFolder; import ghidra.framework.model.DomainObject; import ghidra.pcode.exec.DebuggerPcodeUtils.WatchValue; diff --git a/Ghidra/Debug/Debugger/src/screen/java/ghidra/app/plugin/core/debug/gui/stack/vars/VariableValueHoverPluginScreenShots.java b/Ghidra/Debug/Debugger/src/screen/java/ghidra/app/plugin/core/debug/gui/stack/vars/VariableValueHoverPluginScreenShots.java index c6956671da..7abeb3a9d5 100644 --- a/Ghidra/Debug/Debugger/src/screen/java/ghidra/app/plugin/core/debug/gui/stack/vars/VariableValueHoverPluginScreenShots.java +++ b/Ghidra/Debug/Debugger/src/screen/java/ghidra/app/plugin/core/debug/gui/stack/vars/VariableValueHoverPluginScreenShots.java @@ -32,7 +32,6 @@ import generic.Unique; import ghidra.app.decompiler.component.DecompilerPanel; import ghidra.app.plugin.assembler.*; 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.control.DebuggerControlServicePlugin; @@ -49,6 +48,8 @@ import ghidra.app.services.DebuggerControlService.StateEditor; import ghidra.app.services.DebuggerEmulationService.EmulationResult; import ghidra.app.util.viewer.listingpanel.ListingPanel; import ghidra.async.AsyncTestUtils; +import ghidra.debug.api.control.ControlMode; +import ghidra.debug.api.tracemgr.DebuggerCoordinates; import ghidra.framework.model.DomainFolder; import ghidra.framework.model.DomainObject; import ghidra.pcode.exec.DebuggerPcodeUtils.WatchValue; diff --git a/Ghidra/Debug/Debugger/src/screen/java/ghidra/app/plugin/core/debug/gui/thread/DebuggerThreadsPluginScreenShots.java b/Ghidra/Debug/Debugger/src/screen/java/ghidra/app/plugin/core/debug/gui/thread/DebuggerThreadsPluginScreenShots.java index 511ff9125a..457790cb79 100644 --- a/Ghidra/Debug/Debugger/src/screen/java/ghidra/app/plugin/core/debug/gui/thread/DebuggerThreadsPluginScreenShots.java +++ b/Ghidra/Debug/Debugger/src/screen/java/ghidra/app/plugin/core/debug/gui/thread/DebuggerThreadsPluginScreenShots.java @@ -25,6 +25,8 @@ import ghidra.app.plugin.core.debug.service.model.DebuggerModelServiceProxyPlugi import ghidra.app.plugin.core.debug.service.tracemgr.DebuggerTraceManagerServicePlugin; import ghidra.app.services.*; import ghidra.dbg.model.*; +import ghidra.debug.api.action.ActionSource; +import ghidra.debug.api.model.TraceRecorder; import ghidra.trace.model.Trace; import ghidra.trace.model.thread.TraceThread; import help.screenshot.GhidraScreenShotGenerator; diff --git a/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/disassemble/DebuggerDisassemblyTest.java b/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/disassemble/DebuggerDisassemblyTest.java index 9f698111c2..1ab3a9a6ff 100644 --- a/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/disassemble/DebuggerDisassemblyTest.java +++ b/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/disassemble/DebuggerDisassemblyTest.java @@ -42,6 +42,8 @@ import ghidra.app.services.*; import ghidra.dbg.target.TargetEnvironment; import ghidra.dbg.target.schema.SchemaContext; import ghidra.dbg.target.schema.TargetObjectSchema.SchemaName; +import ghidra.debug.api.control.ControlMode; +import ghidra.debug.api.workflow.DebuggerBot; import ghidra.dbg.target.schema.XmlSchemaContext; import ghidra.program.model.address.Address; import ghidra.program.model.address.AddressSet; diff --git a/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/AbstractGhidraHeadedDebuggerGUITest.java b/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/AbstractGhidraHeadedDebuggerGUITest.java index e1b0b7b702..ebdf071507 100644 --- a/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/AbstractGhidraHeadedDebuggerGUITest.java +++ b/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/AbstractGhidraHeadedDebuggerGUITest.java @@ -51,7 +51,8 @@ import ghidra.app.plugin.core.debug.gui.action.*; import ghidra.app.plugin.core.debug.gui.model.ObjectTableModel.ValueRow; import ghidra.app.plugin.core.debug.gui.model.columns.TraceValueObjectPropertyColumn; import ghidra.app.plugin.core.debug.mapping.*; -import ghidra.app.plugin.core.debug.service.model.*; +import ghidra.app.plugin.core.debug.service.model.DebuggerModelServiceInternal; +import ghidra.app.plugin.core.debug.service.model.DebuggerModelServiceProxyPlugin; import ghidra.app.plugin.core.debug.service.tracemgr.DebuggerTraceManagerServicePlugin; import ghidra.app.services.*; import ghidra.app.util.viewer.listingpanel.ListingPanel; @@ -59,6 +60,8 @@ import ghidra.dbg.model.AbstractTestTargetRegisterBank; import ghidra.dbg.model.TestDebuggerModelBuilder; import ghidra.dbg.target.*; import ghidra.dbg.testutil.DebuggerModelTestUtils; +import ghidra.debug.api.action.*; +import ghidra.debug.api.model.*; import ghidra.docking.settings.SettingsImpl; import ghidra.framework.model.*; import ghidra.framework.plugintool.PluginTool; @@ -223,7 +226,7 @@ public abstract class AbstractGhidraHeadedDebuggerGUITest public static Language getToyBE64Language() { try { return DefaultLanguageService.getLanguageService() - .getLanguage(new LanguageID(LANGID_TOYBE64)); + .getLanguage(new LanguageID(LANGID_TOYBE64)); } catch (LanguageNotFoundException e) { throw new AssertionError("Why is the Toy language missing?", e); @@ -677,8 +680,8 @@ public abstract class AbstractGhidraHeadedDebuggerGUITest protected void intoProject(DomainObject obj) { waitForDomainObject(obj); DomainFolder rootFolder = tool.getProject() - .getProjectData() - .getRootFolder(); + .getProjectData() + .getRootFolder(); waitForCondition(() -> { try { rootFolder.createFile(obj.getName(), obj, monitor); @@ -725,9 +728,9 @@ public abstract class AbstractGhidraHeadedDebuggerGUITest throws Exception { return new TestDebuggerTargetTraceMapper(target) { @Override - public TraceRecorder startRecording(DebuggerModelServicePlugin service, Trace trace) { + public TraceRecorder startRecording(PluginTool tool, Trace trace) { useTrace(trace); - return super.startRecording(service, trace); + return super.startRecording(tool, trace); } }; } @@ -819,8 +822,8 @@ public abstract class AbstractGhidraHeadedDebuggerGUITest // get() is not my favorite, but it'll do for testing // can't remove listener until observedTraceChange has completed. bank.writeRegistersNamed(values) - .thenCompose(__ -> observedTraceChange) - .get(timeoutMillis, TimeUnit.MILLISECONDS); + .thenCompose(__ -> observedTraceChange) + .get(timeoutMillis, TimeUnit.MILLISECONDS); } finally { trace.removeListener(listener); @@ -836,8 +839,8 @@ public abstract class AbstractGhidraHeadedDebuggerGUITest protected DomainFile unpack(File pack) throws Exception { return tool.getProject() - .getProjectData() - .getRootFolder() - .createFile("Restored", pack, monitor); + .getProjectData() + .getRootFolder() + .createFile("Restored", pack, monitor); } } diff --git a/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/breakpoint/DebuggerBreakpointMarkerPluginTest.java b/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/breakpoint/DebuggerBreakpointMarkerPluginTest.java index 73d27deec7..6103287e85 100644 --- a/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/breakpoint/DebuggerBreakpointMarkerPluginTest.java +++ b/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/breakpoint/DebuggerBreakpointMarkerPluginTest.java @@ -44,14 +44,18 @@ import ghidra.app.decompiler.component.DecompileData; import ghidra.app.plugin.core.codebrowser.CodeBrowserPlugin; import ghidra.app.plugin.core.debug.gui.AbstractGhidraHeadedDebuggerGUITest; import ghidra.app.plugin.core.debug.gui.DebuggerResources.*; +import ghidra.app.plugin.core.debug.gui.breakpoint.DebuggerBreakpointMarkerPlugin.AbstractToggleBreakpointAction; import ghidra.app.plugin.core.debug.gui.listing.DebuggerListingPlugin; import ghidra.app.plugin.core.debug.service.modules.DebuggerStaticMappingUtils; import ghidra.app.plugin.core.decompile.DecompilePlugin; import ghidra.app.plugin.core.decompile.DecompilerProvider; import ghidra.app.services.*; -import ghidra.app.services.LogicalBreakpoint.State; import ghidra.app.util.viewer.listingpanel.ListingPanel; import ghidra.dbg.target.TargetBreakpointSpec.TargetBreakpointKind; +import ghidra.debug.api.action.ActionSource; +import ghidra.debug.api.breakpoint.LogicalBreakpoint; +import ghidra.debug.api.breakpoint.LogicalBreakpoint.State; +import ghidra.debug.api.model.TraceRecorder; import ghidra.dbg.target.TargetBreakpointSpecContainer; import ghidra.framework.store.LockException; import ghidra.program.disassemble.Disassembler; @@ -138,8 +142,8 @@ public class DebuggerBreakpointMarkerPluginTest extends AbstractGhidraHeadedDebu .createInitializedBlock(".text", addr(program, 0x00400000), 0x1000, (byte) 0, TaskMonitor.DUMMY, false); program.getBookmarkManager() - .setBookmark(addr(program, 0x00400123), - LogicalBreakpoint.BREAKPOINT_ENABLED_BOOKMARK_TYPE, "SW_EXECUTE;1", ""); + .setBookmark(addr(program, 0x00400123), LogicalBreakpoint.ENABLED_BOOKMARK_TYPE, + "SW_EXECUTE;1", ""); } } diff --git a/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/breakpoint/DebuggerBreakpointsProviderTest.java b/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/breakpoint/DebuggerBreakpointsProviderTest.java index e1c5452718..89508ef53f 100644 --- a/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/breakpoint/DebuggerBreakpointsProviderTest.java +++ b/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/breakpoint/DebuggerBreakpointsProviderTest.java @@ -39,9 +39,13 @@ 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.*; -import ghidra.app.services.LogicalBreakpoint.State; import ghidra.dbg.model.TestTargetProcess; import ghidra.dbg.target.TargetBreakpointSpec.TargetBreakpointKind; +import ghidra.debug.api.action.ActionSource; +import ghidra.debug.api.breakpoint.LogicalBreakpoint; +import ghidra.debug.api.breakpoint.LogicalBreakpoint.State; +import ghidra.debug.api.control.ControlMode; +import ghidra.debug.api.model.TraceRecorder; import ghidra.dbg.target.TargetBreakpointSpecContainer; import ghidra.framework.store.LockException; import ghidra.program.model.address.Address; @@ -102,8 +106,8 @@ public class DebuggerBreakpointsProviderTest extends AbstractGhidraHeadedDebugge .createInitializedBlock(".text", addr(program, 0x00400000), 0x1000, (byte) 0, TaskMonitor.DUMMY, false); program.getBookmarkManager() - .setBookmark(addr(program, 0x00400123), - LogicalBreakpoint.BREAKPOINT_ENABLED_BOOKMARK_TYPE, "SW_EXECUTE;1", ""); + .setBookmark(addr(program, 0x00400123), LogicalBreakpoint.ENABLED_BOOKMARK_TYPE, + "SW_EXECUTE;1", ""); } } diff --git a/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/control/DebuggerControlPluginTest.java b/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/control/DebuggerControlPluginTest.java index 3672d49d9a..4df6f83df3 100644 --- a/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/control/DebuggerControlPluginTest.java +++ b/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/control/DebuggerControlPluginTest.java @@ -42,7 +42,6 @@ import ghidra.app.plugin.core.debug.disassemble.DebuggerDisassemblerPlugin; import ghidra.app.plugin.core.debug.disassemble.DebuggerDisassemblerPluginTestHelper; 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.control.DebuggerControlServicePlugin; import ghidra.app.plugin.core.debug.service.emulation.DebuggerEmulationServicePlugin; @@ -52,6 +51,9 @@ import ghidra.app.services.DebuggerEmulationService.EmulationResult; import ghidra.dbg.model.*; import ghidra.dbg.target.TargetObject; import ghidra.dbg.target.TargetSteppable.TargetStepKind; +import ghidra.debug.api.control.ControlMode; +import ghidra.debug.api.model.DebuggerTargetTraceMapper; +import ghidra.debug.api.model.TraceRecorder; import ghidra.pcode.exec.SuspendedPcodeExecutionException; import ghidra.program.model.address.Address; import ghidra.program.model.data.ShortDataType; diff --git a/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/control/DebuggerMethodActionsPluginTest.java b/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/control/DebuggerMethodActionsPluginTest.java index 6e000e70c2..1286e377d1 100644 --- a/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/control/DebuggerMethodActionsPluginTest.java +++ b/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/control/DebuggerMethodActionsPluginTest.java @@ -34,7 +34,6 @@ import ghidra.app.plugin.core.debug.gui.AbstractGhidraHeadedDebuggerGUITest; import ghidra.app.plugin.core.debug.gui.listing.DebuggerListingPlugin; import ghidra.app.plugin.core.debug.service.modules.DebuggerStaticMappingServicePlugin; import ghidra.app.services.DebuggerStaticMappingService; -import ghidra.app.services.TraceRecorder; import ghidra.async.AsyncUtils; import ghidra.dbg.model.*; import ghidra.dbg.target.TargetMethod; @@ -43,6 +42,7 @@ import ghidra.dbg.target.TargetObject; import ghidra.dbg.target.schema.*; import ghidra.dbg.target.schema.DefaultTargetObjectSchema.DefaultAttributeSchema; import ghidra.dbg.target.schema.TargetObjectSchema.SchemaName; +import ghidra.debug.api.model.TraceRecorder; import ghidra.program.model.address.Address; import ghidra.program.util.ProgramLocation; import ghidra.trace.model.Lifespan; diff --git a/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/copying/DebuggerCopyActionsPluginTest.java b/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/copying/DebuggerCopyActionsPluginTest.java index 2f1242891d..3c9836fb87 100644 --- a/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/copying/DebuggerCopyActionsPluginTest.java +++ b/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/copying/DebuggerCopyActionsPluginTest.java @@ -35,10 +35,10 @@ import ghidra.app.plugin.core.debug.gui.copying.DebuggerCopyIntoProgramDialog.Ra 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.modules.DebuggerStaticMappingServicePlugin; -import ghidra.app.services.ActionSource; import ghidra.app.services.DebuggerStaticMappingService; import ghidra.dbg.DebuggerModelListener; import ghidra.dbg.target.TargetObject; +import ghidra.debug.api.action.ActionSource; import ghidra.program.model.address.*; import ghidra.program.model.listing.Program; import ghidra.program.model.mem.MemoryBlock; diff --git a/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/interpreters/DebuggerInterpreterPluginTest.java b/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/interpreters/DebuggerInterpreterPluginTest.java index a8599fabcf..d7e7d4ab83 100644 --- a/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/interpreters/DebuggerInterpreterPluginTest.java +++ b/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/interpreters/DebuggerInterpreterPluginTest.java @@ -31,6 +31,7 @@ import ghidra.app.plugin.core.debug.gui.AbstractGhidraHeadedDebuggerGUITest; import ghidra.app.plugin.core.interpreter.InterpreterComponentProvider; import ghidra.dbg.model.TestTargetInterpreter.ExecuteCall; import ghidra.dbg.target.TargetConsole.Channel; +import ghidra.debug.api.interpreter.DebuggerInterpreterConnection; @Category(NightlyCategory.class) public class DebuggerInterpreterPluginTest extends AbstractGhidraHeadedDebuggerGUITest { diff --git a/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/listing/DebuggerListingProviderTest.java b/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/listing/DebuggerListingProviderTest.java index 4366be04a0..5f4af28a75 100644 --- a/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/listing/DebuggerListingProviderTest.java +++ b/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/listing/DebuggerListingProviderTest.java @@ -40,7 +40,6 @@ import ghidra.app.plugin.assembler.*; import ghidra.app.plugin.core.codebrowser.CodeBrowserPlugin; import ghidra.app.plugin.core.codebrowser.CodeViewerProvider; import ghidra.app.plugin.core.codebrowser.hover.ReferenceListingHoverPlugin; -import ghidra.app.plugin.core.debug.DebuggerCoordinates; import ghidra.app.plugin.core.debug.gui.AbstractGhidraHeadedDebuggerGUITest; import ghidra.app.plugin.core.debug.gui.DebuggerResources; import ghidra.app.plugin.core.debug.gui.DebuggerResources.FollowsCurrentThreadAction; @@ -53,6 +52,8 @@ import ghidra.app.plugin.core.debug.service.modules.DebuggerStaticMappingUtils; import ghidra.app.services.*; import ghidra.app.util.viewer.listingpanel.ListingPanel; import ghidra.async.SwingExecutorService; +import ghidra.debug.api.model.TraceRecorder; +import ghidra.debug.api.tracemgr.DebuggerCoordinates; import ghidra.framework.model.*; import ghidra.lifecycle.Unfinished; import ghidra.plugin.importer.ImporterPlugin; diff --git a/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/memory/DebuggerMemoryBytesProviderTest.java b/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/memory/DebuggerMemoryBytesProviderTest.java index 233d8f73d0..7fc41d4af2 100644 --- a/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/memory/DebuggerMemoryBytesProviderTest.java +++ b/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/memory/DebuggerMemoryBytesProviderTest.java @@ -43,7 +43,6 @@ import ghidra.GhidraOptions; import ghidra.app.plugin.core.byteviewer.ByteViewerComponent; import ghidra.app.plugin.core.byteviewer.ByteViewerPanel; import ghidra.app.plugin.core.clipboard.ClipboardPlugin; -import ghidra.app.plugin.core.debug.DebuggerCoordinates; import ghidra.app.plugin.core.debug.gui.AbstractGhidraHeadedDebuggerGUITest; import ghidra.app.plugin.core.debug.gui.DebuggerResources; import ghidra.app.plugin.core.debug.gui.DebuggerResources.FollowsCurrentThreadAction; @@ -52,6 +51,9 @@ import ghidra.app.plugin.core.debug.gui.listing.DebuggerListingPlugin; import ghidra.app.plugin.core.debug.service.control.DebuggerControlServicePlugin; import ghidra.app.services.*; import ghidra.async.SwingExecutorService; +import ghidra.debug.api.control.ControlMode; +import ghidra.debug.api.model.TraceRecorder; +import ghidra.debug.api.tracemgr.DebuggerCoordinates; import ghidra.program.model.address.*; import ghidra.program.model.lang.Register; import ghidra.program.model.lang.RegisterValue; diff --git a/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/memory/DebuggerRegionsProviderLegacyTest.java b/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/memory/DebuggerRegionsProviderLegacyTest.java index 7908510505..2814cb6056 100644 --- a/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/memory/DebuggerRegionsProviderLegacyTest.java +++ b/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/memory/DebuggerRegionsProviderLegacyTest.java @@ -34,7 +34,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.memory.DebuggerLegacyRegionsPanel.RegionTableColumns; import ghidra.app.plugin.core.debug.gui.memory.DebuggerRegionMapProposalDialog.RegionMapTableColumns; -import ghidra.app.services.RegionMapProposal.RegionMapEntry; +import ghidra.debug.api.modules.RegionMapProposal.RegionMapEntry; import ghidra.program.model.address.AddressSet; import ghidra.program.model.mem.Memory; import ghidra.program.model.mem.MemoryBlock; diff --git a/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/memory/DebuggerRegionsProviderTest.java b/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/memory/DebuggerRegionsProviderTest.java index db8a4f1981..cd817b1071 100644 --- a/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/memory/DebuggerRegionsProviderTest.java +++ b/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/memory/DebuggerRegionsProviderTest.java @@ -27,7 +27,6 @@ import db.Transaction; import docking.widgets.table.DynamicTableColumn; import generic.Unique; 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.gui.DebuggerBlockChooserDialog; import ghidra.app.plugin.core.debug.gui.DebuggerBlockChooserDialog.MemoryBlockRow; @@ -37,10 +36,11 @@ import ghidra.app.plugin.core.debug.gui.memory.DebuggerRegionMapProposalDialog.R import ghidra.app.plugin.core.debug.gui.model.ObjectTableModel.ValueProperty; import ghidra.app.plugin.core.debug.gui.model.ObjectTableModel.ValueRow; import ghidra.app.plugin.core.debug.gui.model.QueryPanelTestHelper; -import ghidra.app.services.RegionMapProposal.RegionMapEntry; import ghidra.dbg.target.TargetMemoryRegion; import ghidra.dbg.target.schema.SchemaContext; import ghidra.dbg.target.schema.TargetObjectSchema.SchemaName; +import ghidra.debug.api.modules.RegionMapProposal.RegionMapEntry; +import ghidra.debug.api.tracemgr.DebuggerCoordinates; import ghidra.dbg.target.schema.XmlSchemaContext; import ghidra.program.model.address.*; import ghidra.program.model.mem.Memory; diff --git a/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/model/DebuggerModelProviderTest.java b/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/model/DebuggerModelProviderTest.java index 11bfb5b1b8..fe6e9113ea 100644 --- a/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/model/DebuggerModelProviderTest.java +++ b/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/model/DebuggerModelProviderTest.java @@ -31,7 +31,6 @@ import docking.widgets.tree.GTree; import docking.widgets.tree.GTreeNode; import docking.widgets.tree.support.GTreeSelectionEvent.EventOrigin; import generic.Unique; -import ghidra.app.plugin.core.debug.DebuggerCoordinates; import ghidra.app.plugin.core.debug.gui.AbstractGhidraHeadedDebuggerGUITest; import ghidra.app.plugin.core.debug.gui.model.ObjectTableModel.PrimitiveRow; import ghidra.app.plugin.core.debug.gui.model.ObjectTableModel.ValueRow; @@ -42,6 +41,7 @@ import ghidra.dbg.target.TargetEventScope; import ghidra.dbg.target.TargetObject; import ghidra.dbg.target.schema.SchemaContext; import ghidra.dbg.target.schema.TargetObjectSchema.SchemaName; +import ghidra.debug.api.tracemgr.DebuggerCoordinates; import ghidra.dbg.target.schema.XmlSchemaContext; import ghidra.trace.model.Lifespan; import ghidra.trace.model.target.*; diff --git a/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/modules/DebuggerModulesProviderLegacyTest.java b/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/modules/DebuggerModulesProviderLegacyTest.java index a5a727c316..547faf1837 100644 --- a/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/modules/DebuggerModulesProviderLegacyTest.java +++ b/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/modules/DebuggerModulesProviderLegacyTest.java @@ -39,14 +39,14 @@ import ghidra.app.plugin.core.debug.gui.modules.DebuggerModulesProvider.MapModul import ghidra.app.plugin.core.debug.gui.modules.DebuggerModulesProvider.MapSectionsAction; import ghidra.app.plugin.core.debug.gui.modules.DebuggerSectionMapProposalDialog.SectionMapTableColumns; import ghidra.app.services.DebuggerListingService; -import ghidra.app.services.ModuleMapProposal.ModuleMapEntry; -import ghidra.app.services.SectionMapProposal.SectionMapEntry; -import ghidra.app.services.TraceRecorder; import ghidra.dbg.attributes.TargetPrimitiveDataType.DefaultTargetPrimitiveDataType; import ghidra.dbg.attributes.TargetPrimitiveDataType.PrimitiveKind; import ghidra.dbg.model.TestTargetModule; import ghidra.dbg.model.TestTargetTypedefDataType; import ghidra.dbg.util.TargetDataTypeConverter; +import ghidra.debug.api.model.TraceRecorder; +import ghidra.debug.api.modules.ModuleMapProposal.ModuleMapEntry; +import ghidra.debug.api.modules.SectionMapProposal.SectionMapEntry; import ghidra.framework.main.DataTreeDialog; import ghidra.plugin.importer.ImporterPlugin; import ghidra.program.model.address.AddressSet; diff --git a/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/modules/DebuggerModulesProviderTest.java b/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/modules/DebuggerModulesProviderTest.java index 88f6f794a1..8094aa9f75 100644 --- a/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/modules/DebuggerModulesProviderTest.java +++ b/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/modules/DebuggerModulesProviderTest.java @@ -30,7 +30,6 @@ import docking.widgets.filechooser.GhidraFileChooser; import docking.widgets.table.DynamicTableColumn; import generic.Unique; import generic.test.category.NightlyCategory; -import ghidra.app.plugin.core.debug.DebuggerCoordinates; import ghidra.app.plugin.core.debug.gui.*; import ghidra.app.plugin.core.debug.gui.DebuggerBlockChooserDialog.MemoryBlockRow; import ghidra.app.plugin.core.debug.gui.DebuggerResources.AbstractImportFromFileSystemAction; @@ -44,12 +43,8 @@ import ghidra.app.plugin.core.debug.gui.modules.DebuggerModuleMapProposalDialog. import ghidra.app.plugin.core.debug.gui.modules.DebuggerModulesProvider.MapModulesAction; import ghidra.app.plugin.core.debug.gui.modules.DebuggerModulesProvider.MapSectionsAction; import ghidra.app.plugin.core.debug.gui.modules.DebuggerSectionMapProposalDialog.SectionMapTableColumns; -import ghidra.app.plugin.core.debug.mapping.DebuggerTargetTraceMapper; import ghidra.app.plugin.core.debug.mapping.ObjectBasedDebuggerTargetTraceMapper; import ghidra.app.services.DebuggerListingService; -import ghidra.app.services.ModuleMapProposal.ModuleMapEntry; -import ghidra.app.services.SectionMapProposal.SectionMapEntry; -import ghidra.app.services.TraceRecorder; import ghidra.dbg.attributes.TargetPrimitiveDataType.DefaultTargetPrimitiveDataType; import ghidra.dbg.attributes.TargetPrimitiveDataType.PrimitiveKind; import ghidra.dbg.model.TestTargetModule; @@ -59,6 +54,11 @@ import ghidra.dbg.target.schema.SchemaContext; import ghidra.dbg.target.schema.TargetObjectSchema.SchemaName; import ghidra.dbg.target.schema.XmlSchemaContext; import ghidra.dbg.util.*; +import ghidra.debug.api.model.DebuggerTargetTraceMapper; +import ghidra.debug.api.model.TraceRecorder; +import ghidra.debug.api.modules.ModuleMapProposal.ModuleMapEntry; +import ghidra.debug.api.modules.SectionMapProposal.SectionMapEntry; +import ghidra.debug.api.tracemgr.DebuggerCoordinates; import ghidra.framework.main.DataTreeDialog; import ghidra.plugin.importer.ImporterPlugin; import ghidra.program.model.address.*; diff --git a/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/pcode/DebuggerPcodeStepperProviderTest.java b/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/pcode/DebuggerPcodeStepperProviderTest.java index 2124e3d5d7..2e0cd0580c 100644 --- a/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/pcode/DebuggerPcodeStepperProviderTest.java +++ b/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/pcode/DebuggerPcodeStepperProviderTest.java @@ -31,11 +31,12 @@ import ghidra.app.plugin.core.debug.gui.AbstractGhidraHeadedDebuggerGUITest; import ghidra.app.plugin.core.debug.gui.listing.DebuggerListingPlugin; import ghidra.app.plugin.core.debug.gui.pcode.DebuggerPcodeStepperProvider.PcodeRowHtmlFormatter; import ghidra.app.plugin.core.debug.service.emulation.*; -import ghidra.app.plugin.core.debug.service.emulation.data.PcodeDebuggerAccess; import ghidra.app.plugin.core.debug.service.tracemgr.DebuggerTraceManagerServicePlugin; import ghidra.app.plugin.processors.sleigh.SleighLanguage; import ghidra.app.services.DebuggerEmulationService; import ghidra.app.services.DebuggerTraceManagerService; +import ghidra.debug.api.emulation.DebuggerPcodeMachine; +import ghidra.debug.api.emulation.PcodeDebuggerAccess; import ghidra.pcode.exec.*; import ghidra.pcode.exec.PcodeExecutorStatePiece.Reason; import ghidra.pcode.exec.trace.TraceSleighUtils; diff --git a/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/platform/DebuggerPlatformPluginTest.java b/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/platform/DebuggerPlatformPluginTest.java index 5bf700b8d5..ca73dd217c 100644 --- a/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/platform/DebuggerPlatformPluginTest.java +++ b/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/platform/DebuggerPlatformPluginTest.java @@ -26,9 +26,9 @@ import org.junit.Test; import docking.action.ToggleDockingActionIf; import ghidra.app.plugin.core.debug.gui.AbstractGhidraHeadedDebuggerGUITest; -import ghidra.app.plugin.core.debug.mapping.DebuggerPlatformMapper; import ghidra.app.plugin.core.debug.mapping.DebuggerPlatformOffer; import ghidra.app.services.DebuggerPlatformService; +import ghidra.debug.api.platform.DebuggerPlatformMapper; import ghidra.program.model.lang.LanguageID; import ghidra.trace.database.ToyDBTraceBuilder; diff --git a/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/register/DebuggerRegistersProviderGuestTest.java b/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/register/DebuggerRegistersProviderGuestTest.java index ce2fa3a6ff..391ef41a17 100644 --- a/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/register/DebuggerRegistersProviderGuestTest.java +++ b/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/register/DebuggerRegistersProviderGuestTest.java @@ -15,7 +15,7 @@ */ package ghidra.app.plugin.core.debug.gui.register; -import static org.junit.Assert.*; +import static org.junit.Assert.assertEquals; import java.io.IOException; import java.util.Set; @@ -27,12 +27,12 @@ import org.junit.experimental.categories.Category; import db.Transaction; 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.control.DebuggerControlServicePlugin; -import ghidra.app.plugin.core.debug.service.model.DebuggerModelServicePlugin; -import ghidra.app.services.TraceRecorder; import ghidra.dbg.target.TargetObject; +import ghidra.debug.api.model.DebuggerTargetTraceMapper; +import ghidra.debug.api.model.TraceRecorder; +import ghidra.framework.plugintool.PluginTool; import ghidra.program.model.data.*; import ghidra.program.model.lang.*; import ghidra.trace.model.Trace; @@ -104,10 +104,9 @@ public class DebuggerRegistersProviderGuestTest extends DebuggerRegistersProvide return new ObjectBasedDebuggerTargetTraceMapper(target, new LanguageID("DATA:BE:64:default"), new CompilerSpecID("pointer64"), Set.of()) { @Override - public TraceRecorder startRecording(DebuggerModelServicePlugin service, - Trace trace) { + public TraceRecorder startRecording(PluginTool tool, Trace trace) { useTrace(trace); - return super.startRecording(service, trace); + return super.startRecording(tool, trace); } }; } diff --git a/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/register/DebuggerRegistersProviderTest.java b/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/register/DebuggerRegistersProviderTest.java index 52d2aa5c04..75c3a0733d 100644 --- a/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/register/DebuggerRegistersProviderTest.java +++ b/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/register/DebuggerRegistersProviderTest.java @@ -35,6 +35,8 @@ import ghidra.app.plugin.core.debug.gui.register.DebuggerRegistersProvider.Regis import ghidra.app.plugin.core.debug.gui.register.DebuggerRegistersProvider.RegisterTableColumns; import ghidra.app.plugin.core.debug.service.control.DebuggerControlServicePlugin; import ghidra.app.services.*; +import ghidra.debug.api.control.ControlMode; +import ghidra.debug.api.model.TraceRecorder; import ghidra.docking.settings.FormatSettingsDefinition; import ghidra.docking.settings.Settings; import ghidra.program.model.address.AddressSpace; diff --git a/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/stack/DebuggerStackProviderTest.java b/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/stack/DebuggerStackProviderTest.java index e8338bf81e..8d9fe10a96 100644 --- a/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/stack/DebuggerStackProviderTest.java +++ b/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/stack/DebuggerStackProviderTest.java @@ -25,7 +25,6 @@ import org.junit.*; import db.Transaction; import docking.widgets.table.DynamicTableColumn; -import ghidra.app.plugin.core.debug.DebuggerCoordinates; import ghidra.app.plugin.core.debug.gui.AbstractGhidraHeadedDebuggerGUITest; import ghidra.app.plugin.core.debug.gui.model.ObjectTableModel.ValueProperty; import ghidra.app.plugin.core.debug.gui.model.ObjectTableModel.ValueRow; @@ -40,6 +39,7 @@ import ghidra.dbg.target.schema.TargetObjectSchema.SchemaName; import ghidra.dbg.target.schema.XmlSchemaContext; import ghidra.dbg.util.PathPattern; import ghidra.dbg.util.PathUtils; +import ghidra.debug.api.tracemgr.DebuggerCoordinates; import ghidra.program.model.address.Address; import ghidra.program.model.address.AddressSet; import ghidra.program.model.lang.Register; diff --git a/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/thread/DebuggerThreadsProviderTest.java b/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/thread/DebuggerThreadsProviderTest.java index 56c8ea94c6..5e069f397f 100644 --- a/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/thread/DebuggerThreadsProviderTest.java +++ b/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/thread/DebuggerThreadsProviderTest.java @@ -28,14 +28,11 @@ import org.junit.experimental.categories.Category; import db.Transaction; import docking.widgets.table.*; 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.gui.model.ObjectTableModel; import ghidra.app.plugin.core.debug.gui.model.ObjectTableModel.*; import ghidra.app.plugin.core.debug.gui.model.QueryPanelTestHelper; -import ghidra.app.plugin.core.debug.mapping.DebuggerTargetTraceMapper; import ghidra.app.plugin.core.debug.mapping.ObjectBasedDebuggerTargetTraceMapper; -import ghidra.app.services.TraceRecorder; import ghidra.dbg.target.TargetExecutionStateful; import ghidra.dbg.target.TargetExecutionStateful.TargetExecutionState; import ghidra.dbg.target.TargetObject; @@ -44,6 +41,9 @@ import ghidra.dbg.target.schema.TargetObjectSchema.SchemaName; import ghidra.dbg.target.schema.XmlSchemaContext; import ghidra.dbg.util.PathPattern; import ghidra.dbg.util.PathUtils; +import ghidra.debug.api.model.DebuggerTargetTraceMapper; +import ghidra.debug.api.model.TraceRecorder; +import ghidra.debug.api.tracemgr.DebuggerCoordinates; import ghidra.program.model.lang.CompilerSpecID; import ghidra.program.model.lang.LanguageID; import ghidra.trace.model.Lifespan; diff --git a/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/watch/DebuggerWatchesProviderTest.java b/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/watch/DebuggerWatchesProviderTest.java index 4e432c1dd3..cda384585a 100644 --- a/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/watch/DebuggerWatchesProviderTest.java +++ b/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/watch/DebuggerWatchesProviderTest.java @@ -37,6 +37,9 @@ 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; +import ghidra.debug.api.action.ActionSource; +import ghidra.debug.api.control.ControlMode; +import ghidra.debug.api.model.TraceRecorder; import ghidra.docking.settings.FormatSettingsDefinition; import ghidra.docking.settings.Settings; import ghidra.framework.options.SaveState; @@ -58,7 +61,7 @@ import ghidra.util.task.TaskMonitor; public class DebuggerWatchesProviderTest extends AbstractGhidraHeadedDebuggerGUITest { - protected static void assertNoErr(WatchRow row) { + protected static void assertNoErr(DefaultWatchRow row) { Throwable error = row.getError(); if (error != null) { throw new AssertionError(error); @@ -103,7 +106,7 @@ public class DebuggerWatchesProviderTest extends AbstractGhidraHeadedDebuggerGUI @After public void tearDownWatchesProviderTest() throws Exception { - for (WatchRow row : watchesProvider.watchTableModel.getModelData()) { + for (DefaultWatchRow row : watchesProvider.watchTableModel.getModelData()) { Throwable error = row.getError(); if (error != null) { Msg.info(this, "Error on watch row: ", error); @@ -124,7 +127,7 @@ public class DebuggerWatchesProviderTest extends AbstractGhidraHeadedDebuggerGUI setRegisterValues(thread); performAction(watchesProvider.actionAdd); - WatchRow row = Unique.assertOne(watchesProvider.watchTableModel.getModelData()); + DefaultWatchRow row = Unique.assertOne(watchesProvider.watchTableModel.getModelData()); row.setExpression("r0"); traceManager.openTrace(tb.trace); @@ -143,7 +146,7 @@ public class DebuggerWatchesProviderTest extends AbstractGhidraHeadedDebuggerGUI waitForSwing(); performAction(watchesProvider.actionAdd); - WatchRow row = Unique.assertOne(watchesProvider.watchTableModel.getModelData()); + DefaultWatchRow row = Unique.assertOne(watchesProvider.watchTableModel.getModelData()); row.setExpression("r0"); setRegisterValues(thread); @@ -158,7 +161,7 @@ public class DebuggerWatchesProviderTest extends AbstractGhidraHeadedDebuggerGUI setRegisterValues(thread); performAction(watchesProvider.actionAdd); - WatchRow row = Unique.assertOne(watchesProvider.watchTableModel.getModelData()); + DefaultWatchRow row = Unique.assertOne(watchesProvider.watchTableModel.getModelData()); row.setExpression("r0"); row.setDataType(LongLongDataType.dataType); @@ -177,7 +180,7 @@ public class DebuggerWatchesProviderTest extends AbstractGhidraHeadedDebuggerGUI @Test public void testActionApplyDataType() { setRegisterValues(thread); - WatchRow row = watchesProvider.addWatch("*:4 r0"); + DefaultWatchRow row = watchesProvider.addWatch("*:4 r0"); row.setDataType(LongDataType.dataType); FormatSettingsDefinition format = FormatSettingsDefinition.DEF; format.setChoice(row.getSettings(), FormatSettingsDefinition.DECIMAL); @@ -205,7 +208,7 @@ public class DebuggerWatchesProviderTest extends AbstractGhidraHeadedDebuggerGUI setRegisterValues(thread); performAction(watchesProvider.actionAdd); - WatchRow row = Unique.assertOne(watchesProvider.watchTableModel.getModelData()); + DefaultWatchRow row = Unique.assertOne(watchesProvider.watchTableModel.getModelData()); row.setExpression("r0"); row.setDataType(LongLongDataType.dataType); @@ -231,7 +234,7 @@ public class DebuggerWatchesProviderTest extends AbstractGhidraHeadedDebuggerGUI setRegisterValues(thread); performAction(watchesProvider.actionAdd); - WatchRow row = Unique.assertOne(watchesProvider.watchTableModel.getModelData()); + DefaultWatchRow row = Unique.assertOne(watchesProvider.watchTableModel.getModelData()); row.setExpression("r0"); row.setDataType(LongLongDataType.dataType); @@ -258,7 +261,7 @@ public class DebuggerWatchesProviderTest extends AbstractGhidraHeadedDebuggerGUI setRegisterValues(thread); performAction(watchesProvider.actionAdd); - WatchRow row = Unique.assertOne(watchesProvider.watchTableModel.getModelData()); + DefaultWatchRow row = Unique.assertOne(watchesProvider.watchTableModel.getModelData()); row.setExpression("0xdeadbeef:4"); row.setDataType(LongDataType.dataType); @@ -280,7 +283,7 @@ public class DebuggerWatchesProviderTest extends AbstractGhidraHeadedDebuggerGUI setRegisterValues(thread); performAction(watchesProvider.actionAdd); - WatchRow row = Unique.assertOne(watchesProvider.watchTableModel.getModelData()); + DefaultWatchRow row = Unique.assertOne(watchesProvider.watchTableModel.getModelData()); row.setExpression("r0 + 8"); row.setDataType(LongLongDataType.dataType); @@ -330,7 +333,7 @@ public class DebuggerWatchesProviderTest extends AbstractGhidraHeadedDebuggerGUI assertArrayEquals(tb.arr(0, 0, 0, 0), buf.array()); performAction(watchesProvider.actionAdd); - WatchRow row = Unique.assertOne(watchesProvider.watchTableModel.getModelData()); + DefaultWatchRow row = Unique.assertOne(watchesProvider.watchTableModel.getModelData()); row.setExpression("*:4 r0"); row.setDataType(LongDataType.dataType); waitForWatches(); @@ -344,7 +347,7 @@ public class DebuggerWatchesProviderTest extends AbstractGhidraHeadedDebuggerGUI setRegisterValues(thread); performAction(watchesProvider.actionAdd); - WatchRow row = Unique.assertOne(watchesProvider.watchTableModel.getModelData()); + DefaultWatchRow row = Unique.assertOne(watchesProvider.watchTableModel.getModelData()); row.setExpression(expression); assertFalse(row.isRawValueEditable()); @@ -375,11 +378,11 @@ public class DebuggerWatchesProviderTest extends AbstractGhidraHeadedDebuggerGUI runTestIsEditableEmu("*:8 r0", true); } - protected WatchRow prepareTestEditEmu(String expression) { + protected DefaultWatchRow prepareTestEditEmu(String expression) { setRegisterValues(thread); performAction(watchesProvider.actionAdd); - WatchRow row = Unique.assertOne(watchesProvider.watchTableModel.getModelData()); + DefaultWatchRow row = Unique.assertOne(watchesProvider.watchTableModel.getModelData()); row.setExpression(expression); traceManager.openTrace(tb.trace); @@ -400,7 +403,7 @@ public class DebuggerWatchesProviderTest extends AbstractGhidraHeadedDebuggerGUI @Test public void testEditRegisterEmu() { - WatchRow row = prepareTestEditEmu("r0"); + DefaultWatchRow row = prepareTestEditEmu("r0"); TraceMemorySpace regVals = tb.trace.getMemoryManager().getMemoryRegisterSpace(thread, false); @@ -425,7 +428,7 @@ public class DebuggerWatchesProviderTest extends AbstractGhidraHeadedDebuggerGUI @Test public void testEditRegisterRepresentationEmu() { - WatchRow row = prepareTestEditEmu("r0"); + DefaultWatchRow row = prepareTestEditEmu("r0"); assertFalse(row.isValueEditable()); row.setDataType(DoubleDataType.dataType); @@ -448,7 +451,7 @@ public class DebuggerWatchesProviderTest extends AbstractGhidraHeadedDebuggerGUI @Test public void testEditMemoryEmu() { - WatchRow row = prepareTestEditEmu("*:8 r0"); + DefaultWatchRow row = prepareTestEditEmu("*:8 r0"); TraceMemoryOperations mem = tb.trace.getMemoryManager(); ByteBuffer buf = ByteBuffer.allocate(8); @@ -480,7 +483,7 @@ public class DebuggerWatchesProviderTest extends AbstractGhidraHeadedDebuggerGUI @Test public void testEditMemoryRepresentationEmu() { - WatchRow row = prepareTestEditEmu("*:8 r0"); + DefaultWatchRow row = prepareTestEditEmu("*:8 r0"); assertFalse(row.isValueEditable()); row.setDataType(DoubleDataType.dataType); @@ -507,7 +510,7 @@ public class DebuggerWatchesProviderTest extends AbstractGhidraHeadedDebuggerGUI @Test public void testEditMemoryStringEmu() { // Variable size must exceed that of desired string's bytes - WatchRow row = prepareTestEditEmu("*:16 r0"); + DefaultWatchRow row = prepareTestEditEmu("*:16 r0"); assertFalse(row.isValueEditable()); row.setDataType(TerminatedStringDataType.dataType); @@ -529,7 +532,7 @@ public class DebuggerWatchesProviderTest extends AbstractGhidraHeadedDebuggerGUI }); } - protected WatchRow prepareTestEditTarget(String expression) throws Throwable { + protected DefaultWatchRow prepareTestEditTarget(String expression) throws Throwable { createTestModel(); mb.createTestProcessesAndThreads(); bank = mb.testThread1.addRegisterBank(); @@ -551,7 +554,7 @@ public class DebuggerWatchesProviderTest extends AbstractGhidraHeadedDebuggerGUI waitForSwing(); performAction(watchesProvider.actionAdd); - WatchRow row = Unique.assertOne(watchesProvider.watchTableModel.getModelData()); + DefaultWatchRow row = Unique.assertOne(watchesProvider.watchTableModel.getModelData()); row.setExpression(expression); waitForWatches(); @@ -562,7 +565,7 @@ public class DebuggerWatchesProviderTest extends AbstractGhidraHeadedDebuggerGUI @Test public void testEditRegisterTarget() throws Throwable { - WatchRow row = prepareTestEditTarget("r0"); + DefaultWatchRow row = prepareTestEditTarget("r0"); runSwing(() -> row.setRawValueString("0x1234")); retryVoid(() -> { @@ -572,7 +575,7 @@ public class DebuggerWatchesProviderTest extends AbstractGhidraHeadedDebuggerGUI @Test public void testEditMemoryTarget() throws Throwable { - WatchRow row = prepareTestEditTarget("*:8 r0"); + DefaultWatchRow row = prepareTestEditTarget("*:8 r0"); // Wait for the async reads to settle. waitForPass(() -> assertEquals(tb.addr(0x00400000), row.getAddress())); @@ -585,7 +588,7 @@ public class DebuggerWatchesProviderTest extends AbstractGhidraHeadedDebuggerGUI @Test(expected = IllegalArgumentException.class) public void testEditNonMappableRegisterTarget() throws Throwable { - WatchRow row = prepareTestEditTarget("r1"); + DefaultWatchRow row = prepareTestEditTarget("r1"); TraceThread thread = recorder.getTraceThread(mb.testThread1); // Sanity check assertNull(recorder.isRegisterOnTarget(tb.host, thread, 0, r1)); @@ -649,8 +652,8 @@ public class DebuggerWatchesProviderTest extends AbstractGhidraHeadedDebuggerGUI performEnabledAction(listingProvider, watchesProvider.actionAddFromLocation, true); - List watches = new ArrayList<>(watchesProvider.watchTableModel.getModelData()); - watches.sort(Comparator.comparing(WatchRow::getExpression)); + List watches = new ArrayList<>(watchesProvider.watchTableModel.getModelData()); + watches.sort(Comparator.comparing(DefaultWatchRow::getExpression)); assertEquals(2, watches.size()); assertEquals("*:16 0x00600000:8", watches.get(0).getExpression()); assertEquals("*:16 0x00600020:8", watches.get(1).getExpression()); @@ -666,8 +669,8 @@ public class DebuggerWatchesProviderTest extends AbstractGhidraHeadedDebuggerGUI performEnabledAction(codeViewerProvider, watchesProvider.actionAddFromLocation, true); - List watches = new ArrayList<>(watchesProvider.watchTableModel.getModelData()); - watches.sort(Comparator.comparing(WatchRow::getExpression)); + List watches = new ArrayList<>(watchesProvider.watchTableModel.getModelData()); + watches.sort(Comparator.comparing(DefaultWatchRow::getExpression)); assertEquals(2, watches.size()); assertEquals("*:16 0x55750000:8", watches.get(0).getExpression()); assertEquals("*:16 0x55750020:8", watches.get(1).getExpression()); @@ -691,7 +694,7 @@ public class DebuggerWatchesProviderTest extends AbstractGhidraHeadedDebuggerGUI performEnabledAction(listingProvider, watchesProvider.actionAddFromLocation, true); - WatchRow watch = Unique.assertOne(watchesProvider.watchTableModel.getModelData()); + DefaultWatchRow watch = Unique.assertOne(watchesProvider.watchTableModel.getModelData()); assertEquals("*:8 0x00600000:8", watch.getExpression()); assertTypeEquals(structDt, watch.getDataType()); } @@ -713,7 +716,7 @@ public class DebuggerWatchesProviderTest extends AbstractGhidraHeadedDebuggerGUI performEnabledAction(codeViewerProvider, watchesProvider.actionAddFromLocation, true); - WatchRow watch = Unique.assertOne(watchesProvider.watchTableModel.getModelData()); + DefaultWatchRow watch = Unique.assertOne(watchesProvider.watchTableModel.getModelData()); assertEquals("*:8 0x55750000:8", watch.getExpression()); assertTypeEquals(structDt, watch.getDataType()); } @@ -736,7 +739,7 @@ public class DebuggerWatchesProviderTest extends AbstractGhidraHeadedDebuggerGUI performEnabledAction(registersProvider, watchesProvider.actionAddFromRegister, true); waitForWatches(); - WatchRow watch = Unique.assertOne(watchesProvider.watchTableModel.getModelData()); + DefaultWatchRow watch = Unique.assertOne(watchesProvider.watchTableModel.getModelData()); assertEquals("r0", watch.getExpression()); assertTypeEquals(PointerDataType.dataType, watch.getDataType()); } @@ -757,7 +760,7 @@ public class DebuggerWatchesProviderTest extends AbstractGhidraHeadedDebuggerGUI } performAction(watchesProvider.actionAdd); - WatchRow row = Unique.assertOne(watchesProvider.watchTableModel.getModelData()); + DefaultWatchRow row = Unique.assertOne(watchesProvider.watchTableModel.getModelData()); row.setExpression("*:8 r0"); traceManager.activateThread(thread); @@ -769,8 +772,8 @@ public class DebuggerWatchesProviderTest extends AbstractGhidraHeadedDebuggerGUI @Test public void testSaveConfigState() throws Throwable { // Setup some state - WatchRow row0 = watchesProvider.addWatch("r0"); - WatchRow row1 = watchesProvider.addWatch("*:4 r1"); + DefaultWatchRow row0 = watchesProvider.addWatch("r0"); + DefaultWatchRow row1 = watchesProvider.addWatch("*:4 r1"); row0.setDataType(LongLongDataType.dataType); Settings settings = row0.getSettings(); @@ -784,7 +787,7 @@ public class DebuggerWatchesProviderTest extends AbstractGhidraHeadedDebuggerGUI // Change some things row1.setDataType(Pointer64DataType.dataType); - WatchRow row2 = watchesProvider.addWatch("r2"); + DefaultWatchRow row2 = watchesProvider.addWatch("r2"); waitForSwing(); assertEquals(Set.of(row0, row1, row2), Set.copyOf(watchesProvider.watchTableModel.getModelData())); @@ -794,12 +797,12 @@ public class DebuggerWatchesProviderTest extends AbstractGhidraHeadedDebuggerGUI waitForSwing(); // Assert the older state - Map rows = watchesProvider.watchTableModel.getModelData() + Map rows = watchesProvider.watchTableModel.getModelData() .stream() .collect(Collectors.toMap(r -> r.getExpression(), r -> r)); assertEquals(2, rows.size()); - WatchRow rRow0 = rows.get("r0"); + DefaultWatchRow rRow0 = rows.get("r0"); assertTrue(LongLongDataType.dataType.isEquivalent(rRow0.getDataType())); assertEquals(FormatSettingsDefinition.DECIMAL, format.getChoice(rRow0.getSettings())); } diff --git a/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/mapping/DefaultDebuggerRegisterMapperTest.java b/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/mapping/DefaultDebuggerRegisterMapperTest.java index 49ca41c7ec..ff1201ea11 100644 --- a/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/mapping/DefaultDebuggerRegisterMapperTest.java +++ b/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/mapping/DefaultDebuggerRegisterMapperTest.java @@ -25,12 +25,13 @@ import org.junit.Before; import org.junit.Test; import ghidra.app.plugin.core.debug.gui.AbstractGhidraHeadedDebuggerGUITest; -import ghidra.app.services.ActionSource; -import ghidra.app.services.TraceRecorder; import ghidra.dbg.model.TestTargetRegister; import ghidra.dbg.model.TestTargetRegisterValue; import ghidra.dbg.target.TargetObject; import ghidra.dbg.target.TargetRegister; +import ghidra.debug.api.action.ActionSource; +import ghidra.debug.api.model.DebuggerRegisterMapper; +import ghidra.debug.api.model.TraceRecorder; import ghidra.program.model.lang.*; import ghidra.test.ToyProgramBuilder; import ghidra.trace.model.thread.TraceThread; diff --git a/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/mapping/LargestSubDebuggerRegisterMapperTest.java b/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/mapping/LargestSubDebuggerRegisterMapperTest.java index a537b41a00..8f88c74e48 100644 --- a/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/mapping/LargestSubDebuggerRegisterMapperTest.java +++ b/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/mapping/LargestSubDebuggerRegisterMapperTest.java @@ -24,11 +24,11 @@ import org.junit.Before; import org.junit.Test; import ghidra.app.plugin.core.debug.gui.AbstractGhidraHeadedDebuggerGUITest; -import ghidra.app.services.ActionSource; -import ghidra.app.services.TraceRecorder; import ghidra.dbg.model.*; import ghidra.dbg.target.*; import ghidra.dbg.util.CollectionUtils.Delta; +import ghidra.debug.api.action.ActionSource; +import ghidra.debug.api.model.*; import ghidra.program.model.lang.*; import ghidra.test.ToyProgramBuilder; import ghidra.trace.model.thread.TraceThread; diff --git a/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/mapping/TestDebuggerPlatformOpinion.java b/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/mapping/TestDebuggerPlatformOpinion.java index a5956da67e..2909b43bd3 100644 --- a/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/mapping/TestDebuggerPlatformOpinion.java +++ b/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/mapping/TestDebuggerPlatformOpinion.java @@ -17,6 +17,7 @@ package ghidra.app.plugin.core.debug.mapping; import java.util.Set; +import ghidra.debug.api.platform.DebuggerPlatformMapper; import ghidra.framework.plugintool.PluginTool; import ghidra.program.model.lang.*; import ghidra.trace.model.Trace; diff --git a/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/platform/gdb/DefaultGdbDebuggerMappingOpinionTest.java b/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/platform/gdb/DefaultGdbDebuggerMappingOpinionTest.java index f6cadf08e4..d62f08c30b 100644 --- a/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/platform/gdb/DefaultGdbDebuggerMappingOpinionTest.java +++ b/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/platform/gdb/DefaultGdbDebuggerMappingOpinionTest.java @@ -23,11 +23,11 @@ import java.util.stream.Collectors; import org.junit.Test; -import ghidra.app.plugin.core.debug.mapping.DebuggerMappingOffer; -import ghidra.app.plugin.core.debug.mapping.DebuggerMappingOpinion; import ghidra.app.plugin.core.debug.platform.gdb.DefaultGdbDebuggerMappingOpinion.GdbDefaultOffer; import ghidra.dbg.model.TestDebuggerObjectModel; import ghidra.dbg.model.TestTargetProcess; +import ghidra.debug.api.model.DebuggerMappingOffer; +import ghidra.debug.api.model.DebuggerMappingOpinion; import ghidra.program.model.lang.LanguageID; import ghidra.test.AbstractGhidraHeadlessIntegrationTest; diff --git a/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/platform/gdb/GdbArmDebuggerMappingOpinionTest.java b/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/platform/gdb/GdbArmDebuggerMappingOpinionTest.java index af7a580cc1..2ece30b38f 100644 --- a/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/platform/gdb/GdbArmDebuggerMappingOpinionTest.java +++ b/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/platform/gdb/GdbArmDebuggerMappingOpinionTest.java @@ -23,12 +23,12 @@ import java.util.stream.Collectors; import org.junit.Test; -import ghidra.app.plugin.core.debug.mapping.DebuggerMappingOffer; -import ghidra.app.plugin.core.debug.mapping.DebuggerMappingOpinion; import ghidra.app.plugin.core.debug.platform.gdb.GdbArmDebuggerMappingOpinion.GdbAArch64Offer; import ghidra.app.plugin.core.debug.platform.gdb.GdbArmDebuggerMappingOpinion.GdbArmOffer; import ghidra.dbg.model.TestDebuggerObjectModel; import ghidra.dbg.model.TestTargetProcess; +import ghidra.debug.api.model.DebuggerMappingOffer; +import ghidra.debug.api.model.DebuggerMappingOpinion; import ghidra.program.model.lang.LanguageID; import ghidra.test.AbstractGhidraHeadlessIntegrationTest; diff --git a/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/service/breakpoint/DebuggerLogicalBreakpointServiceTest.java b/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/service/breakpoint/DebuggerLogicalBreakpointServiceTest.java index 74785d3e96..2750350efd 100644 --- a/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/service/breakpoint/DebuggerLogicalBreakpointServiceTest.java +++ b/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/service/breakpoint/DebuggerLogicalBreakpointServiceTest.java @@ -29,12 +29,18 @@ import ghidra.app.plugin.core.debug.gui.AbstractGhidraHeadedDebuggerGUITest; 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; import ghidra.async.AsyncReference; import ghidra.dbg.model.TestTargetMemoryRegion; import ghidra.dbg.model.TestTargetProcess; import ghidra.dbg.target.*; import ghidra.dbg.target.TargetBreakpointSpec.TargetBreakpointKind; +import ghidra.debug.api.action.ActionSource; +import ghidra.debug.api.breakpoint.LogicalBreakpoint; +import ghidra.debug.api.breakpoint.LogicalBreakpointsChangeListener; +import ghidra.debug.api.breakpoint.LogicalBreakpoint.State; +import ghidra.debug.api.control.ControlMode; +import ghidra.debug.api.model.TraceRecorder; +import ghidra.debug.api.modules.DebuggerStaticMappingChangeListener; import ghidra.program.model.address.Address; import ghidra.program.model.listing.Bookmark; import ghidra.program.model.listing.Program; @@ -342,22 +348,22 @@ public class DebuggerLogicalBreakpointServiceTest extends AbstractGhidraHeadedDe protected void addProgramBreakpoints(Program p) throws Throwable { try (Transaction tx = p.openTransaction("Create bookmarks")) { enBm = p.getBookmarkManager() - .setBookmark(addr(p, 0x00400123), - LogicalBreakpoint.BREAKPOINT_ENABLED_BOOKMARK_TYPE, "SW_EXECUTE;1", ""); + .setBookmark(addr(p, 0x00400123), LogicalBreakpoint.ENABLED_BOOKMARK_TYPE, + "SW_EXECUTE;1", ""); disBm = p.getBookmarkManager() - .setBookmark(addr(p, 0x00400321), - LogicalBreakpoint.BREAKPOINT_DISABLED_BOOKMARK_TYPE, "SW_EXECUTE;1", ""); + .setBookmark(addr(p, 0x00400321), LogicalBreakpoint.DISABLED_BOOKMARK_TYPE, + "SW_EXECUTE;1", ""); } } protected void refetchProgramBreakpoints(Program p) throws Throwable { // After a redo enBm = p.getBookmarkManager() - .getBookmark(addr(p, 0x00400123), - LogicalBreakpoint.BREAKPOINT_ENABLED_BOOKMARK_TYPE, "SW_EXECUTE;1"); + .getBookmark(addr(p, 0x00400123), LogicalBreakpoint.ENABLED_BOOKMARK_TYPE, + "SW_EXECUTE;1"); disBm = p.getBookmarkManager() - .getBookmark(addr(p, 0x00400321), - LogicalBreakpoint.BREAKPOINT_DISABLED_BOOKMARK_TYPE, "SW_EXECUTE;1"); + .getBookmark(addr(p, 0x00400321), LogicalBreakpoint.DISABLED_BOOKMARK_TYPE, + "SW_EXECUTE;1"); } protected void removeProgramBreakpoints(Program p) throws Throwable { @@ -1550,9 +1556,8 @@ public class DebuggerLogicalBreakpointServiceTest extends AbstractGhidraHeadedDe protected void addEnabledProgramBreakpointWithSleigh(Program p) { try (Transaction tid = p.openTransaction("Create bookmark bp with sleigh")) { enBm = p.getBookmarkManager() - .setBookmark(addr(p, 0x00400123), - LogicalBreakpoint.BREAKPOINT_ENABLED_BOOKMARK_TYPE, "SW_EXECUTE;1", - "{sleigh: 'r0=0xbeef;'}"); + .setBookmark(addr(p, 0x00400123), LogicalBreakpoint.ENABLED_BOOKMARK_TYPE, + "SW_EXECUTE;1", "{sleigh: 'r0=0xbeef;'}"); } } diff --git a/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/service/control/DebuggerControlServiceGuestTest.java b/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/service/control/DebuggerControlServiceGuestTest.java index 9c51d6291e..b00a328d0a 100644 --- a/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/service/control/DebuggerControlServiceGuestTest.java +++ b/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/service/control/DebuggerControlServiceGuestTest.java @@ -19,11 +19,11 @@ import java.io.IOException; import java.util.Set; import db.Transaction; -import ghidra.app.plugin.core.debug.mapping.DebuggerTargetTraceMapper; import ghidra.app.plugin.core.debug.mapping.ObjectBasedDebuggerTargetTraceMapper; -import ghidra.app.plugin.core.debug.service.model.DebuggerModelServicePlugin; -import ghidra.app.services.TraceRecorder; import ghidra.dbg.target.TargetObject; +import ghidra.debug.api.model.DebuggerTargetTraceMapper; +import ghidra.debug.api.model.TraceRecorder; +import ghidra.framework.plugintool.PluginTool; import ghidra.program.model.lang.CompilerSpecID; import ghidra.program.model.lang.LanguageID; import ghidra.trace.model.Trace; @@ -72,10 +72,9 @@ public class DebuggerControlServiceGuestTest extends DebuggerControlServiceTest return new ObjectBasedDebuggerTargetTraceMapper(target, new LanguageID("DATA:BE:64:default"), new CompilerSpecID("pointer64"), Set.of()) { @Override - public TraceRecorder startRecording(DebuggerModelServicePlugin service, - Trace trace) { + public TraceRecorder startRecording(PluginTool tool, Trace trace) { useTrace(trace); - return super.startRecording(service, trace); + return super.startRecording(tool, trace); } }; } diff --git a/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/service/control/DebuggerControlServiceTest.java b/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/service/control/DebuggerControlServiceTest.java index 55b74affa8..8e252c7d27 100644 --- a/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/service/control/DebuggerControlServiceTest.java +++ b/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/service/control/DebuggerControlServiceTest.java @@ -25,12 +25,14 @@ import org.junit.Test; import db.Transaction; import ghidra.app.plugin.assembler.*; -import ghidra.app.plugin.core.debug.DebuggerCoordinates; import ghidra.app.plugin.core.debug.gui.AbstractGhidraHeadedDebuggerGUITest; import ghidra.app.services.*; import ghidra.app.services.DebuggerControlService.StateEditor; import ghidra.async.AsyncUtils.TemperamentalRunnable; import ghidra.dbg.target.TargetRegisterBank; +import ghidra.debug.api.control.ControlMode; +import ghidra.debug.api.model.TraceRecorder; +import ghidra.debug.api.tracemgr.DebuggerCoordinates; import ghidra.program.model.lang.*; import ghidra.program.model.mem.MemoryAccessException; import ghidra.trace.model.Lifespan; diff --git a/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/service/emulation/DebuggerEmulationServiceTest.java b/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/service/emulation/DebuggerEmulationServiceTest.java index de00be020c..8f56fcba21 100644 --- a/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/service/emulation/DebuggerEmulationServiceTest.java +++ b/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/service/emulation/DebuggerEmulationServiceTest.java @@ -31,14 +31,14 @@ import generic.Unique; import generic.test.category.NightlyCategory; import ghidra.app.plugin.assembler.*; import ghidra.app.plugin.core.codebrowser.CodeBrowserPlugin; -import ghidra.app.plugin.core.debug.DebuggerCoordinates; import ghidra.app.plugin.core.debug.gui.AbstractGhidraHeadedDebuggerGUITest; -import ghidra.app.plugin.core.debug.mapping.DebuggerPlatformMapper; import ghidra.app.plugin.core.debug.mapping.DebuggerPlatformOpinion; import ghidra.app.plugin.core.debug.service.platform.DebuggerPlatformServicePlugin; import ghidra.app.services.DebuggerEmulationService.EmulationResult; import ghidra.app.services.DebuggerStaticMappingService; import ghidra.app.services.DebuggerTraceManagerService.ActivationCause; +import ghidra.debug.api.platform.DebuggerPlatformMapper; +import ghidra.debug.api.tracemgr.DebuggerCoordinates; import ghidra.pcode.exec.DecodePcodeExecutionException; import ghidra.pcode.exec.InterruptPcodeExecutionException; import ghidra.pcode.utils.Utils; diff --git a/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/service/model/DebuggerModelServiceTest.java b/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/service/model/DebuggerModelServiceTest.java index 7b3fd73be6..e043ccef3a 100644 --- a/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/service/model/DebuggerModelServiceTest.java +++ b/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/service/model/DebuggerModelServiceTest.java @@ -36,15 +36,15 @@ import ghidra.app.plugin.core.debug.gui.AbstractGhidraHeadedDebuggerGUITest; import ghidra.app.plugin.core.debug.gui.DebuggerResources.AbstractConnectAction; import ghidra.app.plugin.core.debug.service.model.DebuggerConnectDialog.FactoryEntry; import ghidra.app.plugin.core.debug.service.model.TestDebuggerProgramLaunchOpinion.TestDebuggerProgramLaunchOffer; -import ghidra.app.plugin.core.debug.service.model.launch.DebuggerProgramLaunchOffer; -import ghidra.app.services.ActionSource; -import ghidra.app.services.TraceRecorder; import ghidra.async.AsyncPairingQueue; import ghidra.dbg.DebuggerModelFactory; import ghidra.dbg.DebuggerObjectModel; import ghidra.dbg.model.TestDebuggerModelFactory; import ghidra.dbg.model.TestDebuggerObjectModel; import ghidra.dbg.target.TargetEnvironment; +import ghidra.debug.api.action.ActionSource; +import ghidra.debug.api.model.DebuggerProgramLaunchOffer; +import ghidra.debug.api.model.TraceRecorder; import ghidra.trace.model.Trace; import ghidra.trace.model.thread.TraceThread; import ghidra.util.Swing; diff --git a/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/service/model/DefaultTraceRecorderTest.java b/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/service/model/DefaultTraceRecorderTest.java index f6b03a5ae9..36e751b0fb 100644 --- a/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/service/model/DefaultTraceRecorderTest.java +++ b/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/service/model/DefaultTraceRecorderTest.java @@ -24,12 +24,12 @@ import org.junit.Test; import db.Transaction; import ghidra.app.plugin.core.debug.gui.AbstractGhidraHeadedDebuggerGUITest; -import ghidra.app.plugin.core.debug.mapping.DebuggerRegisterMapper; -import ghidra.app.services.ActionSource; -import ghidra.app.services.TraceRecorder; import ghidra.dbg.model.TestTargetMemoryRegion; import ghidra.dbg.model.TestTargetRegisterBankInThread; import ghidra.dbg.util.PathUtils; +import ghidra.debug.api.action.ActionSource; +import ghidra.debug.api.model.DebuggerRegisterMapper; +import ghidra.debug.api.model.TraceRecorder; import ghidra.program.model.data.PointerDataType; import ghidra.program.model.lang.Language; import ghidra.program.model.lang.Register; diff --git a/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/service/model/TestDebuggerProgramLaunchOpinion.java b/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/service/model/TestDebuggerProgramLaunchOpinion.java index faace30e43..be62224400 100644 --- a/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/service/model/TestDebuggerProgramLaunchOpinion.java +++ b/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/service/model/TestDebuggerProgramLaunchOpinion.java @@ -19,9 +19,12 @@ import java.util.Collection; import java.util.List; import java.util.concurrent.CompletableFuture; -import ghidra.app.plugin.core.debug.service.model.launch.DebuggerProgramLaunchOffer; +import javax.swing.Icon; + +import ghidra.app.plugin.core.debug.gui.DebuggerResources; import ghidra.app.plugin.core.debug.service.model.launch.DebuggerProgramLaunchOpinion; import ghidra.app.services.DebuggerModelService; +import ghidra.debug.api.model.DebuggerProgramLaunchOffer; import ghidra.framework.plugintool.PluginTool; import ghidra.program.model.listing.Program; import ghidra.util.task.TaskMonitor; @@ -41,6 +44,11 @@ public class TestDebuggerProgramLaunchOpinion implements DebuggerProgramLaunchOp return "TEST"; } + @Override + public Icon getIcon() { + return DebuggerResources.ICON_DEBUGGER; + } + @Override public String getMenuParentTitle() { return "Debug it"; diff --git a/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/service/model/TestKnownArchDebuggerMappingOpinion.java b/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/service/model/TestKnownArchDebuggerMappingOpinion.java index d84212f2d1..703f484112 100644 --- a/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/service/model/TestKnownArchDebuggerMappingOpinion.java +++ b/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/service/model/TestKnownArchDebuggerMappingOpinion.java @@ -20,6 +20,8 @@ import java.util.Set; import ghidra.app.plugin.core.debug.mapping.*; import ghidra.dbg.target.TargetEnvironment; import ghidra.dbg.target.TargetObject; +import ghidra.debug.api.model.DebuggerMappingOffer; +import ghidra.debug.api.model.DebuggerMappingOpinion; import ghidra.program.model.lang.CompilerSpecID; import ghidra.program.model.lang.LanguageID; diff --git a/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/service/model/record/ObjectBasedTraceRecorderTest.java b/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/service/model/record/ObjectBasedTraceRecorderTest.java index c29638c7dc..e367b7f75b 100644 --- a/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/service/model/record/ObjectBasedTraceRecorderTest.java +++ b/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/service/model/record/ObjectBasedTraceRecorderTest.java @@ -27,14 +27,14 @@ import org.junit.Test; import generic.Unique; import ghidra.app.plugin.core.debug.gui.AbstractGhidraHeadedDebuggerGUITest; import ghidra.app.plugin.core.debug.mapping.*; -import ghidra.app.services.ActionSource; -import ghidra.app.services.TraceRecorder; import ghidra.dbg.error.DebuggerMemoryAccessException; import ghidra.dbg.model.*; import ghidra.dbg.target.*; import ghidra.dbg.target.TargetBreakpointSpec.TargetBreakpointKind; import ghidra.dbg.target.TargetEventScope.TargetEventType; import ghidra.dbg.target.TargetExecutionStateful.TargetExecutionState; +import ghidra.debug.api.action.ActionSource; +import ghidra.debug.api.model.*; import ghidra.program.model.address.Address; import ghidra.program.model.address.AddressRangeImpl; import ghidra.program.model.lang.Language; diff --git a/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/service/tracemgr/DebuggerTraceManagerServiceTest.java b/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/service/tracemgr/DebuggerTraceManagerServiceTest.java index 1e1220f785..c823cd6b87 100644 --- a/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/service/tracemgr/DebuggerTraceManagerServiceTest.java +++ b/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/service/tracemgr/DebuggerTraceManagerServiceTest.java @@ -25,7 +25,6 @@ import org.junit.experimental.categories.Category; import db.Transaction; 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.control.DebuggerControlServicePlugin; import ghidra.app.services.*; @@ -33,6 +32,10 @@ import ghidra.dbg.model.TestTargetStack; import ghidra.dbg.model.TestTargetStackFrameHasRegisterBank; import ghidra.dbg.target.schema.SchemaContext; import ghidra.dbg.target.schema.TargetObjectSchema.SchemaName; +import ghidra.debug.api.action.ActionSource; +import ghidra.debug.api.control.ControlMode; +import ghidra.debug.api.model.TraceRecorder; +import ghidra.debug.api.tracemgr.DebuggerCoordinates; import ghidra.dbg.target.schema.XmlSchemaContext; import ghidra.framework.model.DomainFile; import ghidra.trace.database.target.DBTraceObjectManager; diff --git a/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/stack/StackUnwinderTest.java b/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/stack/StackUnwinderTest.java index 979d64155e..900337bb37 100644 --- a/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/stack/StackUnwinderTest.java +++ b/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/stack/StackUnwinderTest.java @@ -35,7 +35,6 @@ import ghidra.app.decompiler.component.*; import ghidra.app.plugin.assembler.*; import ghidra.app.plugin.assembler.sleigh.sem.*; import ghidra.app.plugin.core.codebrowser.CodeBrowserPlugin; -import ghidra.app.plugin.core.debug.DebuggerCoordinates; import ghidra.app.plugin.core.debug.disassemble.TraceDisassembleCommand; import ghidra.app.plugin.core.debug.gui.AbstractGhidraHeadedDebuggerGUITest; import ghidra.app.plugin.core.debug.gui.listing.DebuggerListingPlugin; @@ -54,6 +53,8 @@ import ghidra.app.services.DebuggerEmulationService.EmulationResult; import ghidra.app.util.viewer.field.FieldFactory; import ghidra.app.util.viewer.field.ListingField; import ghidra.app.util.viewer.listingpanel.ListingPanel; +import ghidra.debug.api.control.ControlMode; +import ghidra.debug.api.tracemgr.DebuggerCoordinates; import ghidra.lifecycle.Unfinished; import ghidra.pcode.exec.DebuggerPcodeUtils.WatchValue; import ghidra.pcode.exec.DebuggerPcodeUtils.WatchValuePcodeArithmetic; diff --git a/Ghidra/Debug/Debugger/src/test/java/ghidra/debug/flatapi/FlatDebuggerAPITest.java b/Ghidra/Debug/Debugger/src/test/java/ghidra/debug/flatapi/FlatDebuggerAPITest.java index b066820cbc..c15f581d41 100644 --- a/Ghidra/Debug/Debugger/src/test/java/ghidra/debug/flatapi/FlatDebuggerAPITest.java +++ b/Ghidra/Debug/Debugger/src/test/java/ghidra/debug/flatapi/FlatDebuggerAPITest.java @@ -33,7 +33,6 @@ import db.Transaction; import generic.Unique; import ghidra.app.plugin.assembler.Assembler; import ghidra.app.plugin.assembler.Assemblers; -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; @@ -41,11 +40,8 @@ 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; -import ghidra.app.plugin.core.debug.service.model.launch.DebuggerProgramLaunchOffer; -import ghidra.app.plugin.core.debug.service.model.launch.DebuggerProgramLaunchOffer.LaunchResult; import ghidra.app.script.GhidraState; import ghidra.app.services.*; -import ghidra.app.services.LogicalBreakpoint.State; import ghidra.dbg.DebuggerModelFactory; import ghidra.dbg.DebuggerObjectModel; import ghidra.dbg.DebuggerObjectModel.RefreshBehavior; @@ -53,6 +49,13 @@ import ghidra.dbg.model.*; import ghidra.dbg.target.TargetLauncher.TargetCmdLineLauncher; import ghidra.dbg.target.TargetObject; import ghidra.dbg.target.TargetSteppable.TargetStepKind; +import ghidra.debug.api.breakpoint.LogicalBreakpoint; +import ghidra.debug.api.breakpoint.LogicalBreakpoint.State; +import ghidra.debug.api.control.ControlMode; +import ghidra.debug.api.model.DebuggerProgramLaunchOffer; +import ghidra.debug.api.model.TraceRecorder; +import ghidra.debug.api.model.DebuggerProgramLaunchOffer.LaunchResult; +import ghidra.debug.api.tracemgr.DebuggerCoordinates; import ghidra.program.model.address.Address; import ghidra.program.model.address.AddressSpace; import ghidra.program.model.lang.*; diff --git a/Ghidra/Debug/Debugger/src/test/java/ghidra/pcode/exec/TraceRecorderPcodeExecTest.java b/Ghidra/Debug/Debugger/src/test/java/ghidra/pcode/exec/TraceRecorderPcodeExecTest.java index 82c8727a20..e036dff4bf 100644 --- a/Ghidra/Debug/Debugger/src/test/java/ghidra/pcode/exec/TraceRecorderPcodeExecTest.java +++ b/Ghidra/Debug/Debugger/src/test/java/ghidra/pcode/exec/TraceRecorderPcodeExecTest.java @@ -23,14 +23,14 @@ import java.util.Map; import org.junit.Test; import db.Transaction; -import ghidra.app.plugin.core.debug.DebuggerCoordinates; import ghidra.app.plugin.core.debug.gui.AbstractGhidraHeadedDebuggerGUITest; -import ghidra.app.plugin.core.debug.mapping.DebuggerRegisterMapper; -import ghidra.app.plugin.core.debug.service.emulation.data.PcodeDebuggerAccess; import ghidra.app.plugin.processors.sleigh.SleighLanguage; -import ghidra.app.services.ActionSource; -import ghidra.app.services.TraceRecorder; import ghidra.dbg.model.TestTargetRegisterBankInThread; +import ghidra.debug.api.action.ActionSource; +import ghidra.debug.api.emulation.PcodeDebuggerAccess; +import ghidra.debug.api.model.DebuggerRegisterMapper; +import ghidra.debug.api.model.TraceRecorder; +import ghidra.debug.api.tracemgr.DebuggerCoordinates; import ghidra.pcode.exec.PcodeExecutorStatePiece.Reason; import ghidra.pcode.exec.trace.DirectBytesTracePcodeExecutorState; import ghidra.pcode.utils.Utils; diff --git a/Ghidra/Debug/Framework-Debugging/src/main/java/ghidra/dbg/target/TargetMethod.java b/Ghidra/Debug/Framework-Debugging/src/main/java/ghidra/dbg/target/TargetMethod.java index 94d4cbad62..f366636893 100644 --- a/Ghidra/Debug/Framework-Debugging/src/main/java/ghidra/dbg/target/TargetMethod.java +++ b/Ghidra/Debug/Framework-Debugging/src/main/java/ghidra/dbg/target/TargetMethod.java @@ -280,7 +280,7 @@ public interface TargetMethod extends TargetObject { * @param the type of the parameter * @param type the class representing the type of the parameter * @param name the name of the parameter - * @param choices the non-empty set of choices + * @param choices the non-empty set of choices. The first is the default. * @param display the human-readable name of this parameter * @param description the human-readable description of this parameter * @return the new parameter description @@ -292,6 +292,27 @@ public interface TargetMethod extends TargetObject { choices); } + /** + * Create a parameter having enumerated choices + * + * @param the type of the parameter + * @param type the class representing the type of the parameter + * @param name the name of the parameter + * @param choices the non-empty set of choices + * @param defaultValue the default value of this parameter + * @param display the human-readable name of this parameter + * @param description the human-readable description of this parameter + * @return the new parameter description + */ + public static ParameterDescription choices(Class type, String name, + Collection choices, T defaultValue, String display, String description) { + if (!choices.contains(defaultValue)) { + throw new IllegalArgumentException("Default must be one of the choices."); + } + return new ParameterDescription<>(type, name, false, defaultValue, display, description, + choices); + } + protected static boolean isRequired(Class type, Param param) { if (!type.isPrimitive()) { return param.required(); @@ -440,7 +461,7 @@ public interface TargetMethod extends TargetObject { } if (required) { throw new DebuggerIllegalArgumentException( - "Missing required parameter '" + name + "'"); + "Missing required parameter '" + display + "' (" + name + ")"); } return defaultValue; } diff --git a/Ghidra/Debug/TaintAnalysis/src/main/java/ghidra/pcode/emu/taint/full/TaintDebuggerPcodeEmulator.java b/Ghidra/Debug/TaintAnalysis/src/main/java/ghidra/pcode/emu/taint/full/TaintDebuggerPcodeEmulator.java index 056c8c59bd..5a02ea8db5 100644 --- a/Ghidra/Debug/TaintAnalysis/src/main/java/ghidra/pcode/emu/taint/full/TaintDebuggerPcodeEmulator.java +++ b/Ghidra/Debug/TaintAnalysis/src/main/java/ghidra/pcode/emu/taint/full/TaintDebuggerPcodeEmulator.java @@ -16,6 +16,7 @@ package ghidra.pcode.emu.taint.full; import ghidra.app.plugin.core.debug.service.emulation.data.*; +import ghidra.debug.api.emulation.PcodeDebuggerAccess; import ghidra.pcode.emu.taint.TaintPartsFactory; import ghidra.pcode.emu.taint.plain.TaintPcodeEmulator; import ghidra.pcode.exec.debug.auxiliary.AuxDebuggerEmulatorPartsFactory; diff --git a/Ghidra/Debug/TaintAnalysis/src/main/java/ghidra/pcode/emu/taint/full/TaintDebuggerPcodeEmulatorFactory.java b/Ghidra/Debug/TaintAnalysis/src/main/java/ghidra/pcode/emu/taint/full/TaintDebuggerPcodeEmulatorFactory.java index 0082d42867..83a44a8748 100644 --- a/Ghidra/Debug/TaintAnalysis/src/main/java/ghidra/pcode/emu/taint/full/TaintDebuggerPcodeEmulatorFactory.java +++ b/Ghidra/Debug/TaintAnalysis/src/main/java/ghidra/pcode/emu/taint/full/TaintDebuggerPcodeEmulatorFactory.java @@ -15,9 +15,9 @@ */ package ghidra.pcode.emu.taint.full; -import ghidra.app.plugin.core.debug.service.emulation.DebuggerPcodeEmulatorFactory; -import ghidra.app.plugin.core.debug.service.emulation.DebuggerPcodeMachine; -import ghidra.app.plugin.core.debug.service.emulation.data.PcodeDebuggerAccess; +import ghidra.app.plugin.core.debug.service.emulation.AbstractDebuggerPcodeEmulatorFactory; +import ghidra.debug.api.emulation.DebuggerPcodeMachine; +import ghidra.debug.api.emulation.PcodeDebuggerAccess; /** * An emulator factory for making the {@link TaintDebuggerPcodeEmulator} discoverable to the UI @@ -26,7 +26,7 @@ import ghidra.app.plugin.core.debug.service.emulation.data.PcodeDebuggerAccess; * This is the final class to create a full Debugger-integrated emulator. This class is what makes * it appear in the menu of possible emulators the user may configure. */ -public class TaintDebuggerPcodeEmulatorFactory implements DebuggerPcodeEmulatorFactory { +public class TaintDebuggerPcodeEmulatorFactory extends AbstractDebuggerPcodeEmulatorFactory { @Override public String getTitle() { diff --git a/Ghidra/Debug/TaintAnalysis/src/main/java/ghidra/taint/gui/field/TaintDebuggerRegisterColumnFactory.java b/Ghidra/Debug/TaintAnalysis/src/main/java/ghidra/taint/gui/field/TaintDebuggerRegisterColumnFactory.java index 03a0c5f54d..9ad98e2380 100644 --- a/Ghidra/Debug/TaintAnalysis/src/main/java/ghidra/taint/gui/field/TaintDebuggerRegisterColumnFactory.java +++ b/Ghidra/Debug/TaintAnalysis/src/main/java/ghidra/taint/gui/field/TaintDebuggerRegisterColumnFactory.java @@ -17,9 +17,9 @@ package ghidra.taint.gui.field; import docking.widgets.table.AbstractDynamicTableColumn; import docking.widgets.table.DynamicTableColumn; -import ghidra.app.plugin.core.debug.DebuggerCoordinates; import ghidra.app.plugin.core.debug.gui.register.DebuggerRegisterColumnFactory; import ghidra.app.plugin.core.debug.gui.register.RegisterRow; +import ghidra.debug.api.tracemgr.DebuggerCoordinates; import ghidra.docking.settings.Settings; import ghidra.framework.plugintool.ServiceProvider; import ghidra.pcode.emu.taint.trace.TaintTracePcodeExecutorStatePiece; diff --git a/Ghidra/Debug/TaintAnalysis/src/test/java/ghidra/pcode/emu/taint/full/TaintDebuggerPcodeEmulatorTest.java b/Ghidra/Debug/TaintAnalysis/src/test/java/ghidra/pcode/emu/taint/full/TaintDebuggerPcodeEmulatorTest.java index a9c781946a..4f8fcd6ce1 100644 --- a/Ghidra/Debug/TaintAnalysis/src/test/java/ghidra/pcode/emu/taint/full/TaintDebuggerPcodeEmulatorTest.java +++ b/Ghidra/Debug/TaintAnalysis/src/test/java/ghidra/pcode/emu/taint/full/TaintDebuggerPcodeEmulatorTest.java @@ -28,10 +28,10 @@ import ghidra.app.plugin.assembler.Assembler; import ghidra.app.plugin.assembler.Assemblers; import ghidra.app.plugin.core.debug.gui.AbstractGhidraHeadedDebuggerGUITest; import ghidra.app.plugin.core.debug.service.emulation.DebuggerEmulationServicePlugin; -import ghidra.app.plugin.core.debug.service.emulation.DebuggerPcodeMachine; import ghidra.app.plugin.core.debug.service.modules.DebuggerStaticMappingServicePlugin; import ghidra.app.services.DebuggerEmulationService; import ghidra.app.services.DebuggerEmulationService.EmulationResult; +import ghidra.debug.api.emulation.DebuggerPcodeMachine; import ghidra.app.services.DebuggerStaticMappingService; import ghidra.pcode.emu.taint.trace.TaintTracePcodeEmulatorTest; import ghidra.pcode.emu.taint.trace.TaintTracePcodeExecutorStatePiece; diff --git a/Ghidra/Features/Base/data/base.icons.theme.properties b/Ghidra/Features/Base/data/base.icons.theme.properties index 3792d7c068..0fc5cf6e53 100644 --- a/Ghidra/Features/Base/data/base.icons.theme.properties +++ b/Ghidra/Features/Base/data/base.icons.theme.properties @@ -180,6 +180,8 @@ icon.plugin.instructiontable.hex = hexData.png icon.plugin.interpreter.provider = icon.console +icon.plugin.terminal.terminate = icon.delete + icon.plugin.locationreferences.highlight = tag_yellow.png icon.plugin.memorymap.provider = memory16.gif diff --git a/Ghidra/Features/Base/data/base.theme.properties b/Ghidra/Features/Base/data/base.theme.properties index d9d338bcf3..9a0cdc82d1 100644 --- a/Ghidra/Features/Base/data/base.theme.properties +++ b/Ghidra/Features/Base/data/base.theme.properties @@ -5,17 +5,17 @@ color.bg.undefined = color.palette.lightgray color.flowtype.fall.through = color.palette.red color.flowtype.jump.conditional = color.palette.green color.flowtype.jump.unconditional = color.palette.blue - + color.bg.table.selection.bundle = [color]system.color.bg.selected.view color.fg.table.selection.bundle = [color]system.color.fg.selected.view color.fg.table.bundle.disabled = color.palette.darkgray color.fg.table.bundle.busy = color.palette.gray color.fg.table.bundle.inactive = color.palette.black color.fg.table.bundle.active = color.palette.green - + color.fg.table.offcut.selected = color.palette.pink -color.fg.table.offcut.unselected = color.fg.error - +color.fg.table.offcut.unselected = color.fg.error + color.bg.splash.infopanel = color.bg color.fg.dialog.equates.equate.selected = color.fg diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/cparser/ParseDialog.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/cparser/ParseDialog.java index b92947ea14..6a42cff0b5 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/cparser/ParseDialog.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/cparser/ParseDialog.java @@ -54,15 +54,14 @@ import ghidra.util.filechooser.ExtensionFileFilter; import resources.Icons; /** - * Dialog that shows files used for parsing C header files. The profile has a list of - * source header files to parse, followed by parse options (compiler directives). - * Ghidra supplies a Windows profile by default in core/parserprofiles. The user can do - * "save as" on this default profile to create new profiles that will be written to the - * user's /userprofiles directory. The CParserPlugin creates this directory if it - * doesn't exist. + * Dialog that shows files used for parsing C header files. The profile has a list of source header + * files to parse, followed by parse options (compiler directives). Ghidra supplies a Windows + * profile by default in core/parserprofiles. The user can do "save as" on this default profile to + * create new profiles that will be written to the user's /userprofiles directory. The + * CParserPlugin creates this directory if it doesn't exist. * - * The data types resulting from the parse operation can either be added to the data type - * manager in the current program, or written to an archive data file. + * The data types resulting from the parse operation can either be added to the data type manager in + * the current program, or written to an archive data file. * * * @@ -202,7 +201,8 @@ class ParseDialog extends ReusableDialogComponentProvider { comboPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); comboPanel.add(cPanel); - pathPanel = new PathnameTablePanel(null, true, false); + // enable edits, add to bottom, ordered + pathPanel = new PathnameTablePanel(null, true, false, true); pathPanel.setBorder(BorderFactory.createTitledBorder("Source files to parse")); String importDir = Preferences.getProperty(LAST_IMPORT_C_DIRECTORY); if (importDir == null) { @@ -257,7 +257,8 @@ class ParseDialog extends ReusableDialogComponentProvider { tableModel = pathPanel.getTable().getModel(); tableModel.addTableModelListener(tableListener); - includePathPanel = new PathnameTablePanel(null, true, false); + // enable edits, add to bottom, ordered + includePathPanel = new PathnameTablePanel(null, true, false, true); includePathPanel.setBorder(BorderFactory.createTitledBorder("Include paths")); includePathPanel.setFileChooserProperties("Choose Source Files", LAST_IMPORT_C_DIRECTORY, GhidraFileChooserMode.FILES_AND_DIRECTORIES, true, @@ -804,13 +805,13 @@ class ParseDialog extends ReusableDialogComponentProvider { paths = expandPaths(paths); pathPanel.setPaths(paths); - if (parseToFile) { + if (parseToFile) { if (languageIDString == null || compilerIDString == null) { Msg.showWarn(getClass(), rootPanel, "Program Architecture not Specified", "A Program Architecture must be specified in order to parse to a file."); return; } - + File file = getSaveFile(); if (file != null) { plugin.parse(paths, includePaths, options, languageIDString, compilerIDString, @@ -818,7 +819,7 @@ class ParseDialog extends ReusableDialogComponentProvider { } return; } - + plugin.parse(paths, includePaths, options); } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/terminal/DefaultTerminal.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/terminal/DefaultTerminal.java index f6e805fbe6..eebfe0eab5 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/terminal/DefaultTerminal.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/terminal/DefaultTerminal.java @@ -40,6 +40,11 @@ public class DefaultTerminal implements Terminal { Swing.runIfSwingOrRunLater(() -> provider.removeFromTool()); } + @Override + public void terminated() { + provider.terminated(); + } + @Override public void addTerminalListener(TerminalListener listener) { provider.addTerminalListener(listener); @@ -55,6 +60,16 @@ public class DefaultTerminal implements Terminal { provider.processInput(bb); } + @Override + public void setSubTitle(String title) { + Swing.runIfSwingOrRunLater(() -> provider.setSubTitle(title)); + } + + @Override + public String getSubTitle() { + return provider.getSubTitle(); + } + @Override public void setFixedSize(short cols, short rows) { provider.setFixedSize(cols, rows); @@ -114,4 +129,9 @@ public class DefaultTerminal implements Terminal { public int getCursorRow() { return provider.getCursorRow(); } + + @Override + public void setTerminateAction(Runnable action) { + Swing.runIfSwingOrRunLater(() -> provider.setTerminateAction(action)); + } } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/terminal/TerminalPlugin.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/terminal/TerminalPlugin.java index ca30fcc15c..0150af43ac 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/terminal/TerminalPlugin.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/terminal/TerminalPlugin.java @@ -52,8 +52,22 @@ public class TerminalPlugin extends Plugin implements TerminalService { clipboardService = tool.getService(ClipboardService.class); } + @Override + public void cleanTerminated() { + Swing.runIfSwingOrRunLater(this::doCleanTerminated); + } + + protected void doCleanTerminated() { + for (TerminalProvider provider : List.copyOf(providers)) { + if (provider.isTerminated()) { + provider.removeFromTool(); + } + } + } + public TerminalProvider createProvider(Charset charset, VtOutput outputCb) { return Swing.runNow(() -> { + cleanTerminated(); TerminalProvider provider = new TerminalProvider(this, charset); provider.setOutputCallback(outputCb); provider.addToTool(); diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/terminal/TerminalProvider.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/terminal/TerminalProvider.java index 80eb78e6cc..48ccac54be 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/terminal/TerminalProvider.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/terminal/TerminalProvider.java @@ -39,6 +39,7 @@ import ghidra.app.plugin.core.terminal.TerminalPanel.FindOptions; import ghidra.app.plugin.core.terminal.vt.VtOutput; import ghidra.app.services.ClipboardService; import ghidra.framework.plugintool.ComponentProviderAdapter; +import ghidra.util.Swing; /** * A window holding a VT100 terminal emulator. @@ -156,6 +157,9 @@ public class TerminalProvider extends ComponentProviderAdapter { protected DockingAction actionFind; protected DockingAction actionFindNext; protected DockingAction actionFindPrevious; + protected DockingAction actionTerminate; + + private boolean terminated = false; public TerminalProvider(TerminalPlugin plugin, Charset charset) { super(plugin.getTool(), "Terminal", plugin.getName()); @@ -168,6 +172,7 @@ public class TerminalProvider extends ComponentProviderAdapter { } }); createActions(); + setWindowMenuGroup("Terminals"); } @Override @@ -209,20 +214,23 @@ public class TerminalProvider extends ComponentProviderAdapter { protected void createActions() { actionFind = new ActionBuilder("Find", plugin.getName()) .menuIcon(new GIcon("icon.search")) - .menuPath(new String[] { "Find" }) + .menuPath("Find") + .menuGroup("Find") .keyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_F, InputEvent.CTRL_DOWN_MASK | InputEvent.SHIFT_DOWN_MASK)) .onAction(this::activatedFind) .buildAndInstallLocal(this); actionFindNext = new ActionBuilder("Find Next", plugin.getName()) - .menuPath(new String[] { "Find Next" }) + .menuPath("Find Next") + .menuGroup("Find") .keyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_H, InputEvent.CTRL_DOWN_MASK | InputEvent.SHIFT_DOWN_MASK)) .enabledWhen(this::isEnabledFindStep) .onAction(this::activatedFindNext) .buildAndInstallLocal(this); actionFindPrevious = new ActionBuilder("Find Previous", plugin.getName()) - .menuPath(new String[] { "Find Previous" }) + .menuPath("Find Previous") + .menuGroup("Find") .keyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_G, InputEvent.CTRL_DOWN_MASK | InputEvent.SHIFT_DOWN_MASK)) .enabledWhen(this::isEnabledFindStep) @@ -337,4 +345,51 @@ public class TerminalProvider extends ComponentProviderAdapter { public int getCursorRow() { return panel.getCursorRow(); } + + /** + * Notify the provider that the terminal's session has terminated + * + *

+ * The title and sub title are adjusted and all terminal listeners are removed. If/when the + * window is closed, it is removed from the tool. + */ + public void terminated() { + Swing.runIfSwingOrRunLater(() -> { + terminated = true; + removeLocalAction(actionTerminate); + panel.terminalListeners.clear(); + setTitle("[Terminal]"); + setSubTitle("Terminated"); + if (!isVisible()) { + removeFromTool(); + } + }); + } + + public boolean isTerminated() { + return terminated; + } + + public void setTerminateAction(Runnable action) { + if (actionTerminate != null) { + removeLocalAction(actionTerminate); + } + if (action != null) { + actionTerminate = new ActionBuilder("Terminate", plugin.getName()) + .menuIcon(new GIcon("icon.plugin.terminal.terminate")) + .menuPath("Terminate") + .menuGroup("Terminate") + .enabledWhen(ctx -> true) + .onAction(ctx -> action.run()) + .buildAndInstallLocal(this); + } + } + + @Override + public void closeComponent() { + super.closeComponent(); + if (terminated) { + removeFromTool(); + } + } } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/services/Terminal.java b/Ghidra/Features/Base/src/main/java/ghidra/app/services/Terminal.java index c24eba8066..20b422d73d 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/services/Terminal.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/services/Terminal.java @@ -60,6 +60,23 @@ public interface Terminal extends AutoCloseable { injectDisplayOutput(ByteBuffer.wrap(arr)); } + /** + * Set the pane's sub title + * + *

+ * The application may also set this sub title using an escape sequence. + * + * @param title the new sub title + */ + void setSubTitle(String title); + + /** + * Get the pane's current sub title + * + * @return the sub title + */ + String getSubTitle(); + /** * Set the terminal size to the given dimensions, and do not resize it to the window. * @@ -170,4 +187,20 @@ public interface Terminal extends AutoCloseable { @Override void close(); + + /** + * Notify the terminal that its session has terminated + * + *

+ * The title and sub title are adjust and all listeners are removed. If/when the terminal is + * closed, it is permanently removed from the tool. + */ + void terminated(); + + /** + * Allow the user to terminate the session forcefully + * + * @param action the action to terminate the session, or null to remove the action + */ + void setTerminateAction(Runnable action); } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/services/TerminalService.java b/Ghidra/Features/Base/src/main/java/ghidra/app/services/TerminalService.java index 1cb2565441..d0573fc3ef 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/services/TerminalService.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/services/TerminalService.java @@ -116,4 +116,12 @@ public interface TerminalService { * @return the terminal */ Terminal createWithStreams(Charset charset, InputStream in, OutputStream out); + + /** + * Remove all terminals whose sessions have terminated from the tool + * + *

+ * This is done automatically when creating any new terminal. + */ + void cleanTerminated(); } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/opinion/LibraryPathsDialog.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/opinion/LibraryPathsDialog.java index 2adbb3d948..c879612201 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/opinion/LibraryPathsDialog.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/opinion/LibraryPathsDialog.java @@ -15,10 +15,8 @@ */ package ghidra.app.util.opinion; -import javax.swing.JComponent; - -import docking.DialogComponentProvider; import docking.widgets.filechooser.GhidraFileChooserMode; +import docking.widgets.pathmanager.AbstractPathsDialog; import docking.widgets.pathmanager.PathnameTablePanel; import ghidra.app.util.importer.LibrarySearchPathManager; @@ -26,40 +24,35 @@ import ghidra.app.util.importer.LibrarySearchPathManager; * Dialog for editing Library Search Paths which are used by the importer to locate referenced * shared libraries. */ -public class LibraryPathsDialog extends DialogComponentProvider { - - private PathnameTablePanel tablePanel; +public class LibraryPathsDialog extends AbstractPathsDialog { public LibraryPathsDialog() { super("Edit Library Paths"); - addWorkPanel(buildWorkPanel()); - addOKButton(); - addCancelButton(); - setPreferredSize(600, 400); - setRememberSize(false); - } - - private JComponent buildWorkPanel() { - String[] libraryPaths = LibrarySearchPathManager.getLibraryPaths(); - tablePanel = new PathnameTablePanel(libraryPaths, false, true, () -> reset()); - // false=> not editable, true=> add new paths to top of the table - - tablePanel.setFileChooserProperties("Select Directory or Filesystem", - "LibrarySearchDirectory", GhidraFileChooserMode.FILES_AND_DIRECTORIES, false, null); - - return tablePanel; - } - - private void reset() { - LibrarySearchPathManager.reset(); - tablePanel.setPaths(LibrarySearchPathManager.getLibraryPaths()); } @Override - protected void okCallback() { - String[] paths = tablePanel.getPaths(); - LibrarySearchPathManager.setLibraryPaths(paths); - close(); + protected String[] loadPaths() { + return LibrarySearchPathManager.getLibraryPaths(); } + @Override + protected void savePaths(String[] paths) { + LibrarySearchPathManager.setLibraryPaths(paths); + } + + @Override + protected PathnameTablePanel newPathnameTablePanel() { + // disable edits, add to top, ordered + PathnameTablePanel tablePanel = + new PathnameTablePanel(null, this::reset, false, true, true); + tablePanel.setFileChooserProperties("Select Directory or Filesystem", + "LibrarySearchDirectory", GhidraFileChooserMode.FILES_AND_DIRECTORIES, false, null); + return tablePanel; + } + + @Override + protected void reset() { + LibrarySearchPathManager.reset(); + super.reset(); + } } diff --git a/Ghidra/Features/SystemEmulation/ghidra_scripts/EmuDeskCheckScript.java b/Ghidra/Features/SystemEmulation/ghidra_scripts/EmuDeskCheckScript.java index cff92c2e48..635334ea5b 100644 --- a/Ghidra/Features/SystemEmulation/ghidra_scripts/EmuDeskCheckScript.java +++ b/Ghidra/Features/SystemEmulation/ghidra_scripts/EmuDeskCheckScript.java @@ -19,13 +19,13 @@ import java.util.*; import org.apache.commons.lang3.tuple.Pair; -import ghidra.app.plugin.core.debug.gui.watch.WatchRow; import ghidra.app.plugin.core.debug.service.emulation.BytesDebuggerPcodeEmulator; import ghidra.app.plugin.core.debug.service.emulation.data.DefaultPcodeDebuggerAccess; import ghidra.app.plugin.processors.sleigh.SleighLanguage; import ghidra.app.script.GhidraScript; import ghidra.app.services.DebuggerWatchesService; import ghidra.app.tablechooser.*; +import ghidra.debug.api.watch.WatchRow; import ghidra.debug.flatapi.FlatDebuggerAPI; import ghidra.docking.settings.*; import ghidra.pcode.emu.BytesPcodeThread; diff --git a/Ghidra/Framework/Docking/src/main/java/docking/menu/MultipleActionDockingToolbarButton.java b/Ghidra/Framework/Docking/src/main/java/docking/menu/MultipleActionDockingToolbarButton.java index 68038daec5..01c4828894 100644 --- a/Ghidra/Framework/Docking/src/main/java/docking/menu/MultipleActionDockingToolbarButton.java +++ b/Ghidra/Framework/Docking/src/main/java/docking/menu/MultipleActionDockingToolbarButton.java @@ -132,7 +132,7 @@ public class MultipleActionDockingToolbarButton extends EmptyBorderButton { return new Rectangle(leftIconWidth, 0, rightButtonWidth, height); } - private ActionContext getActionContext() { + protected ActionContext getActionContext() { ComponentProvider provider = getComponentProvider(); ActionContext context = provider == null ? null : provider.getActionContext(null); final ActionContext actionContext = context == null ? new DefaultActionContext() : context; @@ -152,7 +152,7 @@ public class MultipleActionDockingToolbarButton extends EmptyBorderButton { * * @return the popup menu that was shown */ - JPopupMenu showPopup() { + protected JPopupMenu showPopup() { if (popupIsShowing()) { popupMenu.setVisible(false); @@ -175,6 +175,16 @@ public class MultipleActionDockingToolbarButton extends EmptyBorderButton { return null; } + JPopupMenu menu = doCreateMenu(); + + menu.addPopupMenuListener(popupListener); + Point p = getPopupPoint(); + menu.show(this, p.x, p.y); + return menu; + } + + protected JPopupMenu doCreateMenu() { + JPopupMenu menu = new JPopupMenu(); List actionList = multipleAction.getActionList(getActionContext()); for (DockingActionIf dockingAction : actionList) { @@ -203,10 +213,6 @@ public class MultipleActionDockingToolbarButton extends EmptyBorderButton { menu.add(item); } - - menu.addPopupMenuListener(popupListener); - Point p = getPopupPoint(); - menu.show(this, p.x, p.y); return menu; } diff --git a/Ghidra/Framework/Docking/src/main/java/docking/widgets/pathmanager/AbstractPathsDialog.java b/Ghidra/Framework/Docking/src/main/java/docking/widgets/pathmanager/AbstractPathsDialog.java new file mode 100644 index 0000000000..e84f294cd2 --- /dev/null +++ b/Ghidra/Framework/Docking/src/main/java/docking/widgets/pathmanager/AbstractPathsDialog.java @@ -0,0 +1,58 @@ +/* ### + * 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.widgets.pathmanager; + +import javax.swing.JComponent; + +import docking.DialogComponentProvider; + +public abstract class AbstractPathsDialog extends DialogComponentProvider { + + protected final PathnameTablePanel tablePanel; + + protected AbstractPathsDialog(String title) { + super(title); + tablePanel = newPathnameTablePanel(); + addWorkPanel(buildWorkPanel()); + addOKButton(); + addCancelButton(); + setPreferredSize(600, 400); + setRememberSize(false); + } + + protected abstract String[] loadPaths(); + + protected abstract void savePaths(String[] paths); + + protected abstract PathnameTablePanel newPathnameTablePanel(); + + protected void reset() { + String[] paths = loadPaths(); + tablePanel.setPaths(paths); + } + + protected JComponent buildWorkPanel() { + reset(); + return tablePanel; + } + + @Override + protected void okCallback() { + String[] paths = tablePanel.getPaths(); + savePaths(paths); + close(); + } +} diff --git a/Ghidra/Framework/Docking/src/main/java/docking/widgets/pathmanager/AbstractTypedPropertyEditor.java b/Ghidra/Framework/Docking/src/main/java/docking/widgets/pathmanager/AbstractTypedPropertyEditor.java new file mode 100644 index 0000000000..4a03093b3b --- /dev/null +++ b/Ghidra/Framework/Docking/src/main/java/docking/widgets/pathmanager/AbstractTypedPropertyEditor.java @@ -0,0 +1,119 @@ +/* ### + * 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.widgets.pathmanager; + +import java.awt.*; +import java.beans.*; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +public abstract class AbstractTypedPropertyEditor implements PropertyEditor { + private final List listeners = new ArrayList<>(); + + private T value = getInitialValue(); + + protected T getInitialValue() { + return null; + } + + @SuppressWarnings("unchecked") + protected T cast(Object value) { + return (T) value; + } + + @Override + public void setValue(Object value) { + T newValue = cast(value); + if (Objects.equals(newValue, this.value)) { + return; + } + T oldValue; + List listeners; + synchronized (this.listeners) { + oldValue = this.value; + this.value = newValue; + if (this.listeners.isEmpty()) { + return; + } + listeners = List.copyOf(this.listeners); + } + PropertyChangeEvent evt = new PropertyChangeEvent(this, null, oldValue, newValue); + for (PropertyChangeListener l : listeners) { + l.propertyChange(evt); + } + } + + @Override + public T getValue() { + return value; + } + + @Override + public boolean isPaintable() { + return false; + } + + @Override + public void paintValue(Graphics gfx, Rectangle box) { + // Not paintable + } + + @Override + public String getJavaInitializationString() { + return "???"; + } + + protected String toText(T value) { + return Objects.toString(value); + } + + @Override + public String getAsText() { + return toText(value); + } + + protected abstract T fromText(String text); + + @Override + public void setAsText(String text) throws IllegalArgumentException { + setValue(fromText(text)); + } + + @Override + public String[] getTags() { + return null; + } + + @Override + public boolean supportsCustomEditor() { + return true; + } + + @Override + public void addPropertyChangeListener(PropertyChangeListener listener) { + synchronized (listeners) { + listeners.add(listener); + } + } + + @Override + public void removePropertyChangeListener(PropertyChangeListener listener) { + synchronized (listeners) { + listeners.add(listener); + } + } +} diff --git a/Ghidra/Framework/Docking/src/main/java/docking/widgets/pathmanager/PathnameTableModel.java b/Ghidra/Framework/Docking/src/main/java/docking/widgets/pathmanager/PathnameTableModel.java index b2c0f981d5..3bce6b5b4f 100644 --- a/Ghidra/Framework/Docking/src/main/java/docking/widgets/pathmanager/PathnameTableModel.java +++ b/Ghidra/Framework/Docking/src/main/java/docking/widgets/pathmanager/PathnameTableModel.java @@ -1,6 +1,5 @@ /* ### * IP: GHIDRA - * REVIEWED: YES * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,7 +16,7 @@ package docking.widgets.pathmanager; import java.awt.Rectangle; -import java.util.ArrayList; +import java.util.*; import javax.swing.JTable; import javax.swing.table.AbstractTableModel; @@ -27,9 +26,9 @@ class PathnameTableModel extends AbstractTableModel { private ArrayList pathList; private boolean isEditable; - + /** - * @param paths initial list of paths; may be null + * @param paths initial list of paths; may be null * @param isEditable true if the path should be editable * */ @@ -38,37 +37,40 @@ class PathnameTableModel extends AbstractTableModel { this.isEditable = isEditable; pathList = new ArrayList(); if (paths != null) { - for (int i=0; i getColumnClass(int columnIndex) { + public Class getColumnClass(int columnIndex) { return String.class; } @Override - public boolean isCellEditable(int rowIndex, int columnIndex) { + public boolean isCellEditable(int rowIndex, int columnIndex) { return isEditable; } @Override - public void setValueAt(Object aValue, int rowIndex, int columnIndex) { + public void setValueAt(Object aValue, int rowIndex, int columnIndex) { pathList.remove(rowIndex); pathList.add(rowIndex, aValue.toString()); super.fireTableCellUpdated(rowIndex, 0); } + @Override public int getRowCount() { return pathList.size(); } + @Override public Object getValueAt(int rowIndex, int columnIndex) { if (rowIndex >= pathList.size()) { return null; @@ -79,32 +81,32 @@ class PathnameTableModel extends AbstractTableModel { void setEditingEnabled(boolean isEditable) { this.isEditable = isEditable; } - + void remove(int[] selectedRows) { String[] paths = new String[selectedRows.length]; - for (int i=0; i= pathList.size()) { return; } String path = pathList.remove(index); - int newIndex=0; + int newIndex = 0; if (index == 0) { // place it last in the list pathList.add(path); - newIndex = pathList.size()-1; + newIndex = pathList.size() - 1; } else { - newIndex = index-1; + newIndex = index - 1; pathList.add(newIndex, path); } notifyDataChanged(table, newIndex); @@ -115,43 +117,48 @@ class PathnameTableModel extends AbstractTableModel { return; } int size = pathList.size(); - int newIndex=0; + int newIndex = 0; String path = pathList.remove(index); - if (index == size-1) { + if (index == size - 1) { // move to the top of the list pathList.add(0, path); } else { - newIndex = index+1; - pathList.add(index+1, path); + newIndex = index + 1; + pathList.add(index + 1, path); } notifyDataChanged(table, newIndex); } - void addPaths(String[] paths, boolean addToTop) { - for (int i=0;i paths = new TreeSet<>(pathList); + pathList.clear(); + pathList.addAll(paths); + } + private void notifyDataChanged(JTable table, int newIndex) { fireTableDataChanged(); table.setRowSelectionInterval(newIndex, newIndex); Rectangle rect = table.getCellRect(newIndex, 0, true); table.scrollRectToVisible(rect); } - } diff --git a/Ghidra/Framework/Docking/src/main/java/docking/widgets/pathmanager/PathnameTablePanel.java b/Ghidra/Framework/Docking/src/main/java/docking/widgets/pathmanager/PathnameTablePanel.java index 6562cf9fb8..40360789d8 100644 --- a/Ghidra/Framework/Docking/src/main/java/docking/widgets/pathmanager/PathnameTablePanel.java +++ b/Ghidra/Framework/Docking/src/main/java/docking/widgets/pathmanager/PathnameTablePanel.java @@ -30,16 +30,15 @@ import docking.widgets.filechooser.GhidraFileChooserMode; import docking.widgets.table.*; import generic.theme.GIcon; import ghidra.framework.preferences.Preferences; -import ghidra.util.filechooser.GhidraFileChooserModel; import ghidra.util.filechooser.GhidraFileFilter; import resources.Icons; import utility.function.Callback; /** - * Component that has a table to show pathnames; the panel includes buttons to control - * the order of the paths, and to add and remove paths. The add button brings up a - * file chooser. Call the setFileChooser() method to control how the file chooser should - * behave. If the table entries should not be edited, call setEditingEnabled(false). + * Component that has a table to show pathnames; the panel includes buttons to control the order of + * the paths, and to add and remove paths. The add button brings up a file chooser. Call the + * setFileChooser() method to control how the file chooser should behave. If the table entries + * should not be edited, call setEditingEnabled(false). */ public class PathnameTablePanel extends JPanel { @@ -57,6 +56,7 @@ public class PathnameTablePanel extends JPanel { private boolean allowMultiFileSelection; private GhidraFileFilter filter; private boolean addToTop; + private boolean ordered; private Callback resetCallback; @@ -64,30 +64,43 @@ public class PathnameTablePanel extends JPanel { /** * Construct a new PathnameTablePanel. + * * @param paths list of paths to show; may be null - * @param enableEdits true if edits should be allowed - * @param addToTop true if new paths are to be added to the top of the table, false - * if new paths are to be added to the end of the table + * @param enableEdits true to allow editing of entries directly in the table, i.e., via + * the cell editor. The add and remove buttons still allow modification of the list. + * @param addToTop true if the add button should add entries to the top of the list. False to + * add entries to the bottom. This behavior is overridden if if {@code ordered} is + * false. + * @param ordered true if the order of entries matters. If so, up and down buttons are provided + * so the user may arrange the entries. If not, entries are sorted alphabetically. */ - public PathnameTablePanel(String[] paths, boolean enableEdits, boolean addToTop) { + public PathnameTablePanel(String[] paths, boolean enableEdits, boolean addToTop, + boolean ordered) { super(new BorderLayout(5, 5)); this.addToTop = addToTop; + this.ordered = ordered; tableModel = new PathnameTableModel(paths, enableEdits); create(); } /** - * Construct a new PathnameTablePanel will a reset button + * Construct a new PathnameTablePanel with a reset button + * * @param paths list of paths to show; may be null - * @param enableEdits true if edits should be allowed - * @param addToTop true if new paths are to be added to the top of the table, false - * @param resetCallback Callback containing the action to perform if the reset button is pressed - * if new paths are to be added to the end of the table + * @param resetCallback callback containing the action to perform if the reset button is pressed + * @param enableEdits true to allow editing of entries directly in the table, i.e., via + * the cell editor. The add and remove buttons still allow modification of the list. + * @param addToTop true if the add button should add entries to the top of the list. False to + * add entries to the bottom. This behavior is overridden if if {@code ordered} is + * false. + * @param ordered true if the order of entries matters. If so, up and down buttons are provided + * so the user may arrange the entries. If not, entries are sorted alphabetically. */ - public PathnameTablePanel(String[] paths, boolean enableEdits, boolean addToTop, - Callback resetCallback) { + public PathnameTablePanel(String[] paths, Callback resetCallback, boolean enableEdits, + boolean addToTop, boolean ordered) { super(new BorderLayout(5, 5)); this.addToTop = addToTop; + this.ordered = ordered; this.resetCallback = resetCallback; tableModel = new PathnameTableModel(paths, enableEdits); create(); @@ -95,9 +108,10 @@ public class PathnameTablePanel extends JPanel { /** * Set properties on the file chooser that is displayed when the "Add" button is pressed. + * * @param title title of the file chooser - * @param preferenceForLastSelectedDir Preference to use as the current directory in the - * file chooser + * @param preferenceForLastSelectedDir Preference to use as the current directory in the file + * chooser * @param selectionMode mode defined in GhidraFileFilter, e.g., GhidraFileFilter.FILES_ONLY * @param allowMultiSelection true if multiple files can be selected * @param filter filter to use; may be null if no filtering is required @@ -115,6 +129,7 @@ public class PathnameTablePanel extends JPanel { /** * Set whether the entries in the table can be edited. + * * @param enableEdits false means to not allow editing; the table is editable by default. */ public void setEditingEnabled(boolean enableEdits) { @@ -122,14 +137,35 @@ public class PathnameTablePanel extends JPanel { } /** - * Set whether new paths should be added to the top of the table (true) or at the end of - * the table (false). + * Set whether new paths should be added to the top of the table (true) or at the end of the + * table (false). + * * @param addToTop true means to add to the top of the table */ public void setAddToTop(boolean addToTop) { this.addToTop = addToTop; } + /** + * Set whether the order of entries in the table matters. + * + *

+ * WARNING: When this is set to false, the entries are immediately sorted and the up and + * down buttons removed. Setting it back to true will replace the buttons, but will not + * restore the order. In general, this should be set once, at the start of the table's life + * cycle. + * + * @param ordered true means the user can control the order, false means they cannot. + */ + public void setOrdered(boolean ordered) { + this.ordered = ordered; + upButton.setVisible(ordered); + downButton.setVisible(ordered); + if (!ordered) { + tableModel.sortPaths(); + } + } + public String[] getPaths() { String[] paths = new String[tableModel.getRowCount()]; for (int i = 0; i < paths.length; i++) { @@ -139,7 +175,7 @@ public class PathnameTablePanel extends JPanel { } public void setPaths(String[] paths) { - tableModel.setPaths(paths); + tableModel.setPaths(paths, !ordered); } public JTable getTable() { @@ -160,13 +196,15 @@ public class PathnameTablePanel extends JPanel { upButton.setName("UpArrow"); upButton.setToolTipText("Move the selected path up in list"); upButton.addActionListener(e -> up()); + upButton.setVisible(ordered); downButton = new GButton(Icons.DOWN_ICON); downButton.setName("DownArrow"); downButton.setToolTipText("Move the selected path down in list"); downButton.addActionListener(e -> down()); + downButton.setVisible(ordered); addButton = new GButton(Icons.ADD_ICON); addButton.setName("AddPath"); - addButton.setToolTipText("Display file chooser to select files to add"); + addButton.setToolTipText("Display file chooser to select paths to add"); addButton.addActionListener(e -> add()); removeButton = new GButton(Icons.DELETE_ICON); removeButton.setName("RemovePath"); @@ -178,30 +216,13 @@ public class PathnameTablePanel extends JPanel { resetButton.setToolTipText("Resets path list to the default values"); resetButton.addActionListener(e -> reset()); - JPanel buttonPanel = new JPanel(new GridBagLayout()); - GridBagConstraints gbc = new GridBagConstraints(); - gbc.anchor = GridBagConstraints.NORTH; - gbc.insets = new Insets(0, 0, 0, 0); - gbc.gridx = 0; - gbc.gridy = 0; - buttonPanel.add(upButton, gbc); - gbc.gridy = 1; - buttonPanel.add(downButton, gbc); - gbc.gridy = 2; - buttonPanel.add(addButton, gbc); - + Box buttonBox = Box.createVerticalBox(); + buttonBox.add(upButton); + buttonBox.add(downButton); + buttonBox.add(addButton); + buttonBox.add(removeButton); if (resetCallback != null) { - gbc.gridy = 3; - buttonPanel.add(removeButton, gbc); - - gbc.weighty = 1; - gbc.gridy = 4; - buttonPanel.add(resetButton, gbc); - } - else { - gbc.weighty = 1; - gbc.gridy = 3; - buttonPanel.add(removeButton, gbc); + buttonBox.add(resetButton); } pathnameTable = new GTable(tableModel); @@ -216,7 +237,7 @@ public class PathnameTablePanel extends JPanel { setDefaultCellRenderer(); add(scrollPane, BorderLayout.CENTER); - add(buttonPanel, BorderLayout.EAST); + add(buttonBox, BorderLayout.EAST); ListSelectionModel selModel = pathnameTable.getSelectionModel(); selModel.addListSelectionListener(e -> { @@ -300,17 +321,7 @@ public class PathnameTablePanel extends JPanel { fileChooser.setTitle(title); fileChooser.setApproveButtonToolTipText(title); if (filter != null) { - fileChooser.addFileFilter(new GhidraFileFilter() { - @Override - public String getDescription() { - return filter.getDescription(); - } - - @Override - public boolean accept(File f, GhidraFileChooserModel model) { - return filter.accept(f, model); - } - }); + fileChooser.addFileFilter(filter); } String dir = Preferences.getProperty(preferenceForLastSelectedDir); if (dir != null) { @@ -318,26 +329,20 @@ public class PathnameTablePanel extends JPanel { } List files = fileChooser.getSelectedFiles(); - String[] paths = new String[0]; + String[] paths = files.stream().map(File::getAbsolutePath).toArray(String[]::new); if (!files.isEmpty()) { if (allowMultiFileSelection) { String parent = files.get(0).getParent(); Preferences.setProperty(preferenceForLastSelectedDir, parent); - paths = new String[files.size()]; - for (int i = 0; i < files.size(); i++) { - paths[i] = files.get(i).getAbsolutePath(); - } } else { - paths = new String[1]; - paths[0] = files.get(0).getAbsolutePath(); Preferences.setProperty(preferenceForLastSelectedDir, paths[0]); } } fileChooser.dispose(); - tableModel.addPaths(paths, addToTop); + tableModel.addPaths(paths, addToTop, !ordered); } private void up() { @@ -350,13 +355,19 @@ public class PathnameTablePanel extends JPanel { tableModel.moveDown(pathnameTable, row); } + protected int promptConfirmReset() { + String confirmation = """ + + Are you sure you would like to reset the paths to the default list? + This will remove all paths manually added. + """; + String header = "Reset Paths?"; + + return OptionDialog.showYesNoDialog(this, header, confirmation); + } + private void reset() { - String confirmation = "Are you sure you would like to reset\nlibrary" + - " paths to the default list? This\nwill remove all paths manually added."; - String header = "Reset Library Paths?"; - - int optionChosen = OptionDialog.showYesNoDialog(this, header, confirmation); - + int optionChosen = promptConfirmReset(); if (resetCallback != null && optionChosen == OptionDialog.YES_OPTION) { resetCallback.call(); } diff --git a/Ghidra/Framework/Generic/src/main/java/ghidra/util/task/ConsoleTaskMonitor.java b/Ghidra/Framework/Generic/src/main/java/ghidra/util/task/ConsoleTaskMonitor.java index 97f2e54339..6bc91eb257 100644 --- a/Ghidra/Framework/Generic/src/main/java/ghidra/util/task/ConsoleTaskMonitor.java +++ b/Ghidra/Framework/Generic/src/main/java/ghidra/util/task/ConsoleTaskMonitor.java @@ -22,7 +22,7 @@ import ghidra.util.Msg; */ public class ConsoleTaskMonitor extends TaskMonitorAdapter { @Override - public void setMessage(String msg) { + public void setMessage(String msg) { Msg.info(this, msg); } } diff --git a/Ghidra/Framework/Gui/src/main/java/generic/theme/GIcon.java b/Ghidra/Framework/Gui/src/main/java/generic/theme/GIcon.java index 7c0bbe8dcb..ee6e5be272 100644 --- a/Ghidra/Framework/Gui/src/main/java/generic/theme/GIcon.java +++ b/Ghidra/Framework/Gui/src/main/java/generic/theme/GIcon.java @@ -57,7 +57,7 @@ public class GIcon implements Icon { /** * Construct a GIcon with an id that will be used to look up the current icon associated with * that id, which can be changed at runtime. - * @param id the id used to lookup the current value for this color + * @param id the id used to lookup the current value for this icon */ public GIcon(String id) { this.id = id; diff --git a/Ghidra/Framework/Pty/src/main/java/ghidra/pty/PtyChild.java b/Ghidra/Framework/Pty/src/main/java/ghidra/pty/PtyChild.java index 9c98fc69d2..32f6a3aec8 100644 --- a/Ghidra/Framework/Pty/src/main/java/ghidra/pty/PtyChild.java +++ b/Ghidra/Framework/Pty/src/main/java/ghidra/pty/PtyChild.java @@ -58,6 +58,9 @@ public interface PtyChild extends PtyEndpoint { PtySession session(String[] args, Map env, Collection mode) throws IOException; + /** + * @see #session(String[], Map, Collection) + */ default PtySession session(String[] args, Map env, TermMode... mode) throws IOException { return session(args, env, List.of(mode)); @@ -82,6 +85,9 @@ public interface PtyChild extends PtyEndpoint { */ String nullSession(Collection mode) throws IOException; + /** + * @see #nullSession(Collection) + */ default String nullSession(TermMode... mode) throws IOException { return nullSession(List.of(mode)); } diff --git a/Ghidra/Framework/Pty/src/main/java/ghidra/pty/linux/FdInputStream.java b/Ghidra/Framework/Pty/src/main/java/ghidra/pty/linux/FdInputStream.java index 3bc948b66d..0b580ca1f5 100644 --- a/Ghidra/Framework/Pty/src/main/java/ghidra/pty/linux/FdInputStream.java +++ b/Ghidra/Framework/Pty/src/main/java/ghidra/pty/linux/FdInputStream.java @@ -18,6 +18,7 @@ package ghidra.pty.linux; import java.io.IOException; import java.io.InputStream; +import com.sun.jna.LastErrorException; import com.sun.jna.Memory; /** @@ -69,7 +70,16 @@ public class FdInputStream extends InputStream { return 0; } Memory buf = new Memory(len); - int ret = LIB_POSIX.read(fd, buf, len); + int ret; + try { + ret = LIB_POSIX.read(fd, buf, len); + } + catch (LastErrorException e) { + if (e.getErrorCode() == 5) { + throw new IOException(e); + } + throw e; + } buf.read(0, b, off, ret); return ret; } diff --git a/Ghidra/Framework/Pty/src/main/java/ghidra/pty/linux/LinuxPtySessionLeader.java b/Ghidra/Framework/Pty/src/main/java/ghidra/pty/linux/LinuxPtySessionLeader.java index 6c555bc37d..e5615cec93 100644 --- a/Ghidra/Framework/Pty/src/main/java/ghidra/pty/linux/LinuxPtySessionLeader.java +++ b/Ghidra/Framework/Pty/src/main/java/ghidra/pty/linux/LinuxPtySessionLeader.java @@ -68,6 +68,8 @@ public class LinuxPtySessionLeader { LIB_POSIX.execv(subArgs.get(0), subArgs.toArray(new String[0])); } catch (Throwable t) { + // Print to both redirected and to inherited stderr + System.err.println("Could not execute " + subArgs.get(0) + ": " + t.getMessage()); if (bk != -1) { try { int bkt = bk; diff --git a/Ghidra/Test/IntegrationTest/src/screen/java/ghidraclass/debugger/screenshot/TutorialDebuggerScreenShots.java b/Ghidra/Test/IntegrationTest/src/screen/java/ghidraclass/debugger/screenshot/TutorialDebuggerScreenShots.java index 781940d350..518387b960 100644 --- a/Ghidra/Test/IntegrationTest/src/screen/java/ghidraclass/debugger/screenshot/TutorialDebuggerScreenShots.java +++ b/Ghidra/Test/IntegrationTest/src/screen/java/ghidraclass/debugger/screenshot/TutorialDebuggerScreenShots.java @@ -61,12 +61,9 @@ import ghidra.app.plugin.core.debug.gui.thread.DebuggerThreadsProvider; import ghidra.app.plugin.core.debug.gui.time.DebuggerTimeProvider; import ghidra.app.plugin.core.debug.gui.time.DebuggerTimeSelectionDialog; import ghidra.app.plugin.core.debug.gui.watch.DebuggerWatchesProvider; -import ghidra.app.plugin.core.debug.gui.watch.WatchRow; import ghidra.app.plugin.core.debug.service.emulation.DebuggerEmulationServicePlugin; import ghidra.app.plugin.core.debug.service.emulation.DebuggerEmulationServicePlugin.EmulateProgramAction; import ghidra.app.plugin.core.debug.service.model.DebuggerConnectDialog; -import ghidra.app.plugin.core.debug.service.model.launch.DebuggerProgramLaunchOffer; -import ghidra.app.plugin.core.debug.service.model.launch.DebuggerProgramLaunchOffer.*; import ghidra.app.plugin.core.debug.stack.StackUnwinderTest; import ghidra.app.plugin.core.debug.stack.StackUnwinderTest.HoverLocation; import ghidra.app.plugin.core.debug.stack.UnwindStackCommand; @@ -84,6 +81,10 @@ import ghidra.dbg.target.TargetLauncher; import ghidra.dbg.target.TargetLauncher.TargetCmdLineLauncher; import ghidra.dbg.testutil.DummyProc; import ghidra.dbg.util.ConfigurableFactory.Property; +import ghidra.debug.api.model.DebuggerProgramLaunchOffer; +import ghidra.debug.api.model.DebuggerProgramLaunchOffer.*; +import ghidra.debug.api.watch.WatchRow; +import ghidra.debug.api.workflow.DebuggerBot; import ghidra.debug.flatapi.FlatDebuggerAPI; import ghidra.framework.Application; import ghidra.framework.TestApplicationUtils; diff --git a/Ghidra/Test/IntegrationTest/src/test.slow/java/agent/dbgeng/rmi/AbstractDbgEngTraceRmiTest.java b/Ghidra/Test/IntegrationTest/src/test.slow/java/agent/dbgeng/rmi/AbstractDbgEngTraceRmiTest.java index 6631cb0507..1614829771 100644 --- a/Ghidra/Test/IntegrationTest/src/test.slow/java/agent/dbgeng/rmi/AbstractDbgEngTraceRmiTest.java +++ b/Ghidra/Test/IntegrationTest/src/test.slow/java/agent/dbgeng/rmi/AbstractDbgEngTraceRmiTest.java @@ -15,55 +15,30 @@ */ package agent.dbgeng.rmi; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; +import static org.junit.Assert.*; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.OutputStream; -import java.net.InetAddress; -import java.net.InetSocketAddress; -import java.net.SocketAddress; -import java.net.SocketTimeoutException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.Set; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; +import java.io.*; +import java.net.*; +import java.nio.file.*; +import java.util.*; +import java.util.concurrent.*; import java.util.function.Function; -import java.util.regex.Matcher; -import java.util.regex.Pattern; -import java.util.stream.Collectors; import org.apache.commons.lang3.exception.ExceptionUtils; import org.junit.Before; import ghidra.app.plugin.core.debug.gui.AbstractGhidraHeadedDebuggerGUITest; -import ghidra.app.plugin.core.debug.service.rmi.trace.RemoteAsyncResult; -import ghidra.app.plugin.core.debug.service.rmi.trace.RemoteMethod; -import ghidra.app.plugin.core.debug.service.rmi.trace.TraceRmiAcceptor; -import ghidra.app.plugin.core.debug.service.rmi.trace.TraceRmiHandler; import ghidra.app.plugin.core.debug.service.rmi.trace.TraceRmiPlugin; import ghidra.app.plugin.core.debug.utils.ManagedDomainObject; import ghidra.app.services.TraceRmiService; import ghidra.dbg.testutil.DummyProc; -import ghidra.framework.Application; -import ghidra.framework.OperatingSystem; -import ghidra.framework.TestApplicationUtils; +import ghidra.debug.api.tracermi.*; +import ghidra.framework.*; import ghidra.framework.main.ApplicationLevelOnlyPlugin; import ghidra.framework.model.DomainFile; import ghidra.framework.plugintool.Plugin; import ghidra.framework.plugintool.PluginsConfiguration; -import ghidra.framework.plugintool.util.PluginDescription; -import ghidra.framework.plugintool.util.PluginException; -import ghidra.framework.plugintool.util.PluginPackage; +import ghidra.framework.plugintool.util.*; import ghidra.program.model.address.Address; import ghidra.program.model.address.AddressRangeImpl; import ghidra.trace.model.Lifespan; @@ -174,10 +149,10 @@ public abstract class AbstractDbgEngTraceRmiTest extends AbstractGhidraHeadedDeb // If commands come from file, Python will quit after EOF. Msg.info(this, "outFile: " + outFile); Msg.info(this, "errFile: " + errFile); - + //pb.inheritIO(); pb.redirectInput(ProcessBuilder.Redirect.PIPE); - pb.redirectOutput(outFile.toFile()); + pb.redirectOutput(outFile.toFile()); pb.redirectError(errFile.toFile()); Process pyproc = pb.start(); OutputStream stdin = pyproc.getOutputStream(); @@ -195,7 +170,7 @@ public abstract class AbstractDbgEngTraceRmiTest extends AbstractGhidraHeadedDeb } Msg.info(this, "Python exited with code " + pyproc.exitValue()); return new PythonResult(false, pyproc.exitValue(), Files.readString(outFile), - Files.readString(errFile)); + Files.readString(errFile)); } catch (Exception e) { return ExceptionUtils.rethrow(e); @@ -230,10 +205,10 @@ public abstract class AbstractDbgEngTraceRmiTest extends AbstractGhidraHeadedDeb return result.get(TIMEOUT_SECONDS, TimeUnit.SECONDS).handle(); } - protected record PythonAndHandler(ExecInPython exec, TraceRmiHandler handler) + protected record PythonAndConnection(ExecInPython exec, TraceRmiConnection connection) implements AutoCloseable { protected RemoteMethod getMethod(String name) { - return Objects.requireNonNull(handler.getMethods().get(name)); + return Objects.requireNonNull(connection.getMethods().get(name)); } public void execute(String cmd) { @@ -258,7 +233,7 @@ public abstract class AbstractDbgEngTraceRmiTest extends AbstractGhidraHeadedDeb try { PythonResult r = exec.future.get(TIMEOUT_SECONDS, TimeUnit.SECONDS); r.handle(); - waitForPass(() -> assertTrue(handler.isClosed())); + waitForPass(() -> assertTrue(connection.isClosed())); } finally { exec.python.destroyForcibly(); @@ -266,15 +241,15 @@ public abstract class AbstractDbgEngTraceRmiTest extends AbstractGhidraHeadedDeb } } - protected PythonAndHandler startAndConnectPython(Function scriptSupplier) + protected PythonAndConnection startAndConnectPython(Function scriptSupplier) throws Exception { TraceRmiAcceptor acceptor = traceRmi.acceptOne(null); ExecInPython exec = execInPython(scriptSupplier.apply(sockToStringForPython(acceptor.getAddress()))); acceptor.setTimeout(CONNECT_TIMEOUT_MS); try { - TraceRmiHandler handler = acceptor.accept(); - return new PythonAndHandler(exec, handler); + TraceRmiConnection connection = acceptor.accept(); + return new PythonAndConnection(exec, connection); } catch (SocketTimeoutException e) { exec.python.destroyForcibly(); @@ -283,7 +258,7 @@ public abstract class AbstractDbgEngTraceRmiTest extends AbstractGhidraHeadedDeb } } - protected PythonAndHandler startAndConnectPython() throws Exception { + protected PythonAndConnection startAndConnectPython() throws Exception { return startAndConnectPython(addr -> """ %s ghidra_trace_connect('%s') @@ -293,10 +268,10 @@ public abstract class AbstractDbgEngTraceRmiTest extends AbstractGhidraHeadedDeb @SuppressWarnings("resource") protected String runThrowError(Function scriptSupplier) throws Exception { - PythonAndHandler conn = startAndConnectPython(scriptSupplier); + PythonAndConnection conn = startAndConnectPython(scriptSupplier); PythonResult r = conn.exec.future.get(TIMEOUT_SECONDS, TimeUnit.SECONDS); String stdout = r.handle(); - waitForPass(() -> assertTrue(conn.handler.isClosed())); + waitForPass(() -> assertTrue(conn.connection.isClosed())); return stdout; } diff --git a/Ghidra/Test/IntegrationTest/src/test.slow/java/agent/dbgeng/rmi/DbgEngCommandsTest.java b/Ghidra/Test/IntegrationTest/src/test.slow/java/agent/dbgeng/rmi/DbgEngCommandsTest.java index d8fda64266..1f1725cfe2 100644 --- a/Ghidra/Test/IntegrationTest/src/test.slow/java/agent/dbgeng/rmi/DbgEngCommandsTest.java +++ b/Ghidra/Test/IntegrationTest/src/test.slow/java/agent/dbgeng/rmi/DbgEngCommandsTest.java @@ -15,28 +15,12 @@ */ package agent.dbgeng.rmi; -import static org.hamcrest.Matchers.containsString; -import static org.hamcrest.Matchers.greaterThan; -import static org.hamcrest.Matchers.instanceOf; -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertSame; -import static org.junit.Assert.assertThat; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; +import static org.hamcrest.Matchers.*; +import static org.junit.Assert.*; import java.nio.ByteBuffer; -import java.util.Arrays; -import java.util.Collection; -import java.util.List; -import java.util.Map; +import java.util.*; import java.util.Map.Entry; -import java.util.Objects; -import java.util.Set; import java.util.concurrent.atomic.AtomicReference; import java.util.function.Function; import java.util.stream.Collectors; @@ -45,30 +29,20 @@ import java.util.stream.IntStream; import org.junit.Test; import generic.Unique; -import ghidra.app.plugin.core.debug.service.rmi.trace.TraceRmiAcceptor; -import ghidra.app.plugin.core.debug.service.rmi.trace.TraceRmiHandler; import ghidra.app.plugin.core.debug.utils.ManagedDomainObject; import ghidra.dbg.util.PathPredicates; +import ghidra.debug.api.tracermi.TraceRmiAcceptor; +import ghidra.debug.api.tracermi.TraceRmiConnection; import ghidra.framework.model.DomainFile; -import ghidra.program.model.address.Address; -import ghidra.program.model.address.AddressRange; -import ghidra.program.model.address.AddressRangeImpl; -import ghidra.program.model.address.AddressSpace; +import ghidra.program.model.address.*; import ghidra.program.model.lang.RegisterValue; import ghidra.program.model.listing.CodeUnit; import ghidra.trace.database.ToyDBTraceBuilder; -import ghidra.trace.model.ImmutableTraceAddressSnapRange; -import ghidra.trace.model.Lifespan; -import ghidra.trace.model.Trace; -import ghidra.trace.model.TraceAddressSnapRange; +import ghidra.trace.model.*; import ghidra.trace.model.breakpoint.TraceBreakpointKind; -import ghidra.trace.model.memory.TraceMemoryRegion; -import ghidra.trace.model.memory.TraceMemorySpace; -import ghidra.trace.model.memory.TraceMemoryState; +import ghidra.trace.model.memory.*; import ghidra.trace.model.modules.TraceModule; -import ghidra.trace.model.target.TraceObject; -import ghidra.trace.model.target.TraceObjectKeyPath; -import ghidra.trace.model.target.TraceObjectValue; +import ghidra.trace.model.target.*; import ghidra.trace.model.thread.TraceThread; import ghidra.trace.model.time.TraceSnapshot; import ghidra.util.Msg; @@ -80,9 +54,9 @@ public class DbgEngCommandsTest extends AbstractDbgEngTraceRmiTest { TraceRmiAcceptor acceptor = traceRmi.acceptOne(null); Msg.info(this, "Use: ghidra_trace_connect(" + sockToStringForPython(acceptor.getAddress()) + ")"); - TraceRmiHandler handler = acceptor.accept(); - Msg.info(this, "Connected: " + sockToStringForPython(handler.getRemoteAddress())); - handler.waitClosed(); + TraceRmiConnection connection = acceptor.accept(); + Msg.info(this, "Connected: " + sockToStringForPython(connection.getRemoteAddress())); + connection.waitClosed(); Msg.info(this, "Closed"); } @@ -186,7 +160,8 @@ public class DbgEngCommandsTest extends AbstractDbgEngTraceRmiTest { ghidra_trace_stop() quit() """.formatted(PREAMBLE, addr)); - DomainFile dfBash = env.getProject().getProjectData().getFile("/New Traces/pydbg/notepad.exe"); + DomainFile dfBash = + env.getProject().getProjectData().getFile("/New Traces/pydbg/notepad.exe"); assertNotNull(dfBash); // TODO: Given the 'quit' command, I'm not sure this assertion is checking anything. assertFalse(dfBash.isOpen()); @@ -222,18 +197,18 @@ public class DbgEngCommandsTest extends AbstractDbgEngTraceRmiTest { extractOutSection(out, "---Import---")); assertEquals(""" Connected to Ghidra at %s - + No trace""".formatted(refAddr.get()), - extractOutSection(out, "---Connect---").replaceAll("\r", "").substring(0,48)); + extractOutSection(out, "---Connect---").replaceAll("\r", "").substring(0, 48)); String expected = """ Connected to Ghidra at %s - + Trace active""".formatted(refAddr.get()); String actual = extractOutSection(out, "---Start---").replaceAll("\r", ""); - assertEquals(expected, actual.substring(0,expected.length())); + assertEquals(expected, actual.substring(0, expected.length())); assertEquals(""" Connected to Ghidra at %s - + No trace""".formatted(refAddr.get()), extractOutSection(out, "---Stop---").replaceAll("\r", "")); assertEquals(""" @@ -245,7 +220,7 @@ public class DbgEngCommandsTest extends AbstractDbgEngTraceRmiTest { public void testLcsp() throws Exception { // TODO: This test assumes x86-64 on test system String out = runThrowError( - """ + """ %s print('---Import---') ghidra_trace_info_lcsp() @@ -263,19 +238,20 @@ public class DbgEngCommandsTest extends AbstractDbgEngTraceRmiTest { """.formatted(PREAMBLE)); assertTrue( - extractOutSection(out, "---File---").replaceAll("\r", "").contains( - """ - Selected Ghidra language: x86:LE:64:default - - Selected Ghidra compiler: windows""")); + extractOutSection(out, "---File---").replaceAll("\r", "") + .contains( + """ + Selected Ghidra language: x86:LE:64:default + + Selected Ghidra compiler: windows""")); assertEquals(""" Selected Ghidra language: Toy:BE:64:default - + Selected Ghidra compiler: default""", extractOutSection(out, "---Language---").replaceAll("\r", "")); assertEquals(""" Selected Ghidra language: Toy:BE:64:default - + Selected Ghidra compiler: posStack""", extractOutSection(out, "---Compiler---").replaceAll("\r", "")); } @@ -475,8 +451,8 @@ public class DbgEngCommandsTest extends AbstractDbgEngTraceRmiTest { * code.definedData() // .create(Lifespan.nowOn(0), tb.reg("st0"), * Float10DataType.dataType); // } // assertEquals("1.5", * st0.getDefaultValueRepresentation()); - */ - } + */ + } } @Test @@ -526,8 +502,8 @@ public class DbgEngCommandsTest extends AbstractDbgEngTraceRmiTest { * code.definedData() // .create(Lifespan.nowOn(0), tb.reg("st0"), * Float10DataType.dataType); // } // assertEquals("0.0", * st0.getDefaultValueRepresentation()); - */ - } + */ + } } @Test @@ -814,7 +790,7 @@ public class DbgEngCommandsTest extends AbstractDbgEngTraceRmiTest { assertNotNull(object); String expected = "1\tTest.Objects[1]"; String actual = extractOutSection(out, "---GetObject---"); - assertEquals(expected, actual.substring(0,expected.length())); + assertEquals(expected, actual.substring(0, expected.length())); } } @@ -875,12 +851,14 @@ public class DbgEngCommandsTest extends AbstractDbgEngTraceRmiTest { Test.Objects[1] vshortarr [0,+inf) [1, 2, 3] SHORT_ARR Test.Objects[1] vstring [0,+inf) 'Hello' STRING Test.Objects[1] vaddr [0,+inf) ram:deadbeef ADDRESS""" - .replaceAll(" ", "") + .replaceAll(" ", "") + .replaceAll("\n", ""); + String actual = extractOutSection(out, "---GetValues---").replaceAll(" ", "") + .replaceAll("\r", "") .replaceAll("\n", ""); - String actual = extractOutSection(out, "---GetValues---").replaceAll(" ", "").replaceAll("\r", "").replaceAll("\n", ""); assertEquals( expected, - actual.substring(0,expected.length())); + actual.substring(0, expected.length())); } } @@ -905,7 +883,7 @@ public class DbgEngCommandsTest extends AbstractDbgEngTraceRmiTest { tb = new ToyDBTraceBuilder((Trace) mdo.get()); String expected = """ Parent Key Span Value Type - + Test.Objects[1] vaddr [0,+inf) ram:deadbeef ADDRESS"""; String actual = extractOutSection(out, "---GetValues---").replaceAll("\r", ""); assertEquals(expected, actual.substring(0, expected.length())); @@ -957,7 +935,7 @@ public class DbgEngCommandsTest extends AbstractDbgEngTraceRmiTest { total += cu.getLength(); } String extract = extractOutSection(out, "---Disassemble---"); - String [] split = extract.split("\r\n"); + String[] split = extract.split("\r\n"); assertEquals("Disassembled %d bytes".formatted(total), split[0]); } @@ -1208,14 +1186,14 @@ public class DbgEngCommandsTest extends AbstractDbgEngTraceRmiTest { quit() """.formatted(PREAMBLE, addr)); } - + @Test public void testMinimal2() throws Exception { Function scriptSupplier = addr -> """ %s ghidra_trace_connect('%s') """.formatted(PREAMBLE, addr); - try (PythonAndHandler conn = startAndConnectPython(scriptSupplier)) { + try (PythonAndConnection conn = startAndConnectPython(scriptSupplier)) { conn.execute("print('FINISHED')"); conn.close(); } diff --git a/Ghidra/Test/IntegrationTest/src/test.slow/java/agent/dbgeng/rmi/DbgEngHooksTest.java b/Ghidra/Test/IntegrationTest/src/test.slow/java/agent/dbgeng/rmi/DbgEngHooksTest.java index de1af8159b..0cf0bd57b2 100644 --- a/Ghidra/Test/IntegrationTest/src/test.slow/java/agent/dbgeng/rmi/DbgEngHooksTest.java +++ b/Ghidra/Test/IntegrationTest/src/test.slow/java/agent/dbgeng/rmi/DbgEngHooksTest.java @@ -16,10 +16,7 @@ package agent.dbgeng.rmi; import static org.hamcrest.Matchers.instanceOf; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertThat; -import static org.junit.Assert.assertTrue; +import static org.junit.Assert.*; import java.nio.ByteBuffer; import java.util.List; @@ -28,9 +25,7 @@ import java.util.Objects; import org.junit.Ignore; import org.junit.Test; -import ghidra.app.plugin.core.debug.service.rmi.trace.RemoteMethod; import ghidra.app.plugin.core.debug.utils.ManagedDomainObject; -import ghidra.dbg.testutil.DummyProc; import ghidra.dbg.util.PathPattern; import ghidra.dbg.util.PathPredicates; import ghidra.program.model.address.AddressSpace; @@ -39,14 +34,13 @@ import ghidra.trace.model.Lifespan; import ghidra.trace.model.Trace; import ghidra.trace.model.memory.TraceMemorySpace; import ghidra.trace.model.target.TraceObject; -import ghidra.trace.model.thread.TraceThread; import ghidra.trace.model.time.TraceSnapshot; public class DbgEngHooksTest extends AbstractDbgEngTraceRmiTest { private static final long RUN_TIMEOUT_MS = 20000; private static final long RETRY_MS = 500; - record PythonAndTrace(PythonAndHandler conn, ManagedDomainObject mdo) implements AutoCloseable { + record PythonAndTrace(PythonAndConnection conn, ManagedDomainObject mdo) implements AutoCloseable { public void execute(String cmd) { conn.execute(cmd); } @@ -64,20 +58,20 @@ public class DbgEngHooksTest extends AbstractDbgEngTraceRmiTest { @SuppressWarnings("resource") protected PythonAndTrace startAndSyncPython(String exec) throws Exception { - PythonAndHandler conn = startAndConnectPython(); + PythonAndConnection conn = startAndConnectPython(); try { ManagedDomainObject mdo; conn.execute("from ghidradbg.commands import *"); conn.execute( "util.set_convenience_variable('ghidra-language', 'x86:LE:64:default')"); - if (exec != null) { - start(conn, exec); - mdo = waitDomainObject("/New Traces/pydbg/"+exec); - } - else { - conn.execute("ghidra_trace_start()"); - mdo = waitDomainObject("/New Traces/pydbg/noname"); - } + if (exec != null) { + start(conn, exec); + mdo = waitDomainObject("/New Traces/pydbg/" + exec); + } + else { + conn.execute("ghidra_trace_start()"); + mdo = waitDomainObject("/New Traces/pydbg/noname"); + } tb = new ToyDBTraceBuilder((Trace) mdo.get()); return new PythonAndTrace(conn, mdo); } @@ -88,7 +82,7 @@ public class DbgEngHooksTest extends AbstractDbgEngTraceRmiTest { } protected long lastSnap(PythonAndTrace conn) { - return conn.conn.handler().getLastSnapshot(tb.trace); + return conn.conn.connection().getLastSnapshot(tb.trace); } @Test // The 10s wait makes this a pretty expensive test @@ -110,7 +104,8 @@ public class DbgEngHooksTest extends AbstractDbgEngTraceRmiTest { conn.execute("dbg().go(10)"); - waitForPass(() -> assertTrue(tb.objValues(lastSnap(conn), "Processes[].Threads[]").size() > 4), + waitForPass( + () -> assertTrue(tb.objValues(lastSnap(conn), "Processes[].Threads[]").size() > 4), RUN_TIMEOUT_MS, RETRY_MS); } } @@ -203,8 +198,8 @@ public class DbgEngHooksTest extends AbstractDbgEngTraceRmiTest { conn.execute("ghidra_trace_txstart('Tx')"); conn.execute("ghidra_trace_putmem('$pc 10')"); conn.execute("ghidra_trace_txcommit()"); - long address = getAddressAtOffset(conn, 0); - conn.execute("util.get_debugger().write("+address+", b'\\x7f')"); + long address = getAddressAtOffset(conn, 0); + conn.execute("util.get_debugger().write(" + address + ", b'\\x7f')"); waitForPass(() -> { ByteBuffer buf = ByteBuffer.allocate(10); @@ -322,7 +317,7 @@ public class DbgEngHooksTest extends AbstractDbgEngTraceRmiTest { conn.execute("dbg.stepi()"); assertEquals(false, tb.objValue(brk, lastSnap(conn), "Enabled")); - /* Not currently enabled + /* Not currently enabled assertEquals("", tb.objValue(brk, lastSnap(conn), "Command")); conn.execute("dbg.bp(expr=pc, windbgcmd='bl')"); conn.execute("dbg.stepi()"); @@ -356,23 +351,23 @@ public class DbgEngHooksTest extends AbstractDbgEngTraceRmiTest { } } - private void start(PythonAndHandler conn, String obj) { + private void start(PythonAndConnection conn, String obj) { conn.execute("from ghidradbg.commands import *"); if (obj != null) - conn.execute("ghidra_trace_create('"+obj+"')"); - else - conn.execute("ghidra_trace_create()"); + conn.execute("ghidra_trace_create('" + obj + "')"); + else + conn.execute("ghidra_trace_create()"); conn.execute("ghidra_trace_sync_enable()"); } private void txPut(PythonAndTrace conn, String obj) { conn.execute("ghidra_trace_txstart('Tx" + obj + "')"); - conn.execute("ghidra_trace_put_" + obj +"()"); + conn.execute("ghidra_trace_put_" + obj + "()"); conn.execute("ghidra_trace_txcommit()"); } private long getAddressAtOffset(PythonAndTrace conn, int offset) { - String inst = "util.get_inst(util.get_debugger().reg.get_pc()+"+offset+")"; + String inst = "util.get_inst(util.get_debugger().reg.get_pc()+" + offset + ")"; String ret = conn.executeCapture(inst); String[] split = ret.split("\\s+"); // get target return Long.decode(split[1]); diff --git a/Ghidra/Test/IntegrationTest/src/test.slow/java/agent/dbgeng/rmi/DbgEngMethodsTest.java b/Ghidra/Test/IntegrationTest/src/test.slow/java/agent/dbgeng/rmi/DbgEngMethodsTest.java index 5dcc795318..8dfb533816 100644 --- a/Ghidra/Test/IntegrationTest/src/test.slow/java/agent/dbgeng/rmi/DbgEngMethodsTest.java +++ b/Ghidra/Test/IntegrationTest/src/test.slow/java/agent/dbgeng/rmi/DbgEngMethodsTest.java @@ -24,12 +24,11 @@ import java.util.*; import org.junit.Test; import generic.Unique; -import ghidra.app.plugin.core.debug.service.rmi.trace.RemoteMethod; -import ghidra.app.plugin.core.debug.service.rmi.trace.ValueDecoder; import ghidra.app.plugin.core.debug.utils.ManagedDomainObject; import ghidra.dbg.testutil.DummyProc; import ghidra.dbg.util.PathPattern; import ghidra.dbg.util.PathPredicates; +import ghidra.debug.api.tracermi.RemoteMethod; import ghidra.program.model.address.*; import ghidra.program.model.lang.RegisterValue; import ghidra.trace.database.ToyDBTraceBuilder; @@ -46,7 +45,7 @@ public class DbgEngMethodsTest extends AbstractDbgEngTraceRmiTest { @Test public void testEvaluate() throws Exception { - try (PythonAndHandler conn = startAndConnectPython()) { + try (PythonAndConnection conn = startAndConnectPython()) { RemoteMethod evaluate = conn.getMethod("evaluate"); assertEquals("11", evaluate.invoke(Map.of("expr", "3+4*2"))); @@ -55,10 +54,9 @@ public class DbgEngMethodsTest extends AbstractDbgEngTraceRmiTest { @Test public void testExecuteCapture() throws Exception { - try (PythonAndHandler conn = startAndConnectPython()) { + try (PythonAndConnection conn = startAndConnectPython()) { RemoteMethod execute = conn.getMethod("execute"); - assertEquals(false, - execute.parameters().get("to_string").defaultValue().get(ValueDecoder.DEFAULT)); + assertEquals(false, execute.parameters().get("to_string").getDefaultValue()); assertEquals("11\n", execute.invoke(Map.of("cmd", "print(3+4*2)", "to_string", true))); } @@ -66,7 +64,7 @@ public class DbgEngMethodsTest extends AbstractDbgEngTraceRmiTest { @Test public void testExecute() throws Exception { - try (PythonAndHandler conn = startAndConnectPython()) { + try (PythonAndConnection conn = startAndConnectPython()) { start(conn, "notepad.exe"); conn.execute("ghidra_trace_kill()"); } @@ -77,7 +75,7 @@ public class DbgEngMethodsTest extends AbstractDbgEngTraceRmiTest { @Test public void testRefreshAvailable() throws Exception { - try (PythonAndHandler conn = startAndConnectPython()) { + try (PythonAndConnection conn = startAndConnectPython()) { start(conn, null); txCreate(conn, "Available"); @@ -100,7 +98,7 @@ public class DbgEngMethodsTest extends AbstractDbgEngTraceRmiTest { @Test public void testRefreshBreakpoints() throws Exception { - try (PythonAndHandler conn = startAndConnectPython()) { + try (PythonAndConnection conn = startAndConnectPython()) { start(conn, "notepad.exe"); txPut(conn, "processes"); @@ -113,7 +111,8 @@ public class DbgEngMethodsTest extends AbstractDbgEngTraceRmiTest { conn.execute("dbg.bp(expr=pc)"); conn.execute("dbg.ba(expr=pc+4)"); txPut(conn, "breakpoints"); - TraceObject breakpoints = Objects.requireNonNull(tb.objAny("Processes[].Breakpoints")); + TraceObject breakpoints = + Objects.requireNonNull(tb.objAny("Processes[].Breakpoints")); refreshBreakpoints.invoke(Map.of("node", breakpoints)); List procBreakLocVals = tb.trace.getObjectManager() @@ -138,7 +137,7 @@ public class DbgEngMethodsTest extends AbstractDbgEngTraceRmiTest { @Test public void testRefreshBreakpoints2() throws Exception { - try (PythonAndHandler conn = startAndConnectPython()) { + try (PythonAndConnection conn = startAndConnectPython()) { start(conn, "notepad.exe"); txPut(conn, "all"); @@ -186,7 +185,7 @@ public class DbgEngMethodsTest extends AbstractDbgEngTraceRmiTest { @Test public void testRefreshProcesses() throws Exception { - try (PythonAndHandler conn = startAndConnectPython()) { + try (PythonAndConnection conn = startAndConnectPython()) { start(conn, null); txCreate(conn, "Processes"); txCreate(conn, "Processes[1]"); @@ -210,7 +209,7 @@ public class DbgEngMethodsTest extends AbstractDbgEngTraceRmiTest { @Test public void testRefreshEnvironment() throws Exception { - try (PythonAndHandler conn = startAndConnectPython()) { + try (PythonAndConnection conn = startAndConnectPython()) { String path = "Processes[].Environment"; start(conn, "notepad.exe"); txPut(conn, "all"); @@ -233,7 +232,7 @@ public class DbgEngMethodsTest extends AbstractDbgEngTraceRmiTest { @Test public void testRefreshThreads() throws Exception { - try (PythonAndHandler conn = startAndConnectPython()) { + try (PythonAndConnection conn = startAndConnectPython()) { String path = "Processes[].Threads"; start(conn, "notepad.exe"); txCreate(conn, path); @@ -254,7 +253,7 @@ public class DbgEngMethodsTest extends AbstractDbgEngTraceRmiTest { @Test public void testRefreshStack() throws Exception { - try (PythonAndHandler conn = startAndConnectPython()) { + try (PythonAndConnection conn = startAndConnectPython()) { String path = "Processes[].Threads[].Stack"; start(conn, "notepad.exe"); txPut(conn, "processes"); @@ -280,7 +279,7 @@ public class DbgEngMethodsTest extends AbstractDbgEngTraceRmiTest { @Test public void testRefreshRegisters() throws Exception { - try (PythonAndHandler conn = startAndConnectPython()) { + try (PythonAndConnection conn = startAndConnectPython()) { String path = "Processes[].Threads[].Registers"; start(conn, "notepad.exe"); conn.execute("ghidra_trace_txstart('Tx')"); @@ -309,7 +308,7 @@ public class DbgEngMethodsTest extends AbstractDbgEngTraceRmiTest { @Test public void testRefreshMappings() throws Exception { - try (PythonAndHandler conn = startAndConnectPython()) { + try (PythonAndConnection conn = startAndConnectPython()) { String path = "Processes[].Memory"; start(conn, "notepad.exe"); txCreate(conn, path); @@ -331,7 +330,7 @@ public class DbgEngMethodsTest extends AbstractDbgEngTraceRmiTest { @Test public void testRefreshModules() throws Exception { - try (PythonAndHandler conn = startAndConnectPython()) { + try (PythonAndConnection conn = startAndConnectPython()) { String path = "Processes[].Modules"; start(conn, "notepad.exe"); txCreate(conn, path); @@ -354,7 +353,7 @@ public class DbgEngMethodsTest extends AbstractDbgEngTraceRmiTest { @Test public void testActivateThread() throws Exception { - try (PythonAndHandler conn = startAndConnectPython()) { + try (PythonAndConnection conn = startAndConnectPython()) { start(conn, "notepad.exe"); txPut(conn, "processes"); @@ -384,7 +383,7 @@ public class DbgEngMethodsTest extends AbstractDbgEngTraceRmiTest { @Test public void testRemoveProcess() throws Exception { - try (PythonAndHandler conn = startAndConnectPython()) { + try (PythonAndConnection conn = startAndConnectPython()) { start(conn, "netstat.exe"); txPut(conn, "processes"); @@ -404,7 +403,7 @@ public class DbgEngMethodsTest extends AbstractDbgEngTraceRmiTest { @Test public void testAttachObj() throws Exception { try (DummyProc dproc = DummyProc.run("notepad.exe")) { - try (PythonAndHandler conn = startAndConnectPython()) { + try (PythonAndConnection conn = startAndConnectPython()) { start(conn, null); txPut(conn, "available"); @@ -425,14 +424,15 @@ public class DbgEngMethodsTest extends AbstractDbgEngTraceRmiTest { @Test public void testAttachPid() throws Exception { try (DummyProc dproc = DummyProc.run("notepad.exe")) { - try (PythonAndHandler conn = startAndConnectPython()) { + try (PythonAndConnection conn = startAndConnectPython()) { start(conn, null); txPut(conn, "available"); RemoteMethod attachPid = conn.getMethod("attach_pid"); try (ManagedDomainObject mdo = openDomainObject("/New Traces/pydbg/noname")) { tb = new ToyDBTraceBuilder((Trace) mdo.get()); - Objects.requireNonNull(tb.objAny("Available["+dproc.pid+"]", Lifespan.at(0))); + Objects.requireNonNull( + tb.objAny("Available[" + dproc.pid + "]", Lifespan.at(0))); attachPid.invoke(Map.of("pid", dproc.pid)); String out = conn.executeCapture("list(util.process_list())"); @@ -444,7 +444,7 @@ public class DbgEngMethodsTest extends AbstractDbgEngTraceRmiTest { @Test public void testDetach() throws Exception { - try (PythonAndHandler conn = startAndConnectPython()) { + try (PythonAndConnection conn = startAndConnectPython()) { start(conn, "netstat.exe"); txPut(conn, "processes"); @@ -463,7 +463,7 @@ public class DbgEngMethodsTest extends AbstractDbgEngTraceRmiTest { @Test public void testLaunchEntry() throws Exception { - try (PythonAndHandler conn = startAndConnectPython()) { + try (PythonAndConnection conn = startAndConnectPython()) { start(conn, null); txPut(conn, "processes"); @@ -472,7 +472,7 @@ public class DbgEngMethodsTest extends AbstractDbgEngTraceRmiTest { tb = new ToyDBTraceBuilder((Trace) mdo.get()); launch.invoke(Map.ofEntries( - Map.entry("file", "notepad.exe"))); + Map.entry("file", "notepad.exe"))); String out = conn.executeCapture("list(util.process_list())"); assertThat(out, containsString("notepad.exe")); @@ -482,7 +482,7 @@ public class DbgEngMethodsTest extends AbstractDbgEngTraceRmiTest { @Test //Can't do this test because create(xxx, initial_break=False) doesn't return public void testLaunch() throws Exception { - try (PythonAndHandler conn = startAndConnectPython()) { + try (PythonAndConnection conn = startAndConnectPython()) { start(conn, null); txPut(conn, "processes"); @@ -502,9 +502,9 @@ public class DbgEngMethodsTest extends AbstractDbgEngTraceRmiTest { } } - @Test + @Test public void testKill() throws Exception { - try (PythonAndHandler conn = startAndConnectPython()) { + try (PythonAndConnection conn = startAndConnectPython()) { start(conn, "notepad.exe"); txPut(conn, "processes"); @@ -524,7 +524,7 @@ public class DbgEngMethodsTest extends AbstractDbgEngTraceRmiTest { @Test public void testStepInto() throws Exception { - try (PythonAndHandler conn = startAndConnectPython()) { + try (PythonAndConnection conn = startAndConnectPython()) { start(conn, "notepad.exe"); txPut(conn, "processes"); @@ -547,7 +547,7 @@ public class DbgEngMethodsTest extends AbstractDbgEngTraceRmiTest { // lab1: // addr1 String[] split = disCall.split("\\s+"); // get target - long pcCallee = Long.decode(split[split.length-1]); + long pcCallee = Long.decode(split[split.length - 1]); step_into.invoke(Map.of("thread", thread)); long pc = getAddressAtOffset(conn, 0); @@ -558,7 +558,7 @@ public class DbgEngMethodsTest extends AbstractDbgEngTraceRmiTest { @Test public void testStepOver() throws Exception { - try (PythonAndHandler conn = startAndConnectPython()) { + try (PythonAndConnection conn = startAndConnectPython()) { start(conn, "notepad.exe"); txPut(conn, "processes"); @@ -576,7 +576,7 @@ public class DbgEngMethodsTest extends AbstractDbgEngTraceRmiTest { String disCall = getInst(conn); String[] split = disCall.split("\\s+"); // get target - long pcCallee = Long.decode(split[split.length-1]); + long pcCallee = Long.decode(split[split.length - 1]); step_over.invoke(Map.of("thread", thread)); long pc = getAddressAtOffset(conn, 0); @@ -585,9 +585,9 @@ public class DbgEngMethodsTest extends AbstractDbgEngTraceRmiTest { } } - @Test + @Test public void testStepTo() throws Exception { - try (PythonAndHandler conn = startAndConnectPython()) { + try (PythonAndConnection conn = startAndConnectPython()) { start(conn, "notepad.exe"); RemoteMethod step_into = conn.getMethod("step_into"); @@ -601,7 +601,7 @@ public class DbgEngMethodsTest extends AbstractDbgEngTraceRmiTest { step_into.invoke(Map.of("thread", thread)); } step_into.invoke(Map.of("thread", thread)); - + int sz = Integer.parseInt(getInstSizeAtOffset(conn, 0)); for (int i = 0; i < 4; i++) { sz += Integer.parseInt(getInstSizeAtOffset(conn, sz)); @@ -609,9 +609,10 @@ public class DbgEngMethodsTest extends AbstractDbgEngTraceRmiTest { long pcNext = getAddressAtOffset(conn, sz); - boolean success = (boolean) step_to.invoke(Map.of("thread", thread, "address", tb.addr(pcNext), "max", 10)); + boolean success = (boolean) step_to + .invoke(Map.of("thread", thread, "address", tb.addr(pcNext), "max", 10)); assertTrue(success); - + long pc = getAddressAtOffset(conn, 0); assertEquals(pcNext, pc); } @@ -620,7 +621,7 @@ public class DbgEngMethodsTest extends AbstractDbgEngTraceRmiTest { @Test public void testStepOut() throws Exception { - try (PythonAndHandler conn = startAndConnectPython()) { + try (PythonAndConnection conn = startAndConnectPython()) { start(conn, "notepad.exe"); txPut(conn, "processes"); @@ -650,7 +651,7 @@ public class DbgEngMethodsTest extends AbstractDbgEngTraceRmiTest { @Test public void testBreakAddress() throws Exception { - try (PythonAndHandler conn = startAndConnectPython()) { + try (PythonAndConnection conn = startAndConnectPython()) { start(conn, "notepad.exe"); txPut(conn, "processes"); @@ -659,8 +660,8 @@ public class DbgEngMethodsTest extends AbstractDbgEngTraceRmiTest { tb = new ToyDBTraceBuilder((Trace) mdo.get()); TraceObject proc = Objects.requireNonNull(tb.objAny("Processes[]")); - - long address = getAddressAtOffset(conn, 0); + + long address = getAddressAtOffset(conn, 0); breakAddress.invoke(Map.of("process", proc, "address", tb.addr(address))); String out = conn.executeCapture("list(util.get_breakpoints())"); @@ -671,7 +672,7 @@ public class DbgEngMethodsTest extends AbstractDbgEngTraceRmiTest { @Test public void testBreakExpression() throws Exception { - try (PythonAndHandler conn = startAndConnectPython()) { + try (PythonAndConnection conn = startAndConnectPython()) { start(conn, "notepad.exe"); txPut(conn, "processes"); @@ -688,9 +689,9 @@ public class DbgEngMethodsTest extends AbstractDbgEngTraceRmiTest { } } - @Test + @Test public void testBreakHardwareAddress() throws Exception { - try (PythonAndHandler conn = startAndConnectPython()) { + try (PythonAndConnection conn = startAndConnectPython()) { start(conn, "notepad.exe"); txPut(conn, "processes"); @@ -699,8 +700,8 @@ public class DbgEngMethodsTest extends AbstractDbgEngTraceRmiTest { tb = new ToyDBTraceBuilder((Trace) mdo.get()); TraceObject proc = Objects.requireNonNull(tb.objAny("Processes[]")); - - long address = getAddressAtOffset(conn, 0); + + long address = getAddressAtOffset(conn, 0); breakAddress.invoke(Map.of("process", proc, "address", tb.addr(address))); String out = conn.executeCapture("list(util.get_breakpoints())"); @@ -711,7 +712,7 @@ public class DbgEngMethodsTest extends AbstractDbgEngTraceRmiTest { @Test public void testBreakHardwareExpression() throws Exception { - try (PythonAndHandler conn = startAndConnectPython()) { + try (PythonAndConnection conn = startAndConnectPython()) { start(conn, "notepad.exe"); txPut(conn, "processes"); @@ -730,7 +731,7 @@ public class DbgEngMethodsTest extends AbstractDbgEngTraceRmiTest { @Test public void testBreakReadRange() throws Exception { - try (PythonAndHandler conn = startAndConnectPython()) { + try (PythonAndConnection conn = startAndConnectPython()) { start(conn, "notepad.exe"); txPut(conn, "processes"); @@ -740,7 +741,7 @@ public class DbgEngMethodsTest extends AbstractDbgEngTraceRmiTest { waitStopped(); TraceObject proc = Objects.requireNonNull(tb.objAny("Processes[]")); - long address = getAddressAtOffset(conn, 0); + long address = getAddressAtOffset(conn, 0); AddressRange range = tb.range(address, address + 3); // length 4 breakRange.invoke(Map.of("process", proc, "range", range)); @@ -754,7 +755,7 @@ public class DbgEngMethodsTest extends AbstractDbgEngTraceRmiTest { @Test public void testBreakReadExpression() throws Exception { - try (PythonAndHandler conn = startAndConnectPython()) { + try (PythonAndConnection conn = startAndConnectPython()) { start(conn, "notepad.exe"); txPut(conn, "processes"); @@ -763,10 +764,10 @@ public class DbgEngMethodsTest extends AbstractDbgEngTraceRmiTest { tb = new ToyDBTraceBuilder((Trace) mdo.get()); breakExpression.invoke(Map.of("expression", "ntdll!LdrInitShimEngineDynamic")); - long address = getAddressAtOffset(conn, 0); + long address = getAddressAtOffset(conn, 0); String out = conn.executeCapture("list(util.get_breakpoints())"); - assertThat(out, containsString(Long.toHexString(address>>24))); + assertThat(out, containsString(Long.toHexString(address >> 24))); assertThat(out, containsString("sz=1")); assertThat(out, containsString("type=r")); } @@ -775,7 +776,7 @@ public class DbgEngMethodsTest extends AbstractDbgEngTraceRmiTest { @Test public void testBreakWriteRange() throws Exception { - try (PythonAndHandler conn = startAndConnectPython()) { + try (PythonAndConnection conn = startAndConnectPython()) { start(conn, "notepad.exe"); txPut(conn, "processes"); @@ -785,7 +786,7 @@ public class DbgEngMethodsTest extends AbstractDbgEngTraceRmiTest { waitStopped(); TraceObject proc = Objects.requireNonNull(tb.objAny("Processes[]")); - long address = getAddressAtOffset(conn, 0); + long address = getAddressAtOffset(conn, 0); AddressRange range = tb.range(address, address + 3); // length 4 breakRange.invoke(Map.of("process", proc, "range", range)); @@ -799,7 +800,7 @@ public class DbgEngMethodsTest extends AbstractDbgEngTraceRmiTest { @Test public void testBreakWriteExpression() throws Exception { - try (PythonAndHandler conn = startAndConnectPython()) { + try (PythonAndConnection conn = startAndConnectPython()) { start(conn, "notepad.exe"); txPut(conn, "processes"); @@ -808,10 +809,10 @@ public class DbgEngMethodsTest extends AbstractDbgEngTraceRmiTest { tb = new ToyDBTraceBuilder((Trace) mdo.get()); breakExpression.invoke(Map.of("expression", "ntdll!LdrInitShimEngineDynamic")); - long address = getAddressAtOffset(conn, 0); + long address = getAddressAtOffset(conn, 0); String out = conn.executeCapture("list(util.get_breakpoints())"); - assertThat(out, containsString(Long.toHexString(address>>24))); + assertThat(out, containsString(Long.toHexString(address >> 24))); assertThat(out, containsString("sz=1")); assertThat(out, containsString("type=w")); } @@ -820,7 +821,7 @@ public class DbgEngMethodsTest extends AbstractDbgEngTraceRmiTest { @Test public void testBreakAccessRange() throws Exception { - try (PythonAndHandler conn = startAndConnectPython()) { + try (PythonAndConnection conn = startAndConnectPython()) { start(conn, "notepad.exe"); txPut(conn, "processes"); @@ -830,7 +831,7 @@ public class DbgEngMethodsTest extends AbstractDbgEngTraceRmiTest { waitStopped(); TraceObject proc = Objects.requireNonNull(tb.objAny("Processes[]")); - long address = getAddressAtOffset(conn, 0); + long address = getAddressAtOffset(conn, 0); AddressRange range = tb.range(address, address + 3); // length 4 breakRange.invoke(Map.of("process", proc, "range", range)); @@ -844,7 +845,7 @@ public class DbgEngMethodsTest extends AbstractDbgEngTraceRmiTest { @Test public void testBreakAccessExpression() throws Exception { - try (PythonAndHandler conn = startAndConnectPython()) { + try (PythonAndConnection conn = startAndConnectPython()) { start(conn, "notepad.exe"); txPut(conn, "processes"); @@ -853,10 +854,10 @@ public class DbgEngMethodsTest extends AbstractDbgEngTraceRmiTest { tb = new ToyDBTraceBuilder((Trace) mdo.get()); breakExpression.invoke(Map.of("expression", "ntdll!LdrInitShimEngineDynamic")); - long address = getAddressAtOffset(conn, 0); + long address = getAddressAtOffset(conn, 0); String out = conn.executeCapture("list(util.get_breakpoints())"); - assertThat(out, containsString(Long.toHexString(address>>24))); + assertThat(out, containsString(Long.toHexString(address >> 24))); assertThat(out, containsString("sz=1")); assertThat(out, containsString("type=rw")); } @@ -865,7 +866,7 @@ public class DbgEngMethodsTest extends AbstractDbgEngTraceRmiTest { @Test public void testToggleBreakpoint() throws Exception { - try (PythonAndHandler conn = startAndConnectPython()) { + try (PythonAndConnection conn = startAndConnectPython()) { start(conn, "notepad.exe"); txPut(conn, "processes"); @@ -874,7 +875,7 @@ public class DbgEngMethodsTest extends AbstractDbgEngTraceRmiTest { try (ManagedDomainObject mdo = openDomainObject("/New Traces/pydbg/notepad.exe")) { tb = new ToyDBTraceBuilder((Trace) mdo.get()); - long address = getAddressAtOffset(conn, 0); + long address = getAddressAtOffset(conn, 0); TraceObject proc = Objects.requireNonNull(tb.objAny("Processes[]")); breakAddress.invoke(Map.of("process", proc, "address", tb.addr(address))); @@ -891,7 +892,7 @@ public class DbgEngMethodsTest extends AbstractDbgEngTraceRmiTest { @Test public void testDeleteBreakpoint() throws Exception { - try (PythonAndHandler conn = startAndConnectPython()) { + try (PythonAndConnection conn = startAndConnectPython()) { start(conn, "notepad.exe"); txPut(conn, "processes"); @@ -899,8 +900,8 @@ public class DbgEngMethodsTest extends AbstractDbgEngTraceRmiTest { RemoteMethod deleteBreakpoint = conn.getMethod("delete_breakpoint"); try (ManagedDomainObject mdo = openDomainObject("/New Traces/pydbg/notepad.exe")) { tb = new ToyDBTraceBuilder((Trace) mdo.get()); - - long address = getAddressAtOffset(conn, 0); + + long address = getAddressAtOffset(conn, 0); TraceObject proc = Objects.requireNonNull(tb.objAny("Processes[]")); breakAddress.invoke(Map.of("process", proc, "address", tb.addr(address))); @@ -915,42 +916,43 @@ public class DbgEngMethodsTest extends AbstractDbgEngTraceRmiTest { } } - private void start(PythonAndHandler conn, String obj) { + private void start(PythonAndConnection conn, String obj) { conn.execute("from ghidradbg.commands import *"); if (obj != null) - conn.execute("ghidra_trace_create('"+obj+"')"); - else - conn.execute("ghidra_trace_create()"); } + conn.execute("ghidra_trace_create('" + obj + "')"); + else + conn.execute("ghidra_trace_create()"); + } - private void txPut(PythonAndHandler conn, String obj) { + private void txPut(PythonAndConnection conn, String obj) { conn.execute("ghidra_trace_txstart('Tx')"); conn.execute("ghidra_trace_put_" + obj + "()"); conn.execute("ghidra_trace_txcommit()"); } - private void txCreate(PythonAndHandler conn, String path) { + private void txCreate(PythonAndConnection conn, String path) { conn.execute("ghidra_trace_txstart('Fake')"); conn.execute("ghidra_trace_create_obj('%s')".formatted(path)); conn.execute("ghidra_trace_txcommit()"); } - private String getInst(PythonAndHandler conn) { + private String getInst(PythonAndConnection conn) { return getInstAtOffset(conn, 0); } - private String getInstAtOffset(PythonAndHandler conn, int offset) { - String inst = "util.get_inst(util.get_debugger().reg.get_pc()+"+offset+")"; + private String getInstAtOffset(PythonAndConnection conn, int offset) { + String inst = "util.get_inst(util.get_debugger().reg.get_pc()+" + offset + ")"; String ret = conn.executeCapture(inst); - return ret.substring(1, ret.length()-1); // remove <> + return ret.substring(1, ret.length() - 1); // remove <> } - private String getInstSizeAtOffset(PythonAndHandler conn, int offset) { - String instSize = "util.get_inst_sz(util.get_debugger().reg.get_pc()+"+offset+")"; + private String getInstSizeAtOffset(PythonAndConnection conn, int offset) { + String instSize = "util.get_inst_sz(util.get_debugger().reg.get_pc()+" + offset + ")"; return conn.executeCapture(instSize); } - private long getAddressAtOffset(PythonAndHandler conn, int offset) { - String inst = "util.get_inst(util.get_debugger().reg.get_pc()+"+offset+")"; + private long getAddressAtOffset(PythonAndConnection conn, int offset) { + String inst = "util.get_inst(util.get_debugger().reg.get_pc()+" + offset + ")"; String ret = conn.executeCapture(inst); String[] split = ret.split("\\s+"); // get target return Long.decode(split[1]); diff --git a/Ghidra/Test/IntegrationTest/src/test.slow/java/agent/gdb/rmi/AbstractGdbTraceRmiTest.java b/Ghidra/Test/IntegrationTest/src/test.slow/java/agent/gdb/rmi/AbstractGdbTraceRmiTest.java index ea58ada9bf..fb8654b3c7 100644 --- a/Ghidra/Test/IntegrationTest/src/test.slow/java/agent/gdb/rmi/AbstractGdbTraceRmiTest.java +++ b/Ghidra/Test/IntegrationTest/src/test.slow/java/agent/gdb/rmi/AbstractGdbTraceRmiTest.java @@ -33,11 +33,12 @@ import org.apache.commons.lang3.exception.ExceptionUtils; import org.junit.Before; import ghidra.app.plugin.core.debug.gui.AbstractGhidraHeadedDebuggerGUITest; -import ghidra.app.plugin.core.debug.service.rmi.trace.*; +import ghidra.app.plugin.core.debug.service.rmi.trace.TraceRmiPlugin; import ghidra.app.plugin.core.debug.utils.ManagedDomainObject; import ghidra.app.services.TraceRmiService; import ghidra.dbg.target.TargetExecutionStateful.TargetExecutionState; import ghidra.dbg.testutil.DummyProc; +import ghidra.debug.api.tracermi.*; import ghidra.framework.*; import ghidra.framework.main.ApplicationLevelOnlyPlugin; import ghidra.framework.model.DomainFile; @@ -228,10 +229,10 @@ public abstract class AbstractGdbTraceRmiTest extends AbstractGhidraHeadedDebugg return result.get(TIMEOUT_SECONDS, TimeUnit.SECONDS).handle(); } - protected record GdbAndHandler(ExecInGdb exec, TraceRmiHandler handler) + protected record GdbAndConnection(ExecInGdb exec, TraceRmiConnection connection) implements AutoCloseable { protected RemoteMethod getMethod(String name) { - return Objects.requireNonNull(handler.getMethods().get(name)); + return Objects.requireNonNull(connection.getMethods().get(name)); } public void execute(String cmd) { @@ -282,7 +283,7 @@ public abstract class AbstractGdbTraceRmiTest extends AbstractGhidraHeadedDebugg } GdbResult r = exec.future.get(TIMEOUT_SECONDS, TimeUnit.SECONDS); r.handle(); - waitForPass(() -> assertTrue(handler.isClosed())); + waitForPass(() -> assertTrue(connection.isClosed())); } finally { exec.gdb.destroyForcibly(); @@ -290,14 +291,14 @@ public abstract class AbstractGdbTraceRmiTest extends AbstractGhidraHeadedDebugg } } - protected GdbAndHandler startAndConnectGdb(Function scriptSupplier) + protected GdbAndConnection startAndConnectGdb(Function scriptSupplier) throws Exception { TraceRmiAcceptor acceptor = traceRmi.acceptOne(null); ExecInGdb exec = execInGdb(scriptSupplier.apply(sockToStringForGdb(acceptor.getAddress()))); acceptor.setTimeout(CONNECT_TIMEOUT_MS); try { - TraceRmiHandler handler = acceptor.accept(); - return new GdbAndHandler(exec, handler); + TraceRmiConnection connection = acceptor.accept(); + return new GdbAndConnection(exec, connection); } catch (SocketTimeoutException e) { exec.gdb.destroyForcibly(); @@ -306,7 +307,7 @@ public abstract class AbstractGdbTraceRmiTest extends AbstractGhidraHeadedDebugg } } - protected GdbAndHandler startAndConnectGdb() throws Exception { + protected GdbAndConnection startAndConnectGdb() throws Exception { return startAndConnectGdb(addr -> """ %s ghidra trace connect %s @@ -316,10 +317,10 @@ public abstract class AbstractGdbTraceRmiTest extends AbstractGhidraHeadedDebugg @SuppressWarnings("resource") protected String runThrowError(Function scriptSupplier) throws Exception { - GdbAndHandler conn = startAndConnectGdb(scriptSupplier); + GdbAndConnection conn = startAndConnectGdb(scriptSupplier); GdbResult r = conn.exec.future.get(TIMEOUT_SECONDS, TimeUnit.SECONDS); String stdout = r.handle(); - waitForPass(() -> assertTrue(conn.handler.isClosed())); + waitForPass(() -> assertTrue(conn.connection.isClosed())); return stdout; } diff --git a/Ghidra/Test/IntegrationTest/src/test.slow/java/agent/gdb/rmi/GdbCommandsTest.java b/Ghidra/Test/IntegrationTest/src/test.slow/java/agent/gdb/rmi/GdbCommandsTest.java index d01d8a5e67..588c28ff55 100644 --- a/Ghidra/Test/IntegrationTest/src/test.slow/java/agent/gdb/rmi/GdbCommandsTest.java +++ b/Ghidra/Test/IntegrationTest/src/test.slow/java/agent/gdb/rmi/GdbCommandsTest.java @@ -31,11 +31,11 @@ import org.junit.experimental.categories.Category; import db.Transaction; import generic.Unique; import generic.test.category.NightlyCategory; -import ghidra.app.plugin.core.debug.service.rmi.trace.TraceRmiAcceptor; -import ghidra.app.plugin.core.debug.service.rmi.trace.TraceRmiHandler; import ghidra.app.plugin.core.debug.utils.ManagedDomainObject; import ghidra.dbg.testutil.DummyProc; import ghidra.dbg.util.PathPredicates; +import ghidra.debug.api.tracermi.TraceRmiAcceptor; +import ghidra.debug.api.tracermi.TraceRmiConnection; import ghidra.framework.model.DomainFile; import ghidra.program.model.address.*; import ghidra.program.model.data.Float10DataType; @@ -60,9 +60,9 @@ public class GdbCommandsTest extends AbstractGdbTraceRmiTest { TraceRmiAcceptor acceptor = traceRmi.acceptOne(null); Msg.info(this, "Use: ghidra trace connect " + sockToStringForGdb(acceptor.getAddress())); - TraceRmiHandler handler = acceptor.accept(); - Msg.info(this, "Connected: " + sockToStringForGdb(handler.getRemoteAddress())); - handler.waitClosed(); + TraceRmiConnection connection = acceptor.accept(); + Msg.info(this, "Connected: " + sockToStringForGdb(connection.getRemoteAddress())); + connection.waitClosed(); Msg.info(this, "Closed"); } diff --git a/Ghidra/Test/IntegrationTest/src/test.slow/java/agent/gdb/rmi/GdbHooksTest.java b/Ghidra/Test/IntegrationTest/src/test.slow/java/agent/gdb/rmi/GdbHooksTest.java index 18b9e2508b..05f334a169 100644 --- a/Ghidra/Test/IntegrationTest/src/test.slow/java/agent/gdb/rmi/GdbHooksTest.java +++ b/Ghidra/Test/IntegrationTest/src/test.slow/java/agent/gdb/rmi/GdbHooksTest.java @@ -15,7 +15,8 @@ */ package agent.gdb.rmi; -import static org.hamcrest.Matchers.*; +import static org.hamcrest.Matchers.greaterThan; +import static org.hamcrest.Matchers.instanceOf; import static org.junit.Assert.*; import java.nio.ByteBuffer; @@ -43,7 +44,7 @@ public class GdbHooksTest extends AbstractGdbTraceRmiTest { private static final long RUN_TIMEOUT_MS = 20000; private static final long RETRY_MS = 500; - record GdbAndTrace(GdbAndHandler conn, ManagedDomainObject mdo) implements AutoCloseable { + record GdbAndTrace(GdbAndConnection conn, ManagedDomainObject mdo) implements AutoCloseable { public void execute(String cmd) { conn.execute(cmd); } @@ -61,7 +62,7 @@ public class GdbHooksTest extends AbstractGdbTraceRmiTest { @SuppressWarnings("resource") protected GdbAndTrace startAndSyncGdb() throws Exception { - GdbAndHandler conn = startAndConnectGdb(); + GdbAndConnection conn = startAndConnectGdb(); try { // TODO: Why does using 'set arch' cause a hang at quit? conn.execute(""" @@ -142,7 +143,7 @@ public class GdbHooksTest extends AbstractGdbTraceRmiTest { } protected long lastSnap(GdbAndTrace conn) { - return conn.conn.handler().getLastSnapshot(tb.trace); + return conn.conn.connection().getLastSnapshot(tb.trace); } @Test diff --git a/Ghidra/Test/IntegrationTest/src/test.slow/java/agent/gdb/rmi/GdbMethodsTest.java b/Ghidra/Test/IntegrationTest/src/test.slow/java/agent/gdb/rmi/GdbMethodsTest.java index 32584ca02f..19183218db 100644 --- a/Ghidra/Test/IntegrationTest/src/test.slow/java/agent/gdb/rmi/GdbMethodsTest.java +++ b/Ghidra/Test/IntegrationTest/src/test.slow/java/agent/gdb/rmi/GdbMethodsTest.java @@ -28,12 +28,11 @@ import org.junit.experimental.categories.Category; import db.Transaction; import generic.Unique; import generic.test.category.NightlyCategory; -import ghidra.app.plugin.core.debug.service.rmi.trace.RemoteMethod; -import ghidra.app.plugin.core.debug.service.rmi.trace.ValueDecoder; import ghidra.app.plugin.core.debug.utils.ManagedDomainObject; import ghidra.dbg.testutil.DummyProc; import ghidra.dbg.util.PathPattern; import ghidra.dbg.util.PathPredicates; +import ghidra.debug.api.tracermi.RemoteMethod; import ghidra.program.model.address.*; import ghidra.program.model.data.Float10DataType; import ghidra.program.model.lang.Register; @@ -55,17 +54,16 @@ public class GdbMethodsTest extends AbstractGdbTraceRmiTest { @Test public void testExecuteCapture() throws Exception { - try (GdbAndHandler conn = startAndConnectGdb()) { + try (GdbAndConnection conn = startAndConnectGdb()) { RemoteMethod execute = conn.getMethod("execute"); - assertEquals(false, - execute.parameters().get("to_string").defaultValue().get(ValueDecoder.DEFAULT)); + assertEquals(false, execute.parameters().get("to_string").getDefaultValue()); assertEquals("test", execute.invoke(Map.of("cmd", "echo test", "to_string", true))); } } @Test public void testExecute() throws Exception { - try (GdbAndHandler conn = startAndConnectGdb()) { + try (GdbAndConnection conn = startAndConnectGdb()) { RemoteMethod execute = conn.getMethod("execute"); execute.invoke(Map.of("cmd", """ file bash @@ -80,7 +78,7 @@ public class GdbMethodsTest extends AbstractGdbTraceRmiTest { @Test public void testRefreshAvailable() throws Exception { - try (GdbAndHandler conn = startAndConnectGdb()) { + try (GdbAndConnection conn = startAndConnectGdb()) { conn.execute(""" ghidra trace start ghidra trace tx-open "Fake" 'ghidra trace create-obj Available'"""); @@ -103,7 +101,7 @@ public class GdbMethodsTest extends AbstractGdbTraceRmiTest { @Test public void testRefreshBreakpoints() throws Exception { - try (GdbAndHandler conn = startAndConnectGdb()) { + try (GdbAndConnection conn = startAndConnectGdb()) { conn.execute(""" file bash ghidra trace start @@ -157,7 +155,7 @@ public class GdbMethodsTest extends AbstractGdbTraceRmiTest { @Test public void testRefreshInfBreakpoints() throws Exception { - try (GdbAndHandler conn = startAndConnectGdb()) { + try (GdbAndConnection conn = startAndConnectGdb()) { conn.execute(""" file bash ghidra trace start @@ -211,7 +209,7 @@ public class GdbMethodsTest extends AbstractGdbTraceRmiTest { @Test public void testRefreshInferiors() throws Exception { - try (GdbAndHandler conn = startAndConnectGdb()) { + try (GdbAndConnection conn = startAndConnectGdb()) { conn.execute(""" add-inferior ghidra trace start @@ -235,7 +233,7 @@ public class GdbMethodsTest extends AbstractGdbTraceRmiTest { @Test public void testRefreshEnvironment() throws Exception { - try (GdbAndHandler conn = startAndConnectGdb()) { + try (GdbAndConnection conn = startAndConnectGdb()) { String path = "Inferiors[1].Environment"; conn.execute(""" file bash @@ -260,7 +258,7 @@ public class GdbMethodsTest extends AbstractGdbTraceRmiTest { @Test public void testRefreshThreads() throws Exception { - try (GdbAndHandler conn = startAndConnectGdb()) { + try (GdbAndConnection conn = startAndConnectGdb()) { String path = "Inferiors[1].Threads"; conn.execute(""" file bash @@ -282,7 +280,7 @@ public class GdbMethodsTest extends AbstractGdbTraceRmiTest { @Test public void testRefreshStack() throws Exception { - try (GdbAndHandler conn = startAndConnectGdb()) { + try (GdbAndConnection conn = startAndConnectGdb()) { String path = "Inferiors[1].Threads[1].Stack"; conn.execute(""" file bash @@ -316,7 +314,7 @@ public class GdbMethodsTest extends AbstractGdbTraceRmiTest { String count = IntStream.iterate(0, i -> i < 32, i -> i + 1) .mapToObj(Integer::toString) .collect(Collectors.joining(",", "{", "}")); - try (GdbAndHandler conn = startAndConnectGdb()) { + try (GdbAndConnection conn = startAndConnectGdb()) { String path = "Inferiors[1].Threads[1].Stack[0].Registers"; conn.execute(""" file bash @@ -361,7 +359,7 @@ public class GdbMethodsTest extends AbstractGdbTraceRmiTest { @Test public void testRefreshMappings() throws Exception { - try (GdbAndHandler conn = startAndConnectGdb()) { + try (GdbAndConnection conn = startAndConnectGdb()) { String path = "Inferiors[1].Memory"; conn.execute(""" file bash @@ -385,7 +383,7 @@ public class GdbMethodsTest extends AbstractGdbTraceRmiTest { @Test public void testRefreshModules() throws Exception { - try (GdbAndHandler conn = startAndConnectGdb()) { + try (GdbAndConnection conn = startAndConnectGdb()) { String path = "Inferiors[1].Modules"; conn.execute(""" file bash @@ -410,7 +408,7 @@ public class GdbMethodsTest extends AbstractGdbTraceRmiTest { @Test public void testActivateInferior() throws Exception { - try (GdbAndHandler conn = startAndConnectGdb()) { + try (GdbAndConnection conn = startAndConnectGdb()) { conn.execute(""" add-inferior ghidra trace start @@ -437,7 +435,7 @@ public class GdbMethodsTest extends AbstractGdbTraceRmiTest { @Test public void testActivateThread() throws Exception { - try (GdbAndHandler conn = startAndConnectGdb()) { + try (GdbAndConnection conn = startAndConnectGdb()) { conn.execute(""" add-inferior ghidra trace start @@ -474,7 +472,7 @@ public class GdbMethodsTest extends AbstractGdbTraceRmiTest { @Test public void testActivateFrame() throws Exception { - try (GdbAndHandler conn = startAndConnectGdb()) { + try (GdbAndConnection conn = startAndConnectGdb()) { conn.execute(""" file bash ghidra trace start @@ -508,7 +506,7 @@ public class GdbMethodsTest extends AbstractGdbTraceRmiTest { @Test public void testDeleteInferior() throws Exception { - try (GdbAndHandler conn = startAndConnectGdb()) { + try (GdbAndConnection conn = startAndConnectGdb()) { conn.execute(""" add-inferior ghidra trace start @@ -531,7 +529,7 @@ public class GdbMethodsTest extends AbstractGdbTraceRmiTest { public void testAttachObj() throws Exception { String sleep = DummyProc.which("expTraceableSleep"); try (DummyProc proc = DummyProc.run(sleep)) { - try (GdbAndHandler conn = startAndConnectGdb()) { + try (GdbAndConnection conn = startAndConnectGdb()) { conn.execute(""" ghidra trace start ghidra trace tx-open Init 'ghidra trace put-available' @@ -556,7 +554,7 @@ public class GdbMethodsTest extends AbstractGdbTraceRmiTest { public void testAttachPid() throws Exception { String sleep = DummyProc.which("expTraceableSleep"); try (DummyProc proc = DummyProc.run(sleep)) { - try (GdbAndHandler conn = startAndConnectGdb()) { + try (GdbAndConnection conn = startAndConnectGdb()) { conn.execute(""" ghidra trace start ghidra trace tx-open Init 'ghidra trace put-inferiors'"""); @@ -578,7 +576,7 @@ public class GdbMethodsTest extends AbstractGdbTraceRmiTest { public void testDetach() throws Exception { String sleep = DummyProc.which("expTraceableSleep"); try (DummyProc proc = DummyProc.run(sleep)) { - try (GdbAndHandler conn = startAndConnectGdb()) { + try (GdbAndConnection conn = startAndConnectGdb()) { conn.execute(""" ghidra trace start %s @@ -602,7 +600,7 @@ public class GdbMethodsTest extends AbstractGdbTraceRmiTest { @Test public void testLaunchMain() throws Exception { - try (GdbAndHandler conn = startAndConnectGdb()) { + try (GdbAndConnection conn = startAndConnectGdb()) { conn.execute(""" ghidra trace start %s @@ -626,7 +624,7 @@ public class GdbMethodsTest extends AbstractGdbTraceRmiTest { @Test public void testLaunchLoader() throws Exception { - try (GdbAndHandler conn = startAndConnectGdb()) { + try (GdbAndConnection conn = startAndConnectGdb()) { conn.execute(""" ghidra trace start %s @@ -650,7 +648,7 @@ public class GdbMethodsTest extends AbstractGdbTraceRmiTest { @Test public void testLaunchRun() throws Exception { - try (GdbAndHandler conn = startAndConnectGdb()) { + try (GdbAndConnection conn = startAndConnectGdb()) { conn.execute(""" ghidra trace start %s @@ -679,7 +677,7 @@ public class GdbMethodsTest extends AbstractGdbTraceRmiTest { @Test public void testKill() throws Exception { - try (GdbAndHandler conn = startAndConnectGdb()) { + try (GdbAndConnection conn = startAndConnectGdb()) { conn.execute(""" file bash ghidra trace start @@ -703,7 +701,7 @@ public class GdbMethodsTest extends AbstractGdbTraceRmiTest { @Test public void testResumeInterrupt5() throws Exception { - try (GdbAndHandler conn = startAndConnectGdb()) { + try (GdbAndConnection conn = startAndConnectGdb()) { RemoteMethod resume = conn.getMethod("resume"); RemoteMethod interrupt = conn.getMethod("interrupt"); conn.execute(""" @@ -752,7 +750,7 @@ public class GdbMethodsTest extends AbstractGdbTraceRmiTest { @Test public void testStepInto() throws Exception { - try (GdbAndHandler conn = startAndConnectGdb()) { + try (GdbAndConnection conn = startAndConnectGdb()) { conn.execute(""" file bash ghidra trace start @@ -783,7 +781,7 @@ public class GdbMethodsTest extends AbstractGdbTraceRmiTest { @Test public void testStepOver() throws Exception { - try (GdbAndHandler conn = startAndConnectGdb()) { + try (GdbAndConnection conn = startAndConnectGdb()) { conn.execute(""" file bash ghidra trace start @@ -814,7 +812,7 @@ public class GdbMethodsTest extends AbstractGdbTraceRmiTest { @Test public void testStepOut() throws Exception { - try (GdbAndHandler conn = startAndConnectGdb()) { + try (GdbAndConnection conn = startAndConnectGdb()) { conn.execute(""" file bash ghidra trace start @@ -842,7 +840,7 @@ public class GdbMethodsTest extends AbstractGdbTraceRmiTest { @Test public void testStepAdvance() throws Exception { - try (GdbAndHandler conn = startAndConnectGdb()) { + try (GdbAndConnection conn = startAndConnectGdb()) { conn.execute(""" file bash ghidra trace start @@ -870,7 +868,7 @@ public class GdbMethodsTest extends AbstractGdbTraceRmiTest { @Test public void testStepReturn() throws Exception { - try (GdbAndHandler conn = startAndConnectGdb()) { + try (GdbAndConnection conn = startAndConnectGdb()) { conn.execute(""" file bash ghidra trace start @@ -897,7 +895,7 @@ public class GdbMethodsTest extends AbstractGdbTraceRmiTest { @Test public void testBreakSwExecuteAddress() throws Exception { - try (GdbAndHandler conn = startAndConnectGdb()) { + try (GdbAndConnection conn = startAndConnectGdb()) { conn.execute(""" file bash ghidra trace start @@ -921,7 +919,7 @@ public class GdbMethodsTest extends AbstractGdbTraceRmiTest { @Test public void testBreakSwExecuteExpression() throws Exception { - try (GdbAndHandler conn = startAndConnectGdb()) { + try (GdbAndConnection conn = startAndConnectGdb()) { conn.execute(""" file bash ghidra trace start @@ -943,7 +941,7 @@ public class GdbMethodsTest extends AbstractGdbTraceRmiTest { @Test public void testBreakHwExecuteAddress() throws Exception { - try (GdbAndHandler conn = startAndConnectGdb()) { + try (GdbAndConnection conn = startAndConnectGdb()) { conn.execute(""" file bash ghidra trace start @@ -968,7 +966,7 @@ public class GdbMethodsTest extends AbstractGdbTraceRmiTest { @Test public void testBreakHwExecuteExpression() throws Exception { - try (GdbAndHandler conn = startAndConnectGdb()) { + try (GdbAndConnection conn = startAndConnectGdb()) { conn.execute(""" file bash ghidra trace start @@ -991,7 +989,7 @@ public class GdbMethodsTest extends AbstractGdbTraceRmiTest { @Test public void testBreakReadRange() throws Exception { - try (GdbAndHandler conn = startAndConnectGdb()) { + try (GdbAndConnection conn = startAndConnectGdb()) { conn.execute(""" file bash ghidra trace start @@ -1018,7 +1016,7 @@ public class GdbMethodsTest extends AbstractGdbTraceRmiTest { @Test public void testBreakReadExpression() throws Exception { - try (GdbAndHandler conn = startAndConnectGdb()) { + try (GdbAndConnection conn = startAndConnectGdb()) { conn.execute(""" file bash ghidra trace start @@ -1041,7 +1039,7 @@ public class GdbMethodsTest extends AbstractGdbTraceRmiTest { @Test public void testBreakWriteRange() throws Exception { - try (GdbAndHandler conn = startAndConnectGdb()) { + try (GdbAndConnection conn = startAndConnectGdb()) { conn.execute(""" file bash ghidra trace start @@ -1068,7 +1066,7 @@ public class GdbMethodsTest extends AbstractGdbTraceRmiTest { @Test public void testBreakWriteExpression() throws Exception { - try (GdbAndHandler conn = startAndConnectGdb()) { + try (GdbAndConnection conn = startAndConnectGdb()) { conn.execute(""" file bash ghidra trace start @@ -1091,7 +1089,7 @@ public class GdbMethodsTest extends AbstractGdbTraceRmiTest { @Test public void testBreakAccessRange() throws Exception { - try (GdbAndHandler conn = startAndConnectGdb()) { + try (GdbAndConnection conn = startAndConnectGdb()) { conn.execute(""" file bash ghidra trace start @@ -1118,7 +1116,7 @@ public class GdbMethodsTest extends AbstractGdbTraceRmiTest { @Test public void testBreakAccessExpression() throws Exception { - try (GdbAndHandler conn = startAndConnectGdb()) { + try (GdbAndConnection conn = startAndConnectGdb()) { conn.execute(""" file bash ghidra trace start @@ -1141,7 +1139,7 @@ public class GdbMethodsTest extends AbstractGdbTraceRmiTest { @Test public void testBreakEvent() throws Exception { - try (GdbAndHandler conn = startAndConnectGdb()) { + try (GdbAndConnection conn = startAndConnectGdb()) { conn.execute(""" file bash ghidra trace start @@ -1164,7 +1162,7 @@ public class GdbMethodsTest extends AbstractGdbTraceRmiTest { @Test public void testToggleBreakpoint() throws Exception { - try (GdbAndHandler conn = startAndConnectGdb()) { + try (GdbAndConnection conn = startAndConnectGdb()) { conn.execute(""" file bash ghidra trace start @@ -1190,7 +1188,7 @@ public class GdbMethodsTest extends AbstractGdbTraceRmiTest { @Test public void testToggleBreakpointLocation() throws Exception { - try (GdbAndHandler conn = startAndConnectGdb()) { + try (GdbAndConnection conn = startAndConnectGdb()) { conn.execute(""" file bash ghidra trace start @@ -1232,7 +1230,7 @@ public class GdbMethodsTest extends AbstractGdbTraceRmiTest { @Test public void testDeleteBreakpoint() throws Exception { - try (GdbAndHandler conn = startAndConnectGdb()) { + try (GdbAndConnection conn = startAndConnectGdb()) { conn.execute(""" file bash ghidra trace start diff --git a/Ghidra/Test/IntegrationTest/src/test.slow/java/agent/lldb/rmi/AbstractLldbTraceRmiTest.java b/Ghidra/Test/IntegrationTest/src/test.slow/java/agent/lldb/rmi/AbstractLldbTraceRmiTest.java index 863213531e..b723f1dea0 100644 --- a/Ghidra/Test/IntegrationTest/src/test.slow/java/agent/lldb/rmi/AbstractLldbTraceRmiTest.java +++ b/Ghidra/Test/IntegrationTest/src/test.slow/java/agent/lldb/rmi/AbstractLldbTraceRmiTest.java @@ -32,10 +32,11 @@ import org.apache.commons.lang3.exception.ExceptionUtils; import org.junit.Before; import ghidra.app.plugin.core.debug.gui.AbstractGhidraHeadedDebuggerGUITest; -import ghidra.app.plugin.core.debug.service.rmi.trace.*; +import ghidra.app.plugin.core.debug.service.rmi.trace.TraceRmiPlugin; import ghidra.app.plugin.core.debug.utils.ManagedDomainObject; import ghidra.app.services.TraceRmiService; import ghidra.dbg.testutil.DummyProc; +import ghidra.debug.api.tracermi.*; import ghidra.framework.*; import ghidra.framework.main.ApplicationLevelOnlyPlugin; import ghidra.framework.model.DomainFile; @@ -228,10 +229,10 @@ public abstract class AbstractLldbTraceRmiTest extends AbstractGhidraHeadedDebug return result.get(TIMEOUT_SECONDS, TimeUnit.SECONDS).handle(); } - protected record LldbAndHandler(ExecInLldb exec, TraceRmiHandler handler) + protected record LldbAndConnection(ExecInLldb exec, TraceRmiConnection connection) implements AutoCloseable { protected RemoteMethod getMethod(String name) { - return Objects.requireNonNull(handler.getMethods().get(name)); + return Objects.requireNonNull(connection.getMethods().get(name)); } public void execute(String cmd) { @@ -256,7 +257,7 @@ public abstract class AbstractLldbTraceRmiTest extends AbstractGhidraHeadedDebug try { LldbResult r = exec.future.get(TIMEOUT_SECONDS, TimeUnit.SECONDS); r.handle(); - waitForPass(() -> assertTrue(handler.isClosed())); + waitForPass(() -> assertTrue(connection.isClosed())); } finally { exec.lldb.destroyForcibly(); @@ -264,15 +265,15 @@ public abstract class AbstractLldbTraceRmiTest extends AbstractGhidraHeadedDebug } } - protected LldbAndHandler startAndConnectLldb(Function scriptSupplier) + protected LldbAndConnection startAndConnectLldb(Function scriptSupplier) throws Exception { TraceRmiAcceptor acceptor = traceRmi.acceptOne(null); ExecInLldb exec = execInLldb(scriptSupplier.apply(sockToStringForLldb(acceptor.getAddress()))); acceptor.setTimeout(CONNECT_TIMEOUT_MS); try { - TraceRmiHandler handler = acceptor.accept(); - return new LldbAndHandler(exec, handler); + TraceRmiConnection connection = acceptor.accept(); + return new LldbAndConnection(exec, connection); } catch (SocketTimeoutException e) { exec.lldb.destroyForcibly(); @@ -281,7 +282,7 @@ public abstract class AbstractLldbTraceRmiTest extends AbstractGhidraHeadedDebug } } - protected LldbAndHandler startAndConnectLldb() throws Exception { + protected LldbAndConnection startAndConnectLldb() throws Exception { return startAndConnectLldb(addr -> """ %s ghidra_trace_connect %s @@ -291,10 +292,10 @@ public abstract class AbstractLldbTraceRmiTest extends AbstractGhidraHeadedDebug @SuppressWarnings("resource") protected String runThrowError(Function scriptSupplier) throws Exception { - LldbAndHandler conn = startAndConnectLldb(scriptSupplier); + LldbAndConnection conn = startAndConnectLldb(scriptSupplier); LldbResult r = conn.exec.future.get(TIMEOUT_SECONDS, TimeUnit.SECONDS); String stdout = r.handle(); - waitForPass(() -> assertTrue(conn.handler.isClosed())); + waitForPass(() -> assertTrue(conn.connection.isClosed())); return stdout; } diff --git a/Ghidra/Test/IntegrationTest/src/test.slow/java/agent/lldb/rmi/LldbCommandsTest.java b/Ghidra/Test/IntegrationTest/src/test.slow/java/agent/lldb/rmi/LldbCommandsTest.java index 0481ee649a..aa93892ffc 100644 --- a/Ghidra/Test/IntegrationTest/src/test.slow/java/agent/lldb/rmi/LldbCommandsTest.java +++ b/Ghidra/Test/IntegrationTest/src/test.slow/java/agent/lldb/rmi/LldbCommandsTest.java @@ -31,10 +31,10 @@ import org.junit.experimental.categories.Category; import generic.Unique; import generic.test.category.NightlyCategory; -import ghidra.app.plugin.core.debug.service.rmi.trace.TraceRmiAcceptor; -import ghidra.app.plugin.core.debug.service.rmi.trace.TraceRmiHandler; import ghidra.app.plugin.core.debug.utils.ManagedDomainObject; import ghidra.dbg.util.PathPredicates; +import ghidra.debug.api.tracermi.TraceRmiAcceptor; +import ghidra.debug.api.tracermi.TraceRmiConnection; import ghidra.framework.model.DomainFile; import ghidra.program.model.address.*; import ghidra.program.model.lang.RegisterValue; @@ -56,9 +56,9 @@ public class LldbCommandsTest extends AbstractLldbTraceRmiTest { TraceRmiAcceptor acceptor = traceRmi.acceptOne(null); Msg.info(this, "Use: ghidra_trace_connect " + sockToStringForLldb(acceptor.getAddress())); - TraceRmiHandler handler = acceptor.accept(); - Msg.info(this, "Connected: " + sockToStringForLldb(handler.getRemoteAddress())); - handler.waitClosed(); + TraceRmiConnection connection = acceptor.accept(); + Msg.info(this, "Connected: " + sockToStringForLldb(connection.getRemoteAddress())); + connection.waitClosed(); Msg.info(this, "Closed"); } @@ -1220,7 +1220,7 @@ public class LldbCommandsTest extends AbstractLldbTraceRmiTest { @Test public void testPutFrames() throws Exception { - try (LldbAndHandler conn = startAndConnectLldb()) { + try (LldbAndConnection conn = startAndConnectLldb()) { conn.execute("file bash"); conn.execute("ghidra_trace_start"); conn.execute("ghidra_trace_txstart 'Tx'"); @@ -1256,7 +1256,7 @@ public class LldbCommandsTest extends AbstractLldbTraceRmiTest { %s ghidra_trace_connect %s """.formatted(PREAMBLE, addr); - try (LldbAndHandler conn = startAndConnectLldb(scriptSupplier)) { + try (LldbAndConnection conn = startAndConnectLldb(scriptSupplier)) { conn.execute("script print('FINISHED')"); conn.execute("quit"); } diff --git a/Ghidra/Test/IntegrationTest/src/test.slow/java/agent/lldb/rmi/LldbHooksTest.java b/Ghidra/Test/IntegrationTest/src/test.slow/java/agent/lldb/rmi/LldbHooksTest.java index 3a28a78a79..fd47fb0954 100644 --- a/Ghidra/Test/IntegrationTest/src/test.slow/java/agent/lldb/rmi/LldbHooksTest.java +++ b/Ghidra/Test/IntegrationTest/src/test.slow/java/agent/lldb/rmi/LldbHooksTest.java @@ -44,7 +44,7 @@ public class LldbHooksTest extends AbstractLldbTraceRmiTest { private static final long RUN_TIMEOUT_MS = 20000; private static final long RETRY_MS = 500; - record LldbAndTrace(LldbAndHandler conn, ManagedDomainObject mdo) implements AutoCloseable { + record LldbAndTrace(LldbAndConnection conn, ManagedDomainObject mdo) implements AutoCloseable { public void execute(String cmd) { conn.execute(cmd); } @@ -62,7 +62,7 @@ public class LldbHooksTest extends AbstractLldbTraceRmiTest { @SuppressWarnings("resource") protected LldbAndTrace startAndSyncLldb() throws Exception { - LldbAndHandler conn = startAndConnectLldb(); + LldbAndConnection conn = startAndConnectLldb(); try { // TODO: Why does using 'set arch' cause a hang at quit? conn.execute( @@ -79,7 +79,7 @@ public class LldbHooksTest extends AbstractLldbTraceRmiTest { } protected long lastSnap(LldbAndTrace conn) { - return conn.conn.handler().getLastSnapshot(tb.trace); + return conn.conn.connection().getLastSnapshot(tb.trace); } // TODO: This passes if you single-step through it but fails on some transactional stuff if run diff --git a/Ghidra/Test/IntegrationTest/src/test.slow/java/agent/lldb/rmi/LldbMethodsTest.java b/Ghidra/Test/IntegrationTest/src/test.slow/java/agent/lldb/rmi/LldbMethodsTest.java index 3ea4534290..1601c47609 100644 --- a/Ghidra/Test/IntegrationTest/src/test.slow/java/agent/lldb/rmi/LldbMethodsTest.java +++ b/Ghidra/Test/IntegrationTest/src/test.slow/java/agent/lldb/rmi/LldbMethodsTest.java @@ -15,7 +15,8 @@ */ package agent.lldb.rmi; -import static org.hamcrest.Matchers.*; +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.greaterThan; import static org.junit.Assert.*; import java.util.*; @@ -25,12 +26,11 @@ import org.junit.experimental.categories.Category; import generic.Unique; import generic.test.category.NightlyCategory; -import ghidra.app.plugin.core.debug.service.rmi.trace.RemoteMethod; -import ghidra.app.plugin.core.debug.service.rmi.trace.ValueDecoder; import ghidra.app.plugin.core.debug.utils.ManagedDomainObject; import ghidra.dbg.testutil.DummyProc; import ghidra.dbg.util.PathPattern; import ghidra.dbg.util.PathPredicates; +import ghidra.debug.api.tracermi.RemoteMethod; import ghidra.program.model.address.*; import ghidra.program.model.lang.RegisterValue; import ghidra.trace.database.ToyDBTraceBuilder; @@ -48,10 +48,9 @@ public class LldbMethodsTest extends AbstractLldbTraceRmiTest { @Test public void testExecuteCapture() throws Exception { - try (LldbAndHandler conn = startAndConnectLldb()) { + try (LldbAndConnection conn = startAndConnectLldb()) { RemoteMethod execute = conn.getMethod("execute"); - assertEquals(false, - execute.parameters().get("to_string").defaultValue().get(ValueDecoder.DEFAULT)); + assertEquals(false, execute.parameters().get("to_string").getDefaultValue()); assertEquals("test\n", execute.invoke(Map.of("cmd", "script print('test')", "to_string", true))); } @@ -59,7 +58,7 @@ public class LldbMethodsTest extends AbstractLldbTraceRmiTest { @Test public void testExecute() throws Exception { - try (LldbAndHandler conn = startAndConnectLldb()) { + try (LldbAndConnection conn = startAndConnectLldb()) { start(conn, "bash"); conn.execute("kill"); } @@ -70,7 +69,7 @@ public class LldbMethodsTest extends AbstractLldbTraceRmiTest { @Test public void testRefreshAvailable() throws Exception { - try (LldbAndHandler conn = startAndConnectLldb()) { + try (LldbAndConnection conn = startAndConnectLldb()) { conn.execute("ghidra_trace_start"); txCreate(conn, "Available"); @@ -93,7 +92,7 @@ public class LldbMethodsTest extends AbstractLldbTraceRmiTest { @Test public void testRefreshBreakpoints() throws Exception { - try (LldbAndHandler conn = startAndConnectLldb()) { + try (LldbAndConnection conn = startAndConnectLldb()) { start(conn, "bash"); txPut(conn, "processes"); @@ -131,7 +130,7 @@ public class LldbMethodsTest extends AbstractLldbTraceRmiTest { @Test public void testRefreshProcBreakpoints() throws Exception { - try (LldbAndHandler conn = startAndConnectLldb()) { + try (LldbAndConnection conn = startAndConnectLldb()) { start(conn, "bash"); txPut(conn, "processes"); txPut(conn, "breakpoints"); @@ -169,7 +168,7 @@ public class LldbMethodsTest extends AbstractLldbTraceRmiTest { @Test public void testRefreshProcWatchpoints() throws Exception { - try (LldbAndHandler conn = startAndConnectLldb()) { + try (LldbAndConnection conn = startAndConnectLldb()) { start(conn, "bash"); txPut(conn, "all"); @@ -216,7 +215,7 @@ public class LldbMethodsTest extends AbstractLldbTraceRmiTest { @Test public void testRefreshProcesses() throws Exception { - try (LldbAndHandler conn = startAndConnectLldb()) { + try (LldbAndConnection conn = startAndConnectLldb()) { conn.execute("ghidra_trace_start"); txCreate(conn, "Processes"); txCreate(conn, "Processes[1]"); @@ -240,7 +239,7 @@ public class LldbMethodsTest extends AbstractLldbTraceRmiTest { @Test public void testRefreshEnvironment() throws Exception { - try (LldbAndHandler conn = startAndConnectLldb()) { + try (LldbAndConnection conn = startAndConnectLldb()) { String path = "Processes[].Environment"; start(conn, "bash"); txPut(conn, "all"); @@ -263,7 +262,7 @@ public class LldbMethodsTest extends AbstractLldbTraceRmiTest { @Test public void testRefreshThreads() throws Exception { - try (LldbAndHandler conn = startAndConnectLldb()) { + try (LldbAndConnection conn = startAndConnectLldb()) { String path = "Processes[].Threads"; start(conn, "bash"); txCreate(conn, path); @@ -283,7 +282,7 @@ public class LldbMethodsTest extends AbstractLldbTraceRmiTest { @Test public void testRefreshStack() throws Exception { - try (LldbAndHandler conn = startAndConnectLldb()) { + try (LldbAndConnection conn = startAndConnectLldb()) { String path = "Processes[].Threads[].Stack"; conn.execute("file bash"); conn.execute("ghidra_trace_start"); @@ -312,7 +311,7 @@ public class LldbMethodsTest extends AbstractLldbTraceRmiTest { @Test public void testRefreshRegisters() throws Exception { - try (LldbAndHandler conn = startAndConnectLldb()) { + try (LldbAndConnection conn = startAndConnectLldb()) { String path = "Processes[].Threads[].Stack[].Registers"; start(conn, "bash"); conn.execute("ghidra_trace_txstart 'Tx'"); @@ -341,7 +340,7 @@ public class LldbMethodsTest extends AbstractLldbTraceRmiTest { @Test public void testRefreshMappings() throws Exception { - try (LldbAndHandler conn = startAndConnectLldb()) { + try (LldbAndConnection conn = startAndConnectLldb()) { String path = "Processes[].Memory"; start(conn, "bash"); txCreate(conn, path); @@ -363,7 +362,7 @@ public class LldbMethodsTest extends AbstractLldbTraceRmiTest { @Test public void testRefreshModules() throws Exception { - try (LldbAndHandler conn = startAndConnectLldb()) { + try (LldbAndConnection conn = startAndConnectLldb()) { String path = "Processes[].Modules"; start(conn, "bash"); txCreate(conn, path); @@ -386,7 +385,7 @@ public class LldbMethodsTest extends AbstractLldbTraceRmiTest { @Test public void testActivateThread() throws Exception { - try (LldbAndHandler conn = startAndConnectLldb()) { + try (LldbAndConnection conn = startAndConnectLldb()) { // TODO: need to find this file (same issue in LldbHookTests String dproc = DummyProc.which("expCloneExit"); conn.execute("file " + dproc); @@ -421,7 +420,7 @@ public class LldbMethodsTest extends AbstractLldbTraceRmiTest { @Test public void testActivateFrame() throws Exception { - try (LldbAndHandler conn = startAndConnectLldb()) { + try (LldbAndConnection conn = startAndConnectLldb()) { conn.execute("file bash"); conn.execute("ghidra_trace_start"); txPut(conn, "processes"); @@ -453,7 +452,7 @@ public class LldbMethodsTest extends AbstractLldbTraceRmiTest { @Test public void testRemoveProcess() throws Exception { - try (LldbAndHandler conn = startAndConnectLldb()) { + try (LldbAndConnection conn = startAndConnectLldb()) { start(conn, "bash"); txPut(conn, "processes"); @@ -474,7 +473,7 @@ public class LldbMethodsTest extends AbstractLldbTraceRmiTest { public void testAttachObj() throws Exception { String sleep = DummyProc.which("expTraceableSleep"); try (DummyProc dproc = DummyProc.run(sleep)) { - try (LldbAndHandler conn = startAndConnectLldb()) { + try (LldbAndConnection conn = startAndConnectLldb()) { conn.execute("ghidra_trace_start"); txPut(conn, "available"); txPut(conn, "processes"); @@ -499,7 +498,7 @@ public class LldbMethodsTest extends AbstractLldbTraceRmiTest { public void testAttachPid() throws Exception { String sleep = DummyProc.which("expTraceableSleep"); try (DummyProc dproc = DummyProc.run(sleep)) { - try (LldbAndHandler conn = startAndConnectLldb()) { + try (LldbAndConnection conn = startAndConnectLldb()) { conn.execute("ghidra_trace_start"); txPut(conn, "processes"); @@ -519,7 +518,7 @@ public class LldbMethodsTest extends AbstractLldbTraceRmiTest { @Test public void testDetach() throws Exception { - try (LldbAndHandler conn = startAndConnectLldb()) { + try (LldbAndConnection conn = startAndConnectLldb()) { start(conn, "bash"); txPut(conn, "processes"); //conn.execute("process attach -p %d".formatted(dproc.pid)); @@ -540,7 +539,7 @@ public class LldbMethodsTest extends AbstractLldbTraceRmiTest { @Test public void testLaunchEntry() throws Exception { - try (LldbAndHandler conn = startAndConnectLldb()) { + try (LldbAndConnection conn = startAndConnectLldb()) { conn.execute("ghidra_trace_start"); txPut(conn, "processes"); @@ -562,7 +561,7 @@ public class LldbMethodsTest extends AbstractLldbTraceRmiTest { @Test //Not clear how to send interrupt public void testLaunch() throws Exception { - try (LldbAndHandler conn = startAndConnectLldb()) { + try (LldbAndConnection conn = startAndConnectLldb()) { conn.execute("ghidra_trace_start"); txPut(conn, "processes"); @@ -593,7 +592,7 @@ public class LldbMethodsTest extends AbstractLldbTraceRmiTest { @Test public void testKill() throws Exception { - try (LldbAndHandler conn = startAndConnectLldb()) { + try (LldbAndConnection conn = startAndConnectLldb()) { start(conn, "bash"); txPut(conn, "processes"); @@ -613,7 +612,7 @@ public class LldbMethodsTest extends AbstractLldbTraceRmiTest { @Test public void testStepInto() throws Exception { - try (LldbAndHandler conn = startAndConnectLldb()) { + try (LldbAndConnection conn = startAndConnectLldb()) { start(conn, "bash"); txPut(conn, "processes"); @@ -647,7 +646,7 @@ public class LldbMethodsTest extends AbstractLldbTraceRmiTest { @Test public void testStepOver() throws Exception { - try (LldbAndHandler conn = startAndConnectLldb()) { + try (LldbAndConnection conn = startAndConnectLldb()) { conn.execute("file bash"); conn.execute("ghidra_trace_start"); txPut(conn, "processes"); @@ -681,7 +680,7 @@ public class LldbMethodsTest extends AbstractLldbTraceRmiTest { //@Test Not obvious "thread until -a" works (and definitely requires debug info") public void testAdvance() throws Exception { - try (LldbAndHandler conn = startAndConnectLldb()) { + try (LldbAndConnection conn = startAndConnectLldb()) { start(conn, "bash"); RemoteMethod step_ext = conn.getMethod("step_ext"); @@ -706,7 +705,7 @@ public class LldbMethodsTest extends AbstractLldbTraceRmiTest { @Test public void testFinish() throws Exception { - try (LldbAndHandler conn = startAndConnectLldb()) { + try (LldbAndConnection conn = startAndConnectLldb()) { conn.execute("file bash"); conn.execute("ghidra_trace_start"); txPut(conn, "processes"); @@ -734,7 +733,7 @@ public class LldbMethodsTest extends AbstractLldbTraceRmiTest { @Test public void testReturn() throws Exception { - try (LldbAndHandler conn = startAndConnectLldb()) { + try (LldbAndConnection conn = startAndConnectLldb()) { conn.execute("file bash"); conn.execute("ghidra_trace_start"); txPut(conn, "processes"); @@ -762,7 +761,7 @@ public class LldbMethodsTest extends AbstractLldbTraceRmiTest { @Test public void testBreakAddress() throws Exception { - try (LldbAndHandler conn = startAndConnectLldb()) { + try (LldbAndConnection conn = startAndConnectLldb()) { start(conn, "bash"); txPut(conn, "processes"); @@ -783,7 +782,7 @@ public class LldbMethodsTest extends AbstractLldbTraceRmiTest { @Test public void testBreakExpression() throws Exception { - try (LldbAndHandler conn = startAndConnectLldb()) { + try (LldbAndConnection conn = startAndConnectLldb()) { start(conn, "bash"); txPut(conn, "processes"); @@ -803,7 +802,7 @@ public class LldbMethodsTest extends AbstractLldbTraceRmiTest { //@Test stderr getting populated with warning about exhausted hardware breakpoints // Are hardware breakpoints available on our VMs? public void testBreakHardwareAddress() throws Exception { - try (LldbAndHandler conn = startAndConnectLldb()) { + try (LldbAndConnection conn = startAndConnectLldb()) { start(conn, "bash"); txPut(conn, "processes"); @@ -824,7 +823,7 @@ public class LldbMethodsTest extends AbstractLldbTraceRmiTest { //@Test There appear to be issues with hardware register availability in our virtual environments public void testBreakHardwareExpression() throws Exception { - try (LldbAndHandler conn = startAndConnectLldb()) { + try (LldbAndConnection conn = startAndConnectLldb()) { start(conn, "bash"); txPut(conn, "processes"); @@ -845,7 +844,7 @@ public class LldbMethodsTest extends AbstractLldbTraceRmiTest { @Test public void testBreakReadRange() throws Exception { - try (LldbAndHandler conn = startAndConnectLldb()) { + try (LldbAndConnection conn = startAndConnectLldb()) { start(conn, "bash"); txPut(conn, "processes"); @@ -869,7 +868,7 @@ public class LldbMethodsTest extends AbstractLldbTraceRmiTest { @Test public void testBreakReadExpression() throws Exception { - try (LldbAndHandler conn = startAndConnectLldb()) { + try (LldbAndConnection conn = startAndConnectLldb()) { start(conn, "bash"); txPut(conn, "processes"); @@ -889,7 +888,7 @@ public class LldbMethodsTest extends AbstractLldbTraceRmiTest { @Test public void testBreakWriteRange() throws Exception { - try (LldbAndHandler conn = startAndConnectLldb()) { + try (LldbAndConnection conn = startAndConnectLldb()) { start(conn, "bash"); txPut(conn, "processes"); @@ -913,7 +912,7 @@ public class LldbMethodsTest extends AbstractLldbTraceRmiTest { @Test public void testBreakWriteExpression() throws Exception { - try (LldbAndHandler conn = startAndConnectLldb()) { + try (LldbAndConnection conn = startAndConnectLldb()) { start(conn, "bash"); txPut(conn, "processes"); @@ -933,7 +932,7 @@ public class LldbMethodsTest extends AbstractLldbTraceRmiTest { @Test public void testBreakAccessRange() throws Exception { - try (LldbAndHandler conn = startAndConnectLldb()) { + try (LldbAndConnection conn = startAndConnectLldb()) { start(conn, "bash"); txPut(conn, "processes"); @@ -957,7 +956,7 @@ public class LldbMethodsTest extends AbstractLldbTraceRmiTest { @Test public void testBreakAccessExpression() throws Exception { - try (LldbAndHandler conn = startAndConnectLldb()) { + try (LldbAndConnection conn = startAndConnectLldb()) { start(conn, "bash"); txPut(conn, "processes"); @@ -978,7 +977,7 @@ public class LldbMethodsTest extends AbstractLldbTraceRmiTest { // NB: not really equivalent to gdb's "catch" but... @Test public void testBreakException() throws Exception { - try (LldbAndHandler conn = startAndConnectLldb()) { + try (LldbAndConnection conn = startAndConnectLldb()) { start(conn, "bash"); txPut(conn, "processes"); @@ -997,7 +996,7 @@ public class LldbMethodsTest extends AbstractLldbTraceRmiTest { @Test public void testToggleBreakpoint() throws Exception { - try (LldbAndHandler conn = startAndConnectLldb()) { + try (LldbAndConnection conn = startAndConnectLldb()) { conn.execute("file bash"); conn.execute("ghidra_trace_start"); txPut(conn, "processes"); @@ -1021,7 +1020,7 @@ public class LldbMethodsTest extends AbstractLldbTraceRmiTest { @Test public void testToggleBreakpointLocation() throws Exception { - try (LldbAndHandler conn = startAndConnectLldb()) { + try (LldbAndConnection conn = startAndConnectLldb()) { conn.execute("file bash"); conn.execute("ghidra_trace_start"); txPut(conn, "processes"); @@ -1047,7 +1046,7 @@ public class LldbMethodsTest extends AbstractLldbTraceRmiTest { @Test public void testDeleteBreakpoint() throws Exception { - try (LldbAndHandler conn = startAndConnectLldb()) { + try (LldbAndConnection conn = startAndConnectLldb()) { conn.execute("file bash"); conn.execute("ghidra_trace_start"); txPut(conn, "processes"); @@ -1071,7 +1070,7 @@ public class LldbMethodsTest extends AbstractLldbTraceRmiTest { @Test public void testDeleteWatchpoint() throws Exception { - try (LldbAndHandler conn = startAndConnectLldb()) { + try (LldbAndConnection conn = startAndConnectLldb()) { start(conn, "bash"); txPut(conn, "processes"); @@ -1097,31 +1096,31 @@ public class LldbMethodsTest extends AbstractLldbTraceRmiTest { } } - private void start(LldbAndHandler conn, String obj) { + private void start(LldbAndConnection conn, String obj) { conn.execute("file " + obj); conn.execute("ghidra_trace_start"); conn.execute("process launch --stop-at-entry"); } - private void txPut(LldbAndHandler conn, String obj) { + private void txPut(LldbAndConnection conn, String obj) { conn.execute("ghidra_trace_txstart 'Tx'"); conn.execute("ghidra_trace_put_" + obj); conn.execute("ghidra_trace_txcommit"); } - private void txCreate(LldbAndHandler conn, String path) { + private void txCreate(LldbAndConnection conn, String path) { conn.execute("ghidra_trace_txstart 'Fake'"); conn.execute("ghidra_trace_create_obj %s".formatted(path)); conn.execute("ghidra_trace_txcommit"); } - private void breakAt(LldbAndHandler conn, String fn) { + private void breakAt(LldbAndConnection conn, String fn) { conn.execute("ghidra_trace_sync_enable"); conn.execute("breakpoint set -n " + fn); conn.execute("run"); } - private int getDepth(LldbAndHandler conn) { + private int getDepth(LldbAndConnection conn) { String[] split = conn.executeCapture("bt").split("\n"); int initDepth = 0; for (String str : split) { diff --git a/Ghidra/Test/IntegrationTest/src/test.slow/java/ghidra/app/plugin/core/debug/gui/tracermi/launcher/TraceRmiLauncherServicePluginTest.java b/Ghidra/Test/IntegrationTest/src/test.slow/java/ghidra/app/plugin/core/debug/gui/tracermi/launcher/TraceRmiLauncherServicePluginTest.java new file mode 100644 index 0000000000..aa113545ea --- /dev/null +++ b/Ghidra/Test/IntegrationTest/src/test.slow/java/ghidra/app/plugin/core/debug/gui/tracermi/launcher/TraceRmiLauncherServicePluginTest.java @@ -0,0 +1,90 @@ +/* ### + * IP: GHIDRA + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ghidra.app.plugin.core.debug.gui.tracermi.launcher; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; + +import java.util.*; + +import org.junit.Before; +import org.junit.Test; + +import db.Transaction; +import ghidra.app.plugin.core.debug.gui.AbstractGhidraHeadedDebuggerGUITest; +import ghidra.app.services.TraceRmiLauncherService; +import ghidra.debug.api.tracermi.TraceRmiLaunchOffer; +import ghidra.debug.api.tracermi.TraceRmiLaunchOffer.*; +import ghidra.util.task.ConsoleTaskMonitor; + +public class TraceRmiLauncherServicePluginTest extends AbstractGhidraHeadedDebuggerGUITest { + TraceRmiLauncherService launcherService; + + @Before + public void setupRmiLauncherTest() throws Exception { + launcherService = addPlugin(tool, TraceRmiLauncherServicePlugin.class); + } + + protected TraceRmiLaunchOffer findByTitle(Collection offers, + String title) { + return offers.stream().filter(o -> o.getTitle().equals(title)).findFirst().get(); + } + + @Test + public void testGetOpinions() throws Exception { + assertFalse(launcherService.getOpinions().isEmpty()); + } + + @Test + public void testGetOffers() throws Exception { + createProgram(getSLEIGH_X86_64_LANGUAGE()); + + assertFalse(launcherService.getOffers(program).isEmpty()); + } + + protected LaunchConfigurator fileOnly(String file) { + return new LaunchConfigurator() { + @Override + public Map configureLauncher(TraceRmiLaunchOffer offer, + Map arguments, RelPrompt relPrompt) { + Map args = new HashMap<>(arguments); + args.put("arg:1", file); + return args; + } + }; + } + + @Test + public void testLaunchLocalGdb() throws Exception { + createProgram(getSLEIGH_X86_64_LANGUAGE()); + try (Transaction tx = program.openTransaction("Rename")) { + program.setName("bash"); + } + programManager.openProgram(program); + + TraceRmiLaunchOffer gdbOffer = findByTitle(launcherService.getOffers(program), "gdb"); + + try (LaunchResult result = + gdbOffer.launchProgram(new ConsoleTaskMonitor(), fileOnly("/usr/bin/bash"))) { + if (result.exception() != null) { + throw new AssertionError(result.exception()); + } + + assertEquals("bash", result.trace().getName()); + assertEquals(getSLEIGH_X86_64_LANGUAGE(), result.trace().getBaseLanguage()); + } + } +} diff --git a/Ghidra/Test/IntegrationTest/src/test/java/ghidra/util/bean/PathnameTablePanelTest.java b/Ghidra/Test/IntegrationTest/src/test/java/ghidra/util/bean/PathnameTablePanelTest.java index 77ee85f85e..0c2ae03da3 100644 --- a/Ghidra/Test/IntegrationTest/src/test/java/ghidra/util/bean/PathnameTablePanelTest.java +++ b/Ghidra/Test/IntegrationTest/src/test/java/ghidra/util/bean/PathnameTablePanelTest.java @@ -18,6 +18,9 @@ package ghidra.util.bean; import static org.junit.Assert.*; import java.io.File; +import java.util.ArrayList; +import java.util.List; +import java.util.stream.IntStream; import javax.swing.*; @@ -55,7 +58,8 @@ public class PathnameTablePanelTest extends AbstractDockingTest { @Before public void setUp() throws Exception { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); - panel = new PathnameTablePanel(tablePaths, true, false, () -> reset()); + // enable edits, add to bottom, ordered + panel = new PathnameTablePanel(tablePaths, () -> reset(), true, false, true); table = panel.getTable(); frame = new JFrame("Test"); frame.getContentPane().add(panel); @@ -245,6 +249,32 @@ public class PathnameTablePanelTest extends AbstractDockingTest { } + @Test + public void testUnordered() throws Exception { + panel.setOrdered(false); + File temp = createTempFileForTest(); + Preferences.setProperty(Preferences.LAST_PATH_DIRECTORY, temp.getParent()); + panel.setFileChooserProperties("Select Source Files", Preferences.LAST_PATH_DIRECTORY, + GhidraFileChooserMode.FILES_AND_DIRECTORIES, true, + new ExtensionFileFilter(new String[] { "h" }, "C Header Files")); + + assertNotNull(addButton); + pressButton(addButton, false); + + waitForSwing(); + selectFromFileChooser(); + + assertEquals(6, table.getRowCount()); + + List expected = new ArrayList<>(List.of(tablePaths)); + expected.add(new File(temp.getParentFile(), "fred.h").getAbsolutePath()); + expected.sort(String::compareTo); + List actual = IntStream.range(0, 6) + .mapToObj(i -> (String) table.getModel().getValueAt(i, 0)) + .toList(); + assertEquals(expected, actual); + } + @Test public void testReset() throws Exception { diff --git a/GhidraDocs/GhidraClass/Debugger/ghidra_scripts/InstallCustomLibraryScript.java b/GhidraDocs/GhidraClass/Debugger/ghidra_scripts/InstallCustomLibraryScript.java index c991629623..8039dc61b1 100644 --- a/GhidraDocs/GhidraClass/Debugger/ghidra_scripts/InstallCustomLibraryScript.java +++ b/GhidraDocs/GhidraClass/Debugger/ghidra_scripts/InstallCustomLibraryScript.java @@ -14,9 +14,10 @@ * limitations under the License. */ import ghidra.app.plugin.core.debug.service.emulation.*; -import ghidra.app.plugin.core.debug.service.emulation.data.PcodeDebuggerAccess; import ghidra.app.plugin.processors.sleigh.SleighLanguage; import ghidra.app.script.GhidraScript; +import ghidra.debug.api.emulation.DebuggerPcodeMachine; +import ghidra.debug.api.emulation.PcodeDebuggerAccess; import ghidra.debug.flatapi.FlatDebuggerAPI; import ghidra.pcode.exec.PcodeUseropLibrary; diff --git a/GhidraDocs/GhidraClass/Debugger/ghidra_scripts/ModelingScript.java b/GhidraDocs/GhidraClass/Debugger/ghidra_scripts/ModelingScript.java index 9f1454da33..f2ef831912 100644 --- a/GhidraDocs/GhidraClass/Debugger/ghidra_scripts/ModelingScript.java +++ b/GhidraDocs/GhidraClass/Debugger/ghidra_scripts/ModelingScript.java @@ -21,9 +21,10 @@ import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.tuple.Pair; import ghidra.app.plugin.core.debug.service.emulation.*; -import ghidra.app.plugin.core.debug.service.emulation.data.PcodeDebuggerAccess; import ghidra.app.plugin.processors.sleigh.SleighLanguage; import ghidra.app.script.GhidraScript; +import ghidra.debug.api.emulation.DebuggerPcodeMachine; +import ghidra.debug.api.emulation.PcodeDebuggerAccess; import ghidra.lifecycle.Unfinished; import ghidra.pcode.emu.DefaultPcodeThread.PcodeThreadExecutor; import ghidra.pcode.emu.PcodeThread; @@ -649,7 +650,7 @@ public class ModelingScript extends GhidraScript { } public static class BytesExprDebuggerPcodeEmulatorFactory - implements DebuggerPcodeEmulatorFactory { + extends AbstractDebuggerPcodeEmulatorFactory { @Override public String getTitle() { diff --git a/GhidraDocs/GhidraClass/Debugger/ghidra_scripts/ZeroTimerScript.java b/GhidraDocs/GhidraClass/Debugger/ghidra_scripts/ZeroTimerScript.java index f156d67526..a208618829 100644 --- a/GhidraDocs/GhidraClass/Debugger/ghidra_scripts/ZeroTimerScript.java +++ b/GhidraDocs/GhidraClass/Debugger/ghidra_scripts/ZeroTimerScript.java @@ -21,8 +21,8 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import ghidra.app.script.GhidraScript; -import ghidra.app.services.LogicalBreakpoint; import ghidra.dbg.target.TargetExecutionStateful.TargetExecutionState; +import ghidra.debug.api.breakpoint.LogicalBreakpoint; import ghidra.debug.flatapi.FlatDebuggerAPI; import ghidra.program.model.address.Address; import ghidra.program.model.listing.Function;