mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-05 10:49:34 +02:00
Merge remote-tracking branch
'origin/GP-4345_ghidra1_OtherOverlayMemRefs--SQUASHED' (Closes #6245)
This commit is contained in:
commit
b30cf1089f
6 changed files with 108 additions and 39 deletions
|
@ -1166,10 +1166,13 @@ c<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||||
<BLOCKQUOTE>
|
<BLOCKQUOTE>
|
||||||
<P>[<I><B><IMG src="images/unchecked.png" alt="" valign="middle" align="middle">
|
<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
|
Offset</B></I>] The <I>To Address</I> 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).
|
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
|
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>
|
</P>
|
||||||
</BLOCKQUOTE>
|
</BLOCKQUOTE>
|
||||||
|
|
||||||
|
@ -1178,10 +1181,19 @@ c<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||||
<BLOCKQUOTE>
|
<BLOCKQUOTE>
|
||||||
<P>[<B><I><IMG src="images/checked.png" alt="" valign="middle" align="middle">
|
<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
|
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. This entry is always
|
and specifies the offset base location. See <B>To Address</B> entry above for
|
||||||
interpretted as a unsigned hex value (i.e., the 0x entry prefix is assumed).
|
entry details.<BR>
|
||||||
For those processors with multiple address-spaces, a pull-down is also provided
|
</P>
|
||||||
allowing the address-space to be selected.<BR>
|
</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>
|
</P>
|
||||||
</BLOCKQUOTE>
|
</BLOCKQUOTE>
|
||||||
|
|
||||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 28 KiB |
|
@ -38,6 +38,7 @@ import docking.widgets.label.GLabel;
|
||||||
import generic.theme.GColor;
|
import generic.theme.GColor;
|
||||||
import generic.theme.GThemeDefaults.Colors;
|
import generic.theme.GThemeDefaults.Colors;
|
||||||
import ghidra.app.util.AddressInput;
|
import ghidra.app.util.AddressInput;
|
||||||
|
import ghidra.framework.preferences.Preferences;
|
||||||
import ghidra.program.model.address.*;
|
import ghidra.program.model.address.*;
|
||||||
import ghidra.program.model.listing.*;
|
import ghidra.program.model.listing.*;
|
||||||
import ghidra.program.model.scalar.Scalar;
|
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 int MAX_HISTORY_LENGTH = 10;
|
||||||
|
|
||||||
|
private static final String INCLUDE_OTHER_OVERLAY_PREFERENCE = "RefEditIncludeOtherOverlays";
|
||||||
|
|
||||||
private WeakHashMap<Program, List<Address>> addrHistoryMap = new WeakHashMap<>();
|
private WeakHashMap<Program, List<Address>> addrHistoryMap = new WeakHashMap<>();
|
||||||
|
|
||||||
private ReferencesPlugin plugin;
|
private ReferencesPlugin plugin;
|
||||||
|
@ -68,6 +71,7 @@ class EditMemoryReferencePanel extends EditReferencePanel {
|
||||||
private Reference editRef;
|
private Reference editRef;
|
||||||
private JLabel addrLabel;
|
private JLabel addrLabel;
|
||||||
private AddressInput toAddressField;
|
private AddressInput toAddressField;
|
||||||
|
private JCheckBox includeOtherOverlaysCheckbox;
|
||||||
private JButton addrHistoryButton;
|
private JButton addrHistoryButton;
|
||||||
private JCheckBox offsetCheckbox;
|
private JCheckBox offsetCheckbox;
|
||||||
private JTextField offsetField;
|
private JTextField offsetField;
|
||||||
|
@ -113,18 +117,16 @@ class EditMemoryReferencePanel extends EditReferencePanel {
|
||||||
toggleAddressHistoryPopup();
|
toggleAddressHistoryPopup();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void mouseReleased(MouseEvent e) {
|
|
||||||
// TODO Auto-generated method stub
|
|
||||||
super.mouseReleased(e);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
addrHistoryButton.setText(null);
|
addrHistoryButton.setText(null);
|
||||||
addrHistoryButton.setMargin(new Insets(0, 0, 0, 0));
|
addrHistoryButton.setMargin(new Insets(0, 0, 0, 0));
|
||||||
addrHistoryButton.setFocusable(false);
|
addrHistoryButton.setFocusable(false);
|
||||||
addrHistoryButton.setToolTipText("Address History");
|
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);
|
refTypes = new GhidraComboBox<>(MEM_REF_TYPES);
|
||||||
|
|
||||||
JPanel addrPanel = new JPanel(new BorderLayout());
|
JPanel addrPanel = new JPanel(new BorderLayout());
|
||||||
|
@ -137,6 +139,9 @@ class EditMemoryReferencePanel extends EditReferencePanel {
|
||||||
add(addrLabel);
|
add(addrLabel);
|
||||||
add(addrPanel);
|
add(addrPanel);
|
||||||
|
|
||||||
|
add(new JLabel());
|
||||||
|
add(includeOtherOverlaysCheckbox);
|
||||||
|
|
||||||
add(new GLabel("Ref-Type:", SwingConstants.RIGHT));
|
add(new GLabel("Ref-Type:", SwingConstants.RIGHT));
|
||||||
add(refTypes);
|
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
|
@Override
|
||||||
void initialize(CodeUnit fromCu, Reference editReference) {
|
void initialize(CodeUnit fromCu, Reference editReference) {
|
||||||
|
|
||||||
isValidState = false;
|
isValidState = false;
|
||||||
this.fromCodeUnit = fromCu;
|
this.fromCodeUnit = fromCu;
|
||||||
this.editRef = editReference;
|
this.editRef = editReference;
|
||||||
|
@ -199,8 +235,8 @@ class EditMemoryReferencePanel extends EditReferencePanel {
|
||||||
toAddr = toAddr.subtractWrap(defaultOffset);
|
toAddr = toAddr.subtractWrap(defaultOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
toAddressField.setAddressFactory(fromCu.getProgram().getAddressFactory());
|
initializeToAddressField(toAddr);
|
||||||
toAddressField.setAddress(toAddr);
|
|
||||||
enableOffsetField(editReference.isOffsetReference());
|
enableOffsetField(editReference.isOffsetReference());
|
||||||
|
|
||||||
RefType rt = editReference.getReferenceType();
|
RefType rt = editReference.getReferenceType();
|
||||||
|
@ -215,6 +251,7 @@ class EditMemoryReferencePanel extends EditReferencePanel {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
boolean initialize(CodeUnit fromCu, int fromOpIndex, int fromSubIndex) {
|
boolean initialize(CodeUnit fromCu, int fromOpIndex, int fromSubIndex) {
|
||||||
|
|
||||||
isValidState = false;
|
isValidState = false;
|
||||||
this.editRef = null;
|
this.editRef = null;
|
||||||
this.fromCodeUnit = fromCu;
|
this.fromCodeUnit = fromCu;
|
||||||
|
@ -224,8 +261,6 @@ class EditMemoryReferencePanel extends EditReferencePanel {
|
||||||
|
|
||||||
addrHistoryButton.setEnabled(getAddressHistorySize(p) != 0);
|
addrHistoryButton.setEnabled(getAddressHistorySize(p) != 0);
|
||||||
|
|
||||||
toAddressField.setAddressFactory(p.getAddressFactory());
|
|
||||||
|
|
||||||
Address cuAddr = fromCu.getMinAddress();
|
Address cuAddr = fromCu.getMinAddress();
|
||||||
|
|
||||||
RefType rt = RefTypeFactory.getDefaultMemoryRefType(fromCu, fromOpIndex, null, false);
|
RefType rt = RefTypeFactory.getDefaultMemoryRefType(fromCu, fromOpIndex, null, false);
|
||||||
|
@ -238,15 +273,12 @@ class EditMemoryReferencePanel extends EditReferencePanel {
|
||||||
Address toAddr = null;
|
Address toAddr = null;
|
||||||
if (p == program && location != null) {
|
if (p == program && location != null) {
|
||||||
toAddr = getSuggestedLocationAddress(program, location);
|
toAddr = getSuggestedLocationAddress(program, location);
|
||||||
}
|
if (toAddr != null && toAddr.equals(cuAddr)) {
|
||||||
if (toAddr == null || toAddr.equals(cuAddr)) {
|
toAddr = null;
|
||||||
toAddressField.clear();
|
}
|
||||||
}
|
|
||||||
else {
|
|
||||||
toAddressField.setAddress(toAddr);
|
|
||||||
}
|
}
|
||||||
enableOffsetField(false);
|
enableOffsetField(false);
|
||||||
toAddressField.select();
|
initializeToAddressField(toAddr);
|
||||||
return setOpIndex(fromOpIndex);
|
return setOpIndex(fromOpIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -310,14 +342,12 @@ class EditMemoryReferencePanel extends EditReferencePanel {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (toAddr != null && !toAddr.equals(cuAddr)) {
|
if (toAddr != null && toAddr.equals(cuAddr)) {
|
||||||
toAddressField.setAddress(toAddr);
|
toAddr = null;
|
||||||
toAddressField.select();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
toAddressField.clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
initializeToAddressField(toAddr);
|
||||||
|
|
||||||
if (toAddr != null) {
|
if (toAddr != null) {
|
||||||
rt = RefTypeFactory.getDefaultMemoryRefType(fromCu, fromOpIndex, toAddr, false);
|
rt = RefTypeFactory.getDefaultMemoryRefType(fromCu, fromOpIndex, toAddr, false);
|
||||||
populateRefTypes(rt);
|
populateRefTypes(rt);
|
||||||
|
|
|
@ -69,6 +69,7 @@ public class EditReferenceDialog extends ReusableDialogComponentProvider {
|
||||||
addCancelButton();
|
addCancelButton();
|
||||||
|
|
||||||
setDefaultButton(applyButton);
|
setDefaultButton(applyButton);
|
||||||
|
setUseSharedLocation(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -71,16 +71,18 @@ import ghidra.framework.plugintool.Plugin;
|
||||||
import ghidra.framework.plugintool.PluginTool;
|
import ghidra.framework.plugintool.PluginTool;
|
||||||
import ghidra.framework.plugintool.util.PluginException;
|
import ghidra.framework.plugintool.util.PluginException;
|
||||||
import ghidra.program.database.data.ProgramDataTypeManager;
|
import ghidra.program.database.data.ProgramDataTypeManager;
|
||||||
import ghidra.program.model.address.Address;
|
import ghidra.program.model.address.*;
|
||||||
import ghidra.program.model.address.AddressSet;
|
|
||||||
import ghidra.program.model.data.BuiltInDataTypeManager;
|
import ghidra.program.model.data.BuiltInDataTypeManager;
|
||||||
import ghidra.program.model.data.DataTypeManager;
|
import ghidra.program.model.data.DataTypeManager;
|
||||||
import ghidra.program.model.listing.Program;
|
import ghidra.program.model.listing.Program;
|
||||||
|
import ghidra.program.model.mem.Memory;
|
||||||
import ghidra.program.util.ProgramSelection;
|
import ghidra.program.util.ProgramSelection;
|
||||||
import ghidra.test.AbstractGhidraHeadedIntegrationTest;
|
import ghidra.test.AbstractGhidraHeadedIntegrationTest;
|
||||||
import ghidra.test.TestEnv;
|
import ghidra.test.TestEnv;
|
||||||
import ghidra.util.ColorUtils;
|
import ghidra.util.ColorUtils;
|
||||||
import ghidra.util.exception.AssertException;
|
import ghidra.util.exception.AssertException;
|
||||||
|
import ghidra.util.exception.UsrException;
|
||||||
|
import ghidra.util.task.TaskMonitor;
|
||||||
import resources.ResourceManager;
|
import resources.ResourceManager;
|
||||||
|
|
||||||
public abstract class AbstractScreenShotGenerator extends AbstractGhidraHeadedIntegrationTest {
|
public abstract class AbstractScreenShotGenerator extends AbstractGhidraHeadedIntegrationTest {
|
||||||
|
@ -161,6 +163,19 @@ public abstract class AbstractScreenShotGenerator extends AbstractGhidraHeadedIn
|
||||||
public Program loadProgram(final String programName) {
|
public Program loadProgram(final String programName) {
|
||||||
runSwing(() -> {
|
runSwing(() -> {
|
||||||
program = env.getProgram(programName);
|
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);
|
ProgramManager pm = tool.getService(ProgramManager.class);
|
||||||
pm.openProgram(program.getDomainFile());
|
pm.openProgram(program.getDomainFile());
|
||||||
});
|
});
|
||||||
|
@ -1637,7 +1652,7 @@ public abstract class AbstractScreenShotGenerator extends AbstractGhidraHeadedIn
|
||||||
|
|
||||||
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
|
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
|
||||||
|
|
||||||
g2.setColor(Colors.BORDER);
|
g2.setColor(Color.BLACK);
|
||||||
g2.setStroke(new BasicStroke(3f));
|
g2.setStroke(new BasicStroke(3f));
|
||||||
g2.draw(topPath);
|
g2.draw(topPath);
|
||||||
g2.draw(bottomPath);
|
g2.draw(bottomPath);
|
||||||
|
|
|
@ -230,15 +230,24 @@ public class ReferencesPluginScreenShots extends GhidraScreenShotGenerator {
|
||||||
CodeUnit cu = program.getListing().getCodeUnitAt(addr(0x401008));
|
CodeUnit cu = program.getListing().getCodeUnitAt(addr(0x401008));
|
||||||
ReferencesPlugin plugin = getPlugin(tool, ReferencesPlugin.class);
|
ReferencesPlugin plugin = getPlugin(tool, ReferencesPlugin.class);
|
||||||
final EditReferenceDialog dialog = new EditReferenceDialog(plugin);
|
final EditReferenceDialog dialog = new EditReferenceDialog(plugin);
|
||||||
dialog.initDialog(cu, 0, 0, null);
|
|
||||||
runSwing(() -> {
|
runSwing(() -> {
|
||||||
JRadioButton choiceButton = (JRadioButton) getInstanceField("memRefChoice", dialog);
|
dialog.initDialog(cu, 0, 0, null);
|
||||||
invokeInstanceMethod("refChoiceActivated", dialog,
|
|
||||||
new Class<?>[] { JRadioButton.class }, new Object[] { choiceButton });
|
|
||||||
}, true);
|
}, true);
|
||||||
showDialogWithoutBlocking(tool, dialog);
|
|
||||||
|
JRadioButton choiceButton = (JRadioButton) getInstanceField("memRefChoice", dialog);
|
||||||
|
pressButton(choiceButton);
|
||||||
|
|
||||||
final JPanel panel = (JPanel) getInstanceField("memRefPanel", dialog);
|
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);
|
JButton button = (JButton) getInstanceField("addrHistoryButton", panel);
|
||||||
Rectangle buttonBounds = button.getBounds();
|
Rectangle buttonBounds = button.getBounds();
|
||||||
buttonBounds = SwingUtilities.convertRectangle(button.getParent(), buttonBounds, panel);
|
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()
|
buttonBounds.y += buttonBounds.height / 2 + 20; // half button height + padding added by takeSnippet()
|
||||||
System.out.println("Button bounds = " + buttonBounds);
|
System.out.println("Button bounds = " + buttonBounds);
|
||||||
Rectangle bounds = panel.getBounds();
|
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);
|
bounds = SwingUtilities.convertRectangle(panel.getParent(), bounds, null);
|
||||||
captureDialog();
|
captureDialog();
|
||||||
takeSnippet(bounds);
|
takeSnippet(bounds);
|
||||||
|
@ -257,7 +267,8 @@ public class ReferencesPluginScreenShots extends GhidraScreenShotGenerator {
|
||||||
checkbox.setSelected(true);
|
checkbox.setSelected(true);
|
||||||
});
|
});
|
||||||
bounds = panel.getBounds();
|
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);
|
bounds = SwingUtilities.convertRectangle(panel.getParent(), bounds, null);
|
||||||
captureDialog();
|
captureDialog();
|
||||||
takeSnippet(bounds);
|
takeSnippet(bounds);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue