From 4a7d8b6984ceb2803cecb017a45226c8d6305341 Mon Sep 17 00:00:00 2001 From: Dan <46821332+nsadeveloper789@users.noreply.github.com> Date: Thu, 15 May 2025 16:39:02 +0000 Subject: [PATCH] GP-5678: Move timeout error on PE-header read to debug console. Heed Auto-Read spec. --- .../app/services/DebuggerListingService.java | 10 +- .../debug/api}/action/AutoReadMemorySpec.java | 101 +++----- .../api/action/AutoReadMemorySpecFactory.java | 80 ++++++ .../action/LocationTrackingSpecFactory.java | 1 + .../Debugger/data/ExtensionPoint.manifest | 3 +- .../gui/action/BasicAutoReadMemorySpec.java | 242 ++++++++++++++++++ .../BasicAutoReadMemorySpecFactory.java | 44 ++++ .../action/DebuggerAutoReadMemoryAction.java | 9 +- .../gui/action/DebuggerReadsMemoryTrait.java | 6 +- .../LoadEmulatorAutoReadMemorySpec.java | 116 --------- .../gui/action/NoneAutoReadMemorySpec.java | 60 ----- .../gui/action/VisibleAutoReadMemorySpec.java | 72 ------ .../VisibleROOnceAutoReadMemorySpec.java | 96 ------- .../gui/listing/DebuggerListingPlugin.java | 14 +- .../gui/listing/DebuggerListingProvider.java | 3 +- .../memory/DebuggerMemoryBytesProvider.java | 8 +- .../dbgeng/DbgengDebuggerPlatformOpinion.java | 53 ++-- .../gui/AbstractGhidraHeadedDebuggerTest.java | 13 +- .../DebuggerCopyActionsPluginTest.java | 6 +- .../listing/DebuggerListingProviderTest.java | 1 + 20 files changed, 482 insertions(+), 456 deletions(-) rename Ghidra/Debug/{Debugger/src/main/java/ghidra/app/plugin/core/debug/gui => Debugger-api/src/main/java/ghidra/debug/api}/action/AutoReadMemorySpec.java (53%) create mode 100644 Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/action/AutoReadMemorySpecFactory.java create mode 100644 Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/BasicAutoReadMemorySpec.java create mode 100644 Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/BasicAutoReadMemorySpecFactory.java delete mode 100644 Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/LoadEmulatorAutoReadMemorySpec.java delete mode 100644 Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/NoneAutoReadMemorySpec.java delete mode 100644 Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/VisibleAutoReadMemorySpec.java delete mode 100644 Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/VisibleROOnceAutoReadMemorySpec.java diff --git a/Ghidra/Debug/Debugger-api/src/main/java/ghidra/app/services/DebuggerListingService.java b/Ghidra/Debug/Debugger-api/src/main/java/ghidra/app/services/DebuggerListingService.java index c8d5e725b2..d4e90cbecb 100644 --- a/Ghidra/Debug/Debugger-api/src/main/java/ghidra/app/services/DebuggerListingService.java +++ b/Ghidra/Debug/Debugger-api/src/main/java/ghidra/app/services/DebuggerListingService.java @@ -16,6 +16,7 @@ package ghidra.app.services; import ghidra.app.util.viewer.listingpanel.ListingPanel; +import ghidra.debug.api.action.AutoReadMemorySpec; import ghidra.debug.api.action.LocationTrackingSpec; import ghidra.debug.api.listing.MultiBlendedListingBackgroundColorModel; import ghidra.framework.plugintool.ServiceInfo; @@ -50,12 +51,19 @@ public interface DebuggerListingService extends CodeViewerService { void setTrackingSpec(LocationTrackingSpec spec); /** - * Get the tracking specification of the listing. + * Get the tracking specification of the main listing. * * @return the current specification */ LocationTrackingSpec getTrackingSpec(); + /** + * Get the auto-read memory specification of the main listing. + * + * @return the current specification + */ + AutoReadMemorySpec getAutoReadMemorySpec(); + /** * Add a listener for changes to the tracking specification. * diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/AutoReadMemorySpec.java b/Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/action/AutoReadMemorySpec.java similarity index 53% rename from Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/AutoReadMemorySpec.java rename to Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/action/AutoReadMemorySpec.java index 5eeba15463..fae66f216a 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/AutoReadMemorySpec.java +++ b/Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/action/AutoReadMemorySpec.java @@ -13,58 +13,33 @@ * 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.Map; -import java.util.TreeMap; import java.util.concurrent.CompletableFuture; -import java.util.function.Function; import javax.swing.Icon; -import javax.swing.event.ChangeEvent; -import javax.swing.event.ChangeListener; -import ghidra.app.plugin.core.debug.gui.control.TargetActionTask; -import ghidra.app.plugin.core.debug.service.emulation.ProgramEmulationUtils; -import ghidra.debug.api.action.InstanceUtils; import ghidra.debug.api.tracemgr.DebuggerCoordinates; import ghidra.framework.options.SaveState; import ghidra.framework.plugintool.AutoConfigState.ConfigFieldCodec; import ghidra.framework.plugintool.PluginTool; import ghidra.program.model.address.AddressSetView; -import ghidra.trace.model.Trace; -import ghidra.util.classfinder.ClassSearcher; -import ghidra.util.classfinder.ExtensionPoint; -import ghidra.util.task.TaskMonitor; /** * An interface for specifying how to automatically read target memory. */ -public interface AutoReadMemorySpec extends ExtensionPoint { - class Private { - private final Map specsByName = new TreeMap<>(); - private final ChangeListener classListener = this::classesChanged; - - private Private() { - ClassSearcher.addChangeListener(classListener); - classesChanged(null); - } - - private synchronized void classesChanged(ChangeEvent evt) { - InstanceUtils.collectUniqueInstances(AutoReadMemorySpec.class, specsByName, - AutoReadMemorySpec::getConfigName); - } - } - - Private PRIVATE = new Private(); +public interface AutoReadMemorySpec { + /** + * Codec for saving/restoring the auto-read specification + */ public static class AutoReadMemorySpecConfigFieldCodec implements ConfigFieldCodec { @Override public AutoReadMemorySpec read(SaveState state, String name, AutoReadMemorySpec current) { String specName = state.getString(name, null); - return fromConfigName(specName); + return AutoReadMemorySpecFactory.fromConfigName(specName); } @Override @@ -73,31 +48,43 @@ public interface AutoReadMemorySpec extends ExtensionPoint { } } - static AutoReadMemorySpec fromConfigName(String name) { - synchronized (PRIVATE) { - return PRIVATE.specsByName.get(name); - } - } - - static Map allSpecs() { - synchronized (PRIVATE) { - return new TreeMap<>(PRIVATE.specsByName); - } - } - + /** + * Get the configuration name + * + *

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

+ * This is the text displayed in menus + * + * @return the menu name, or null to omit from menus + */ String getMenuName(); + /** + * Get the icon for this specification + * + * @return the icon + */ Icon getMenuIcon(); - default AutoReadMemorySpec getEffective(DebuggerCoordinates coordinates) { - Trace trace = coordinates.getTrace(); - if (trace != null && ProgramEmulationUtils.isEmulatedProgram(trace)) { - return LoadEmulatorAutoReadMemorySpec.INSTANCE; - } - return this; - } + /** + * Get the "effective" specification. + *

+ * This allows a specification to defer to some other (possibly hidden) specification, depending + * on the coordinates. + * + * @param coordinates the current coordinates + * @return the specification + */ + AutoReadMemorySpec getEffective(DebuggerCoordinates coordinates); /** * Perform the automatic read, if applicable @@ -120,18 +107,4 @@ public interface AutoReadMemorySpec extends ExtensionPoint { */ CompletableFuture readMemory(PluginTool tool, DebuggerCoordinates coordinates, AddressSetView visible); - - /** - * A convenience for performing target memory reads with progress displayed - * - * @param tool the tool for displaying progress - * @param reader the method to perform the read, asynchronously - * @return a future which returns true if the read completes - */ - default CompletableFuture doRead(PluginTool tool, - Function> reader) { - return TargetActionTask - .executeTask(tool, getMenuName(), true, true, false, m -> reader.apply(m)) - .thenApply(__ -> true); - } } diff --git a/Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/action/AutoReadMemorySpecFactory.java b/Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/action/AutoReadMemorySpecFactory.java new file mode 100644 index 0000000000..b71cba7f70 --- /dev/null +++ b/Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/action/AutoReadMemorySpecFactory.java @@ -0,0 +1,80 @@ +/* ### + * 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.action; + +import java.util.*; + +import ghidra.framework.plugintool.PluginTool; +import ghidra.util.classfinder.ClassSearcher; +import ghidra.util.classfinder.ExtensionPoint; + +/** + * A discoverable factory of auto-read memory specifications + */ +public interface AutoReadMemorySpecFactory extends ExtensionPoint { + + /** + * Get the specification for the given configuration name + * + * @param name the name + * @return the spec, or null + */ + static AutoReadMemorySpec fromConfigName(String name) { + for (AutoReadMemorySpecFactory factory : ClassSearcher + .getInstances(AutoReadMemorySpecFactory.class)) { + AutoReadMemorySpec spec = factory.parseSpec(name); + if (spec != null) { + return spec; + } + } + return null; + } + + /** + * Get a copy of all the known and visible specifications + * + * @param tool the plugin tool or context + * @return the specifications by configuration name + */ + static Map allSuggested(PluginTool tool) { + Map all = new TreeMap<>(); + for (AutoReadMemorySpecFactory factory : ClassSearcher + .getInstances(AutoReadMemorySpecFactory.class)) { + for (AutoReadMemorySpec spec : factory.getSuggested(tool)) { + if (spec.getMenuName() != null) { + all.put(spec.getConfigName(), spec); + } + } + } + return all; + } + + /** + * Get all the specifications currently suggested by this factory + * + * @param tool the plugin tool or context + * @return the list of suggested specifications + */ + List getSuggested(PluginTool tool); + + /** + * Attempt to parse the given configuration name as a specification + * + * @param name the configuration name, usually including a prefix unique to each factory + * @return the specification, or null if this factory cannot parse it + */ + AutoReadMemorySpec parseSpec(String name); +} diff --git a/Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/action/LocationTrackingSpecFactory.java b/Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/action/LocationTrackingSpecFactory.java index 84ddb9331c..0fb054d4fb 100644 --- a/Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/action/LocationTrackingSpecFactory.java +++ b/Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/action/LocationTrackingSpecFactory.java @@ -46,6 +46,7 @@ public interface LocationTrackingSpecFactory extends ExtensionPoint { /** * Get a copy of all the known specifications * + * @param tool the plugin tool or context * @return the specifications by configuration name */ static Map allSuggested(PluginTool tool) { diff --git a/Ghidra/Debug/Debugger/data/ExtensionPoint.manifest b/Ghidra/Debug/Debugger/data/ExtensionPoint.manifest index d57c51f6d0..5c3f89f08d 100644 --- a/Ghidra/Debug/Debugger/data/ExtensionPoint.manifest +++ b/Ghidra/Debug/Debugger/data/ExtensionPoint.manifest @@ -1,6 +1,5 @@ AutoMapSpec -AutoReadMemorySpec -DebuggerBot +AutoReadMemorySpecFactory DebuggerMappingOpinion DebuggerModelFactory DebuggerPcodeEmulatorFactory diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/BasicAutoReadMemorySpec.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/BasicAutoReadMemorySpec.java new file mode 100644 index 0000000000..5fec26d692 --- /dev/null +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/BasicAutoReadMemorySpec.java @@ -0,0 +1,242 @@ +/* ### + * IP: GHIDRA + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ghidra.app.plugin.core.debug.gui.action; + +import java.nio.ByteBuffer; +import java.util.Map.Entry; +import java.util.concurrent.CompletableFuture; +import java.util.function.Function; + +import javax.swing.Icon; + +import db.Transaction; +import ghidra.app.plugin.core.debug.gui.DebuggerResources.AutoReadMemoryAction; +import ghidra.app.plugin.core.debug.gui.control.TargetActionTask; +import ghidra.app.plugin.core.debug.service.emulation.ProgramEmulationUtils; +import ghidra.app.plugin.core.debug.utils.AbstractMappedMemoryBytesVisitor; +import ghidra.app.services.DebuggerStaticMappingService; +import ghidra.debug.api.action.AutoReadMemorySpec; +import ghidra.debug.api.target.Target; +import ghidra.debug.api.tracemgr.DebuggerCoordinates; +import ghidra.framework.plugintool.PluginTool; +import ghidra.program.model.address.*; +import ghidra.program.model.mem.MemoryAccessException; +import ghidra.trace.model.*; +import ghidra.trace.model.memory.*; +import ghidra.util.task.TaskMonitor; + +public enum BasicAutoReadMemorySpec implements AutoReadMemorySpec { + /** + * Never automatically read memory + */ + NONE("0_READ_NONE", AutoReadMemoryAction.NAME_NONE, AutoReadMemoryAction.ICON_NONE) { + @Override + public CompletableFuture readMemory(PluginTool tool, + DebuggerCoordinates coordinates, AddressSetView visible) { + return CompletableFuture.completedFuture(false); + } + }, + /** + * Automatically read all visible memory + */ + VISIBLE("1_READ_VISIBLE", AutoReadMemoryAction.NAME_VISIBLE, AutoReadMemoryAction.ICON_VISIBLE) { + @Override + public CompletableFuture readMemory(PluginTool tool, + DebuggerCoordinates coordinates, + AddressSetView visible) { + if (!coordinates.isAliveAndReadsPresent()) { + return CompletableFuture.completedFuture(false); + } + Target target = coordinates.getTarget(); + TraceMemoryManager mm = coordinates.getTrace().getMemoryManager(); + AddressSetView alreadyKnown = mm.getAddressesWithState(coordinates.getSnap(), visible, + s -> s == TraceMemoryState.KNOWN || s == TraceMemoryState.ERROR); + AddressSet toRead = visible.subtract(alreadyKnown); + + if (toRead.isEmpty()) { + return CompletableFuture.completedFuture(false); + } + + return doRead(tool, monitor -> target.readMemoryAsync(toRead, monitor)); + } + }, + /** + * Automatically read all visible memory, unless it is read-only, in which case, only read it if + * it has not already been read. + */ + VIS_RO_ONCE("2_READ_VIS_RO_ONCE", AutoReadMemoryAction.NAME_VIS_RO_ONCE, AutoReadMemoryAction.ICON_VIS_RO_ONCE) { + @Override + public CompletableFuture readMemory(PluginTool tool, + DebuggerCoordinates coordinates, + AddressSetView visible) { + if (!coordinates.isAliveAndReadsPresent()) { + return CompletableFuture.completedFuture(false); + } + Target target = coordinates.getTarget(); + TraceMemoryManager mm = coordinates.getTrace().getMemoryManager(); + long snap = coordinates.getSnap(); + AddressSetView alreadyKnown = mm.getAddressesWithState(snap, visible, + s -> s == TraceMemoryState.KNOWN || s == TraceMemoryState.ERROR); + AddressSet toRead = visible.subtract(alreadyKnown); + + if (toRead.isEmpty()) { + return CompletableFuture.completedFuture(false); + } + + AddressSet everKnown = new AddressSet(); + for (AddressRange range : visible) { + for (Entry ent : mm.getMostRecentStates( + snap, + range)) { + everKnown.add(ent.getKey().getRange()); + } + } + AddressSet readOnly = new AddressSet(); + for (AddressRange range : visible) { + for (TraceMemoryRegion region : mm.getRegionsIntersecting(Lifespan.at(snap), + range)) { + if (region.isWrite(snap)) { + continue; + } + readOnly.add(region.getRange(snap)); + } + } + toRead.delete(everKnown.intersect(readOnly)); + + if (toRead.isEmpty()) { + return CompletableFuture.completedFuture(false); + } + + return doRead(tool, monitor -> target.readMemoryAsync(toRead, monitor)); + } + }, + /** + * Load memory from programs for "pure" emulation traces. + */ + LOAD_EMULATOR(null, null, null) { + protected AddressSetView quantize(int blockBits, AddressSetView set) { + if (blockBits == 1) { + return set; + } + long blockMask = -1L << blockBits; + AddressSet result = new AddressSet(); + // Not terribly efficient, but this is one range most of the time + for (AddressRange range : set) { + AddressSpace space = range.getAddressSpace(); + Address min = space.getAddress(range.getMinAddress().getOffset() & blockMask); + Address max = space.getAddress(range.getMaxAddress().getOffset() | ~blockMask); + result.add(new AddressRangeImpl(min, max)); + } + return result; + } + + @Override + public CompletableFuture readMemory(PluginTool tool, + DebuggerCoordinates coordinates, AddressSetView visible) { + DebuggerStaticMappingService mappingService = + tool.getService(DebuggerStaticMappingService.class); + if (mappingService == null) { + return CompletableFuture.completedFuture(false); + } + Trace trace = coordinates.getTrace(); + if (trace == null || coordinates.isAlive() || + !ProgramEmulationUtils.isEmulatedProgram(trace)) { + // Never interfere with a live target + return CompletableFuture.completedFuture(false); + } + TraceMemoryManager mm = trace.getMemoryManager(); + AddressSet toRead = new AddressSet(quantize(12, visible)); + for (Lifespan span : coordinates.getView().getViewport().getOrderedSpans()) { + AddressSetView alreadyKnown = + mm.getAddressesWithState(span.lmin(), visible, + s -> s == TraceMemoryState.KNOWN); + toRead.delete(alreadyKnown); + if (span.lmax() != span.lmin() || toRead.isEmpty()) { + break; + } + } + + if (toRead.isEmpty()) { + return CompletableFuture.completedFuture(false); + } + + long snap = coordinates.getSnap(); + ByteBuffer buf = ByteBuffer.allocate(4096); + try (Transaction tx = trace.openTransaction("Load Visible")) { + new AbstractMappedMemoryBytesVisitor(mappingService, buf.array()) { + @Override + protected void visitData(Address hostAddr, byte[] data, int size) { + buf.position(0); + buf.limit(size); + mm.putBytes(snap, hostAddr, buf); + } + }.visit(trace, snap, toRead); + return CompletableFuture.completedFuture(true); + } + catch (MemoryAccessException e) { + throw new AssertionError(e); + } + } + }; + + private final String configName; + private final String menuName; + private final Icon menuIcon; + + private BasicAutoReadMemorySpec(String configName, String menuName, Icon menuIcon) { + this.configName = configName; + this.menuName = menuName; + this.menuIcon = menuIcon; + } + + @Override + public String getConfigName() { + return configName; + } + + @Override + public String getMenuName() { + return menuName; + } + + @Override + public Icon getMenuIcon() { + return menuIcon; + } + + @Override + public AutoReadMemorySpec getEffective(DebuggerCoordinates coordinates) { + Trace trace = coordinates.getTrace(); + if (trace != null && ProgramEmulationUtils.isEmulatedProgram(trace)) { + return LOAD_EMULATOR; + } + return this; + } + + /** + * A convenience for performing target memory reads with progress displayed + * + * @param tool the tool for displaying progress + * @param reader the method to perform the read, asynchronously + * @return a future which returns true if the read completes + */ + protected CompletableFuture doRead(PluginTool tool, + Function> reader) { + return TargetActionTask + .executeTask(tool, getMenuName(), true, true, false, m -> reader.apply(m)) + .thenApply(__ -> true); + } +} diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/BasicAutoReadMemorySpecFactory.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/BasicAutoReadMemorySpecFactory.java new file mode 100644 index 0000000000..c104b72857 --- /dev/null +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/BasicAutoReadMemorySpecFactory.java @@ -0,0 +1,44 @@ +/* ### + * IP: GHIDRA + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ghidra.app.plugin.core.debug.gui.action; + +import java.util.List; +import java.util.Map; +import java.util.function.Function; +import java.util.stream.Collectors; + +import ghidra.debug.api.action.AutoReadMemorySpec; +import ghidra.debug.api.action.AutoReadMemorySpecFactory; +import ghidra.framework.plugintool.PluginTool; + +public class BasicAutoReadMemorySpecFactory implements AutoReadMemorySpecFactory { + public static final List ALL = List.of(BasicAutoReadMemorySpec.values()); + public static final Map BY_CONFIG_NAME = ALL.stream() + .filter(s -> s.getConfigName() != null) + .collect(Collectors.toUnmodifiableMap( + AutoReadMemorySpec::getConfigName, + Function.identity())); + + @Override + public List getSuggested(PluginTool tool) { + return ALL; + } + + @Override + public AutoReadMemorySpec parseSpec(String name) { + return BY_CONFIG_NAME.get(name); + } +} diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/DebuggerAutoReadMemoryAction.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/DebuggerAutoReadMemoryAction.java index 61e3a3709c..806b55ae83 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/DebuggerAutoReadMemoryAction.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/DebuggerAutoReadMemoryAction.java @@ -4,9 +4,9 @@ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -17,6 +17,8 @@ package ghidra.app.plugin.core.debug.gui.action; import docking.action.builder.MultiStateActionBuilder; import ghidra.app.plugin.core.debug.gui.DebuggerResources.AutoReadMemoryAction; +import ghidra.debug.api.action.AutoReadMemorySpec; +import ghidra.debug.api.action.AutoReadMemorySpecFactory; import ghidra.framework.plugintool.Plugin; public interface DebuggerAutoReadMemoryAction extends AutoReadMemoryAction { @@ -24,7 +26,8 @@ public interface DebuggerAutoReadMemoryAction extends AutoReadMemoryAction { static MultiStateActionBuilder builder(Plugin owner) { MultiStateActionBuilder builder = AutoReadMemoryAction.builder(owner); builder.toolBarGroup(NAME); - for (AutoReadMemorySpec spec : AutoReadMemorySpec.allSpecs().values()) { + for (AutoReadMemorySpec spec : AutoReadMemorySpecFactory.allSuggested(owner.getTool()) + .values()) { builder.addState(spec.getMenuName(), spec.getMenuIcon(), spec); } return builder; 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 91e60752ee..906c01e2d3 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 @@ -29,9 +29,10 @@ import docking.menu.MultiStateDockingAction; import docking.widgets.EventTrigger; 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.gui.control.TargetActionTask; import ghidra.app.util.viewer.listingpanel.AddressSetDisplayListener; +import ghidra.debug.api.action.AutoReadMemorySpec; +import ghidra.debug.api.action.AutoReadMemorySpec.AutoReadMemorySpecConfigFieldCodec; import ghidra.debug.api.target.Target; import ghidra.debug.api.tracemgr.DebuggerCoordinates; import ghidra.framework.model.DomainObjectChangeRecord; @@ -149,8 +150,7 @@ public abstract class DebuggerReadsMemoryTrait { protected MultiStateDockingAction actionAutoRead; protected RefreshSelectedMemoryAction actionRefreshSelected; - private final AutoReadMemorySpec defaultAutoSpec = - AutoReadMemorySpec.fromConfigName(VisibleROOnceAutoReadMemorySpec.CONFIG_NAME); + private final AutoReadMemorySpec defaultAutoSpec = BasicAutoReadMemorySpec.VIS_RO_ONCE; @AutoConfigStateField(codec = AutoReadMemorySpecConfigFieldCodec.class) protected AutoReadMemorySpec autoSpec = defaultAutoSpec; 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 deleted file mode 100644 index 539fc0c322..0000000000 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/LoadEmulatorAutoReadMemorySpec.java +++ /dev/null @@ -1,116 +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.gui.action; - -import java.nio.ByteBuffer; -import java.util.concurrent.CompletableFuture; - -import javax.swing.Icon; - -import db.Transaction; -import ghidra.app.plugin.core.debug.service.emulation.ProgramEmulationUtils; -import ghidra.app.plugin.core.debug.utils.AbstractMappedMemoryBytesVisitor; -import ghidra.app.services.DebuggerStaticMappingService; -import ghidra.debug.api.tracemgr.DebuggerCoordinates; -import ghidra.framework.plugintool.PluginTool; -import ghidra.program.model.address.*; -import ghidra.program.model.mem.MemoryAccessException; -import ghidra.trace.model.Lifespan; -import ghidra.trace.model.Trace; -import ghidra.trace.model.memory.TraceMemoryManager; -import ghidra.trace.model.memory.TraceMemoryState; - -enum LoadEmulatorAutoReadMemorySpec implements AutoReadMemorySpec { - INSTANCE; - - @Override - public String getConfigName() { - return null; - } - - @Override - public String getMenuName() { - return null; - } - - @Override - public Icon getMenuIcon() { - return null; - } - - protected AddressSetView quantize(int blockBits, AddressSetView set) { - if (blockBits == 1) { - return set; - } - long blockMask = -1L << blockBits; - AddressSet result = new AddressSet(); - // Not terribly efficient, but this is one range most of the time - for (AddressRange range : set) { - AddressSpace space = range.getAddressSpace(); - Address min = space.getAddress(range.getMinAddress().getOffset() & blockMask); - Address max = space.getAddress(range.getMaxAddress().getOffset() | ~blockMask); - result.add(new AddressRangeImpl(min, max)); - } - return result; - } - - @Override - public CompletableFuture readMemory(PluginTool tool, DebuggerCoordinates coordinates, - AddressSetView visible) { - DebuggerStaticMappingService mappingService = - tool.getService(DebuggerStaticMappingService.class); - if (mappingService == null) { - return CompletableFuture.completedFuture(false); - } - Trace trace = coordinates.getTrace(); - if (trace == null || coordinates.isAlive() || - !ProgramEmulationUtils.isEmulatedProgram(trace)) { - // Never interfere with a live target - return CompletableFuture.completedFuture(false); - } - TraceMemoryManager mm = trace.getMemoryManager(); - AddressSet toRead = new AddressSet(quantize(12, visible)); - for (Lifespan span : coordinates.getView().getViewport().getOrderedSpans()) { - AddressSetView alreadyKnown = - mm.getAddressesWithState(span.lmin(), visible, s -> s == TraceMemoryState.KNOWN); - toRead.delete(alreadyKnown); - if (span.lmax() != span.lmin() || toRead.isEmpty()) { - break; - } - } - - if (toRead.isEmpty()) { - return CompletableFuture.completedFuture(false); - } - - long snap = coordinates.getSnap(); - ByteBuffer buf = ByteBuffer.allocate(4096); - try (Transaction tx = trace.openTransaction("Load Visible")) { - new AbstractMappedMemoryBytesVisitor(mappingService, buf.array()) { - @Override - protected void visitData(Address hostAddr, byte[] data, int size) { - buf.position(0); - buf.limit(size); - mm.putBytes(snap, hostAddr, buf); - } - }.visit(trace, snap, toRead); - return CompletableFuture.completedFuture(true); - } - catch (MemoryAccessException e) { - throw new AssertionError(e); - } - } -} 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 deleted file mode 100644 index b03e11ebfb..0000000000 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/NoneAutoReadMemorySpec.java +++ /dev/null @@ -1,60 +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.gui.action; - -import java.util.concurrent.CompletableFuture; - -import javax.swing.Icon; - -import ghidra.app.plugin.core.debug.gui.DebuggerResources.AutoReadMemoryAction; -import ghidra.debug.api.tracemgr.DebuggerCoordinates; -import ghidra.framework.plugintool.PluginTool; -import ghidra.program.model.address.AddressSetView; - -public class NoneAutoReadMemorySpec implements AutoReadMemorySpec { - public static final String CONFIG_NAME = "0_READ_NONE"; - - @Override - public boolean equals(Object obj) { - return this.getClass() == obj.getClass(); - } - - @Override - public String getConfigName() { - return CONFIG_NAME; - } - - @Override - public String getMenuName() { - return AutoReadMemoryAction.NAME_NONE; - } - - @Override - public Icon getMenuIcon() { - return AutoReadMemoryAction.ICON_NONE; - } - - @Override - public AutoReadMemorySpec getEffective(DebuggerCoordinates coordinates) { - return this; - } - - @Override - public CompletableFuture readMemory(PluginTool tool, DebuggerCoordinates coordinates, - AddressSetView visible) { - return CompletableFuture.completedFuture(false); - } -} 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 deleted file mode 100644 index 55cfd0072b..0000000000 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/VisibleAutoReadMemorySpec.java +++ /dev/null @@ -1,72 +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.gui.action; - -import java.util.concurrent.CompletableFuture; - -import javax.swing.Icon; - -import ghidra.app.plugin.core.debug.gui.DebuggerResources.AutoReadMemoryAction; -import ghidra.debug.api.target.Target; -import ghidra.debug.api.tracemgr.DebuggerCoordinates; -import ghidra.framework.plugintool.PluginTool; -import ghidra.program.model.address.AddressSet; -import ghidra.program.model.address.AddressSetView; -import ghidra.trace.model.memory.TraceMemoryManager; -import ghidra.trace.model.memory.TraceMemoryState; - -public class VisibleAutoReadMemorySpec implements AutoReadMemorySpec { - public static final String CONFIG_NAME = "1_READ_VISIBLE"; - - @Override - public boolean equals(Object obj) { - return this.getClass() == obj.getClass(); - } - - @Override - public String getConfigName() { - return CONFIG_NAME; - } - - @Override - public String getMenuName() { - return AutoReadMemoryAction.NAME_VISIBLE; - } - - @Override - public Icon getMenuIcon() { - return AutoReadMemoryAction.ICON_VISIBLE; - } - - @Override - public CompletableFuture readMemory(PluginTool tool, DebuggerCoordinates coordinates, - AddressSetView visible) { - if (!coordinates.isAliveAndReadsPresent()) { - return CompletableFuture.completedFuture(false); - } - Target target = coordinates.getTarget(); - TraceMemoryManager mm = coordinates.getTrace().getMemoryManager(); - AddressSetView alreadyKnown = mm.getAddressesWithState(coordinates.getSnap(), visible, - s -> s == TraceMemoryState.KNOWN || s == TraceMemoryState.ERROR); - AddressSet toRead = visible.subtract(alreadyKnown); - - if (toRead.isEmpty()) { - return CompletableFuture.completedFuture(false); - } - - return doRead(tool, monitor -> target.readMemoryAsync(toRead, monitor)); - } -} 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 deleted file mode 100644 index e4b961d811..0000000000 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/VisibleROOnceAutoReadMemorySpec.java +++ /dev/null @@ -1,96 +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.gui.action; - -import java.util.Map.Entry; -import java.util.concurrent.CompletableFuture; - -import javax.swing.Icon; - -import ghidra.app.plugin.core.debug.gui.DebuggerResources.AutoReadMemoryAction; -import ghidra.debug.api.target.Target; -import ghidra.debug.api.tracemgr.DebuggerCoordinates; -import ghidra.framework.plugintool.PluginTool; -import ghidra.program.model.address.*; -import ghidra.trace.model.Lifespan; -import ghidra.trace.model.TraceAddressSnapRange; -import ghidra.trace.model.memory.*; - -public class VisibleROOnceAutoReadMemorySpec implements AutoReadMemorySpec { - public static final String CONFIG_NAME = "1_READ_VIS_RO_ONCE"; - - @Override - public boolean equals(Object obj) { - return this.getClass() == obj.getClass(); - } - - @Override - public String getConfigName() { - return CONFIG_NAME; - } - - @Override - public String getMenuName() { - return AutoReadMemoryAction.NAME_VIS_RO_ONCE; - } - - @Override - public Icon getMenuIcon() { - return AutoReadMemoryAction.ICON_VIS_RO_ONCE; - } - - @Override - public CompletableFuture readMemory(PluginTool tool, DebuggerCoordinates coordinates, - AddressSetView visible) { - if (!coordinates.isAliveAndReadsPresent()) { - return CompletableFuture.completedFuture(false); - } - Target target = coordinates.getTarget(); - TraceMemoryManager mm = coordinates.getTrace().getMemoryManager(); - long snap = coordinates.getSnap(); - AddressSetView alreadyKnown = mm.getAddressesWithState(snap, visible, - s -> s == TraceMemoryState.KNOWN || s == TraceMemoryState.ERROR); - AddressSet toRead = visible.subtract(alreadyKnown); - - if (toRead.isEmpty()) { - return CompletableFuture.completedFuture(false); - } - - AddressSet everKnown = new AddressSet(); - for (AddressRange range : visible) { - for (Entry ent : mm.getMostRecentStates(snap, - range)) { - everKnown.add(ent.getKey().getRange()); - } - } - AddressSet readOnly = new AddressSet(); - for (AddressRange range : visible) { - for (TraceMemoryRegion region : mm.getRegionsIntersecting(Lifespan.at(snap), range)) { - if (region.isWrite(snap)) { - continue; - } - readOnly.add(region.getRange(snap)); - } - } - toRead.delete(everKnown.intersect(readOnly)); - - if (toRead.isEmpty()) { - return CompletableFuture.completedFuture(false); - } - - return doRead(tool, monitor -> target.readMemoryAsync(toRead, monitor)); - } -} 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 2a04eb4260..105c9d9ad6 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 @@ -15,7 +15,7 @@ */ package ghidra.app.plugin.core.debug.gui.listing; -import static ghidra.app.plugin.core.debug.gui.DebuggerResources.*; +import static ghidra.app.plugin.core.debug.gui.DebuggerResources.GROUP_TRANSIENT_VIEWS; import java.util.List; import java.util.function.Consumer; @@ -32,11 +32,11 @@ import ghidra.app.plugin.core.codebrowser.CodeViewerProvider; import ghidra.app.plugin.core.debug.DebuggerPluginPackage; import ghidra.app.plugin.core.debug.event.*; import ghidra.app.plugin.core.debug.gui.DebuggerResources.AbstractNewListingAction; -import ghidra.app.plugin.core.debug.gui.action.DebuggerProgramLocationActionContext; -import ghidra.app.plugin.core.debug.gui.action.NoneLocationTrackingSpec; +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.AutoReadMemorySpec; import ghidra.debug.api.action.LocationTrackingSpec; import ghidra.debug.api.listing.MultiBlendedListingBackgroundColorModel; import ghidra.debug.api.tracemgr.DebuggerCoordinates; @@ -81,8 +81,7 @@ import ghidra.trace.model.program.TraceProgramView; }, servicesProvided = { DebuggerListingService.class, - } -) + }) public class DebuggerListingPlugin extends AbstractCodeBrowserPlugin implements DebuggerListingService { private static final String KEY_CONNECTED_PROVIDER = "connectedProvider"; @@ -332,6 +331,11 @@ public class DebuggerListingPlugin extends AbstractCodeBrowserPlugin modules = trace.getModuleManager().getModulesAt(snap, address); - Msg.debug(Mode.class, "Disassembling in modules: " + + Msg.debug(Mode.class, "Computing mode from modules: " + modules.stream().map(m -> m.getName(snap)).collect(Collectors.joining(","))); Set modes = modules.stream() - .map(m -> modeForModule(target, trace, snap, m)) + .map(m -> modeForModule(tool, readSpec, coords, m)) .filter(m -> m != UNK) .collect(Collectors.toSet()); - Msg.debug(Mode.class, "Disassembling in mode(s): " + modes); + Msg.debug(Mode.class, " Got mode(s): " + modes); if (modes.size() != 1) { return UNK; } return modes.iterator().next(); } - static Mode modeForModule(Target target, Trace trace, long snap, TraceModule module) { - if (target != null && target.getSnap() == snap) { - AddressSet set = new AddressSet(); - set.add(module.getBase(snap), module.getBase(snap)); // Recorder should read page - try { - target.readMemoryAsync(set, TaskMonitor.DUMMY).get(1, TimeUnit.SECONDS); - trace.flushEvents(); + static Mode modeForModule(PluginTool tool, AutoReadMemorySpec readSpec, + DebuggerCoordinates coords, TraceModule module) { + AddressSet set = new AddressSet(); + Trace trace = coords.getTrace(); + long snap = coords.getSnap(); + Address base = module.getBase(snap); + set.add(base, base); // Recorder should read page + try { + readSpec.readMemory(tool, coords, set).get(1, TimeUnit.SECONDS); + trace.flushEvents(); + } + catch (InterruptedException | ExecutionException | TimeoutException e) { + DebuggerConsoleService console = tool.getService(DebuggerConsoleService.class); + String message = "Could not read PE header of %s to determine x86 vs x64 mode" + .formatted(module.getName(snap)); + if (console != null) { + console.log(DebuggerResources.ICON_LOG_ERROR, message, e); } - catch (InterruptedException | ExecutionException | TimeoutException e) { - throw new AssertionError(e); + else { + Msg.error(Mode.class, message, e); } + // Let it fall through in case stale memory is still accurate } MemBuffer bufferAt = trace.getMemoryManager().getBufferAt(snap, module.getBase(snap)); try (ByteProvider bp = new MemBufferByteProvider(bufferAt)) { @@ -111,7 +132,7 @@ public class DbgengDebuggerPlatformOpinion extends AbstractDebuggerPlatformOpini CompilerSpec cSpec) { super(tool, trace, cSpec); } - // TODO: Map registers: efl,rfl,rflags->eflags + // LATER: Map registers: efl,rfl,rflags->eflags @Override protected TracePlatform getDisassemblyPlatform(TraceObject object, Address start, @@ -165,7 +186,7 @@ public class DbgengDebuggerPlatformOpinion extends AbstractDebuggerPlatformOpini } enum Offer implements DebuggerPlatformOffer { - // TODO: X86? + // LATER: X86, as in a 32-bit host? Not likely. X64 { @Override public String getDescription() { diff --git a/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/AbstractGhidraHeadedDebuggerTest.java b/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/AbstractGhidraHeadedDebuggerTest.java index b9ba722336..1877db7003 100644 --- a/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/AbstractGhidraHeadedDebuggerTest.java +++ b/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/AbstractGhidraHeadedDebuggerTest.java @@ -45,7 +45,7 @@ import docking.widgets.tree.GTree; import docking.widgets.tree.GTreeNode; import ghidra.GhidraTestApplicationLayout; import ghidra.app.nav.Navigatable; -import ghidra.app.plugin.core.debug.gui.action.*; +import ghidra.app.plugin.core.debug.gui.action.BasicAutoReadMemorySpec; 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.service.target.DebuggerTargetServicePlugin; @@ -53,8 +53,7 @@ import ghidra.app.plugin.core.debug.service.tracemgr.DebuggerTraceManagerService import ghidra.app.services.*; import ghidra.app.util.viewer.listingpanel.ListingPanel; import ghidra.async.AsyncTestUtils; -import ghidra.debug.api.action.LocationTrackingSpec; -import ghidra.debug.api.action.LocationTrackingSpecFactory; +import ghidra.debug.api.action.*; import ghidra.docking.settings.SettingsImpl; import ghidra.framework.model.*; import ghidra.framework.plugintool.PluginTool; @@ -600,15 +599,15 @@ public abstract class AbstractGhidraHeadedDebuggerTest } protected static AutoReadMemorySpec getAutoReadMemorySpec(String name) { - return AutoReadMemorySpec.fromConfigName(name); + return AutoReadMemorySpecFactory.fromConfigName(name); } protected final AutoReadMemorySpec readNone = - getAutoReadMemorySpec(NoneAutoReadMemorySpec.CONFIG_NAME); + getAutoReadMemorySpec(BasicAutoReadMemorySpec.NONE.getConfigName()); protected final AutoReadMemorySpec readVisible = - getAutoReadMemorySpec(VisibleAutoReadMemorySpec.CONFIG_NAME); + getAutoReadMemorySpec(BasicAutoReadMemorySpec.VISIBLE.getConfigName()); protected final AutoReadMemorySpec readVisROOnce = - getAutoReadMemorySpec(VisibleROOnceAutoReadMemorySpec.CONFIG_NAME); + getAutoReadMemorySpec(BasicAutoReadMemorySpec.VIS_RO_ONCE.getConfigName()); protected TestEnv env; protected PluginTool tool; diff --git a/Ghidra/Test/DebuggerIntegrationTest/src/test/java/ghidra/app/plugin/core/debug/gui/copying/DebuggerCopyActionsPluginTest.java b/Ghidra/Test/DebuggerIntegrationTest/src/test/java/ghidra/app/plugin/core/debug/gui/copying/DebuggerCopyActionsPluginTest.java index 14cbba96bf..75f2ac9e8c 100644 --- a/Ghidra/Test/DebuggerIntegrationTest/src/test/java/ghidra/app/plugin/core/debug/gui/copying/DebuggerCopyActionsPluginTest.java +++ b/Ghidra/Test/DebuggerIntegrationTest/src/test/java/ghidra/app/plugin/core/debug/gui/copying/DebuggerCopyActionsPluginTest.java @@ -28,8 +28,7 @@ import docking.action.DockingActionIf; import generic.Unique; import generic.test.category.NightlyCategory; import ghidra.app.plugin.core.debug.gui.AbstractGhidraHeadedDebuggerIntegrationTest; -import ghidra.app.plugin.core.debug.gui.action.AutoReadMemorySpec; -import ghidra.app.plugin.core.debug.gui.action.NoneAutoReadMemorySpec; +import ghidra.app.plugin.core.debug.gui.action.BasicAutoReadMemorySpec; import ghidra.app.plugin.core.debug.gui.copying.DebuggerCopyIntoProgramDialog.RangeEntry; import ghidra.app.plugin.core.debug.gui.listing.DebuggerListingPlugin; import ghidra.app.plugin.core.debug.gui.listing.DebuggerListingProvider; @@ -442,8 +441,7 @@ public class DebuggerCopyActionsPluginTest extends AbstractGhidraHeadedDebuggerI TraceObject process = tb.obj("Processes[1]"); rmiCx.publishTarget(tool, tb.trace); - listingProvider.setAutoReadMemorySpec( - AutoReadMemorySpec.fromConfigName(NoneAutoReadMemorySpec.CONFIG_NAME)); + listingProvider.setAutoReadMemorySpec(BasicAutoReadMemorySpec.NONE); traceManager.activateTrace(tb.trace); assertDisabled(copyActionsPlugin.actionCopyIntoNewProgram); diff --git a/Ghidra/Test/DebuggerIntegrationTest/src/test/java/ghidra/app/plugin/core/debug/gui/listing/DebuggerListingProviderTest.java b/Ghidra/Test/DebuggerIntegrationTest/src/test/java/ghidra/app/plugin/core/debug/gui/listing/DebuggerListingProviderTest.java index f8180980be..e8cba9443e 100644 --- a/Ghidra/Test/DebuggerIntegrationTest/src/test/java/ghidra/app/plugin/core/debug/gui/listing/DebuggerListingProviderTest.java +++ b/Ghidra/Test/DebuggerIntegrationTest/src/test/java/ghidra/app/plugin/core/debug/gui/listing/DebuggerListingProviderTest.java @@ -50,6 +50,7 @@ import ghidra.app.services.DebuggerControlService; import ghidra.app.services.DebuggerStaticMappingService; import ghidra.app.util.viewer.listingpanel.ListingPanel; import ghidra.async.SwingExecutorService; +import ghidra.debug.api.action.AutoReadMemorySpec; import ghidra.debug.api.control.ControlMode; import ghidra.debug.api.tracemgr.DebuggerCoordinates; import ghidra.program.model.address.*;