Class Memory
- Author:
- Pete Sanderson, August 2003; Sean Clarke, May 2024
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionstatic class
Class representing an arbitrary contiguous region of memory which contains data.static interface
Interface representing a listener of memory read/write operations.static class
Class representing an arbitrary contiguous region of memory which contains text. -
Field Summary
FieldsModifier and TypeFieldDescriptionstatic final int
MIPS doubleword length in bytes.static final int
MIPS halfword length in bytes.static final int
MIPS word length in bytes. -
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionvoid
addListener
(Memory.Listener listener) Register the given listener to all memory addresses (0x00000000
through0xFFFFFFFF
).void
addListener
(Memory.Listener listener, int address) Register the given listener to a single address.void
addListener
(Memory.Listener listener, int firstAddress, int lastAddress) Register the given listener to a range of memory addresses.static int
alignToNext
(int address, int alignment) Align the given address to the next alignment boundary.static int
alignToPrevious
(int address, int alignment) Align the given address to the previous alignment boundary.int
allocateHeapSpace
(int numBytes) Returns the next available word-aligned heap address.static void
enforceDoublewordAlignment
(int address, int exceptionCause) Ensure that a given address is aligned on a doubleword boundary, throwing an exception otherwise.static void
enforceHalfwordAlignment
(int address, int exceptionCause) Ensure that a given address is aligned on a halfword boundary, throwing an exception otherwise.static void
enforceWordAlignment
(int address, int exceptionCause) Ensure that a given address is aligned on a word boundary, throwing an exception otherwise.int
fetch
(int address, int length, boolean notify) Fetch a byte, halfword, or word from memory at a given address, which must be aligned properly.int
fetchByte
(int address, boolean notify) Fetch a byte from memory at a given address.long
fetchDoubleword
(int address, boolean notify) Fetch a doubleword from memory at a given address, which must be aligned to a word boundary.int
fetchHalfword
(int address, boolean notify) Fetch a halfword from memory at a given address, which must be aligned to a halfword boundary.fetchNullTerminatedString
(int address) Reads a null-terminated string from memory starting at the given address.fetchStatement
(int address, boolean notify) Fetch a statement from memory at a given address, which must be aligned to a word boundary.int
fetchWord
(int address, boolean notify) Fetch a word from memory at a given address, which must be aligned to a word boundary.fetchWordOrNull
(int address) Fetch a word from memory at a given address, which must be aligned to a word boundary.int
getAddress
(int key) int
getAddressOfFirstNullWord
(int firstAddress, int lastAddress) Search for first "null" memory value in an address range, as indicated by the return value offetchWordOrNull(int)
.getDataRegionForAddress
(int address) Get the data memory region a given address is mapped to, if applicable.Get the current endianness (i.e. byte ordering) in use.static Memory
Get the singleton memory instance.int
Get the next address on the heap which will be used for dynamic memory allocation.getTextRegionForAddress
(int address) Get the text memory region a given address is mapped to, if applicable.static boolean
isDoublewordAligned
(int address) Determine whether a given address is aligned on a doubleword boundary.static boolean
isHalfwordAligned
(int address) Determine whether a given address is aligned on a halfword boundary.boolean
isInDataSegment
(int address) Determine whether the given memory address is contained within the data segment, as defined by the current memory configuration.boolean
isInKernelDataSegment
(int address) Determine whether the given memory address is contained within the kernel data segment, as defined by the current memory configuration.boolean
isInKernelTextSegment
(int address) Determine whether the given memory address is contained within the kernel text segment, as defined by the current memory configuration.boolean
isInMemoryMappedIO
(int address) Determine whether the given memory address is contained within the memory-mapped I/O range, as defined by the current memory configuration.boolean
isInTextSegment
(int address) Determine whether the given memory address is contained within the text segment, as defined by the current memory configuration.boolean
Determine whether the current memory configuration fits a 16-bit address space.static boolean
isWordAligned
(int address) Determine whether a given address is aligned on a word boundary.static boolean
rangesIntersect
(int start1, int end1, int start2, int end2) Determine whether two inclusive ranges of unsigned integers intersect.static boolean
rangesMergeable
(int start1, int end1, int start2, int end2) Determine whether two inclusive ranges of unsigned integers can be merged into a single range.void
removeListener
(Memory.Listener listener) Unregister the given listener from all memory addresses it is registered to.void
reset()
Reinitialize the memory contents with the current memory configuration (MemoryConfigurations.getCurrentConfiguration()
) and reset the heap address to its initial state.void
store
(int address, int value, int length, boolean notify) Store a byte, halfword, or word in memory at a given address, which must be aligned properly.void
storeByte
(int address, int value, boolean notify) Store a byte in memory at a given address.void
storeDoubleword
(int address, long value, boolean notify) Store a doubleword in memory at a given address, which must be aligned to a word boundary.void
storeHalfword
(int address, int value, boolean notify) Store a halfword in memory at a given address, which must be aligned to a halfword boundary.void
storeStatement
(int address, BasicStatement statement, boolean notify) Store a statement in memory at a given address, which must be aligned to a word boundary.void
storeWord
(int address, int value, boolean notify) Store a word in memory at a given address, which must be aligned to a word boundary.
-
Field Details
-
BYTES_PER_WORD
public static final int BYTES_PER_WORDMIPS word length in bytes.- See Also:
-
BYTES_PER_HALFWORD
public static final int BYTES_PER_HALFWORDMIPS halfword length in bytes.- See Also:
-
BYTES_PER_DOUBLEWORD
public static final int BYTES_PER_DOUBLEWORDMIPS doubleword length in bytes.- See Also:
-
-
Constructor Details
-
Memory
public Memory()
-
-
Method Details
-
isWordAligned
public static boolean isWordAligned(int address) Determine whether a given address is aligned on a word boundary.- Parameters:
address
- The address to check.- Returns:
- True if address is word-aligned, false otherwise.
-
enforceWordAlignment
public static void enforceWordAlignment(int address, int exceptionCause) throws AddressErrorException Ensure that a given address is aligned on a word boundary, throwing an exception otherwise.- Parameters:
address
- The address to check.exceptionCause
- The cause given if an exception is thrown (usually eitherExceptionCause.ADDRESS_STORE
orExceptionCause.ADDRESS_FETCH
).- Throws:
AddressErrorException
- Thrown if the address is not word-aligned.
-
isHalfwordAligned
public static boolean isHalfwordAligned(int address) Determine whether a given address is aligned on a halfword boundary.- Parameters:
address
- The address to check.- Returns:
- True if address is halfword-aligned, false otherwise.
-
enforceHalfwordAlignment
public static void enforceHalfwordAlignment(int address, int exceptionCause) throws AddressErrorException Ensure that a given address is aligned on a halfword boundary, throwing an exception otherwise.- Parameters:
address
- The address to check.exceptionCause
- The cause given if an exception is thrown (usually eitherExceptionCause.ADDRESS_STORE
orExceptionCause.ADDRESS_FETCH
).- Throws:
AddressErrorException
- Thrown if the address is not halfword-aligned.
-
isDoublewordAligned
public static boolean isDoublewordAligned(int address) Determine whether a given address is aligned on a doubleword boundary.- Parameters:
address
- The address to check.- Returns:
- True if address is doubleword-aligned, false otherwise.
-
enforceDoublewordAlignment
public static void enforceDoublewordAlignment(int address, int exceptionCause) throws AddressErrorException Ensure that a given address is aligned on a doubleword boundary, throwing an exception otherwise.- Parameters:
address
- The address to check.exceptionCause
- The cause given if an exception is thrown (usually eitherExceptionCause.ADDRESS_STORE
orExceptionCause.ADDRESS_FETCH
).- Throws:
AddressErrorException
- Thrown if the address is not doubleword-aligned.
-
alignToNext
public static int alignToNext(int address, int alignment) Align the given address to the next alignment boundary. If the address is already aligned, it is left unchanged.- Parameters:
address
- The memory address to align.alignment
- The alignment required in bytes, which must be a power of 2.- Returns:
- The next address divisible by
alignment
.
-
alignToPrevious
public static int alignToPrevious(int address, int alignment) Align the given address to the previous alignment boundary. If the address is already aligned, it is left unchanged.- Parameters:
address
- The memory address to align.alignment
- The alignment required in bytes, which must be a power of 2.- Returns:
- The previous address divisible by
alignment
.
-
rangesIntersect
public static boolean rangesIntersect(int start1, int end1, int start2, int end2) Determine whether two inclusive ranges of unsigned integers intersect. In order for the ranges to intersect, they must share at least one integer between them; thus, ranges that "touch" but do not overlap are not considered to intersect.For meaningful results, it should hold that
start1
≤end1
andstart2
≤end2
(when treated as unsigned integers).- Parameters:
start1
- The first unsigned integer specified by the first range.end1
- The last unsigned integer specified by the first range.start2
- The first unsigned integer specified by the second range.end2
- The last unsigned integer specified by the second range.- Returns:
true
if the ranges[start1, end1]
and[start2, end2]
share any elements, orfalse
otherwise.- See Also:
-
rangesMergeable
public static boolean rangesMergeable(int start1, int end1, int start2, int end2) Determine whether two inclusive ranges of unsigned integers can be merged into a single range. In order for the ranges to be mergeable, they must either intersect or be adjacent. This is different than the condition forrangesIntersect(int, int, int, int)
since ranges that only "touch" are also considered mergeable.For meaningful results, it should hold that
start1
≤end1
andstart2
≤end2
(when treated as unsigned integers).- Parameters:
start1
- The first unsigned integer specified by the first range.end1
- The last unsigned integer specified by the first range.start2
- The first unsigned integer specified by the second range.end2
- The last unsigned integer specified by the second range.- Returns:
true
if the ranges[start1, end1]
and[start2, end2]
can be merged into a single range, orfalse
otherwise.- See Also:
-
getInstance
Get the singleton memory instance. -
reset
public void reset()Reinitialize the memory contents with the current memory configuration (MemoryConfigurations.getCurrentConfiguration()
) and reset the heap address to its initial state. -
getAddress
public int getAddress(int key) -
getEndianness
Get the current endianness (i.e. byte ordering) in use. This reflects the value ofSettings.useBigEndian
; however, it is only updated whenreset()
is called.- Returns:
- Either
Endianness.LITTLE_ENDIAN
orEndianness.BIG_ENDIAN
.
-
getNextHeapAddress
public int getNextHeapAddress()Get the next address on the heap which will be used for dynamic memory allocation.- Returns:
- The next heap address, which is always word-aligned.
-
allocateHeapSpace
Returns the next available word-aligned heap address. This is roughly equivalent tomalloc
in C. Unfortunately, there is currently no way to deallocate space. (Might be added in the future.)- Parameters:
numBytes
- Number of contiguous bytes to allocate.- Returns:
- Address of the allocated heap storage.
- Throws:
IllegalArgumentException
- Thrown if the number of requested bytes is negative or exceeds available heap storage.
-
isUsingCompactAddressSpace
public boolean isUsingCompactAddressSpace()Determine whether the current memory configuration fits a 16-bit address space.- Returns:
- True if the highest mapped address can be stored in 16 bits, false otherwise.
-
isInTextSegment
public boolean isInTextSegment(int address) Determine whether the given memory address is contained within the text segment, as defined by the current memory configuration.- Parameters:
address
- The byte address to check.- Returns:
- True if the address is within the text segment, false otherwise.
-
isInKernelTextSegment
public boolean isInKernelTextSegment(int address) Determine whether the given memory address is contained within the kernel text segment, as defined by the current memory configuration.- Parameters:
address
- The byte address to check.- Returns:
- True if the address is within the kernel text segment, false otherwise.
-
isInDataSegment
public boolean isInDataSegment(int address) Determine whether the given memory address is contained within the data segment, as defined by the current memory configuration.- Parameters:
address
- The byte address to check.- Returns:
- True if the address is within the data segment, false otherwise.
-
isInKernelDataSegment
public boolean isInKernelDataSegment(int address) Determine whether the given memory address is contained within the kernel data segment, as defined by the current memory configuration.- Parameters:
address
- The byte address to check.- Returns:
- True if the address is within the kernel data segment, false otherwise.
-
isInMemoryMappedIO
public boolean isInMemoryMappedIO(int address) Determine whether the given memory address is contained within the memory-mapped I/O range, as defined by the current memory configuration.- Parameters:
address
- The byte address to check.- Returns:
- True if the address is within the memory-mapped I/O range, false otherwise.
-
getDataRegionForAddress
Get the data memory region a given address is mapped to, if applicable.- Parameters:
address
- The address to find the region for.- Returns:
- The corresponding data region, or null if no data regions use the given address.
-
getTextRegionForAddress
Get the text memory region a given address is mapped to, if applicable.- Parameters:
address
- The address to find the region for.- Returns:
- The corresponding text region, or null if no text regions use the given address.
-
store
Store a byte, halfword, or word in memory at a given address, which must be aligned properly. May write to a memory region containing text, but only ifSettings.selfModifyingCodeEnabled
is set to true.This method simply delegates to
storeByte(int, int, boolean)
,storeHalfword(int, int, boolean)
, orstoreWord(int, int, boolean)
.- Parameters:
address
- Address where memory will be written.value
- Value to be stored at that address.length
- Number of bytes to be written. Must be 1 (single byte),BYTES_PER_HALFWORD
, orBYTES_PER_WORD
. No other values are accepted.notify
- Whether to notify listeners of the write operation.- Throws:
AddressErrorException
- Thrown if the given address is not word-aligned, is out of range, or does not allow this operation.
-
storeWord
Store a word in memory at a given address, which must be aligned to a word boundary. May write to a memory region containing text, but only ifSettings.selfModifyingCodeEnabled
is set to true.- Parameters:
address
- Address of the word where memory will be written.value
- Value to be stored at that address.notify
- Whether to notify listeners of the write operation.- Throws:
AddressErrorException
- Thrown if the given address is not word-aligned, is out of range, or does not allow this operation.
-
storeHalfword
Store a halfword in memory at a given address, which must be aligned to a halfword boundary. May write to a memory region containing text, but only ifSettings.selfModifyingCodeEnabled
is set to true.- Parameters:
address
- Address of the halfword where memory will be written.value
- Value to be stored at that address. (Only the lowest 16 bits are used.)notify
- Whether to notify listeners of the write operation.- Throws:
AddressErrorException
- Thrown if the given address is not halfword-aligned, is out of range, or does not allow this operation.
-
storeByte
Store a byte in memory at a given address. May write to a memory region containing text, but only ifSettings.selfModifyingCodeEnabled
is set to true.- Parameters:
address
- Address of the byte where memory will be written.value
- Value to be stored at that address. (Only the lowest 8 bits are used.)notify
- Whether to notify listeners of the write operation.- Throws:
AddressErrorException
- Thrown if the given address is out of range or does not allow this operation.
-
storeDoubleword
Store a doubleword in memory at a given address, which must be aligned to a word boundary. (Note that aligning to a doubleword boundary is not required.) May write to a memory region containing text, but only ifSettings.selfModifyingCodeEnabled
is set to true.- Parameters:
address
- Address of the first word where memory will be written.value
- Value to be stored at that address.notify
- Whether to notify listeners of the 2 write operations (1 for each word).- Throws:
AddressErrorException
- Thrown if the given address is not word-aligned, is out of range, or does not allow this operation.
-
storeStatement
public void storeStatement(int address, BasicStatement statement, boolean notify) throws AddressErrorException Store a statement in memory at a given address, which must be aligned to a word boundary. May write to a memory region containing data, but only ifSettings.selfModifyingCodeEnabled
is set to true.- Parameters:
address
- Word-aligned address where memory will be written.statement
- Value to be stored at that address.notify
- Whether to notify listeners of the write operation.- Throws:
AddressErrorException
- Thrown if the given address is not word-aligned, is out of range, or does not allow this operation.
-
fetch
Fetch a byte, halfword, or word from memory at a given address, which must be aligned properly. May read from a memory region containing text, even ifSettings.selfModifyingCodeEnabled
is set to false.This method simply delegates to
fetchByte(int, boolean)
,fetchHalfword(int, boolean)
, orfetchWord(int, boolean)
.- Parameters:
address
- Address where memory will be read.length
- Number of bytes to read. Must be 1 (single byte),BYTES_PER_HALFWORD
, orBYTES_PER_WORD
. No other values are accepted.notify
- Whether to notify listeners of the read operation.- Returns:
- The value fetched from memory.
- Throws:
AddressErrorException
- Thrown if the given address is not word-aligned or is out of range.
-
fetchWord
Fetch a word from memory at a given address, which must be aligned to a word boundary. May read from a memory region containing text, even ifSettings.selfModifyingCodeEnabled
is set to false.- Parameters:
address
- Address of the word to fetch.notify
- Whether to notify listeners of the read operation.- Returns:
- The value fetched from memory.
- Throws:
AddressErrorException
- Thrown if the given address is not word-aligned or is out of range.
-
fetchWordOrNull
Fetch a word from memory at a given address, which must be aligned to a word boundary. May read from a memory region containing text, even ifSettings.selfModifyingCodeEnabled
is set to false. Listeners are not notified of a read operation.Returns null if one of the following is true:
- The address lies in a region containing text and there is no instruction at the given address.
- The address lies in a region containing data and the 4-KiB block surrounding it
has not been written to since the last call to
reset()
. - The address lies in an unmapped portion of memory.
This method was originally developed by Greg Giberling of UC Berkeley to support the memory dump feature that he implemented in Fall 2007.
- Parameters:
address
- Word-aligned address where memory will be read.- Returns:
- The value fetched from memory, or null as described above.
- Throws:
AddressErrorException
- Thrown if the given address is not word-aligned.
-
fetchHalfword
Fetch a halfword from memory at a given address, which must be aligned to a halfword boundary. May read from a memory region containing text, even ifSettings.selfModifyingCodeEnabled
is set to false.- Parameters:
address
- Address of the halfword to fetch.notify
- Whether to notify listeners of the read operation.- Returns:
- The zero-extended value fetched from memory. (Only the lowest 16 bits are used.)
- Throws:
AddressErrorException
- Thrown if the given address is not halfword-aligned or is out of range.
-
fetchByte
Fetch a byte from memory at a given address. May read from a memory region containing text, even ifSettings.selfModifyingCodeEnabled
is set to false.- Parameters:
address
- Address of the byte to fetch.notify
- Whether to notify listeners of the read operation.- Returns:
- The zero-extended value fetched from memory. (Only the lowest 8 bits are used.)
- Throws:
AddressErrorException
- Thrown if the given address is out of range.
-
fetchDoubleword
Fetch a doubleword from memory at a given address, which must be aligned to a word boundary. (Note that aligning to a doubleword boundary is not required.) May read from a memory region containing text, even ifSettings.selfModifyingCodeEnabled
is set to false.- Parameters:
address
- Address of the first word to fetch.notify
- Whether to notify listeners of the 2 read operations (1 for each word).- Returns:
- The value fetched from memory.
- Throws:
AddressErrorException
- Thrown if the given address is not word-aligned or is out of range.
-
fetchStatement
Fetch a statement from memory at a given address, which must be aligned to a word boundary. May read from a memory region containing data, but only ifSettings.selfModifyingCodeEnabled
is set to true.- Parameters:
address
- Address of the statement to fetch.notify
- Whether to notify listeners of the read operation.- Returns:
- The statement fetched from memory, or null if no statement exists at the given address.
- Throws:
AddressErrorException
- Thrown if the given address is not word-aligned, is out of range, or does not allow this operation.
-
fetchNullTerminatedString
Reads a null-terminated string from memory starting at the given address.- Parameters:
address
- The address of the first byte in the string.- Returns:
- The string from memory, excluding the null terminator.
- Throws:
AddressErrorException
- If a byte cannot be read at any point.
-
getAddressOfFirstNullWord
public int getAddressOfFirstNullWord(int firstAddress, int lastAddress) throws AddressErrorException Search for first "null" memory value in an address range, as indicated by the return value offetchWordOrNull(int)
.- Parameters:
firstAddress
- First address to be searched; the starting point. Must be word-aligned.lastAddress
- Last address to be searched.- Returns:
- Address of the first word within the specified range that does not contain a value.
- Throws:
AddressErrorException
- Thrown if the first address is not word-aligned.
-
addListener
Register the given listener to all memory addresses (0x00000000
through0xFFFFFFFF
). The listener will be notified when any read/write operations occur anywhere in memory.This is equivalent to calling
addListener(listener, 0x00000000, 0xFFFFFFFF)
.- Parameters:
listener
- The listener to add.
-
addListener
Register the given listener to a single address. The listener will be notified when any read/write operations occur on the byte at that address.This is equivalent to calling
addListener(listener, address, address)
.- Parameters:
listener
- The listener to add.address
- The memory address of the byte to attach the listener to.
-
addListener
Register the given listener to a range of memory addresses. The range is inclusive; that is, all bytes starting atfirstAddress
up to (and including)lastAddress
will notify the listener if a read/write operation occurs.If the
listener
object has already been attached to an adjacent or overlapping range of memory, those ranges will be merged- Parameters:
listener
- The listener to add.firstAddress
- The memory address of the first byte in the range.lastAddress
- The memory address of the last byte in the range.
-
removeListener
Unregister the given listener from all memory addresses it is registered to. The listener will no longer be notified of any read/write operations unless it is added again.- Parameters:
listener
- The listener to remove.
-