Merge remote-tracking branch 'origin/GP-4402_ghidra1_InvalidAddressRanges'

This commit is contained in:
Ryan Kurtz 2024-03-08 08:57:56 -05:00
commit cba4f432c7
15 changed files with 110 additions and 133 deletions

View file

@ -17,8 +17,7 @@ package ghidra.program.database;
import java.io.IOException; import java.io.IOException;
import ghidra.program.model.address.Address; import ghidra.program.model.address.*;
import ghidra.program.model.address.AddressOverflowException;
import ghidra.util.exception.CancelledException; import ghidra.util.exception.CancelledException;
import ghidra.util.task.TaskMonitor; import ghidra.util.task.TaskMonitor;
@ -44,8 +43,8 @@ public interface ManagerDB {
* @throws IOException if a database io error occurs. * @throws IOException if a database io error occurs.
* @throws CancelledException if the user cancelled the operation via the task monitor. * @throws CancelledException if the user cancelled the operation via the task monitor.
*/ */
void programReady(int openMode, int currentRevision, TaskMonitor monitor) throws IOException, void programReady(int openMode, int currentRevision, TaskMonitor monitor)
CancelledException; throws IOException, CancelledException;
/** /**
* Clears all data caches. * Clears all data caches.
@ -59,6 +58,9 @@ public interface ManagerDB {
/** /**
* Delete all objects which have been applied to the address range startAddr to endAddr * Delete all objects which have been applied to the address range startAddr to endAddr
* and update the database accordingly. * and update the database accordingly.
* The specified start and end addresses must form a valid range within
* a single {@link AddressSpace}.
*
* @param startAddr the first address in the range. * @param startAddr the first address in the range.
* @param endAddr the last address in the range. * @param endAddr the last address in the range.
* @param monitor the task monitor to use in any upgrade operations. * @param monitor the task monitor to use in any upgrade operations.
@ -69,6 +71,7 @@ public interface ManagerDB {
/** /**
* Move all objects within an address range to a new location. * Move all objects within an address range to a new location.
*
* @param fromAddr the first address of the range to be moved. * @param fromAddr the first address of the range to be moved.
* @param toAddr the address where to the range is to be moved. * @param toAddr the address where to the range is to be moved.
* @param length the number of addresses to move. * @param length the number of addresses to move.

View file

@ -724,6 +724,8 @@ public class CodeManager implements ErrorHandler, ManagerDB {
public void deleteAddressRange(Address start, Address end, TaskMonitor monitor) public void deleteAddressRange(Address start, Address end, TaskMonitor monitor)
throws CancelledException { throws CancelledException {
AddressRange.checkValidRange(start, end);
// Expand range to include any overlapping or delay-slotted instructions // Expand range to include any overlapping or delay-slotted instructions
CodeUnit cu = getCodeUnitContaining(start); CodeUnit cu = getCodeUnitContaining(start);
if (cu != null) { if (cu != null) {
@ -2194,11 +2196,14 @@ public class CodeManager implements ErrorHandler, ManagerDB {
/** /**
* Clears all comments in the given range (inclusive). * Clears all comments in the given range (inclusive).
* The specified start and end addresses must form a valid range within
* a single {@link AddressSpace}.
* *
* @param start the start address of the range to clear * @param start the start address of the range to clear
* @param end the end address of the range to clear * @param end the end address of the range to clear
*/ */
public void clearComments(Address start, Address end) { public void clearComments(Address start, Address end) {
AddressRange.checkValidRange(start, end);
lock.acquire(); lock.acquire();
try { try {
try { try {
@ -2227,6 +2232,8 @@ public class CodeManager implements ErrorHandler, ManagerDB {
/** /**
* Clears the properties in the given range (inclusive). * Clears the properties in the given range (inclusive).
* The specified start and end addresses must form a valid range within
* a single {@link AddressSpace}.
* *
* @param start the start address of the range to clear * @param start the start address of the range to clear
* @param end the end address of the range to clear * @param end the end address of the range to clear
@ -2289,6 +2296,9 @@ public class CodeManager implements ErrorHandler, ManagerDB {
/** /**
* Remove code units, symbols, equates, and references to code units in the given range * Remove code units, symbols, equates, and references to code units in the given range
* (inclusive). Comments and comment history will be retained. * (inclusive). Comments and comment history will be retained.
* The specified start and end addresses must form a valid range within
* a single {@link AddressSpace}.
*
* @param start the start address of the range to clear * @param start the start address of the range to clear
* @param end the end address of the range to clear * @param end the end address of the range to clear
* @param clearContext if true all context-register values will be cleared over range * @param clearContext if true all context-register values will be cleared over range
@ -2297,6 +2307,7 @@ public class CodeManager implements ErrorHandler, ManagerDB {
*/ */
public void clearCodeUnits(Address start, Address end, boolean clearContext, public void clearCodeUnits(Address start, Address end, boolean clearContext,
TaskMonitor monitor) throws CancelledException { TaskMonitor monitor) throws CancelledException {
AddressRange.checkValidRange(start, end);
lock.acquire(); lock.acquire();
try { try {
// Expand range to include any overlapping or delay-slotted instructions // Expand range to include any overlapping or delay-slotted instructions
@ -2336,10 +2347,10 @@ public class CodeManager implements ErrorHandler, ManagerDB {
* @param monitor the task monitor * @param monitor the task monitor
*/ */
public void clearAll(boolean clearContext, TaskMonitor monitor) { public void clearAll(boolean clearContext, TaskMonitor monitor) {
Address minAddr = program.getMinAddress();
Address maxAddr = program.getMaxAddress();
try { try {
clearCodeUnits(minAddr, maxAddr, clearContext, monitor); for (AddressRange range : program.getMemory().getAddressRanges()) {
clearCodeUnits(range.getMinAddress(), range.getMaxAddress(), clearContext, monitor);
}
} }
catch (CancelledException e) { catch (CancelledException e) {
// nothing to do // nothing to do
@ -2571,17 +2582,18 @@ public class CodeManager implements ErrorHandler, ManagerDB {
} }
/** /**
* Check if any instruction intersects the specified address range * Check if any instruction intersects the specified address range.
* The specified start and end addresses must form a valid range within
* a single {@link AddressSpace}.
*
* @param start start of range * @param start start of range
* @param end end of range * @param end end of range
* @throws ContextChangeException if there is a context register change conflict * @throws ContextChangeException if there is a context register change conflict
*/ */
public void checkContextWrite(Address start, Address end) throws ContextChangeException { public void checkContextWrite(Address start, Address end) throws ContextChangeException {
AddressRange.checkValidRange(start, end);
lock.acquire(); lock.acquire();
try { try {
if (!start.getAddressSpace().equals(end.getAddressSpace())) {
throw new IllegalArgumentException();
}
if (!contextLockingEnabled || creatingInstruction || if (!contextLockingEnabled || creatingInstruction ||
!program.getMemory().contains(start, end)) { !program.getMemory().contains(start, end)) {
return; return;

View file

@ -22,8 +22,7 @@ import db.*;
import db.util.ErrorHandler; import db.util.ErrorHandler;
import ghidra.docking.settings.SettingsDefinition; import ghidra.docking.settings.SettingsDefinition;
import ghidra.program.database.map.AddressMap; import ghidra.program.database.map.AddressMap;
import ghidra.program.model.address.Address; import ghidra.program.model.address.*;
import ghidra.program.model.address.KeyRange;
import ghidra.program.model.data.*; import ghidra.program.model.data.*;
import ghidra.program.model.listing.Data; import ghidra.program.model.listing.Data;
import ghidra.util.Lock; import ghidra.util.Lock;
@ -66,12 +65,12 @@ public abstract class ProgramBasedDataTypeManagerDB extends DataTypeManagerDB
super(handle, addrMap, openMode, tablePrefix, errHandler, lock, monitor); super(handle, addrMap, openMode, tablePrefix, errHandler, lock, monitor);
} }
@Override
protected void initializeOtherAdapters(int openMode, TaskMonitor monitor) protected void initializeOtherAdapters(int openMode, TaskMonitor monitor)
throws CancelledException, IOException, VersionException { throws CancelledException, IOException, VersionException {
if (addrMap != null) { if (addrMap != null) {
instanceSettingsAdapter = instanceSettingsAdapter = SettingsDBAdapter.getAdapter(
SettingsDBAdapter.getAdapter(tablePrefix + INSTANCE_SETTINGS_TABLE_NAME, dbHandle, tablePrefix + INSTANCE_SETTINGS_TABLE_NAME, dbHandle, openMode, addrMap, monitor);
openMode, addrMap, monitor);
} }
} }
@ -97,8 +96,7 @@ public abstract class ProgramBasedDataTypeManagerDB extends DataTypeManagerDB
abstract protected void dataSettingChanged(Address address); abstract protected void dataSettingChanged(Address address);
@Override @Override
public boolean isChangeAllowed(Data data, public boolean isChangeAllowed(Data data, SettingsDefinition settingsDefinition) {
SettingsDefinition settingsDefinition) {
if (settingsDefinition instanceof TypeDefSettingsDefinition) { if (settingsDefinition instanceof TypeDefSettingsDefinition) {
return false; return false;
} }
@ -261,9 +259,8 @@ public abstract class ProgramBasedDataTypeManagerDB extends DataTypeManagerDB
monitor.checkCancelled(); monitor.checkCancelled();
DBRecord rec = iter.next(); DBRecord rec = iter.next();
// update address key (i.e., settings association ID) and re-introduce into table // update address key (i.e., settings association ID) and re-introduce into table
Address addr = addrMap Address addr = addrMap.decodeAddress(
.decodeAddress( rec.getLongValue(SettingsDBAdapter.SETTINGS_ASSOCIATION_ID_COL));
rec.getLongValue(SettingsDBAdapter.SETTINGS_ASSOCIATION_ID_COL));
long offset = addr.subtract(fromAddr); long offset = addr.subtract(fromAddr);
addr = toAddr.add(offset); addr = toAddr.add(offset);
rec.setLongValue(SettingsDBAdapter.SETTINGS_ASSOCIATION_ID_COL, rec.setLongValue(SettingsDBAdapter.SETTINGS_ASSOCIATION_ID_COL,
@ -410,6 +407,7 @@ public abstract class ProgramBasedDataTypeManagerDB extends DataTypeManagerDB
if (instanceSettingsAdapter == null) { if (instanceSettingsAdapter == null) {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
AddressRange.checkValidRange(startAddr, endAddr);
lock.acquire(); lock.acquire();
try { try {
List<?> addrKeyRanges = addrMap.getKeyRanges(startAddr, endAddr, false); List<?> addrKeyRanges = addrMap.getKeyRanges(startAddr, endAddr, false);

View file

@ -98,9 +98,7 @@ public class TreeManager implements ManagerDB {
public void imageBaseChanged(boolean commit) { public void imageBaseChanged(boolean commit) {
lock.acquire(); lock.acquire();
try { try {
Iterator<ModuleManager> iter = treeMap.values().iterator(); for (ModuleManager m : treeMap.values()) {
while (iter.hasNext()) {
ModuleManager m = iter.next();
m.imageBaseChanged(commit); m.imageBaseChanged(commit);
} }
} }
@ -376,6 +374,7 @@ public class TreeManager implements ManagerDB {
@Override @Override
public void deleteAddressRange(Address startAddr, Address endAddr, TaskMonitor monitor) public void deleteAddressRange(Address startAddr, Address endAddr, TaskMonitor monitor)
throws CancelledException { throws CancelledException {
AddressRange.checkValidRange(startAddr, endAddr);
lock.acquire(); lock.acquire();
try { try {
Iterator<String> keys = treeMap.keySet().iterator(); Iterator<String> keys = treeMap.keySet().iterator();

View file

@ -28,6 +28,7 @@ import ghidra.program.database.ProgramDB;
import ghidra.program.database.bookmark.OldBookmark; import ghidra.program.database.bookmark.OldBookmark;
import ghidra.program.database.map.AddressMap; import ghidra.program.database.map.AddressMap;
import ghidra.program.model.address.Address; import ghidra.program.model.address.Address;
import ghidra.program.model.address.AddressRange;
import ghidra.program.model.listing.BookmarkManager; import ghidra.program.model.listing.BookmarkManager;
import ghidra.program.model.util.*; import ghidra.program.model.util.*;
import ghidra.program.util.ChangeManager; import ghidra.program.util.ChangeManager;
@ -576,9 +577,7 @@ public class DBPropertyMapManager implements PropertyMapManager, ManagerDB {
public void removeAll(Address addr) { public void removeAll(Address addr) {
lock.acquire(); lock.acquire();
try { try {
Iterator<PropertyMapDB<?>> iter = propertyMapCache.values().iterator(); for (PropertyMapDB<?> pm : propertyMapCache.values()) {
while (iter.hasNext()) {
PropertyMapDB<?> pm = iter.next();
pm.remove(addr); pm.remove(addr);
} }
@ -591,15 +590,13 @@ public class DBPropertyMapManager implements PropertyMapManager, ManagerDB {
@Override @Override
public void removeAll(Address startAddr, Address endAddr, TaskMonitor monitor) public void removeAll(Address startAddr, Address endAddr, TaskMonitor monitor)
throws CancelledException { throws CancelledException {
AddressRange.checkValidRange(startAddr, endAddr);
lock.acquire(); lock.acquire();
try { try {
Iterator<PropertyMapDB<?>> iter = propertyMapCache.values().iterator(); for (PropertyMapDB<?> pm : propertyMapCache.values()) {
while (iter.hasNext()) {
monitor.checkCancelled(); monitor.checkCancelled();
PropertyMapDB<?> pm = iter.next();
pm.removeRange(startAddr, endAddr); pm.removeRange(startAddr, endAddr);
} }
} }
finally { finally {
lock.release(); lock.release();
@ -611,13 +608,10 @@ public class DBPropertyMapManager implements PropertyMapManager, ManagerDB {
throws CancelledException { throws CancelledException {
lock.acquire(); lock.acquire();
try { try {
Iterator<PropertyMapDB<?>> iter = propertyMapCache.values().iterator(); for (PropertyMapDB<?> pm : propertyMapCache.values()) {
while (iter.hasNext()) {
monitor.checkCancelled(); monitor.checkCancelled();
PropertyMapDB<?> pm = iter.next();
pm.moveRange(fromAddr, fromAddr.add(length - 1), toAddr); pm.moveRange(fromAddr, fromAddr.add(length - 1), toAddr);
} }
} }
finally { finally {
lock.release(); lock.release();

View file

@ -210,6 +210,7 @@ public class ProgramRegisterContextDB extends AbstractStoredProgramContext imple
@Override @Override
public void deleteAddressRange(Address start, Address end, TaskMonitor monitor) { public void deleteAddressRange(Address start, Address end, TaskMonitor monitor) {
AddressRange.checkValidRange(start, end);
lock.acquire(); lock.acquire();
try { try {
super.deleteAddressRange(start, end, monitor); super.deleteAddressRange(start, end, monitor);

View file

@ -312,6 +312,7 @@ public class EquateManager implements EquateTable, ErrorHandler, ManagerDB {
@Override @Override
public void deleteAddressRange(Address startAddr, Address endAddr, TaskMonitor monitor) public void deleteAddressRange(Address startAddr, Address endAddr, TaskMonitor monitor)
throws CancelledException { throws CancelledException {
AddressRange.checkValidRange(startAddr, endAddr);
lock.acquire(); lock.acquire();
try { try {
ArrayList<EquateRefDB> list = new ArrayList<>(); ArrayList<EquateRefDB> list = new ArrayList<>();

View file

@ -2427,6 +2427,7 @@ public class SymbolManager implements SymbolTable, ManagerDB {
@Override @Override
public void deleteAddressRange(Address startAddr, Address endAddr, TaskMonitor monitor) public void deleteAddressRange(Address startAddr, Address endAddr, TaskMonitor monitor)
throws CancelledException { throws CancelledException {
AddressRange.checkValidRange(startAddr, endAddr);
lock.acquire(); lock.acquire();
try { try {
invalidateCache(true); invalidateCache(true);

View file

@ -214,13 +214,7 @@ public class AddressRangeMapDB implements DBListener {
* @throws IllegalArgumentException if the end address is greater then the start address * @throws IllegalArgumentException if the end address is greater then the start address
*/ */
public void paintRange(Address startAddress, Address endAddress, Field value) { public void paintRange(Address startAddress, Address endAddress, Field value) {
if (!startAddress.hasSameAddressSpace(endAddress)) { AddressRange.checkValidRange(startAddress, endAddress);
throw new IllegalArgumentException("Addresses must be in the same space!");
}
if (startAddress.compareTo(endAddress) > 0) {
throw new IllegalArgumentException("Start address must be <= end address!");
}
lock.acquire(); lock.acquire();
try { try {
clearCache(); clearCache();
@ -566,8 +560,7 @@ public class AddressRangeMapDB implements DBListener {
record = getRecordAfter(address); record = getRecordAfter(address);
if (record != null) { if (record != null) {
Address startAddress = getStartAddress(record); Address startAddress = getStartAddress(record);
if (startAddress.hasSameAddressSpace(address) && if (startAddress.hasSameAddressSpace(address) && startAddress.compareTo(address) > 0) {
startAddress.compareTo(address) > 0) {
gapEnd = startAddress.subtract(1); gapEnd = startAddress.subtract(1);
} }
} }

View file

@ -101,4 +101,25 @@ public interface AddressRange extends Comparable<AddressRange>, Iterable<Address
*/ */
public AddressSpace getAddressSpace(); public AddressSpace getAddressSpace();
/**
* Change the specified start and end addresses to see if they form a valid
* range within the same {@link AddressSpace}.
* @param start range start address
* @param end range end address
*/
public static void checkValidRange(Address start, Address end) {
if (start == null || end == null) {
throw new IllegalArgumentException("Null start or end address was specified");
}
if (!start.getAddressSpace().equals(end.getAddressSpace())) {
throw new IllegalArgumentException(
"Start and end addresses must be in same address space! Start " + start +
" end = " + end);
}
if (start.compareTo(end) > 0) {
throw new IllegalArgumentException("Start address must be less than or equal to " +
"end address: Start " + start + " end = " + end);
}
}
} }

View file

@ -39,16 +39,6 @@ public class AddressSet implements AddressSetView {
public AddressSet() { public AddressSet() {
} }
/**
* Create a new empty Address Set.
* @param factory NOT USED.
* @deprecated use {@link #AddressSet()} (will be kept until at least Ghidra 6.2)
*/
@Deprecated
public AddressSet(AddressFactory factory) {
this();
}
/** /**
* Create a new Address Set from an address range. * Create a new Address Set from an address range.
* @param range the range of addresses to include in this set. * @param range the range of addresses to include in this set.
@ -57,19 +47,11 @@ public class AddressSet implements AddressSetView {
add(range); add(range);
} }
/**
* Create a new Address Set from an address range.
* @param factory NOT USED.
* @param range the range of addresses to include in this set.
* @deprecated use {@link #AddressSet(AddressRange)} (will be kept until at least Ghidra 6.2)
*/
@Deprecated
public AddressSet(AddressFactory factory, AddressRange range) {
add(range);
}
/** /**
* Creates a new Address set containing a single range * Creates a new Address set containing a single range
* The specified start and end addresses must form a valid range within
* a single {@link AddressSpace}.
*
* @param start the start address of the range * @param start the start address of the range
* @param end the end address of the range * @param end the end address of the range
* @throws IllegalArgumentException if the start and end addresses are in different spaces. To * @throws IllegalArgumentException if the start and end addresses are in different spaces. To
@ -80,19 +62,11 @@ public class AddressSet implements AddressSetView {
} }
/** /**
* Creates a new Address set containing a single range * Creates a new Address set containing a single range.
* @param start the start address of the range * Use of this method is generally discouraged since the set of addresses between a start and
* @param end the end address of the range * end address not contained within the same {@link AddressSpace} may be contain unexpected
* @param factory NOT USED. * memory regions.
* @deprecated use {@link #AddressSet(Address, Address)} (will be kept until at least Ghidra 6.2) *
*/
@Deprecated
public AddressSet(AddressFactory factory, Address start, Address end) {
addRange(start, end);
}
/**
* Creates a new Address set containing a single range
* @param start the start address of the range * @param start the start address of the range
* @param end the end address of the range * @param end the end address of the range
* @param program the program whose AddressFactory is used to resolve address ranges where the * @param program the program whose AddressFactory is used to resolve address ranges where the
@ -104,17 +78,6 @@ public class AddressSet implements AddressSetView {
addRange(program, start, end); addRange(program, start, end);
} }
/**
* Create a new Address Set from an existing Address Set.
* @param set Existing Address Set to clone.
* @param factory NOT USED.
* @deprecated use {@link #AddressSet(AddressSetView)} (will be kept until at least Ghidra 6.2)
*/
@Deprecated
public AddressSet(AddressFactory factory, AddressSetView set) {
add(set);
}
/** /**
* Create a new Address Set from an existing Address Set. * Create a new Address Set from an existing Address Set.
* @param set Existing Address Set to clone. * @param set Existing Address Set to clone.
@ -123,17 +86,6 @@ public class AddressSet implements AddressSetView {
add(set); add(set);
} }
/**
* Create a new Address containing a single address.
* @param addr the address to be included in this address set.
* @param factory NOT USED.
* @deprecated use {@link #AddressSet(Address)} (will be kept until at least Ghidra 6.2)
*/
@Deprecated
public AddressSet(AddressFactory factory, Address addr) {
this(addr, addr);
}
/** /**
* Create a new Address containing a single address. * Create a new Address containing a single address.
* @param addr the address to be included in this address set. * @param addr the address to be included in this address set.
@ -167,7 +119,7 @@ public class AddressSet implements AddressSetView {
* @param end the end address of the range to add * @param end the end address of the range to add
*/ */
public void add(Address start, Address end) { public void add(Address start, Address end) {
checkValidRange(start, end); AddressRange.checkValidRange(start, end);
if (lastNode != null && !lastNode.isDisposed()) { if (lastNode != null && !lastNode.isDisposed()) {
Address value = lastNode.getValue(); Address value = lastNode.getValue();
@ -422,6 +374,8 @@ public class AddressSet implements AddressSetView {
@Override @Override
public final boolean contains(Address start, Address end) { public final boolean contains(Address start, Address end) {
AddressRange.checkValidRange(start, end);
// See if there is a tree node whose range encapsulates the given range. // See if there is a tree node whose range encapsulates the given range.
RedBlackEntry<Address, Address> entry = rbTree.getEntryLessThanEqual(start); RedBlackEntry<Address, Address> entry = rbTree.getEntryLessThanEqual(start);
if (entry == null) { if (entry == null) {
@ -1136,10 +1090,6 @@ public class AddressSet implements AddressSetView {
return newSet; return newSet;
} }
private AddressRange getRange(RedBlackEntry<Address, Address> entry) {
return new AddressRangeImpl(entry.getKey(), entry.getValue());
}
private boolean contains(RedBlackEntry<Address, Address> entry, Address start) { private boolean contains(RedBlackEntry<Address, Address> entry, Address start) {
return entry.getKey().compareTo(start) <= 0 && entry.getValue().compareTo(start) >= 0; return entry.getKey().compareTo(start) <= 0 && entry.getValue().compareTo(start) >= 0;
} }
@ -1193,23 +1143,6 @@ public class AddressSet implements AddressSetView {
} }
private void checkValidRange(Address start, Address end) {
if (start == null || end == null) {
throw new IllegalArgumentException("Attempted to add a null address to this set.");
}
if (start.compareTo(end) > 0) {
throw new IllegalArgumentException("Start address must be less than or equal to " +
"end address: Start " + start + " end = " + end);
}
if (!start.getAddressSpace().equals(end.getAddressSpace())) {
throw new IllegalArgumentException(
"Start and end addresses must be in same address space! Start " + start +
" end = " + end);
}
}
private RedBlackEntry<Address, Address> createRangeNode(Address start, Address end) { private RedBlackEntry<Address, Address> createRangeNode(Address start, Address end) {
RedBlackEntry<Address, Address> newEntry = rbTree.getOrCreateEntry(start); RedBlackEntry<Address, Address> newEntry = rbTree.getOrCreateEntry(start);
newEntry.setValue(end); newEntry.setValue(end);

View file

@ -33,6 +33,8 @@ public interface AddressSetView extends Iterable<AddressRange> {
/** /**
* Test if the given address range is contained in this set. * Test if the given address range is contained in this set.
* The specified start and end addresses must form a valid range within
* a single {@link AddressSpace}.
* <P> * <P>
* @param start the first address in the range. * @param start the first address in the range.
* @param end the last address in the range. * @param end the last address in the range.
@ -56,11 +58,19 @@ public interface AddressSetView extends Iterable<AddressRange> {
public boolean isEmpty(); public boolean isEmpty();
/** /**
* Get the minimum address for this address set.
* NOTE: An {@link AddressRange} should generally not be formed using this address
* and {@link #getMaxAddress()} since it may span multiple {@link AddressSpace}s.
*
* @return the minimum address for this set. Returns null if the set is empty. * @return the minimum address for this set. Returns null if the set is empty.
*/ */
public Address getMinAddress(); public Address getMinAddress();
/** /**
* Get the maximum address for this address set.
* NOTE: An {@link AddressRange} should generally not be formed using this address
* and {@link #getMaxAddress()} since it may span multiple {@link AddressSpace}s.
*
* @return the maximum address for this set. Returns null if the set is empty. * @return the maximum address for this set. Returns null if the set is empty.
*/ */
public Address getMaxAddress(); public Address getMaxAddress();
@ -151,8 +161,9 @@ public interface AddressSetView extends Iterable<AddressRange> {
public boolean intersects(AddressSetView addrSet); public boolean intersects(AddressSetView addrSet);
/** /**
* Determine if the start and end range * Determine if the start and end range intersects with the specified address set.
* intersects with the specified address set. * The specified start and end addresses must form a valid range within
* a single {@link AddressSpace}.
* @param start start of range * @param start start of range
* @param end end of range * @param end end of range
* @return true if the given range intersects this address set. * @return true if the given range intersects this address set.
@ -171,6 +182,8 @@ public interface AddressSetView extends Iterable<AddressRange> {
/** /**
* Computes the intersection of this address set with the given address range. * Computes the intersection of this address set with the given address range.
* This method does not modify this address set. * This method does not modify this address set.
* The specified start and end addresses must form a valid range within
* a single {@link AddressSpace}.
* @param start start of range * @param start start of range
* @param end end of range * @param end end of range
* @return AddressSet a new address set that contains all addresses that are * @return AddressSet a new address set that contains all addresses that are

View file

@ -305,7 +305,10 @@ public interface Program extends DataTypeManagerDomainObject, ProgramArchitectur
public ProgramContext getProgramContext(); public ProgramContext getProgramContext();
/** /**
* get the program's minimum address. * Get the program's minimum address.
* NOTE: An {@link AddressRange} should generally not be formed using this address
* and {@link #getMaxAddress()} since it may span multiple {@link AddressSpace}s.
*
* @return the program's minimum address or null if no memory blocks * @return the program's minimum address or null if no memory blocks
* have been defined in the program. * have been defined in the program.
*/ */
@ -313,6 +316,9 @@ public interface Program extends DataTypeManagerDomainObject, ProgramArchitectur
/** /**
* Get the programs maximum address. * Get the programs maximum address.
* NOTE: An {@link AddressRange} should generally not be formed using this address
* and {@link #getMinAddress()} since it may span multiple {@link AddressSpace}s.
*
* @return the program's maximum address or null if no memory blocks * @return the program's maximum address or null if no memory blocks
* have been defined in the program. * have been defined in the program.
*/ */

View file

@ -18,6 +18,7 @@ package ghidra.program.model.util;
import java.util.Iterator; import java.util.Iterator;
import ghidra.program.model.address.Address; import ghidra.program.model.address.Address;
import ghidra.program.model.address.AddressSpace;
import ghidra.util.Saveable; import ghidra.util.Saveable;
import ghidra.util.exception.CancelledException; import ghidra.util.exception.CancelledException;
import ghidra.util.exception.DuplicateNameException; import ghidra.util.exception.DuplicateNameException;
@ -153,7 +154,10 @@ public interface PropertyMapManager {
/** /**
* Removes all properties in the given range from all user * Removes all properties in the given range from all user
* defined PropertyMaps. * defined PropertyMaps.
* The specified start and end addresses must form a valid range within
* a single {@link AddressSpace}.
*
* @param startAddr the first address in the range of addresses where * @param startAddr the first address in the range of addresses where
* propertie values are to be removed. * propertie values are to be removed.
* @param endAddr the last address in the range of addresses where * @param endAddr the last address in the range of addresses where

View file

@ -152,9 +152,7 @@ public class RegisterValueStore {
while (rangeIt.hasNext()) { while (rangeIt.hasNext()) {
list.add(rangeIt.next()); list.add(rangeIt.next());
} }
Iterator<AddressRange> it = list.iterator(); for (AddressRange indexRange : list) {
while (it.hasNext()) {
AddressRange indexRange = it.next();
Address rangeStart = indexRange.getMinAddress(); Address rangeStart = indexRange.getMinAddress();
Address rangeEnd = indexRange.getMaxAddress(); Address rangeEnd = indexRange.getMaxAddress();
if (rangeStart.compareTo(start) > 0) { if (rangeStart.compareTo(start) > 0) {
@ -194,6 +192,8 @@ public class RegisterValueStore {
*/ */
public void clearValue(Address start, Address end, Register register) { public void clearValue(Address start, Address end, Register register) {
AddressRange.checkValidRange(start, end);
flushWriteCache(); flushWriteCache();
// if the mask is all on, then just clear any values that are stored in this range // if the mask is all on, then just clear any values that are stored in this range
@ -208,9 +208,7 @@ public class RegisterValueStore {
while (rangeIt.hasNext()) { while (rangeIt.hasNext()) {
list.add(rangeIt.next()); list.add(rangeIt.next());
} }
Iterator<AddressRange> it = list.iterator(); for (AddressRange indexRange : list) {
while (it.hasNext()) {
AddressRange indexRange = it.next();
Address rangeStart = indexRange.getMinAddress(); Address rangeStart = indexRange.getMinAddress();
Address rangeEnd = indexRange.getMaxAddress(); Address rangeEnd = indexRange.getMaxAddress();
@ -243,7 +241,7 @@ public class RegisterValueStore {
if (bytes != null) { if (bytes != null) {
value = new RegisterValue(register, bytes); value = new RegisterValue(register, bytes);
} }
synchronized (this) { synchronized (this) {
if (rangeWriteCacheValue != null && address.compareTo(rangeWriteCacheMin) >= 0 && if (rangeWriteCacheValue != null && address.compareTo(rangeWriteCacheMin) >= 0 &&
address.compareTo(rangeWriteCacheMax) <= 0) { address.compareTo(rangeWriteCacheMax) <= 0) {