GP-3898: Add disabled go-to's for addresses out of the map.

This commit is contained in:
Dan 2024-08-22 08:22:55 -04:00
parent d33af2b972
commit 6504662422
6 changed files with 63 additions and 28 deletions

View File

@ -160,6 +160,11 @@
<IMG alt="" src="images/DebuggerGoToDialog.png">
</DIV>
<P>Note that a Go-To action can fail for many reasons, e.g., syntax errors, computation
failures. One possible reason is that the address is not part of a memory region known to the
debugger. This failure can be overcome by enabling <A href=
"help/topics/DebuggerRegionsPlugin/DebuggerRegionsPlugin.html">Force Full View</A>.</P>
<P>Some examples:</P>
<UL>

View File

@ -71,6 +71,15 @@
<P>The register window provides the following actions:</P>
<H3><A name="go_to"></A>Go To [address]</H3>
<P>Right-clicking a registers' value will display a <B>Go-To</B> action for each address space
in which the value is a valid offset. Selecting one will navigate the <A href=
"help/topics/DebuggerListingPlugin/DebuggerListingPlugin.html">Dynamic Listing</A> to the given
address. The action will be disabled if the address is not in the trace's address map, i.e., it
is not contained in a region of memory known to the debugger. To prevent this behavior, enable
<A href="help/topics/DebuggerRegionsPlugin/DebuggerRegionsPlugin.html">Force Full View</A>.</P>
<H3><A name="select_registers"></A><A name="add"></A><A name="remove"></A><IMG alt="" src=
"icon.debugger.select.registers"> Select Registers</H3>

View File

@ -4,9 +4,9 @@
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*
* http://www.apache.org/licenses/LICENSE-2.0
*
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@ -29,7 +29,6 @@ import ghidra.app.plugin.core.debug.gui.DebuggerResources;
import ghidra.app.plugin.core.debug.gui.action.DebuggerGoToTrait.GoToResult;
import ghidra.app.plugin.core.debug.gui.breakpoint.AbstractDebuggerSleighInputDialog;
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;
@ -82,10 +81,9 @@ public class DebuggerGoToDialog extends AbstractDebuggerSleighInputDialog {
});
}
protected void populateSpaces(SleighLanguage language) {
protected void populateSpaces(AddressFactory factory) {
String curSpace = (String) comboSpaces.getSelectedItem();
modelSpaces.removeAllElements();
AddressFactory factory = language.getAddressFactory();
List<String> names = Stream.of(factory.getAddressSpaces())
.filter(AddressSpace::isMemorySpace)
.map(AddressSpace::getName)
@ -128,7 +126,11 @@ public class DebuggerGoToDialog extends AbstractDebuggerSleighInputDialog {
}
future.thenAccept(result -> {
if (!result.success()) {
setStatusText("<html>Address <code>" + result.address() + "</code> not in trace", MessageType.ERROR,
setStatusText("""
<html>Address <code>%s</code> not in address map.
Consider <b>Force Full View</b>.
""".formatted(result.address()),
MessageType.ERROR,
true);
}
else {
@ -147,9 +149,9 @@ public class DebuggerGoToDialog extends AbstractDebuggerSleighInputDialog {
close();
}
public void show(SleighLanguage language, GoToInput defaultInput) {
populateSpaces(language);
if (language.getAddressFactory().getAddressSpace(defaultInput.space()) != null) {
public void show(AddressFactory factory, GoToInput defaultInput) {
populateSpaces(factory);
if (factory.getAddressSpace(defaultInput.space()) != null) {
comboSpaces.setSelectedItem(defaultInput.space());
}
prompt(trait.tool, defaultInput.offset());

View File

@ -4,9 +4,9 @@
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*
* http://www.apache.org/licenses/LICENSE-2.0
*
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@ -37,8 +37,7 @@ public abstract class DebuggerGoToTrait {
/**
* @see DebuggerGoToTrait#goTo(String, String)
*/
public record GoToResult(Address address, Boolean success) {
}
public record GoToResult(Address address, Boolean success) {}
protected DockingAction action;
@ -74,7 +73,7 @@ public abstract class DebuggerGoToTrait {
private void activatedGoTo(ActionContext context) {
DebuggerGoToDialog goToDialog = new DebuggerGoToDialog(this);
TracePlatform platform = current.getPlatform();
goToDialog.show((SleighLanguage) platform.getLanguage(), getDefaultInput());
goToDialog.show(platform.getAddressFactory(), getDefaultInput());
}
/**

View File

@ -43,6 +43,7 @@ import ghidra.app.plugin.core.data.DataSettingsDialog;
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.gui.DebuggerResources.GoToAction;
import ghidra.app.services.*;
import ghidra.app.services.DebuggerControlService.StateEditor;
import ghidra.async.AsyncLazyValue;
@ -621,7 +622,10 @@ public class DebuggerRegistersProvider extends ComponentProviderAdapter
List<DockingActionIf> result = new ArrayList<>();
String pluginName = plugin.getName();
for (AddressSpace space : currentTrace.getBaseAddressFactory().getAddressSpaces()) {
if (space.isRegisterSpace()) {
if (!space.isMemorySpace()) {
continue;
}
if (space.getType() == AddressSpace.TYPE_OTHER) {
continue;
}
Address address;
@ -631,18 +635,29 @@ public class DebuggerRegistersProvider extends ComponentProviderAdapter
catch (AddressOutOfBoundsException e) {
continue;
}
String name = GoToAction.NAME + " " + address.toString(true);
// Use program view, not memory manager, so that "Force Full View" is respected.
if (!currentTrace.getProgramView().getMemory().contains(address)) {
continue;
}
String name = "Goto " + address.toString(true);
result.add(new ActionBuilder(name, pluginName).popupMenuPath(name).onAction(ctx -> {
if (listingService == null) {
return;
}
ProgramLocation loc = new ProgramLocation(current.getView(), address);
listingService.goTo(loc, true);
}).build());
boolean enabled = currentTrace.getProgramView().getMemory().contains(address);
String extraDesc = enabled ? "" : ". Enable via Force Full View.";
result.add(new ActionBuilder(name, pluginName)
.popupMenuPath(name)
.popupMenuGroup("Go To")
.description(
"Navigate the dynamic listing to " + address.toString(true) + extraDesc)
.helpLocation(
new HelpLocation(pluginName, DebuggerResources.GoToAction.HELP_ANCHOR))
.enabledWhen(ctx -> enabled)
.popupWhen(ctx -> true)
.onAction(ctx -> {
if (listingService == null) {
return;
}
ProgramLocation loc = new ProgramLocation(current.getView(), address);
listingService.goTo(loc, true);
})
.build());
}
return result;
}

View File

@ -4,9 +4,9 @@
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*
* http://www.apache.org/licenses/LICENSE-2.0
*
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@ -230,6 +230,11 @@ public class DBTraceGuestPlatform extends DBAnnotatedObject
return languageEntry == null ? manager.baseLanguage : languageEntry.getLanguage();
}
@Override
public AddressFactory getAddressFactory() {
return manager.trace.getBaseAddressFactory();
}
@Override
public CompilerSpec getCompilerSpec() {
return compilerSpec;