Merge remote-tracking branch

'origin/GP-4345_ghidra1_OtherOverlayMemRefs--SQUASHED' (Closes #6245)
This commit is contained in:
Ryan Kurtz 2024-03-25 06:09:37 -04:00
commit b30cf1089f
6 changed files with 108 additions and 39 deletions

View file

@ -1166,10 +1166,13 @@ c<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<BLOCKQUOTE>
<P>[<I><B><IMG src="images/unchecked.png" alt="" valign="middle" align="middle">
Offset</B></I>] The <I>To Address</I> entry is required for normal memory references
and specifies the reference destination as a memory offset. &nbsp;This entry is always
and specifies the reference destination as a memory offset within a selected address
space. &nbsp;The address offset entry is always
interpretted as a unsigned hex value &nbsp;(i.e., the "0x" entry prefix is assumed).
&nbsp;For those processors with multiple address-spaces, a pull-down is also provided
allowing the address-space to be selected.<BR>
allowing the address-space to be selected. Address spaces which overlay the
</I>OTHER</I> non-loaded space are only included if the <B>Include OTHER overlay spaces</B>
checkbox is selected.<BR>
</P>
</BLOCKQUOTE>
@ -1178,10 +1181,19 @@ c<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<BLOCKQUOTE>
<P>[<B><I><IMG src="images/checked.png" alt="" valign="middle" align="middle">
Offset</I></B>] The <I>Base Address</I> entry is required for offset memory references
and specifies the offset base location as a memory offset. &nbsp;This entry is always
interpretted as a unsigned hex value &nbsp;(i.e., the 0x entry prefix is assumed).
&nbsp;For those processors with multiple address-spaces, a pull-down is also provided
allowing the address-space to be selected.<BR>
and specifies the offset base location. &nbsp;See <B>To Address</B> entry above for
entry details.<BR>
</P>
</BLOCKQUOTE>
<H3>Include OTHER overlay spaces</H3>
<BLOCKQUOTE>
<P>The <I>Include OTHER overlay spaces</I> checkbox when selected allows address spaces
which overlay the </I>OTHER</I> non-loaded space to be included in the <I>To Address</I>
or <I>Base Address</I> address space selection pulldown list. This may be appropriate
when working with special purpose overlay spaces which can facilitate flow overrides
(e.g., <I>syscall</I>).<BR>
</P>
</BLOCKQUOTE>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 28 KiB

Before After
Before After

View file

@ -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<Program, List<Address>> 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);

View file

@ -69,6 +69,7 @@ public class EditReferenceDialog extends ReusableDialogComponentProvider {
addCancelButton();
setDefaultButton(applyButton);
setUseSharedLocation(true);
}
@Override

View file

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

View file

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