Package ghidra.program.database.util
Class AddressRangeMapDB
java.lang.Object
ghidra.program.database.util.AddressRangeMapDB
- All Implemented Interfaces:
DBListener
AddressRangeMapDB
provides a generic value range map backed by a database table.
Values can be stored for ranges of addresses. When a value is stored for a range, it replaces
any previous values for that range. It is kind of like painting. If you first paint a region
red, but then later paint a region in the middle of the red region green, you end up with
three regions - a green region surrounded by two red regions.
This is implemented by storing records for each contiguous range with the same value.
- The key is the encoded start address of the range.
- The TO_COL column of the record stores the encoded end address of the range.
- The VALUE_COL column of the record stores the value for the range.
This implementation is complicated by several issues.
- Addresses stored in Ghidra database records are encoded as long keys (see
AddressMap
). Encoded addresses do not necessarily encode to keys that have the same ordering. Therefore, all comparisons must be done in address space and not in the encoded space. Also, record iterators must use theAddressKeyRecordIterator
which will return records in address order versus encoded key order. - The default space's image base can be changed after records have been created. This can cause the address ranges represented by a record to wrap around. For example, suppose the image base is 0 and you paint a range from address 0 to 0x20, which say maps to keys 0 and 20, respectively. Now suppose the image base changes to 0xfffffffe, which means key 0 maps to address 0xfffffffe and key 0x20 maps to address 0x1e,(the addresses have been effectively shifted down by 2). So now the stored record has a start key of 0 and an end key of 0x20 which now maps to start address of 0xfffffffe and an end address of 0x1e. For our purposes, it is important that we don't just flip the start and end address which be a very large range instead of a small range. Instead, we need to interpret that as 2 ranges (0xfffffffe - 0xffffffff) and (0 - 0x1e). So all methods in this class have be coded to handle this special case. To simplify the painting logic, any wrapping record will first be split into two records before painting. However we can only do this during a write operation (when we can make changes). Since the getter methods and iterators cannot modify the database, they have to deal with wrapping records on the fly.
-
Field Summary
-
Constructor Summary
ConstructorDescriptionAddressRangeMapDB
(DBHandle dbHandle, AddressMap addressMap, Lock lock, String name, ErrorHandler errHandler, Field valueField, boolean indexed) Construct a generic range map -
Method Summary
Modifier and TypeMethodDescriptionvoid
clearRange
(Address startAddr, Address endAddr) Remove values from the given range.void
Database has been closedvoid
dbRestored
(DBHandle dbh) Provides notification that an undo or redo was performed.void
dispose()
Deletes the database table used to store this range map.static boolean
Tests if an AddressRangeMap table exists with the given namegetAddressRangeContaining
(Address address) Returns the bounding address range for the given address where all addresses in that range have the same value (this also works for now value.Returns an address range iterator over all ranges in the map where a value has been setgetAddressRanges
(Address startAddress) Returns an address range iterator over all ranges in the map where a value has been set starting with the given addressgetAddressRanges
(Address startAddress, Address endAddr) Returns an address range iterator over all ranges in the map where a value has been set starting with the given address and ending with the given end addressReturns set of addresses where a values has been setgetAddressSet
(Field value) Returns set of addresses where the given value has been setint
Returns the number of records contained within this map.Returns the value associated with the given addressvoid
Notification that that something may have changed (undo/redo/image base change) and we need to invalidate our cache and possibly have a wrapping record again.boolean
isEmpty()
Returns true if this map is emptyvoid
moveAddressRange
(Address fromAddr, Address toAddr, long length, TaskMonitor monitor) Move all values within an address range to a new range.void
paintRange
(Address startAddress, Address endAddress, Field value) Associates the given value with every address from start to end (inclusive) Any previous associates are overwritten.boolean
Set the name associated with this range mapvoid
tableAdded
(DBHandle dbh, Table table) Provides notification that a table was added.void
tableDeleted
(DBHandle dbh, Table table) Provides notification that a table was deleted.
-
Field Details
-
RANGE_MAP_TABLE_PREFIX
- See Also:
-
-
Constructor Details
-
AddressRangeMapDB
public AddressRangeMapDB(DBHandle dbHandle, AddressMap addressMap, Lock lock, String name, ErrorHandler errHandler, Field valueField, boolean indexed) Construct a generic range map- Parameters:
dbHandle
- database handleaddressMap
- the address maplock
- the program lockname
- map name used in naming the underlying database table This name must be unique across all range mapserrHandler
- database error handlervalueField
- specifies the type for the values stored in this mapindexed
- if true, values will be indexed allowing use of the getValueRangeIterator method
-
-
Method Details
-
exists
Tests if an AddressRangeMap table exists with the given name- Parameters:
dbHandle
- the database handlename
- the name to test for- Returns:
- true if the a table exists for the given name
-
setName
Set the name associated with this range map- Parameters:
newName
- the new name for this range map- Returns:
- true if successful, else false
- Throws:
DuplicateNameException
- if there is already range map with that name
-
isEmpty
public boolean isEmpty()Returns true if this map is empty- Returns:
- true if this map is empty
-
getRecordCount
public int getRecordCount()Returns the number of records contained within this map. NOTE: This number will be greater or equal to the number of address ranges contained within the map.- Returns:
- record count
-
getValue
Returns the value associated with the given address- Parameters:
address
- the address of the value- Returns:
- value or null no value exists
-
paintRange
Associates the given value with every address from start to end (inclusive) Any previous associates are overwritten.- Parameters:
startAddress
- the start address.endAddress
- the end address.value
- value to be painted, or null for value removal.- Throws:
IllegalArgumentException
- if the start and end addresses are not in the same address spaceIllegalArgumentException
- if the end address is greater then the start address
-
moveAddressRange
public void moveAddressRange(Address fromAddr, Address toAddr, long length, TaskMonitor monitor) throws CancelledException Move all values within an address range to a new range.- Parameters:
fromAddr
- the first address of the range to be moved.toAddr
- the address where to the range is to be moved.length
- the number of addresses to move.monitor
- the task monitor.- Throws:
CancelledException
- if the user canceled the operation via the task monitor.
-
clearRange
Remove values from the given range.- Parameters:
startAddr
- the start address.endAddr
- the end address.
-
getAddressSet
Returns set of addresses where a values has been set- Returns:
- set of addresses where a values has been set
-
getAddressSet
Returns set of addresses where the given value has been set- Parameters:
value
- the value to search for- Returns:
- set of addresses where the given value has been set
-
getAddressRanges
Returns an address range iterator over all ranges in the map where a value has been set- Returns:
- AddressRangeIterator that iterates over all occupied ranges in the map
-
getAddressRanges
Returns an address range iterator over all ranges in the map where a value has been set starting with the given address- Parameters:
startAddress
- The address at which to start iterating ranges- Returns:
- AddressRangeIterator that iterates over all occupied ranges in the map from the given start address
-
getAddressRanges
Returns an address range iterator over all ranges in the map where a value has been set starting with the given address and ending with the given end address- Parameters:
startAddress
- the address at which to start iterating rangesendAddr
- the address at which to end the iterator- Returns:
- AddressRangeIterator that iterates over all occupied ranges in the map from the given start address
-
dbRestored
Description copied from interface:DBListener
Provides notification that an undo or redo was performed. During the restore processDBListener.tableAdded(DBHandle, Table)
andDBListener.tableDeleted(DBHandle, Table)
notifications will be supressed. Any listener concerned with tables added or removed should reacquire their table(s).- Specified by:
dbRestored
in interfaceDBListener
- Parameters:
dbh
- associated database handle
-
dbClosed
Description copied from interface:DBListener
Database has been closed- Specified by:
dbClosed
in interfaceDBListener
- Parameters:
dbh
- associated database handle
-
tableDeleted
Description copied from interface:DBListener
Provides notification that a table was deleted. The state of the database may still be in transition and should not be accessed by this callback method.- Specified by:
tableDeleted
in interfaceDBListener
- Parameters:
dbh
- associated database handletable
-
-
tableAdded
Description copied from interface:DBListener
Provides notification that a table was added. The state of the database may still be in transition and should not be accessed by this callback method.- Specified by:
tableAdded
in interfaceDBListener
- Parameters:
dbh
- associated database handletable
-
-
dispose
public void dispose()Deletes the database table used to store this range map. -
invalidate
public void invalidate()Notification that that something may have changed (undo/redo/image base change) and we need to invalidate our cache and possibly have a wrapping record again. -
getAddressRangeContaining
Returns the bounding address range for the given address where all addresses in that range have the same value (this also works for now value. i.e finding a gap)- Parameters:
address
- the address to find a range for- Returns:
- an address range that contains the given address and has all the same value
-