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);