GP-2393 - Removed size restriction in Select Bytes dialog

This commit is contained in:
dragonmacher
2026-05-05 15:14:26 -04:00
parent 62dc049cb0
commit 1fc22ba44f
4 changed files with 522 additions and 379 deletions
@@ -31,30 +31,28 @@ import ghidra.framework.plugintool.PluginTool;
import ghidra.program.model.address.*; import ghidra.program.model.address.*;
import ghidra.program.util.ProgramSelection; import ghidra.program.util.ProgramSelection;
import ghidra.util.HelpLocation; import ghidra.util.HelpLocation;
import ghidra.util.Msg;
import ghidra.util.layout.PairLayout; import ghidra.util.layout.PairLayout;
/** /**
* Class to set up dialog box that will enable the user * Dialog for making program selections
* to set the available options for block selection
*/ */
class SelectBlockDialog extends ReusableDialogComponentProvider { class SelectBlockDialog extends ReusableDialogComponentProvider {
private static final String OVERFLOW_SELECTION_WARNING =
"Selection is larger than available " + "bytes, using the end of the address space"; private PluginTool tool;
private Navigatable navigatable;
private JTextField toAddressField; private JTextField toAddressField;
private IntegerTextField numberInputField; // AddressInput allows decimal and hex input private IntegerTextField lengthField;
private JRadioButton forwardButton; private JRadioButton forwardButton;
private JRadioButton backwardButton; private JRadioButton backwardButton;
private JRadioButton allButton; private JRadioButton allButton;
private JRadioButton toButton; private JRadioButton toButton;
private Navigatable navigatable;
private PluginTool tool;
SelectBlockDialog(PluginTool tool, Navigatable navigatable) { SelectBlockDialog(PluginTool tool, Navigatable navigatable) {
super("Select Bytes", false, true, true, false); super("Select Bytes", false, true, true, false);
this.tool = tool; this.tool = tool;
this.navigatable = navigatable; this.navigatable = navigatable;
// navigatable.addNavigatableListener(this);
addWorkPanel(buildPanel()); addWorkPanel(buildPanel());
addOKButton(); addOKButton();
@@ -62,7 +60,6 @@ class SelectBlockDialog extends ReusableDialogComponentProvider {
addDismissButton(); addDismissButton();
setHelpLocation(new HelpLocation("SelectBlockPlugin", "Select_Block_Help")); setHelpLocation(new HelpLocation("SelectBlockPlugin", "Select_Block_Help"));
// make sure the state of the widgets is correct
setItemsEnabled(false); setItemsEnabled(false);
forwardButton.doClick(); forwardButton.doClick();
} }
@@ -94,11 +91,10 @@ class SelectBlockDialog extends ReusableDialogComponentProvider {
main.add(toAddressField); main.add(toAddressField);
main.add(new GLabel("Length: ")); main.add(new GLabel("Length: "));
numberInputField = new IntegerTextField(10); lengthField = new IntegerTextField(10);
numberInputField.getComponent().getAccessibleContext().setAccessibleName("Number Input"); lengthField.getComponent().getAccessibleContext().setAccessibleName("Number Input");
numberInputField.setMaxValue(BigInteger.valueOf(Integer.MAX_VALUE)); lengthField.setMinValue(BigInteger.ZERO);
numberInputField.setMinValue(BigInteger.ZERO); main.add(lengthField.getComponent());
main.add(numberInputField.getComponent());
main.getAccessibleContext().setAccessibleName("Block"); main.getAccessibleContext().setAccessibleName("Block");
return main; return main;
} }
@@ -169,6 +165,11 @@ class SelectBlockDialog extends ReusableDialogComponentProvider {
navigatable = null; navigatable = null;
} }
void setNavigatable(Navigatable navigatable) {
this.navigatable = navigatable;
setOkEnabled(navigatable != null);
}
void show(ComponentProvider provider) { void show(ComponentProvider provider) {
tool.showDialog(this, provider); tool.showDialog(this, provider);
repack(); repack();
@@ -187,188 +188,147 @@ class SelectBlockDialog extends ReusableDialogComponentProvider {
private void setLengthInputEnabled(boolean enabled) { private void setLengthInputEnabled(boolean enabled) {
if (!enabled) { if (!enabled) {
numberInputField.setValue(null); lengthField.setValue(null);
} }
numberInputField.setEnabled(enabled); lengthField.setEnabled(enabled);
} }
@Override @Override
protected void okCallback() { protected void okCallback() {
if (toButton.isSelected()) { if (toButton.isSelected()) {
handleToAddressSelection(); selectToAddress();
} }
else if (allButton.isSelected()) { else if (allButton.isSelected()) {
handleAllSelection(); selectAll();
} }
else if (forwardButton.isSelected()) { else if (forwardButton.isSelected()) {
handleForwardSelection(); createSelection(true);
} }
else if (backwardButton.isSelected()) { else if (backwardButton.isSelected()) {
handleBackwardSelection(); createSelection(false);
} }
else { else {
setStatusText("You must choose the type of selection to make"); setStatusText("You must choose the type of selection to make");
} }
} }
private void handleAllSelection() { private void selectAll() {
AddressSetView addressSet = navigatable.getProgram().getMemory(); AddressSetView addressSet = navigatable.getProgram().getMemory();
ProgramSelection selection = new ProgramSelection(addressSet); ProgramSelection selection = new ProgramSelection(addressSet);
NavigationUtils.setSelection(tool, navigatable, selection); NavigationUtils.setSelection(tool, navigatable, selection);
clearStatusText(); clearStatusText();
} }
private void handleToAddressSelection() { private void selectToAddress() {
Address toAddress = null;
String addressValue = toAddressField.getText(); String addressValue = toAddressField.getText();
clearStatusText(); clearStatusText();
// make sure the order of the addresses is correct // make sure the order of the addresses is correct
Address currentAddress = navigatable.getLocation().getAddress(); Address currentAddress = navigatable.getLocation().getAddress();
Address to = null;
try { try {
toAddress = currentAddress.getAddress(addressValue); to = currentAddress.getAddress(addressValue);
} }
catch (AddressFormatException e) { catch (AddressFormatException e) {
// use the fact that toAddress remains null // use the fact that toAddress remains null
} }
if (toAddress == null) {
if (to == null) {
setStatusText("Invalid address value, enter another address"); setStatusText("Invalid address value, enter another address");
return; return;
} }
if (toAddress.compareTo(currentAddress) < 0) {
Address tmp = toAddress; if (to.compareTo(currentAddress) < 0) {
toAddress = currentAddress; Address tmp = to;
to = currentAddress;
currentAddress = tmp; currentAddress = tmp;
} }
AddressSet addressSet = new AddressSet(currentAddress, toAddress); AddressSet addressSet = new AddressSet(currentAddress, to);
ProgramSelection selection = new ProgramSelection(addressSet); ProgramSelection selection = new ProgramSelection(addressSet);
NavigationUtils.setSelection(tool, navigatable, selection); NavigationUtils.setSelection(tool, navigatable, selection);
} }
private void handleForwardSelection() { private void createSelection(boolean forward) {
// value is a length BigInteger length = lengthField.getValue();
int length = numberInputField.getIntValue(); // throws NFE if (length == null || length == BigInteger.ZERO) {
if (length == 0) {
setStatusText("length must be > 0"); setStatusText("length must be > 0");
return; return;
} }
clearStatusText(); clearStatusText();
Address currentAddress = navigatable.getLocation().getAddress(); AddressSet startSet;
ProgramSelection currentSelection = navigatable.getSelection();
AddressSet addressSet = new AddressSet(navigatable.getSelection()); if (!currentSelection.isEmpty()) {
startSet = new AddressSet(currentSelection);
if (addressSet.isEmpty()) { }
addressSet.addRange(currentAddress, currentAddress); else {
Address currentAddress = navigatable.getLocation().getAddress();
startSet = new AddressSet(currentAddress);
} }
AddressRangeIterator aiter = addressSet.getAddressRanges(); AddressRangeIterator it = startSet.getAddressRanges();
AddressSet newSet = new AddressSet(); AddressSet newSet = new AddressSet();
while (aiter.hasNext()) { while (it.hasNext()) {
AddressRange range = aiter.next(); AddressRange range = it.next();
Address toAddress = createForwardToAddress(range.getMinAddress(), length - 1);
if (toAddress != null) { if (forward) {
newSet.addRange(range.getMinAddress(), toAddress); Address from = range.getMinAddress();
createForwardRange(newSet, from, length);
}
else {
Address to = range.getMaxAddress();
createBackwardRange(newSet, to, length);
} }
} }
ProgramSelection selection = new ProgramSelection(newSet);
NavigationUtils.setSelection(tool, navigatable, selection); ProgramSelection newSelection = new ProgramSelection(newSet);
NavigationUtils.setSelection(tool, navigatable, newSelection);
} }
private void handleBackwardSelection() { private void createForwardRange(AddressSet set, Address from, BigInteger length) {
// value is a length Address to = getToAddress(from, length);
int length = numberInputField.getIntValue(); set.addRange(from, to);
if (length == 0) {
setStatusText("length must be > 0");
return;
}
clearStatusText();
Address currentAddress = navigatable.getLocation().getAddress();
AddressSet addressSet = new AddressSet(navigatable.getSelection());
if (addressSet.isEmpty()) {
addressSet.addRange(currentAddress, currentAddress);
}
AddressRangeIterator aiter = addressSet.getAddressRanges();
AddressSet newSet = new AddressSet();
while (aiter.hasNext()) {
AddressRange range = aiter.next();
Address fromAddress = createBackwardToAddress(range.getMaxAddress(), length - 1);
if (fromAddress != null) {
newSet.addRange(fromAddress, range.getMaxAddress());
}
}
ProgramSelection selection = new ProgramSelection(newSet);
NavigationUtils.setSelection(tool, navigatable, selection);
} }
private Address createBackwardToAddress(Address toAddress, long length) { private void createBackwardRange(AddressSet set, Address to, BigInteger length) {
AddressSpace addressSpace = toAddress.getAddressSpace(); Address from = getFromAddress(to, length);
if (addressSpace.isOverlaySpace()) { set.addRange(from, to);
OverlayAddressSpace oas = (OverlayAddressSpace) addressSpace; }
AddressRange range = oas.getOverlayAddressSet().getRangeContaining(toAddress);
if (range == null) {
showWarningDialog(OVERFLOW_SELECTION_WARNING);
return toAddress;
}
long avail = toAddress.subtract(range.getMinAddress());
if (avail < (length - 1)) {
showWarningDialog(OVERFLOW_SELECTION_WARNING);
return range.getMinAddress();
}
}
Address addr = null; private Address getFromAddress(Address to, BigInteger length) {
// subtract one to be inclusive; address ranges are inclusive
BigInteger inclusiveLength = length.subtract(BigInteger.ONE);
try { try {
addr = toAddress.subtractNoWrap(length); return to.subtractNoWrap(inclusiveLength);
} }
catch (AddressOverflowException aoobe) { catch (AddressOverflowException e) {
showWarningDialog(OVERFLOW_SELECTION_WARNING); showWarningDialog();
addr = addressSpace.getMinAddress(); AddressSpace space = to.getAddressSpace();
return space.getMinAddress();
} }
return addr;
} }
private Address createForwardToAddress(Address fromAddress, long length) { private Address getToAddress(Address from, BigInteger length) {
AddressSpace addressSpace = fromAddress.getAddressSpace(); // subtract one to be inclusive; address ranges are inclusive
if (addressSpace.isOverlaySpace()) { BigInteger inclusiveLength = length.subtract(BigInteger.ONE);
OverlayAddressSpace oas = (OverlayAddressSpace) addressSpace;
AddressRange range = oas.getOverlayAddressSet().getRangeContaining(fromAddress);
if (range == null) {
showWarningDialog(OVERFLOW_SELECTION_WARNING);
return fromAddress;
}
long avail = range.getMaxAddress().subtract(fromAddress);
if (avail < (length - 1)) {
showWarningDialog(OVERFLOW_SELECTION_WARNING);
return range.getMaxAddress();
}
}
Address addr = null;
try { try {
addr = fromAddress.addNoWrap(length); return from.addNoWrap(inclusiveLength);
} }
catch (AddressOverflowException aoobe) { catch (AddressOverflowException e) {
showWarningDialog(OVERFLOW_SELECTION_WARNING); showWarningDialog();
addr = addressSpace.getMaxAddress(); AddressSpace space = from.getAddressSpace();
return space.getMaxAddress();
} }
return addr;
} }
private void showWarningDialog(final String text) { private void showWarningDialog() {
SwingUtilities.invokeLater(() -> JOptionPane.showMessageDialog(getComponent(), text)); Msg.showWarn(this, getComponent(), "Selection Overflow",
"Selection is larger than available bytes. Using the boundary of the address space.");
} }
public void setNavigatable(Navigatable navigatable) {
this.navigatable = navigatable;
setOkEnabled(navigatable != null);
}
} }
@@ -68,6 +68,7 @@ public interface Address extends Comparable<Address> {
/** /**
* Returns a new address in this address's space with the given offset. * Returns a new address in this address's space with the given offset.
*
* <P>NOTE: for those spaces with an addressable unit size other than 1, the address returned * <P>NOTE: for those spaces with an addressable unit size other than 1, the address returned
* may not correspond to an addressable unit/word boundary if a byte-offset is specified. * may not correspond to an addressable unit/word boundary if a byte-offset is specified.
* *
@@ -81,14 +82,16 @@ public interface Address extends Comparable<Address> {
* @throws AddressOutOfBoundsException if the offset is less than 0 or greater than the max * @throws AddressOutOfBoundsException if the offset is less than 0 or greater than the max
* offset allowed for this space. * offset allowed for this space.
*/ */
Address getNewAddress(long offset, boolean isAddressableWordOffset) public Address getNewAddress(long offset, boolean isAddressableWordOffset)
throws AddressOutOfBoundsException; throws AddressOutOfBoundsException;
/** /**
* Returns a new address in this address's space with the given offset. The specified offset * Returns a new address in this address's space with the given offset. The specified offset
* will be truncated within the space and will not throw an exception. * will be truncated within the space and will not throw an exception.
*
* <p>NOTE: for those spaces with an addressable unit size other than 1, the address returned * <p>NOTE: for those spaces with an addressable unit size other than 1, the address returned
* may not correspond to a word boundary (addressable unit) if a byte-offset is specified. * may not correspond to a word boundary (addressable unit) if a byte-offset is specified.
*
* @param offset the offset for the new address. * @param offset the offset for the new address.
* @param isAddressableWordOffset if true the specified offset is an addressable unit/word * @param isAddressableWordOffset if true the specified offset is an addressable unit/word
* offset, otherwise offset is a byte offset. See * offset, otherwise offset is a byte offset. See
@@ -97,7 +100,7 @@ public interface Address extends Comparable<Address> {
* (i.e., wordOffset = byteOffset * addressableUnitSize). * (i.e., wordOffset = byteOffset * addressableUnitSize).
* @return address with given byte offset truncated to the physical space size * @return address with given byte offset truncated to the physical space size
*/ */
Address getNewTruncatedAddress(long offset, boolean isAddressableWordOffset); public Address getNewTruncatedAddress(long offset, boolean isAddressableWordOffset);
/** /**
* Returns the number of bytes needed to form a pointer to this address. The result will be * Returns the number of bytes needed to form a pointer to this address. The result will be
@@ -193,7 +196,7 @@ public interface Address extends Comparable<Address> {
* Creates a new address by subtracting the displacement from the current address. If the * Creates a new address by subtracting the displacement from the current address. If the
* offset is greater than the max offset of the address space, the high order bits are masked * offset is greater than the max offset of the address space, the high order bits are masked
* off, making the address wrap. For non-segmented addresses this will be the same as * off, making the address wrap. For non-segmented addresses this will be the same as
* subtractWrap(). For segmented addresses, the address will wrap when the 20 bit (oxfffff) * subtractWrap(). For segmented addresses, the address will wrap when the 20 bit (0xfffff)
* offset is exceeded, as opposed to when the segment offset is exceeded. * offset is exceeded, as opposed to when the segment offset is exceeded.
* @param displacement the displacement to add. * @param displacement the displacement to add.
* @return The new Address formed by subtracting the displacement from this address's offset. * @return The new Address formed by subtracting the displacement from this address's offset.
@@ -212,6 +215,18 @@ public interface Address extends Comparable<Address> {
*/ */
public Address subtractNoWrap(long displacement) throws AddressOverflowException; public Address subtractNoWrap(long displacement) throws AddressOverflowException;
/**
* Creates a new Address by subtracting displacement from the Address. The Address will not
* wrap within the space and in fact will throw an exception if the result is less than the min
* address in this space or greater than the max address in this space.
*
* @param displacement the displacement to subtract.
* @return The new Address
* @throws AddressOverflowException if the offset in this Address would overflow due to this
* operation.
*/
public Address subtractNoWrap(BigInteger displacement) throws AddressOverflowException;
/** /**
* Creates a new address (possibly in a new space) by subtracting the displacement to this * Creates a new address (possibly in a new space) by subtracting the displacement to this
* address. * address.
@@ -235,7 +250,7 @@ public interface Address extends Comparable<Address> {
* Creates a new address by adding the displacement to the current address. If the offset is * Creates a new address by adding the displacement to the current address. If the offset is
* greater than the max offset of the address space, the high order bits are masked off, making * greater than the max offset of the address space, the high order bits are masked off, making
* the address wrap. For non-segmented addresses this will be the same as addWrap(). For * the address wrap. For non-segmented addresses this will be the same as addWrap(). For
* segmented addresses, the address will wrap when the 20 bit (oxfffff) offset is exceeded, as * segmented addresses, the address will wrap when the 20 bit (0xfffff) offset is exceeded, as
* opposed to when the segment offset is exceeded. * opposed to when the segment offset is exceeded.
* @param displacement the displacement to add. * @param displacement the displacement to add.
* @return The new Address formed by adding the displacement to this address's offset. * @return The new Address formed by adding the displacement to this address's offset.
@@ -253,8 +268,16 @@ public interface Address extends Comparable<Address> {
*/ */
public Address addNoWrap(long displacement) throws AddressOverflowException; public Address addNoWrap(long displacement) throws AddressOverflowException;
/**
* Creates a new Address with a displacement relative to this Address. The Address will not
* wrap around! An exception will be throw if the result is not within this address space.
*
* @param displacement the displacement to add.
* @return the new address.
* @throws AddressOverflowException if the offset in this Address would overflow (wrap around)
* due to this operation.
*/
public Address addNoWrap(BigInteger displacement) throws AddressOverflowException; public Address addNoWrap(BigInteger displacement) throws AddressOverflowException;
public Address subtractNoWrap(BigInteger displacement) throws AddressOverflowException;
/** /**
* Creates a new address (possibly in a new space) by adding the displacement to this address. * Creates a new address (possibly in a new space) by adding the displacement to this address.
@@ -394,6 +417,7 @@ public interface Address extends Comparable<Address> {
/** /**
* Returns true if this address represents a location in the register space. * Returns true if this address represents a location in the register space.
*
* <P>NOTE: It is important to note that a {@link Register} could reside within a memory space * <P>NOTE: It is important to note that a {@link Register} could reside within a memory space
* and not the register space in which case this method would return false for its address. * and not the register space in which case this method would return false for its address.
* @return true if a register address * @return true if a register address
@@ -105,20 +105,20 @@ public interface AddressSpace extends Comparable<AddressSpace> {
* {@return the name of this address space}. * {@return the name of this address space}.
* With the exception of {@link OverlayAddressSpace}, the name of an address space may not change. * With the exception of {@link OverlayAddressSpace}, the name of an address space may not change.
*/ */
String getName(); public String getName();
/** /**
* Get the ID for this space * Get the ID for this space
* *
* @return space ID * @return space ID
*/ */
int getSpaceID(); public int getSpaceID();
/** /**
* {@return the number of bits that are used to form the address.} Thus * {@return the number of bits that are used to form the address.} Thus
* the maximum offset for this address space will be 2^size-1. * the maximum offset for this address space will be 2^size-1.
*/ */
int getSize(); public int getSize();
/** /**
* {@return the number of data bytes which correspond to each addressable * {@return the number of data bytes which correspond to each addressable
@@ -134,7 +134,7 @@ public interface AddressSpace extends Comparable<AddressSpace> {
* wordOffset = getAddressableWordOffset(byteOffset) * wordOffset = getAddressableWordOffset(byteOffset)
* </pre> * </pre>
*/ */
int getAddressableUnitSize(); public int getAddressableUnitSize();
/** /**
* Get the addressable memory word offset which corresponds to the specified * Get the addressable memory word offset which corresponds to the specified
@@ -151,17 +151,17 @@ public interface AddressSpace extends Comparable<AddressSpace> {
* @see Program#getDefaultPointerSize() for a user adjustable pointer size which is derived from the * @see Program#getDefaultPointerSize() for a user adjustable pointer size which is derived from the
* CompilerSpec store pointer size. * CompilerSpec store pointer size.
*/ */
int getPointerSize(); public int getPointerSize();
/** /**
* {@return the type of this address space} * {@return the type of this address space}
*/ */
int getType(); public int getType();
/** /**
* {@return the unique index for this address space} * {@return the unique index for this address space}
*/ */
int getUnique(); public int getUnique();
/** /**
* Parses the String into an address within this address space. * Parses the String into an address within this address space.
@@ -171,7 +171,7 @@ public interface AddressSpace extends Comparable<AddressSpace> {
* @throws AddressFormatException if the string cannot be parsed or the * @throws AddressFormatException if the string cannot be parsed or the
* parsed offset is larger than the size for this space. * parsed offset is larger than the size for this space.
*/ */
Address getAddress(String addrString) throws AddressFormatException; public Address getAddress(String addrString) throws AddressFormatException;
/** /**
* Parses the String into an address within this address space. * Parses the String into an address within this address space.
@@ -182,47 +182,54 @@ public interface AddressSpace extends Comparable<AddressSpace> {
* @throws AddressFormatException if the string cannot be parsed or the * @throws AddressFormatException if the string cannot be parsed or the
* parsed offset is larger than the size for this space. * parsed offset is larger than the size for this space.
*/ */
Address getAddress(String addrString, boolean caseSensitive) throws AddressFormatException; public Address getAddress(String addrString, boolean caseSensitive)
throws AddressFormatException;
/** /**
* Returns a new address in this space with the given byte offset. * Returns a new address in this space with the given byte offset.
* <p>
* NOTE: This method is the same as invoking getAddress(long byteOffset, false). * NOTE: This method is the same as invoking getAddress(long byteOffset, false).
*
* @param byteOffset the byte offset for the new address. * @param byteOffset the byte offset for the new address.
* @return address with given byte offset * @return address with given byte offset
* @throws AddressOutOfBoundsException if the offset is less than 0 or greater * @throws AddressOutOfBoundsException if the offset is less than 0 or greater
* than the max offset allowed for this space. * than the max offset allowed for this space.
*/ */
Address getAddress(long byteOffset) throws AddressOutOfBoundsException; public Address getAddress(long byteOffset) throws AddressOutOfBoundsException;
/** /**
* Returns a new address in this space with the given offset. * Returns a new address in this space with the given offset.
* <p>
* NOTE: for those spaces with an addressable unit size other than 1, the address * NOTE: for those spaces with an addressable unit size other than 1, the address
* returned may not correspond to an addressable unit/word boundary if a byte-offset * returned may not correspond to an addressable unit/word boundary if a byte-offset
* is specified. * is specified.
*
* @param offset the offset for the new address. * @param offset the offset for the new address.
* @param isAddressableWordOffset if true the specified offset is an addressable unit/word offset, * @param isAddressableWordOffset if true the specified offset is an addressable unit/word
* otherwise offset is a byte offset. See {@link #getAddressableUnitSize()} * offset, otherwise offset is a byte offset. See {@link #getAddressableUnitSize()}
* to understand the distinction (i.e., wordOffset = byteOffset * addressableUnitSize). * to understand the distinction (i.e., wordOffset = byteOffset * addressableUnitSize).
* @return address with given offset * @return address with given offset
* @throws AddressOutOfBoundsException if the offset is less than 0 or greater * @throws AddressOutOfBoundsException if the offset is less than 0 or greater
* than the max offset allowed for this space. * than the max offset allowed for this space.
*/ */
Address getAddress(long offset, boolean isAddressableWordOffset) public Address getAddress(long offset, boolean isAddressableWordOffset)
throws AddressOutOfBoundsException; throws AddressOutOfBoundsException;
/** /**
* Returns a new address in this space with the given offset. The specified * Returns a new address in this space with the given offset. The specified
* offset will be truncated within the space and will not throw an exception. * offset will be truncated within the space and will not throw an exception.
* <p>
* NOTE: for those spaces with an addressable unit size other than 1, the address * NOTE: for those spaces with an addressable unit size other than 1, the address
* returned may not correspond to a word boundary (addressable unit) if a byte-offset * returned may not correspond to a word boundary (addressable unit) if a byte-offset
* is specified. * is specified.
*
* @param offset the offset for the new address. * @param offset the offset for the new address.
* @param isAddressableWordOffset if true the specified offset is an addressable unit/word offset, * @param isAddressableWordOffset if true the specified offset is an addressable unit/word offset,
* otherwise offset is a byte offset. See {@link #getAddressableUnitSize()} * otherwise offset is a byte offset. See {@link #getAddressableUnitSize()}
* to understand the distinction (i.e., wordOffset = byteOffset * addressableUnitSize). * to understand the distinction (i.e., wordOffset = byteOffset * addressableUnitSize).
* @return address with given byte offset truncated to the physical space size * @return address with given byte offset truncated to the physical space size
*/ */
Address getTruncatedAddress(long offset, boolean isAddressableWordOffset); public Address getTruncatedAddress(long offset, boolean isAddressableWordOffset);
/** /**
* Get a byte address from this address space. Don't allow overlay spaces * Get a byte address from this address space. Don't allow overlay spaces
@@ -231,18 +238,17 @@ public interface AddressSpace extends Comparable<AddressSpace> {
* *
* @param byteOffset the byte offset for the new address. * @param byteOffset the byte offset for the new address.
* @return an address if the offset is valid. * @return an address if the offset is valid.
*
* @throws AddressOutOfBoundsException if the offset is less than 0 or greater * @throws AddressOutOfBoundsException if the offset is less than 0 or greater
* than the max offset allowed for this space. * than the max offset allowed for this space.
*/ */
Address getAddressInThisSpaceOnly(long byteOffset) throws AddressOutOfBoundsException; public Address getAddressInThisSpaceOnly(long byteOffset) throws AddressOutOfBoundsException;
/** /**
* Truncate the specified byte offset within this space to produce a valid offset. * Truncate the specified byte offset within this space to produce a valid offset.
* @param byteOffset any byte offset * @param byteOffset any byte offset
* @return truncated byte offset * @return truncated byte offset
*/ */
long truncateOffset(long byteOffset); public long truncateOffset(long byteOffset);
/** /**
* Truncate the specified addressable unit/word offset within this space to produce a * Truncate the specified addressable unit/word offset within this space to produce a
@@ -250,7 +256,7 @@ public interface AddressSpace extends Comparable<AddressSpace> {
* @param wordOffset any addressable unit/word offset * @param wordOffset any addressable unit/word offset
* @return truncated word offset * @return truncated word offset
*/ */
long truncateAddressableWordOffset(long wordOffset); public long truncateAddressableWordOffset(long wordOffset);
/** /**
* Get an address that is relative to this address space. * Get an address that is relative to this address space.
@@ -258,10 +264,9 @@ public interface AddressSpace extends Comparable<AddressSpace> {
* this space, return an address based in this space. * this space, return an address based in this space.
* *
* @param addr address possibly falling within this overlay space. * @param addr address possibly falling within this overlay space.
*
* @return an address relative to this overlay * @return an address relative to this overlay
*/ */
Address getOverlayAddress(Address addr); public Address getOverlayAddress(Address addr);
/** /**
* Calculates the displacement between addr1 and addr2 (addr1 - addr2) * Calculates the displacement between addr1 and addr2 (addr1 - addr2)
@@ -277,6 +282,7 @@ public interface AddressSpace extends Comparable<AddressSpace> {
/** /**
* Creates a new address by subtracting displacement from addr's offset. * Creates a new address by subtracting displacement from addr's offset.
*
* @param addr the original address. The new address will wrap in a manner * @param addr the original address. The new address will wrap in a manner
* that depends on the address space. For a generic address space this will * that depends on the address space. For a generic address space this will
* wrap at the extents of the address space. For a segmented address space * wrap at the extents of the address space. For a segmented address space
@@ -291,12 +297,12 @@ public interface AddressSpace extends Comparable<AddressSpace> {
* address. If the offset is greater than the max offset of the address space, the high * address. If the offset is greater than the max offset of the address space, the high
* order bits are masked off, making the address wrap. For non-segmented addresses this * order bits are masked off, making the address wrap. For non-segmented addresses this
* will be the same as subtractWrap(). For segmented addresses, the address will wrap when * will be the same as subtractWrap(). For segmented addresses, the address will wrap when
* the 20 bit (oxfffff) offset is exceeded, as opposed to when the segment offset is exceeded. * the 20 bit (0xfffff) offset is exceeded, as opposed to when the segment offset is exceeded.
* @param addr the address to subtract the displacement from. * @param addr the address to subtract the displacement from.
* @param displacement the displacement to subtract. * @param displacement the displacement to subtract.
* @return The new Address formed by subtracting the displacement from the specified address. * @return The new Address formed by subtracting the displacement from the specified address.
*/ */
Address subtractWrapSpace(Address addr, long displacement); public Address subtractWrapSpace(Address addr, long displacement);
/** /**
* Creates a new address by subtracting displacement from addr's offset. * Creates a new address by subtracting displacement from addr's offset.
@@ -308,6 +314,17 @@ public interface AddressSpace extends Comparable<AddressSpace> {
*/ */
public Address subtractNoWrap(Address addr, long displacement) throws AddressOverflowException; public Address subtractNoWrap(Address addr, long displacement) throws AddressOverflowException;
/**
* Creates a new address by subtracting the displacement to the given address. The
* new address will NOT wrap!
* @param addr the original address.
* @param displacement the displacement to subtract.
* @return The new address created by subtracting the displacement to addr.offset.
* @throws AddressOverflowException if the addition would cause a wrap,
*/
public Address subtractNoWrap(GenericAddress addr, BigInteger displacement)
throws AddressOverflowException;
/** /**
* Creates a new address (possibly in a new space) by subtracting the given * Creates a new address (possibly in a new space) by subtracting the given
* displacement from the given address. * displacement from the given address.
@@ -335,12 +352,12 @@ public interface AddressSpace extends Comparable<AddressSpace> {
* address. If the offset is greater than the max offset of the address space, the high * address. If the offset is greater than the max offset of the address space, the high
* order bits are masked off, making the address wrap. For non-segmented addresses this * order bits are masked off, making the address wrap. For non-segmented addresses this
* will be the same as addWrap(). For segmented addresses, the address will wrap when * will be the same as addWrap(). For segmented addresses, the address will wrap when
* the 20 bit (oxfffff) offset is exceeded, as opposed to when the segment offset is exceeded. * the 20 bit (0xfffff) offset is exceeded, as opposed to when the segment offset is exceeded.
* @param addr the address to add the displacement to. * @param addr the address to add the displacement to.
* @param displacement the displacement to add. * @param displacement the displacement to add.
* @return The new Address formed by adding the displacement to the specified addresst. * @return The new Address formed by adding the displacement to the specified address.
*/ */
Address addWrapSpace(Address addr, long displacement); public Address addWrapSpace(Address addr, long displacement);
/** /**
* Creates a new address by adding displacement to the given address. The * Creates a new address by adding displacement to the given address. The
@@ -363,17 +380,6 @@ public interface AddressSpace extends Comparable<AddressSpace> {
public Address addNoWrap(GenericAddress addr, BigInteger displacement) public Address addNoWrap(GenericAddress addr, BigInteger displacement)
throws AddressOverflowException; throws AddressOverflowException;
/**
* Creates a new address by subtracting the displacement to the given address. The
* new address will NOT wrap!
* @param addr the original address.
* @param displacement the displacement to subtract.
* @return The new address created by subtracting the displacement to addr.offset.
* @throws AddressOverflowException if the addition would cause a wrap,
*/
public Address subtractNoWrap(GenericAddress addr, BigInteger displacement)
throws AddressOverflowException;
/** /**
* Creates a new address (possibly in a new space) by adding the given * Creates a new address (possibly in a new space) by adding the given
* displacement from the given address. * displacement from the given address.
@@ -402,7 +408,7 @@ public interface AddressSpace extends Comparable<AddressSpace> {
/** /**
* Get the maximum address allowed for this AddressSpace. * Get the maximum address allowed for this AddressSpace.
* * <p>
* NOTE: Use of this method to identify the region associated with an overlay memory block * NOTE: Use of this method to identify the region associated with an overlay memory block
* within its overlay address space is no longer supported. Defined regions of an overlay space * within its overlay address space is no longer supported. Defined regions of an overlay space
* may now be determined using {@link OverlayAddressSpace#getOverlayAddressSet()}. * may now be determined using {@link OverlayAddressSpace#getOverlayAddressSet()}.
@@ -414,7 +420,7 @@ public interface AddressSpace extends Comparable<AddressSpace> {
/** /**
* Get the minimum address allowed for this AddressSpace. * Get the minimum address allowed for this AddressSpace.
* For a memory space the returned address will have an offset of 0 within this address space. * For a memory space the returned address will have an offset of 0 within this address space.
* * <p>
* NOTE: Use of this method to identify the region associated with an overlay memory block * NOTE: Use of this method to identify the region associated with an overlay memory block
* within its overlay address space is no longer supported. Defined regions of an overlay space * within its overlay address space is no longer supported. Defined regions of an overlay space
* may now be determined using {@link OverlayAddressSpace#getOverlayAddressSet()}. * may now be determined using {@link OverlayAddressSpace#getOverlayAddressSet()}.
@@ -506,22 +512,22 @@ public interface AddressSpace extends Comparable<AddressSpace> {
* *
* @return true if this space has any registers mapped in it. * @return true if this space has any registers mapped in it.
*/ */
boolean hasMappedRegisters(); public boolean hasMappedRegisters();
/** /**
* {@return true if the address should display its addressSpace name} * {@return true if the address should display its addressSpace name}
*/ */
boolean showSpaceName(); public boolean showSpaceName();
/** /**
* {@return true if this addressSpace is an overlay address space} * {@return true if this addressSpace is an overlay address space}
*/ */
boolean isOverlaySpace(); public boolean isOverlaySpace();
/** /**
* {@return true if space uses signed offset} * {@return true if space uses signed offset}
*/ */
boolean hasSignedOffset(); public boolean hasSignedOffset();
/** /**
* Determine if the specific name is a valid address space name (e.g., allowed * Determine if the specific name is a valid address space name (e.g., allowed