diff --git a/Ghidra/Features/Base/src/main/help/help/topics/ReferencesPlugin/References_from.htm b/Ghidra/Features/Base/src/main/help/help/topics/ReferencesPlugin/References_from.htm
index 2d722752dd..654d973b05 100644
--- a/Ghidra/Features/Base/src/main/help/help/topics/ReferencesPlugin/References_from.htm
+++ b/Ghidra/Features/Base/src/main/help/help/topics/ReferencesPlugin/References_from.htm
@@ -1166,10 +1166,13 @@ c
[
Offset] The To Address entry is required for normal memory references
- and specifies the reference destination as a memory offset. This entry is always
+ and specifies the reference destination as a memory offset within a selected address
+ space. The address offset entry is always
interpretted as a unsigned hex value (i.e., the "0x" entry prefix is assumed).
For those processors with multiple address-spaces, a pull-down is also provided
- allowing the address-space to be selected.
+ allowing the address-space to be selected. Address spaces which overlay the
+ OTHER non-loaded space are only included if the Include OTHER overlay spaces
+ checkbox is selected.
@@ -1178,10 +1181,19 @@ c
[
Offset] The Base Address entry is required for offset memory references
- and specifies the offset base location as a memory offset. This entry is always
- interpretted as a unsigned hex value (i.e., the 0x entry prefix is assumed).
- For those processors with multiple address-spaces, a pull-down is also provided
- allowing the address-space to be selected.
+ and specifies the offset base location. See To Address entry above for
+ entry details.
+
+
+
+ Include OTHER overlay spaces
+
+
+ The Include OTHER overlay spaces checkbox when selected allows address spaces
+ which overlay the OTHER non-loaded space to be included in the To Address
+ or Base Address address space selection pulldown list. This may be appropriate
+ when working with special purpose overlay spaces which can facilitate flow overrides
+ (e.g., syscall).
diff --git a/Ghidra/Features/Base/src/main/help/help/topics/ReferencesPlugin/images/MemRefPanel.png b/Ghidra/Features/Base/src/main/help/help/topics/ReferencesPlugin/images/MemRefPanel.png
index 9b768d87d3..d2749741fa 100644
Binary files a/Ghidra/Features/Base/src/main/help/help/topics/ReferencesPlugin/images/MemRefPanel.png and b/Ghidra/Features/Base/src/main/help/help/topics/ReferencesPlugin/images/MemRefPanel.png differ
diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/references/EditMemoryReferencePanel.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/references/EditMemoryReferencePanel.java
index 47d0f284e3..9e9ea44b6e 100644
--- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/references/EditMemoryReferencePanel.java
+++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/references/EditMemoryReferencePanel.java
@@ -38,6 +38,7 @@ import docking.widgets.label.GLabel;
import generic.theme.GColor;
import generic.theme.GThemeDefaults.Colors;
import ghidra.app.util.AddressInput;
+import ghidra.framework.preferences.Preferences;
import ghidra.program.model.address.*;
import ghidra.program.model.listing.*;
import ghidra.program.model.scalar.Scalar;
@@ -56,6 +57,8 @@ class EditMemoryReferencePanel extends EditReferencePanel {
private static final int MAX_HISTORY_LENGTH = 10;
+ private static final String INCLUDE_OTHER_OVERLAY_PREFERENCE = "RefEditIncludeOtherOverlays";
+
private WeakHashMap> addrHistoryMap = new WeakHashMap<>();
private ReferencesPlugin plugin;
@@ -68,6 +71,7 @@ class EditMemoryReferencePanel extends EditReferencePanel {
private Reference editRef;
private JLabel addrLabel;
private AddressInput toAddressField;
+ private JCheckBox includeOtherOverlaysCheckbox;
private JButton addrHistoryButton;
private JCheckBox offsetCheckbox;
private JTextField offsetField;
@@ -113,18 +117,16 @@ class EditMemoryReferencePanel extends EditReferencePanel {
toggleAddressHistoryPopup();
}
}
-
- @Override
- public void mouseReleased(MouseEvent e) {
- // TODO Auto-generated method stub
- super.mouseReleased(e);
- }
});
addrHistoryButton.setText(null);
addrHistoryButton.setMargin(new Insets(0, 0, 0, 0));
addrHistoryButton.setFocusable(false);
addrHistoryButton.setToolTipText("Address History");
+ includeOtherOverlaysCheckbox = new JCheckBox("Include OTHER overlay spaces",
+ Boolean.getBoolean(Preferences.getProperty(INCLUDE_OTHER_OVERLAY_PREFERENCE, "false")));
+ includeOtherOverlaysCheckbox.addChangeListener(e -> refreshToAddressField());
+
refTypes = new GhidraComboBox<>(MEM_REF_TYPES);
JPanel addrPanel = new JPanel(new BorderLayout());
@@ -137,6 +139,9 @@ class EditMemoryReferencePanel extends EditReferencePanel {
add(addrLabel);
add(addrPanel);
+ add(new JLabel());
+ add(includeOtherOverlaysCheckbox);
+
add(new GLabel("Ref-Type:", SwingConstants.RIGHT));
add(refTypes);
@@ -182,8 +187,39 @@ class EditMemoryReferencePanel extends EditReferencePanel {
}
}
+ private void refreshToAddressField() {
+ initializeToAddressField(toAddressField.getAddress());
+ }
+
+ private void initializeToAddressField(Address toAddr) {
+ toAddressField.setAddressFactory(fromCodeUnit.getProgram().getAddressFactory(), (s) -> {
+ if (s.isLoadedMemorySpace()) {
+ return true;
+ }
+ if (s.equals(fromCodeUnit.getAddress().getAddressSpace())) {
+ return true;
+ }
+ if (toAddr != null && s.equals(toAddr.getAddressSpace())) {
+ return true;
+ }
+ if (includeOtherOverlaysCheckbox.isSelected() && s.isOverlaySpace()) {
+ return true;
+ }
+ return false;
+ });
+ if (toAddr != null) {
+ toAddressField.setAddress(toAddr);
+ toAddressField.select();
+ }
+ else {
+ toAddressField.clear();
+ }
+ toAddressField.invalidate();
+ }
+
@Override
void initialize(CodeUnit fromCu, Reference editReference) {
+
isValidState = false;
this.fromCodeUnit = fromCu;
this.editRef = editReference;
@@ -199,8 +235,8 @@ class EditMemoryReferencePanel extends EditReferencePanel {
toAddr = toAddr.subtractWrap(defaultOffset);
}
- toAddressField.setAddressFactory(fromCu.getProgram().getAddressFactory());
- toAddressField.setAddress(toAddr);
+ initializeToAddressField(toAddr);
+
enableOffsetField(editReference.isOffsetReference());
RefType rt = editReference.getReferenceType();
@@ -215,6 +251,7 @@ class EditMemoryReferencePanel extends EditReferencePanel {
@Override
boolean initialize(CodeUnit fromCu, int fromOpIndex, int fromSubIndex) {
+
isValidState = false;
this.editRef = null;
this.fromCodeUnit = fromCu;
@@ -224,8 +261,6 @@ class EditMemoryReferencePanel extends EditReferencePanel {
addrHistoryButton.setEnabled(getAddressHistorySize(p) != 0);
- toAddressField.setAddressFactory(p.getAddressFactory());
-
Address cuAddr = fromCu.getMinAddress();
RefType rt = RefTypeFactory.getDefaultMemoryRefType(fromCu, fromOpIndex, null, false);
@@ -238,15 +273,12 @@ class EditMemoryReferencePanel extends EditReferencePanel {
Address toAddr = null;
if (p == program && location != null) {
toAddr = getSuggestedLocationAddress(program, location);
- }
- if (toAddr == null || toAddr.equals(cuAddr)) {
- toAddressField.clear();
- }
- else {
- toAddressField.setAddress(toAddr);
+ if (toAddr != null && toAddr.equals(cuAddr)) {
+ toAddr = null;
+ }
}
enableOffsetField(false);
- toAddressField.select();
+ initializeToAddressField(toAddr);
return setOpIndex(fromOpIndex);
}
@@ -310,14 +342,12 @@ class EditMemoryReferencePanel extends EditReferencePanel {
}
}
- if (toAddr != null && !toAddr.equals(cuAddr)) {
- toAddressField.setAddress(toAddr);
- toAddressField.select();
- }
- else {
- toAddressField.clear();
+ if (toAddr != null && toAddr.equals(cuAddr)) {
+ toAddr = null;
}
+ initializeToAddressField(toAddr);
+
if (toAddr != null) {
rt = RefTypeFactory.getDefaultMemoryRefType(fromCu, fromOpIndex, toAddr, false);
populateRefTypes(rt);
diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/references/EditReferenceDialog.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/references/EditReferenceDialog.java
index a993eeecf0..11fd2e5640 100644
--- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/references/EditReferenceDialog.java
+++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/references/EditReferenceDialog.java
@@ -69,6 +69,7 @@ public class EditReferenceDialog extends ReusableDialogComponentProvider {
addCancelButton();
setDefaultButton(applyButton);
+ setUseSharedLocation(true);
}
@Override
diff --git a/Ghidra/Features/Base/src/main/java/help/screenshot/AbstractScreenShotGenerator.java b/Ghidra/Features/Base/src/main/java/help/screenshot/AbstractScreenShotGenerator.java
index 5db7727009..64283b30c5 100644
--- a/Ghidra/Features/Base/src/main/java/help/screenshot/AbstractScreenShotGenerator.java
+++ b/Ghidra/Features/Base/src/main/java/help/screenshot/AbstractScreenShotGenerator.java
@@ -71,16 +71,18 @@ import ghidra.framework.plugintool.Plugin;
import ghidra.framework.plugintool.PluginTool;
import ghidra.framework.plugintool.util.PluginException;
import ghidra.program.database.data.ProgramDataTypeManager;
-import ghidra.program.model.address.Address;
-import ghidra.program.model.address.AddressSet;
+import ghidra.program.model.address.*;
import ghidra.program.model.data.BuiltInDataTypeManager;
import ghidra.program.model.data.DataTypeManager;
import ghidra.program.model.listing.Program;
+import ghidra.program.model.mem.Memory;
import ghidra.program.util.ProgramSelection;
import ghidra.test.AbstractGhidraHeadedIntegrationTest;
import ghidra.test.TestEnv;
import ghidra.util.ColorUtils;
import ghidra.util.exception.AssertException;
+import ghidra.util.exception.UsrException;
+import ghidra.util.task.TaskMonitor;
import resources.ResourceManager;
public abstract class AbstractScreenShotGenerator extends AbstractGhidraHeadedIntegrationTest {
@@ -161,6 +163,19 @@ public abstract class AbstractScreenShotGenerator extends AbstractGhidraHeadedIn
public Program loadProgram(final String programName) {
runSwing(() -> {
program = env.getProgram(programName);
+
+ try {
+ program.withTransaction("Add OTHER Overlay Space", () -> {
+ Memory memory = program.getMemory();
+ memory.createInitializedBlock("OtherOv1",
+ AddressSpace.OTHER_SPACE.getAddress(0), 100, (byte) 0, TaskMonitor.DUMMY,
+ true);
+ });
+ }
+ catch (UsrException e) {
+ failWithException("Unexpected", e);
+ }
+
ProgramManager pm = tool.getService(ProgramManager.class);
pm.openProgram(program.getDomainFile());
});
@@ -1637,7 +1652,7 @@ public abstract class AbstractScreenShotGenerator extends AbstractGhidraHeadedIn
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
- g2.setColor(Colors.BORDER);
+ g2.setColor(Color.BLACK);
g2.setStroke(new BasicStroke(3f));
g2.draw(topPath);
g2.draw(bottomPath);
diff --git a/Ghidra/Test/IntegrationTest/src/screen/java/help/screenshot/ReferencesPluginScreenShots.java b/Ghidra/Test/IntegrationTest/src/screen/java/help/screenshot/ReferencesPluginScreenShots.java
index f30b4634a9..9ac8628190 100644
--- a/Ghidra/Test/IntegrationTest/src/screen/java/help/screenshot/ReferencesPluginScreenShots.java
+++ b/Ghidra/Test/IntegrationTest/src/screen/java/help/screenshot/ReferencesPluginScreenShots.java
@@ -230,15 +230,24 @@ public class ReferencesPluginScreenShots extends GhidraScreenShotGenerator {
CodeUnit cu = program.getListing().getCodeUnitAt(addr(0x401008));
ReferencesPlugin plugin = getPlugin(tool, ReferencesPlugin.class);
final EditReferenceDialog dialog = new EditReferenceDialog(plugin);
- dialog.initDialog(cu, 0, 0, null);
+
runSwing(() -> {
- JRadioButton choiceButton = (JRadioButton) getInstanceField("memRefChoice", dialog);
- invokeInstanceMethod("refChoiceActivated", dialog,
- new Class>[] { JRadioButton.class }, new Object[] { choiceButton });
+ dialog.initDialog(cu, 0, 0, null);
}, true);
- showDialogWithoutBlocking(tool, dialog);
+
+ JRadioButton choiceButton = (JRadioButton) getInstanceField("memRefChoice", dialog);
+ pressButton(choiceButton);
final JPanel panel = (JPanel) getInstanceField("memRefPanel", dialog);
+
+ runSwing(() -> {
+ JCheckBox ovCheckbox =
+ (JCheckBox) getInstanceField("includeOtherOverlaysCheckbox", panel);
+ ovCheckbox.setSelected(true);
+ });
+
+ showDialogWithoutBlocking(tool, dialog);
+
JButton button = (JButton) getInstanceField("addrHistoryButton", panel);
Rectangle buttonBounds = button.getBounds();
buttonBounds = SwingUtilities.convertRectangle(button.getParent(), buttonBounds, panel);
@@ -246,7 +255,8 @@ public class ReferencesPluginScreenShots extends GhidraScreenShotGenerator {
buttonBounds.y += buttonBounds.height / 2 + 20; // half button height + padding added by takeSnippet()
System.out.println("Button bounds = " + buttonBounds);
Rectangle bounds = panel.getBounds();
- bounds.height = 3 * bounds.height / 5; // get rid of empty space
+ bounds.y -= 10;
+ bounds.height = 4 * bounds.height / 5; // get rid of empty space
bounds = SwingUtilities.convertRectangle(panel.getParent(), bounds, null);
captureDialog();
takeSnippet(bounds);
@@ -257,7 +267,8 @@ public class ReferencesPluginScreenShots extends GhidraScreenShotGenerator {
checkbox.setSelected(true);
});
bounds = panel.getBounds();
- bounds.height = 3 * bounds.height / 5;
+ bounds.y -= 10;
+ bounds.height = 4 * bounds.height / 5;
bounds = SwingUtilities.convertRectangle(panel.getParent(), bounds, null);
captureDialog();
takeSnippet(bounds);